Replace tabs with 4 spaces in all remaining OST code, since this inconsistency can now result in 'misleading indentation' warnings in GCC 6.0+.
This commit is contained in:
parent
5819201c68
commit
728795af3d
|
@ -32,10 +32,10 @@
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// archive.cpp -- classes that abstract a raw byte archive
|
// archive.cpp -- classes that abstract a raw byte archive
|
||||||
//
|
//
|
||||||
// cArchive -- interface for single-direction (one pass) reads and writes
|
// cArchive -- interface for single-direction (one pass) reads and writes
|
||||||
// cBidirArchive -- interface for a random-access archive
|
// cBidirArchive -- interface for a random-access archive
|
||||||
// cMemArchive -- implementation of a bidirectional archive in memory
|
// cMemArchive -- implementation of a bidirectional archive in memory
|
||||||
// cFileArchive -- implementation of a bidirectional archive as a file
|
// cFileArchive -- implementation of a bidirectional archive as a file
|
||||||
|
|
||||||
#include "stdcore.h"
|
#include "stdcore.h"
|
||||||
#include "archive.h"
|
#include "archive.h"
|
||||||
|
@ -219,34 +219,34 @@ void cArchive::WriteBlob(const void* pBlob, int count) // throw(eArchive)
|
||||||
|
|
||||||
int32 cArchive::GetStorageSize(const TSTRING& str)
|
int32 cArchive::GetStorageSize(const TSTRING& str)
|
||||||
{
|
{
|
||||||
int32 size = sizeof(int32); // the length is always stored
|
int32 size = sizeof(int32); // the length is always stored
|
||||||
//
|
//
|
||||||
// after the length, all of the characters in the string are written as 16-bit values,
|
// after the length, all of the characters in the string are written as 16-bit values,
|
||||||
// except for the null character
|
// except for the null character
|
||||||
//
|
//
|
||||||
size += ( str.length() * 2 );
|
size += ( str.length() * 2 );
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 cArchive::Copy(cArchive* pFrom, int64 amt)
|
int64 cArchive::Copy(cArchive* pFrom, int64 amt)
|
||||||
{
|
{
|
||||||
enum { BUF_SIZE = 2048 };
|
enum { BUF_SIZE = 2048 };
|
||||||
int8 buf[BUF_SIZE];
|
int8 buf[BUF_SIZE];
|
||||||
int64 amtLeft = amt;
|
int64 amtLeft = amt;
|
||||||
|
|
||||||
while(amtLeft > 0)
|
while(amtLeft > 0)
|
||||||
{
|
{
|
||||||
int64 amtToRead = amtLeft > (int64)BUF_SIZE ? (int64)BUF_SIZE : amtLeft;
|
int64 amtToRead = amtLeft > (int64)BUF_SIZE ? (int64)BUF_SIZE : amtLeft;
|
||||||
int64 amtRead = pFrom->ReadBlob(buf, static_cast<int>( amtToRead ) );
|
int64 amtRead = pFrom->ReadBlob(buf, static_cast<int>( amtToRead ) );
|
||||||
amtLeft -= amtRead;
|
amtLeft -= amtRead;
|
||||||
WriteBlob(buf, static_cast<int>( amtRead ) );
|
WriteBlob(buf, static_cast<int>( amtRead ) );
|
||||||
if(amtRead < amtToRead)
|
if(amtRead < amtToRead)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return the amount copied ...
|
// return the amount copied ...
|
||||||
return (amt - amtLeft);
|
return (amt - amtLeft);
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -429,7 +429,7 @@ void cMemoryArchive::AllocateMemory(int len) // throw(eArchive)
|
||||||
if (len > mAllocatedLen)
|
if (len > mAllocatedLen)
|
||||||
{
|
{
|
||||||
// grow the buffer
|
// grow the buffer
|
||||||
// only error if we are in debug mode
|
// only error if we are in debug mode
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
if (len > mMaxAllocatedLen)
|
if (len > mMaxAllocatedLen)
|
||||||
ThrowAndAssert(eArchiveOutOfMem());
|
ThrowAndAssert(eArchiveOutOfMem());
|
||||||
|
@ -486,9 +486,9 @@ class cFixedMemArchive : public cBidirArchive
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
int8* mpMemory;
|
int8* mpMemory;
|
||||||
int32 mSize;
|
int32 mSize;
|
||||||
int32 mReadHead;
|
int32 mReadHead;
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -496,18 +496,18 @@ public:
|
||||||
// cFixedMemArchive
|
// cFixedMemArchive
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
cFixedMemArchive::cFixedMemArchive()
|
cFixedMemArchive::cFixedMemArchive()
|
||||||
: mpMemory (0),
|
: mpMemory (0),
|
||||||
mSize (0),
|
mSize (0),
|
||||||
mReadHead (0)
|
mReadHead (0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
cFixedMemArchive::cFixedMemArchive( int8* pMem, int32 size )
|
cFixedMemArchive::cFixedMemArchive( int8* pMem, int32 size )
|
||||||
: mpMemory (0),
|
: mpMemory (0),
|
||||||
mSize (0),
|
mSize (0),
|
||||||
mReadHead (0)
|
mReadHead (0)
|
||||||
{
|
{
|
||||||
Attach( pMem, size );
|
Attach( pMem, size );
|
||||||
}
|
}
|
||||||
|
|
||||||
cFixedMemArchive::~cFixedMemArchive()
|
cFixedMemArchive::~cFixedMemArchive()
|
||||||
|
@ -516,9 +516,9 @@ cFixedMemArchive::~cFixedMemArchive()
|
||||||
|
|
||||||
void cFixedMemArchive::Attach( int8* pMem, int32 size )
|
void cFixedMemArchive::Attach( int8* pMem, int32 size )
|
||||||
{
|
{
|
||||||
mpMemory = pMem;
|
mpMemory = pMem;
|
||||||
mSize = size;
|
mSize = size;
|
||||||
mReadHead = 0;
|
mReadHead = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cFixedMemArchive::Seek(int64 offset, SeekFrom from) // throw(eArchive)
|
void cFixedMemArchive::Seek(int64 offset, SeekFrom from) // throw(eArchive)
|
||||||
|
@ -545,28 +545,28 @@ void cFixedMemArchive::Seek(int64 offset, SeekFrom from) // throw(eArchive)
|
||||||
|
|
||||||
int64 cFixedMemArchive::CurrentPos() const
|
int64 cFixedMemArchive::CurrentPos() const
|
||||||
{
|
{
|
||||||
return mReadHead;
|
return mReadHead;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 cFixedMemArchive::Length() const
|
int64 cFixedMemArchive::Length() const
|
||||||
{
|
{
|
||||||
return mSize;
|
return mSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cFixedMemArchive::EndOfFile()
|
bool cFixedMemArchive::EndOfFile()
|
||||||
{
|
{
|
||||||
return (mReadHead >= mSize);
|
return (mReadHead >= mSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
int cFixedMemArchive::Read(void* pDest, int count) // throw(eArchive)
|
int cFixedMemArchive::Read(void* pDest, int count) // throw(eArchive)
|
||||||
{
|
{
|
||||||
ASSERT( pDest );
|
ASSERT( pDest );
|
||||||
if (mReadHead + count > mSize)
|
if (mReadHead + count > mSize)
|
||||||
{
|
{
|
||||||
count = static_cast<int>( mSize - mReadHead );
|
count = static_cast<int>( mSize - mReadHead );
|
||||||
if (count <= 0)
|
if (count <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pDest != 0)
|
if (pDest != 0)
|
||||||
memcpy(pDest, mpMemory + mReadHead, count);
|
memcpy(pDest, mpMemory + mReadHead, count);
|
||||||
|
@ -576,12 +576,12 @@ int cFixedMemArchive::Read(void* pDest, int count) // throw(eArchive)
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cFixedMemArchive::Write(const void* pDest, int count) // throw(eArchive)
|
int cFixedMemArchive::Write(const void* pDest, int count) // throw(eArchive)
|
||||||
{
|
{
|
||||||
if (mReadHead + count > mSize)
|
if (mReadHead + count > mSize)
|
||||||
{
|
{
|
||||||
ASSERT( false );
|
ASSERT( false );
|
||||||
throw eArchiveWrite();
|
throw eArchiveWrite();
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(mpMemory + mReadHead, pDest, count);
|
memcpy(mpMemory + mReadHead, pDest, count);
|
||||||
|
@ -598,9 +598,9 @@ int cFixedMemArchive::Write(const void* pDest, int count) // throw(eArchive)
|
||||||
|
|
||||||
//Ctor -- Initialize member variables to 0 or NULL equivalents.
|
//Ctor -- Initialize member variables to 0 or NULL equivalents.
|
||||||
cFileArchive::cFileArchive() :
|
cFileArchive::cFileArchive() :
|
||||||
mFileSize(0),
|
mFileSize(0),
|
||||||
mReadHead(0),
|
mReadHead(0),
|
||||||
isWritable(false)
|
isWritable(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
cFileArchive::~cFileArchive()
|
cFileArchive::~cFileArchive()
|
||||||
|
@ -609,7 +609,7 @@ cFileArchive::~cFileArchive()
|
||||||
|
|
||||||
bool cFileArchive::EndOfFile()
|
bool cFileArchive::EndOfFile()
|
||||||
{
|
{
|
||||||
return ( mReadHead >= mFileSize );
|
return ( mReadHead >= mFileSize );
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -618,38 +618,38 @@ bool cFileArchive::EndOfFile()
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
void cFileArchive::Seek( int64 offset, SeekFrom from) // throw(eArchive)
|
void cFileArchive::Seek( int64 offset, SeekFrom from) // throw(eArchive)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
switch (from)
|
switch (from)
|
||||||
{
|
{
|
||||||
case cBidirArchive::BEGINNING:
|
case cBidirArchive::BEGINNING:
|
||||||
break;
|
break;
|
||||||
case cBidirArchive::CURRENT:
|
case cBidirArchive::CURRENT:
|
||||||
offset = mReadHead + offset;
|
offset = mReadHead + offset;
|
||||||
break;
|
break;
|
||||||
case cBidirArchive::END:
|
case cBidirArchive::END:
|
||||||
offset = mFileSize + offset;
|
offset = mFileSize + offset;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw eArchiveSeek( mCurrentFilename, iFSServices::GetInstance()->GetErrString() ) ;
|
throw eArchiveSeek( mCurrentFilename, iFSServices::GetInstance()->GetErrString() ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( offset > mFileSize )
|
if ( offset > mFileSize )
|
||||||
throw eArchiveSeek( mCurrentFilename, iFSServices::GetInstance()->GetErrString() ) ;
|
throw eArchiveSeek( mCurrentFilename, iFSServices::GetInstance()->GetErrString() ) ;
|
||||||
mReadHead = offset;
|
mReadHead = offset;
|
||||||
|
|
||||||
mCurrentFile.Seek(mReadHead, cFile::SEEK_BEGIN);
|
mCurrentFile.Seek(mReadHead, cFile::SEEK_BEGIN);
|
||||||
//This is where the actual read/writehead is set!!
|
//This is where the actual read/writehead is set!!
|
||||||
}//try
|
}//try
|
||||||
catch( eFile& fileError )
|
catch( eFile& fileError )
|
||||||
{
|
{
|
||||||
throw( eArchiveSeek( mCurrentFilename, fileError.GetDescription() ) );
|
throw( eArchiveSeek( mCurrentFilename, fileError.GetDescription() ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 cFileArchive::CurrentPos(void) const
|
int64 cFileArchive::CurrentPos(void) const
|
||||||
{
|
{
|
||||||
return mReadHead;
|
return mReadHead;
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -657,14 +657,14 @@ int64 cFileArchive::CurrentPos(void) const
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
int64 cFileArchive::Length(void) const
|
int64 cFileArchive::Length(void) const
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return mCurrentFile.GetSize();
|
return mCurrentFile.GetSize();
|
||||||
}
|
}
|
||||||
catch(eFile& fileError)
|
catch(eFile& fileError)
|
||||||
{
|
{
|
||||||
throw( eArchiveSeek( mCurrentFilename, fileError.GetDescription() ) );
|
throw( eArchiveSeek( mCurrentFilename, fileError.GetDescription() ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -672,25 +672,25 @@ int64 cFileArchive::Length(void) const
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
void cFileArchive::OpenRead(const TCHAR* filename, uint32 openFlags)
|
void cFileArchive::OpenRead(const TCHAR* filename, uint32 openFlags)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// set up open flags
|
// set up open flags
|
||||||
uint32 flags = cFile::OPEN_READ;
|
uint32 flags = cFile::OPEN_READ;
|
||||||
flags |= ( ( openFlags & FA_OPEN_TRUNCATE ) ? cFile::OPEN_TRUNCATE : 0 );
|
flags |= ( ( openFlags & FA_OPEN_TRUNCATE ) ? cFile::OPEN_TRUNCATE : 0 );
|
||||||
flags |= ( ( openFlags & FA_OPEN_TEXT ) ? cFile::OPEN_TEXT : 0 );
|
flags |= ( ( openFlags & FA_OPEN_TEXT ) ? cFile::OPEN_TEXT : 0 );
|
||||||
flags |= ( ( openFlags & FA_NONBLOCKING ) ? cFile::OPEN_NONBLOCKING :0 );
|
flags |= ( ( openFlags & FA_NONBLOCKING ) ? cFile::OPEN_NONBLOCKING :0 );
|
||||||
|
|
||||||
mCurrentFilename = filename;
|
mCurrentFilename = filename;
|
||||||
mCurrentFile.Open( filename, flags );
|
mCurrentFile.Open( filename, flags );
|
||||||
isWritable = false;
|
isWritable = false;
|
||||||
|
|
||||||
mFileSize = mCurrentFile.GetSize();
|
mFileSize = mCurrentFile.GetSize();
|
||||||
mReadHead = mCurrentFile.Seek( 0, cFile::SEEK_BEGIN );
|
mReadHead = mCurrentFile.Seek( 0, cFile::SEEK_BEGIN );
|
||||||
}
|
}
|
||||||
catch(eFile& fileError)
|
catch(eFile& fileError)
|
||||||
{
|
{
|
||||||
throw(eArchiveOpen( mCurrentFilename, fileError.GetDescription() ) );
|
throw(eArchiveOpen( mCurrentFilename, fileError.GetDescription() ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -698,34 +698,34 @@ void cFileArchive::OpenRead(const TCHAR* filename, uint32 openFlags)
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
void cFileArchive::OpenReadWrite(const TCHAR* filename, uint32 openFlags)
|
void cFileArchive::OpenReadWrite(const TCHAR* filename, uint32 openFlags)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// set up open flags
|
// set up open flags
|
||||||
uint32 flags = cFile::OPEN_WRITE;
|
uint32 flags = cFile::OPEN_WRITE;
|
||||||
flags |= ( ( openFlags & FA_OPEN_TRUNCATE ) ? cFile::OPEN_TRUNCATE : 0 );
|
flags |= ( ( openFlags & FA_OPEN_TRUNCATE ) ? cFile::OPEN_TRUNCATE : 0 );
|
||||||
flags |= ( ( openFlags & FA_OPEN_TEXT ) ? cFile::OPEN_TEXT : 0 );
|
flags |= ( ( openFlags & FA_OPEN_TEXT ) ? cFile::OPEN_TEXT : 0 );
|
||||||
flags |= ( ( openFlags & FA_NONBLOCKING ) ? cFile::OPEN_NONBLOCKING :0 );
|
flags |= ( ( openFlags & FA_NONBLOCKING ) ? cFile::OPEN_NONBLOCKING :0 );
|
||||||
|
|
||||||
mCurrentFilename = filename;
|
mCurrentFilename = filename;
|
||||||
mCurrentFile.Open( filename, flags );
|
mCurrentFile.Open( filename, flags );
|
||||||
isWritable = true;
|
isWritable = true;
|
||||||
|
|
||||||
mFileSize = mCurrentFile.GetSize();
|
mFileSize = mCurrentFile.GetSize();
|
||||||
mReadHead = mCurrentFile.Seek( 0, cFile::SEEK_BEGIN );
|
mReadHead = mCurrentFile.Seek( 0, cFile::SEEK_BEGIN );
|
||||||
}
|
}
|
||||||
catch(eFile& fileError)
|
catch(eFile& fileError)
|
||||||
{
|
{
|
||||||
throw( eArchiveOpen( mCurrentFilename, fileError.GetDescription() ) );
|
throw( eArchiveOpen( mCurrentFilename, fileError.GetDescription() ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
// GetCurrentFilename -- Returns the name of the file currently associated
|
// GetCurrentFilename -- Returns the name of the file currently associated
|
||||||
// with the FileArchive.
|
// with the FileArchive.
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
TSTRING cFileArchive::GetCurrentFilename(void) const
|
TSTRING cFileArchive::GetCurrentFilename(void) const
|
||||||
{
|
{
|
||||||
return mCurrentFilename;
|
return mCurrentFilename;
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -733,18 +733,18 @@ TSTRING cFileArchive::GetCurrentFilename(void) const
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
void cFileArchive::Close()
|
void cFileArchive::Close()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
mCurrentFile.Close();
|
mCurrentFile.Close();
|
||||||
mFileSize = 0;
|
mFileSize = 0;
|
||||||
mReadHead = 0;
|
mReadHead = 0;
|
||||||
|
|
||||||
mCurrentFilename = _T("");
|
mCurrentFilename = _T("");
|
||||||
}
|
}
|
||||||
catch(eFile& fileError)
|
catch(eFile& fileError)
|
||||||
{
|
{
|
||||||
throw( eArchive( mCurrentFilename, fileError.GetDescription() ) );
|
throw( eArchive( mCurrentFilename, fileError.GetDescription() ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -753,22 +753,22 @@ void cFileArchive::Close()
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
int cFileArchive::Read(void* pDest, int count)
|
int cFileArchive::Read(void* pDest, int count)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if ( mReadHead + count > mFileSize )
|
if ( mReadHead + count > mFileSize )
|
||||||
count = static_cast<int>( mFileSize - mReadHead );
|
count = static_cast<int>( mFileSize - mReadHead );
|
||||||
|
|
||||||
if ( pDest != NULL )
|
if ( pDest != NULL )
|
||||||
{
|
{
|
||||||
int nbRead =
|
int nbRead =
|
||||||
static_cast<int>( mCurrentFile.Read( pDest, count ) );
|
static_cast<int>( mCurrentFile.Read( pDest, count ) );
|
||||||
|
|
||||||
// 'count' may not be equal to 'nbRead' if the file is open in
|
// 'count' may not be equal to 'nbRead' if the file is open in
|
||||||
// text mode.
|
// text mode.
|
||||||
count = nbRead;
|
count = nbRead;
|
||||||
if(count < 0) count = 0;
|
if(count < 0) count = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int32 dummy;
|
int32 dummy;
|
||||||
|
@ -777,20 +777,20 @@ int cFileArchive::Read(void* pDest, int count)
|
||||||
if (i < (int)sizeof(int32))
|
if (i < (int)sizeof(int32))
|
||||||
{
|
{
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
mCurrentFile.Read( &dummy, i );
|
mCurrentFile.Read( &dummy, i );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
mCurrentFile.Read( &dummy, i );
|
mCurrentFile.Read( &dummy, i );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mReadHead += count;
|
mReadHead += count;
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
catch( eFile& fileError )
|
catch( eFile& fileError )
|
||||||
{
|
{
|
||||||
throw( eArchiveRead( mCurrentFilename, fileError.GetDescription() ) );
|
throw( eArchiveRead( mCurrentFilename, fileError.GetDescription() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -841,20 +841,20 @@ int cFileArchive::Write(const void* pDest, int count) // throw(eArchive)
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
void cFileArchive::Truncate() // throw(eArchive)
|
void cFileArchive::Truncate() // throw(eArchive)
|
||||||
{
|
{
|
||||||
ASSERT( mCurrentFile.IsOpen() );
|
ASSERT( mCurrentFile.IsOpen() );
|
||||||
ASSERT( mCurrentFile.isWritable );
|
ASSERT( mCurrentFile.isWritable );
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
mCurrentFile.Truncate ( mReadHead );
|
mCurrentFile.Truncate ( mReadHead );
|
||||||
}
|
}
|
||||||
catch( eFile& fileError )
|
catch( eFile& fileError )
|
||||||
{
|
{
|
||||||
//TODO: create an error number for truncate...
|
//TODO: create an error number for truncate...
|
||||||
throw( eArchiveWrite( mCurrentFilename, fileError.GetDescription() ) );
|
throw( eArchiveWrite( mCurrentFilename, fileError.GetDescription() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
mFileSize = mReadHead;
|
mFileSize = mReadHead;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -871,8 +871,8 @@ void cLockedTemporaryFileArchive::OpenReadWrite( const TCHAR* filename, uint32 o
|
||||||
try {
|
try {
|
||||||
|
|
||||||
ASSERT( !mCurrentFile.IsOpen() ); // shouldn't be able to create a new file when we're already open
|
ASSERT( !mCurrentFile.IsOpen() ); // shouldn't be able to create a new file when we're already open
|
||||||
if ( mCurrentFile.IsOpen() )
|
if ( mCurrentFile.IsOpen() )
|
||||||
throw( eArchive( mCurrentFilename, _T("Internal Error") ) );
|
throw( eArchive( mCurrentFilename, _T("Internal Error") ) );
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -32,10 +32,10 @@
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// archive.h -- classes that abstract a raw byte archive
|
// archive.h -- classes that abstract a raw byte archive
|
||||||
//
|
//
|
||||||
// cArchive -- interface for single-direction (one pass) reads and writes
|
// cArchive -- interface for single-direction (one pass) reads and writes
|
||||||
// cBidirArchive -- interface for a random-access archive
|
// cBidirArchive -- interface for a random-access archive
|
||||||
// cMemArchive -- implementation of a bidirectional archive in memory
|
// cMemArchive -- implementation of a bidirectional archive in memory
|
||||||
// cFileArchive -- implementation of a bidirectional archive as a file
|
// cFileArchive -- implementation of a bidirectional archive as a file
|
||||||
|
|
||||||
#ifndef __ARCHIVE_H
|
#ifndef __ARCHIVE_H
|
||||||
#define __ARCHIVE_H
|
#define __ARCHIVE_H
|
||||||
|
@ -56,26 +56,26 @@
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// eArchive exception classes
|
// eArchive exception classes
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
TSS_FILE_EXCEPTION( eArchive, eFileError );
|
TSS_FILE_EXCEPTION( eArchive, eFileError );
|
||||||
TSS_FILE_EXCEPTION( eArchiveOpen, eArchive );
|
TSS_FILE_EXCEPTION( eArchiveOpen, eArchive );
|
||||||
TSS_FILE_EXCEPTION( eArchiveWrite, eArchive );
|
TSS_FILE_EXCEPTION( eArchiveWrite, eArchive );
|
||||||
TSS_FILE_EXCEPTION( eArchiveRead, eArchive );
|
TSS_FILE_EXCEPTION( eArchiveRead, eArchive );
|
||||||
TSS_FILE_EXCEPTION( eArchiveEOF, eArchive );
|
TSS_FILE_EXCEPTION( eArchiveEOF, eArchive );
|
||||||
TSS_FILE_EXCEPTION( eArchiveSeek, eArchive );
|
TSS_FILE_EXCEPTION( eArchiveSeek, eArchive );
|
||||||
TSS_FILE_EXCEPTION( eArchiveMemmap, eArchive );
|
TSS_FILE_EXCEPTION( eArchiveMemmap, eArchive );
|
||||||
TSS_FILE_EXCEPTION( eArchiveOutOfMem, eArchive );
|
TSS_FILE_EXCEPTION( eArchiveOutOfMem, eArchive );
|
||||||
TSS_FILE_EXCEPTION( eArchiveInvalidOp, eArchive );
|
TSS_FILE_EXCEPTION( eArchiveInvalidOp, eArchive );
|
||||||
TSS_FILE_EXCEPTION( eArchiveFormat, eArchive );
|
TSS_FILE_EXCEPTION( eArchiveFormat, eArchive );
|
||||||
TSS_FILE_EXCEPTION( eArchiveNotRegularFile, eArchive );
|
TSS_FILE_EXCEPTION( eArchiveNotRegularFile, eArchive );
|
||||||
TSS_BEGIN_EXCEPTION( eArchiveCrypto, eArchive )
|
TSS_BEGIN_EXCEPTION( eArchiveCrypto, eArchive )
|
||||||
|
|
||||||
virtual TSTRING GetMsg() const;
|
virtual TSTRING GetMsg() const;
|
||||||
// eCryptoArchive appends a special string to the end of
|
// eCryptoArchive appends a special string to the end of
|
||||||
// all exception messages
|
// all exception messages
|
||||||
TSS_END_EXCEPTION()
|
TSS_END_EXCEPTION()
|
||||||
TSS_EXCEPTION( eArchiveStringTooLong, eArchive );
|
TSS_EXCEPTION( eArchiveStringTooLong, eArchive );
|
||||||
|
|
||||||
// throw( eArchiveOpen( cErrorUtil::MakeFileError( fileError.GetMsg(), strTempFile ) ) );
|
// throw( eArchiveOpen( cErrorUtil::MakeFileError( fileError.GetMsg(), strTempFile ) ) );
|
||||||
|
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
@ -87,7 +87,7 @@ class cArchive
|
||||||
public:
|
public:
|
||||||
virtual ~cArchive() {}
|
virtual ~cArchive() {}
|
||||||
|
|
||||||
// convenience methods
|
// convenience methods
|
||||||
//
|
//
|
||||||
// Specific Read functions throw(eArchive) if EOF is reached because
|
// Specific Read functions throw(eArchive) if EOF is reached because
|
||||||
// if the caller is requesting a certain amount of data to be present,
|
// if the caller is requesting a certain amount of data to be present,
|
||||||
|
@ -101,33 +101,33 @@ public:
|
||||||
// All write functions throw exceptions for unexpected events like
|
// All write functions throw exceptions for unexpected events like
|
||||||
// running out of memory or disk space.
|
// running out of memory or disk space.
|
||||||
//
|
//
|
||||||
void ReadInt16(int16& ret); // throw(eArchive)
|
void ReadInt16(int16& ret); // throw(eArchive)
|
||||||
void ReadInt32(int32& ret); // throw(eArchive)
|
void ReadInt32(int32& ret); // throw(eArchive)
|
||||||
void ReadInt64(int64& ret); // throw(eArchive)
|
void ReadInt64(int64& ret); // throw(eArchive)
|
||||||
void ReadString(TSTRING& ret); // throw(eArchive)
|
void ReadString(TSTRING& ret); // throw(eArchive)
|
||||||
int ReadBlob(void* pBlob, int count);
|
int ReadBlob(void* pBlob, int count);
|
||||||
void WriteInt16(int16 i); // throw(eArchive)
|
void WriteInt16(int16 i); // throw(eArchive)
|
||||||
void WriteInt32(int32 i); // throw(eArchive)
|
void WriteInt32(int32 i); // throw(eArchive)
|
||||||
void WriteInt64(int64 i); // throw(eArchive)
|
void WriteInt64(int64 i); // throw(eArchive)
|
||||||
void WriteString(TSTRING s); // throw(eArchive)
|
void WriteString(TSTRING s); // throw(eArchive)
|
||||||
void WriteBlob(const void* pBlob, int count); // throw(eArchive)
|
void WriteBlob(const void* pBlob, int count); // throw(eArchive)
|
||||||
|
|
||||||
static int32 GetStorageSize(const TSTRING& str);
|
static int32 GetStorageSize(const TSTRING& str);
|
||||||
// this method calculates how many bytes the given string will take up in the archive and returns
|
// this method calculates how many bytes the given string will take up in the archive and returns
|
||||||
// that value
|
// that value
|
||||||
// NOTE -- if the implementation of ReadString() or WriteString() ever changes, this method will also
|
// NOTE -- if the implementation of ReadString() or WriteString() ever changes, this method will also
|
||||||
// need to change.
|
// need to change.
|
||||||
|
|
||||||
int64 Copy(cArchive* pFrom, int64 amt); // throw(eArchive)
|
int64 Copy(cArchive* pFrom, int64 amt); // throw(eArchive)
|
||||||
// this method copies amt bytes from pFrom to itself, throwing an eArchive if anything goes wrong.
|
// this method copies amt bytes from pFrom to itself, throwing an eArchive if anything goes wrong.
|
||||||
|
|
||||||
// only makes sense to call for reading archives
|
// only makes sense to call for reading archives
|
||||||
virtual bool EndOfFile() = 0;
|
virtual bool EndOfFile() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// overrides
|
// overrides
|
||||||
virtual int Read(void* pDest, int count) = 0;
|
virtual int Read(void* pDest, int count) = 0;
|
||||||
virtual int Write(const void* pDest, int count) = 0; // throw(eArchive);
|
virtual int Write(const void* pDest, int count) = 0; // throw(eArchive);
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -202,7 +202,7 @@ public:
|
||||||
|
|
||||||
void Truncate(); // set the length to the current pos
|
void Truncate(); // set the length to the current pos
|
||||||
|
|
||||||
int8* GetMemory() const { return mpMemory; }
|
int8* GetMemory() const { return mpMemory; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int8* mpMemory;
|
int8* mpMemory;
|
||||||
|
@ -211,50 +211,50 @@ protected:
|
||||||
int mLogicalSize;
|
int mLogicalSize;
|
||||||
int mReadHead;
|
int mReadHead;
|
||||||
|
|
||||||
virtual int Read(void* pDest, int count);
|
virtual int Read(void* pDest, int count);
|
||||||
virtual int Write(const void* pDest, int count); // throw(eArchive)
|
virtual int Write(const void* pDest, int count); // throw(eArchive)
|
||||||
virtual void AllocateMemory(int len); // throw(eArchive)
|
virtual void AllocateMemory(int len); // throw(eArchive)
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// cFixedMemArchive -- a memory archive that operates on a fixed-sized block of
|
// cFixedMemArchive -- a memory archive that operates on a fixed-sized block of
|
||||||
// memory that has already been allocated
|
// memory that has already been allocated
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
class cFixedMemArchive : public cBidirArchive
|
class cFixedMemArchive : public cBidirArchive
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cFixedMemArchive();
|
cFixedMemArchive();
|
||||||
cFixedMemArchive( int8* pMem, int32 size );
|
cFixedMemArchive( int8* pMem, int32 size );
|
||||||
virtual ~cFixedMemArchive();
|
virtual ~cFixedMemArchive();
|
||||||
|
|
||||||
void Attach( int8* pMem, int32 size );
|
void Attach( int8* pMem, int32 size );
|
||||||
// this method associates the archive with pMem and sets the size of the
|
// this method associates the archive with pMem and sets the size of the
|
||||||
// archive. Unlike cMemoryArchive, this may never grow or shrink in size.
|
// archive. Unlike cMemoryArchive, this may never grow or shrink in size.
|
||||||
|
|
||||||
//-----------------------------------
|
//-----------------------------------
|
||||||
// cBidirArchive interface
|
// cBidirArchive interface
|
||||||
//-----------------------------------
|
//-----------------------------------
|
||||||
virtual void Seek (int64 offset, SeekFrom from) ; // throw(eArchive);
|
virtual void Seek (int64 offset, SeekFrom from) ; // throw(eArchive);
|
||||||
virtual int64 CurrentPos () const ;
|
virtual int64 CurrentPos () const ;
|
||||||
virtual int64 Length () const ;
|
virtual int64 Length () const ;
|
||||||
virtual bool EndOfFile();
|
virtual bool EndOfFile();
|
||||||
protected:
|
protected:
|
||||||
//-----------------------------------
|
//-----------------------------------
|
||||||
// cArchive interface
|
// cArchive interface
|
||||||
//-----------------------------------
|
//-----------------------------------
|
||||||
virtual int Read(void* pDest, int count); // throw(eArchive)
|
virtual int Read(void* pDest, int count); // throw(eArchive)
|
||||||
virtual int Write(const void* pDest, int count); // throw(eArchive)
|
virtual int Write(const void* pDest, int count); // throw(eArchive)
|
||||||
|
|
||||||
int8* mpMemory;
|
int8* mpMemory;
|
||||||
int32 mSize;
|
int32 mSize;
|
||||||
int32 mReadHead;
|
int32 mReadHead;
|
||||||
};
|
};
|
||||||
|
|
||||||
class cFileArchive : public cBidirArchive
|
class cFileArchive : public cBidirArchive
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cFileArchive();
|
cFileArchive();
|
||||||
virtual ~cFileArchive();
|
virtual ~cFileArchive();
|
||||||
|
|
||||||
enum OpenFlags
|
enum OpenFlags
|
||||||
{
|
{
|
||||||
|
@ -264,34 +264,34 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: Open should throw
|
// TODO: Open should throw
|
||||||
virtual void OpenRead(const TCHAR* filename, uint32 openFlags = 0 );
|
virtual void OpenRead(const TCHAR* filename, uint32 openFlags = 0 );
|
||||||
virtual void OpenReadWrite(const TCHAR* filename, uint32 openFlags = FA_OPEN_TRUNCATE );
|
virtual void OpenReadWrite(const TCHAR* filename, uint32 openFlags = FA_OPEN_TRUNCATE );
|
||||||
// opens a file for reading or writing; the file is always created if it doesn't exist,
|
// opens a file for reading or writing; the file is always created if it doesn't exist,
|
||||||
// and is truncated to zero length if truncateFile is set to true;
|
// and is truncated to zero length if truncateFile is set to true;
|
||||||
TSTRING GetCurrentFilename(void) const;
|
TSTRING GetCurrentFilename(void) const;
|
||||||
virtual void Close(void);
|
virtual void Close(void);
|
||||||
void Truncate(); // throw(eArchive) // set the length to the current pos
|
void Truncate(); // throw(eArchive) // set the length to the current pos
|
||||||
|
|
||||||
//-----------------------------------
|
//-----------------------------------
|
||||||
// cBidirArchive interface
|
// cBidirArchive interface
|
||||||
//-----------------------------------
|
//-----------------------------------
|
||||||
virtual bool EndOfFile();
|
virtual bool EndOfFile();
|
||||||
virtual void Seek(int64 offset, SeekFrom from); // throw(eArchive)
|
virtual void Seek(int64 offset, SeekFrom from); // throw(eArchive)
|
||||||
virtual int64 CurrentPos() const;
|
virtual int64 CurrentPos() const;
|
||||||
virtual int64 Length() const;
|
virtual int64 Length() const;
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int64 mFileSize; //Size of FileArchive
|
int64 mFileSize; //Size of FileArchive
|
||||||
int64 mReadHead; //Current position of read/write head
|
int64 mReadHead; //Current position of read/write head
|
||||||
//-----------------------------------
|
//-----------------------------------
|
||||||
// cArchive interface
|
// cArchive interface
|
||||||
//-----------------------------------
|
//-----------------------------------
|
||||||
virtual int Read(void* pDest, int count);
|
virtual int Read(void* pDest, int count);
|
||||||
virtual int Write(const void* pDest, int count); //throw(eArchive)
|
virtual int Write(const void* pDest, int count); //throw(eArchive)
|
||||||
bool isWritable;
|
bool isWritable;
|
||||||
cFile mCurrentFile;
|
cFile mCurrentFile;
|
||||||
TSTRING mCurrentFilename; //current file
|
TSTRING mCurrentFilename; //current file
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////
|
||||||
|
@ -305,15 +305,15 @@ protected:
|
||||||
class cLockedTemporaryFileArchive : public cFileArchive
|
class cLockedTemporaryFileArchive : public cFileArchive
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void OpenReadWrite ( const TCHAR* filename = NULL, uint32 openFlags = FA_OPEN_TRUNCATE );
|
virtual void OpenReadWrite ( const TCHAR* filename = NULL, uint32 openFlags = FA_OPEN_TRUNCATE );
|
||||||
// creates the file. filename must not exist on the file system.
|
// creates the file. filename must not exist on the file system.
|
||||||
// if filename is NULL, the class will create and use a temporary file.
|
// if filename is NULL, the class will create and use a temporary file.
|
||||||
// truncateFile has no meaning
|
// truncateFile has no meaning
|
||||||
//virtual void OpenReadWriteThrow ( const TCHAR* filename = NULL, bool truncateFile = true ) throw (eArchive);
|
//virtual void OpenReadWriteThrow ( const TCHAR* filename = NULL, bool truncateFile = true ) throw (eArchive);
|
||||||
// this is the same as OpenReadWrite, except an exception is thrown on error (of type
|
// this is the same as OpenReadWrite, except an exception is thrown on error (of type
|
||||||
// cArchive::ERR_OPEN_FAILED)
|
// cArchive::ERR_OPEN_FAILED)
|
||||||
|
|
||||||
virtual void Close();
|
virtual void Close();
|
||||||
// close and delete the file
|
// close and delete the file
|
||||||
private:
|
private:
|
||||||
// open for read only makes no sense if we're always creating the file,
|
// open for read only makes no sense if we're always creating the file,
|
||||||
|
|
|
@ -39,8 +39,8 @@
|
||||||
// ctor, dotr
|
// ctor, dotr
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
cCmdLineParser::cCmdLineParser() :
|
cCmdLineParser::cCmdLineParser() :
|
||||||
mArgTable(HASH_VERY_SMALL),
|
mArgTable(HASH_VERY_SMALL),
|
||||||
mLastArgInfo(-1, PARAM_NONE)
|
mLastArgInfo(-1, PARAM_NONE)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,26 +53,26 @@ cCmdLineParser::~cCmdLineParser()
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
void cCmdLineParser::AddArg(int argId, const TSTRING& arg, const TSTRING& alias, ParamCount numParams, bool multipleAllowed)
|
void cCmdLineParser::AddArg(int argId, const TSTRING& arg, const TSTRING& alias, ParamCount numParams, bool multipleAllowed)
|
||||||
{
|
{
|
||||||
if(arg.empty() && alias.empty())
|
if(arg.empty() && alias.empty())
|
||||||
{
|
{
|
||||||
// this refers to the list of parameters that comes after all the cmd line switches
|
// this refers to the list of parameters that comes after all the cmd line switches
|
||||||
mLastArgInfo.mId = argId;
|
mLastArgInfo.mId = argId;
|
||||||
mLastArgInfo.mNumParams = numParams;
|
mLastArgInfo.mNumParams = numParams;
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(! arg.empty())
|
if(! arg.empty())
|
||||||
mArgTable.Insert(arg, cArgInfo(argId, numParams));
|
mArgTable.Insert(arg, cArgInfo(argId, numParams));
|
||||||
if(! alias.empty())
|
if(! alias.empty())
|
||||||
{
|
{
|
||||||
// put the alias in the table with a '-' prepended to it so it matches '--'
|
// put the alias in the table with a '-' prepended to it so it matches '--'
|
||||||
TSTRING str(_T("-"));
|
TSTRING str(_T("-"));
|
||||||
str += alias;
|
str += alias;
|
||||||
mArgTable.Insert(str, cArgInfo(argId, numParams));
|
mArgTable.Insert(str, cArgInfo(argId, numParams));
|
||||||
}
|
}
|
||||||
// This argument can appear more than once on the command line.
|
// This argument can appear more than once on the command line.
|
||||||
if( multipleAllowed )
|
if( multipleAllowed )
|
||||||
mMultipleAllowed.insert( argId );
|
mMultipleAllowed.insert( argId );
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -80,11 +80,11 @@ void cCmdLineParser::AddArg(int argId, const TSTRING& arg, const TSTRING& alias,
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
void cCmdLineParser::Clear()
|
void cCmdLineParser::Clear()
|
||||||
{
|
{
|
||||||
mLastArgInfo.mId = -1;
|
mLastArgInfo.mId = -1;
|
||||||
mLastArgInfo.mNumParams = PARAM_INVALID;
|
mLastArgInfo.mNumParams = PARAM_INVALID;
|
||||||
mArgTable.Clear();
|
mArgTable.Clear();
|
||||||
mArgData.clear();
|
mArgData.clear();
|
||||||
mMutExList.clear();
|
mMutExList.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -92,54 +92,54 @@ void cCmdLineParser::Clear()
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
void cCmdLineParser::Parse(int argc, const TCHAR *const * argv)
|
void cCmdLineParser::Parse(int argc, const TCHAR *const * argv)
|
||||||
{
|
{
|
||||||
// clear out any existing data
|
// clear out any existing data
|
||||||
mArgData.clear();
|
mArgData.clear();
|
||||||
|
|
||||||
const TCHAR* pCurArg = 0;
|
const TCHAR* pCurArg = 0;
|
||||||
bool bProcessedFinalParams = false; // gets set to true when the parameters to the command line are processed
|
bool bProcessedFinalParams = false; // gets set to true when the parameters to the command line are processed
|
||||||
|
|
||||||
// I assume argv[0] is the executable name...
|
// I assume argv[0] is the executable name...
|
||||||
for(int i=1; i < argc; i++)
|
for(int i=1; i < argc; i++)
|
||||||
{
|
{
|
||||||
if(argv[i][0] == _T('-'))
|
if(argv[i][0] == _T('-'))
|
||||||
{
|
{
|
||||||
pCurArg = argv[i];
|
pCurArg = argv[i];
|
||||||
|
|
||||||
// this is a switch; find it in the table...
|
// this is a switch; find it in the table...
|
||||||
cArgInfo argInfo;
|
cArgInfo argInfo;
|
||||||
if ( !mArgTable.Lookup( TSTRING(&argv[i][1] ), argInfo ) )
|
if ( !mArgTable.Lookup( TSTRING(&argv[i][1] ), argInfo ) )
|
||||||
{
|
{
|
||||||
// unknown switch!
|
// unknown switch!
|
||||||
throw eCmdLineInvalidArg(
|
throw eCmdLineInvalidArg(
|
||||||
TSS_GetString( cCore, core::STR_ERR2_BAD_ARG_PARAMS )
|
TSS_GetString( cCore, core::STR_ERR2_BAD_ARG_PARAMS )
|
||||||
+ pCurArg );
|
+ pCurArg );
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// make sure this hasn't been specified yet...
|
// make sure this hasn't been specified yet...
|
||||||
//
|
//
|
||||||
if( ArgInList( argInfo.mId ) )
|
if( ArgInList( argInfo.mId ) )
|
||||||
{
|
{
|
||||||
// Make sure it isn't okay for this one to appear more than once...
|
// Make sure it isn't okay for this one to appear more than once...
|
||||||
std::set<int>::iterator it = mMultipleAllowed.find( argInfo.mId );
|
std::set<int>::iterator it = mMultipleAllowed.find( argInfo.mId );
|
||||||
if( it == mMultipleAllowed.end() )
|
if( it == mMultipleAllowed.end() )
|
||||||
{
|
{
|
||||||
// It wasn't in our list of allowed params, so error.
|
// It wasn't in our list of allowed params, so error.
|
||||||
throw eCmdLineMultiArg(
|
throw eCmdLineMultiArg(
|
||||||
TSS_GetString( cCore, core::STR_ERR2_BAD_ARG_PARAMS )
|
TSS_GetString( cCore, core::STR_ERR2_BAD_ARG_PARAMS )
|
||||||
+ argv[i] );
|
+ argv[i] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// add it to the list..
|
// add it to the list..
|
||||||
//
|
//
|
||||||
mArgData.push_back(cArgData(argInfo.mId, TSTRING(argv[i])));
|
mArgData.push_back(cArgData(argInfo.mId, TSTRING(argv[i])));
|
||||||
cArgData& curArg = mArgData.back();
|
cArgData& curArg = mArgData.back();
|
||||||
switch( argInfo.mNumParams )
|
switch( argInfo.mNumParams )
|
||||||
{
|
{
|
||||||
case PARAM_NONE:
|
case PARAM_NONE:
|
||||||
// make sure there are no parameters to this, but be careful because
|
// make sure there are no parameters to this, but be careful because
|
||||||
// it is legal to start the parameters to the executable here.
|
// it is legal to start the parameters to the executable here.
|
||||||
if((i+1 < argc) && (argv[i+1][0] != _T('-')))
|
if((i+1 < argc) && (argv[i+1][0] != _T('-')))
|
||||||
{
|
{
|
||||||
// search for any more parameters
|
// search for any more parameters
|
||||||
// TODO: In the future we may want to support a '--' switch that specifies the start
|
// TODO: In the future we may want to support a '--' switch that specifies the start
|
||||||
|
@ -147,121 +147,121 @@ void cCmdLineParser::Parse(int argc, const TCHAR *const * argv)
|
||||||
for (int j = i + 2; j < argc; ++j )
|
for (int j = i + 2; j < argc; ++j )
|
||||||
{
|
{
|
||||||
if (argv[j][0] == _T('-'))
|
if (argv[j][0] == _T('-'))
|
||||||
{
|
{
|
||||||
// >0 parameter passed !
|
// >0 parameter passed !
|
||||||
throw eCmdLineBadParam(
|
throw eCmdLineBadParam(
|
||||||
TSS_GetString( cCore, core::STR_ERR2_BAD_ARG_PARAMS )
|
TSS_GetString( cCore, core::STR_ERR2_BAD_ARG_PARAMS )
|
||||||
+ pCurArg );
|
+ pCurArg );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case PARAM_ONE:
|
|
||||||
// get the next parameter...
|
|
||||||
i++;
|
|
||||||
if ( (i >= argc) || (argv[i][0] == _T('-')) )
|
|
||||||
{
|
|
||||||
// zero parameters passed to something that needed one param
|
|
||||||
throw eCmdLineBadParam(
|
|
||||||
TSS_GetString( cCore, core::STR_ERR2_BAD_ARG_PARAMS )
|
|
||||||
+ pCurArg );
|
|
||||||
}
|
|
||||||
|
|
||||||
curArg.mParams.push_back( TSTRING(argv[i]) );
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PARAM_MANY:
|
case PARAM_ONE:
|
||||||
i++;
|
// get the next parameter...
|
||||||
while((i < argc) && (argv[i][0] != _T('-')))
|
i++;
|
||||||
{
|
if ( (i >= argc) || (argv[i][0] == _T('-')) )
|
||||||
curArg.mParams.push_back(TSTRING(argv[i]));
|
{
|
||||||
i++;
|
// zero parameters passed to something that needed one param
|
||||||
}
|
throw eCmdLineBadParam(
|
||||||
i--; // since we have gone too far at this point
|
TSS_GetString( cCore, core::STR_ERR2_BAD_ARG_PARAMS )
|
||||||
break;
|
+ pCurArg );
|
||||||
|
}
|
||||||
|
|
||||||
|
curArg.mParams.push_back( TSTRING(argv[i]) );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PARAM_MANY:
|
||||||
|
i++;
|
||||||
|
while((i < argc) && (argv[i][0] != _T('-')))
|
||||||
|
{
|
||||||
|
curArg.mParams.push_back(TSTRING(argv[i]));
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
i--; // since we have gone too far at this point
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ASSERTMSG( false, "Unknown number of arguments to parser" );
|
ASSERTMSG( false, "Unknown number of arguments to parser" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bProcessedFinalParams = true;
|
bProcessedFinalParams = true;
|
||||||
// this must be the final "unnamed" arg
|
// this must be the final "unnamed" arg
|
||||||
// first, make sure it is consistent with the current info...
|
// first, make sure it is consistent with the current info...
|
||||||
bool bResult = true;
|
bool bResult = true;
|
||||||
switch(mLastArgInfo.mNumParams)
|
switch(mLastArgInfo.mNumParams)
|
||||||
{
|
{
|
||||||
case PARAM_NONE:
|
case PARAM_NONE:
|
||||||
// this is an error; they didn't want any command line parameters...
|
// this is an error; they didn't want any command line parameters...
|
||||||
bResult = false;
|
bResult = false;
|
||||||
break;
|
break;
|
||||||
case PARAM_ONE:
|
case PARAM_ONE:
|
||||||
if(i+1 != argc)
|
if(i+1 != argc)
|
||||||
// there is >1 final parameter; it is an error
|
// there is >1 final parameter; it is an error
|
||||||
bResult = false;
|
bResult = false;
|
||||||
break;
|
break;
|
||||||
case PARAM_MANY:
|
case PARAM_MANY:
|
||||||
// we'll catch errors below
|
// we'll catch errors below
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ASSERT(false);
|
ASSERT(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
if(! bResult)
|
if(! bResult)
|
||||||
{
|
{
|
||||||
throw eCmdLineBadParam( );
|
throw eCmdLineBadParam( );
|
||||||
}
|
}
|
||||||
|
|
||||||
// ok, we can push the final parameter info onto the list...
|
// ok, we can push the final parameter info onto the list...
|
||||||
mArgData.push_back(cArgData(mLastArgInfo.mId));
|
mArgData.push_back(cArgData(mLastArgInfo.mId));
|
||||||
cArgData& curArg = mArgData.back();
|
cArgData& curArg = mArgData.back();
|
||||||
|
|
||||||
while ( i < argc )
|
while ( i < argc )
|
||||||
{
|
{
|
||||||
if ( argv[i][0] == _T('-') )
|
if ( argv[i][0] == _T('-') )
|
||||||
{
|
{
|
||||||
if ( ! pCurArg )
|
if ( ! pCurArg )
|
||||||
{
|
{
|
||||||
throw eCmdLineBadSwitchPos(
|
throw eCmdLineBadSwitchPos(
|
||||||
TSS_GetString( cCore, core::STR_ERR2_BAD_ARG_PARAMS )
|
TSS_GetString( cCore, core::STR_ERR2_BAD_ARG_PARAMS )
|
||||||
+ argv[i] );
|
+ argv[i] );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// there was an extra parameter passed somewhere!
|
// there was an extra parameter passed somewhere!
|
||||||
throw eCmdLineBadArgParam(
|
throw eCmdLineBadArgParam(
|
||||||
TSS_GetString( cCore, core::STR_ERR2_BAD_ARG_PARAMS )
|
TSS_GetString( cCore, core::STR_ERR2_BAD_ARG_PARAMS )
|
||||||
+ pCurArg );
|
+ pCurArg );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add this param to the list
|
// add this param to the list
|
||||||
curArg.mParams.push_back(TSTRING(argv[i]));
|
curArg.mParams.push_back(TSTRING(argv[i]));
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// it is possible not to process the final command line parameters in the "else" case above
|
// it is possible not to process the final command line parameters in the "else" case above
|
||||||
// (this only occurs if there are no command line parameters specified) so let's make sure that
|
// (this only occurs if there are no command line parameters specified) so let's make sure that
|
||||||
// is consistent with what we are configured with...
|
// is consistent with what we are configured with...
|
||||||
// NOTE -- it is ok to have no cmd line parameters if they specified PARAM_NONE or PARAM_MANY
|
// NOTE -- it is ok to have no cmd line parameters if they specified PARAM_NONE or PARAM_MANY
|
||||||
if(! bProcessedFinalParams)
|
if(! bProcessedFinalParams)
|
||||||
{
|
{
|
||||||
if(mLastArgInfo.mNumParams == PARAM_ONE)
|
if(mLastArgInfo.mNumParams == PARAM_ONE)
|
||||||
{
|
{
|
||||||
throw eCmdLineBadParam( );
|
throw eCmdLineBadParam( );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for "relationship errors":
|
// Check for "relationship errors":
|
||||||
TestMutEx();
|
TestMutEx();
|
||||||
TestDependency();
|
TestDependency();
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -269,27 +269,27 @@ void cCmdLineParser::Parse(int argc, const TCHAR *const * argv)
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
void cCmdLineParser::TestMutEx()
|
void cCmdLineParser::TestMutEx()
|
||||||
{
|
{
|
||||||
std::list<std::pair<int,int> >::const_iterator i;
|
std::list<std::pair<int,int> >::const_iterator i;
|
||||||
cCmdLineIter iter1(*this), iter2(*this);
|
cCmdLineIter iter1(*this), iter2(*this);
|
||||||
for(i = mMutExList.begin(); i != mMutExList.end(); i++)
|
for(i = mMutExList.begin(); i != mMutExList.end(); i++)
|
||||||
{
|
{
|
||||||
//TODO -- there is a much more efficent way to do this (using cFCOPropVector, for example)
|
//TODO -- there is a much more efficent way to do this (using cFCOPropVector, for example)
|
||||||
// the command line is presumably small enough, tho, that it probably isn't a big
|
// the command line is presumably small enough, tho, that it probably isn't a big
|
||||||
// deal to do it this way.
|
// deal to do it this way.
|
||||||
iter1.SeekToArg(i->first);
|
iter1.SeekToArg(i->first);
|
||||||
if(! iter1.Done())
|
if(! iter1.Done())
|
||||||
{
|
{
|
||||||
iter2.SeekToArg(i->second);
|
iter2.SeekToArg(i->second);
|
||||||
if(! iter2.Done())
|
if(! iter2.Done())
|
||||||
{
|
{
|
||||||
// we have a mutual exclusion violation!
|
// we have a mutual exclusion violation!
|
||||||
throw eCmdLineMutEx(
|
throw eCmdLineMutEx(
|
||||||
iter1.ActualParam()
|
iter1.ActualParam()
|
||||||
+ _T(", ")
|
+ _T(", ")
|
||||||
+ iter2.ActualParam() );
|
+ iter2.ActualParam() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,55 +298,55 @@ void cCmdLineParser::TestMutEx()
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
void cCmdLineParser::TestDependency()
|
void cCmdLineParser::TestDependency()
|
||||||
{
|
{
|
||||||
std::list< std::pair< std::pair< int, int>, bool > >::const_iterator i;
|
std::list< std::pair< std::pair< int, int>, bool > >::const_iterator i;
|
||||||
cCmdLineIter iter1(*this), iter2(*this);
|
cCmdLineIter iter1(*this), iter2(*this);
|
||||||
|
|
||||||
for( i = mDependencyList.begin(); i != mDependencyList.end(); ++i)
|
for( i = mDependencyList.begin(); i != mDependencyList.end(); ++i)
|
||||||
{
|
{
|
||||||
iter1.SeekToArg( i->first.first );
|
iter1.SeekToArg( i->first.first );
|
||||||
// was it on the command line?
|
// was it on the command line?
|
||||||
if( !iter1.Done() )
|
if( !iter1.Done() )
|
||||||
{
|
{
|
||||||
// it was, is the corresponding arg on the command line?
|
// it was, is the corresponding arg on the command line?
|
||||||
iter2.SeekToArg( i->first.second );
|
iter2.SeekToArg( i->first.second );
|
||||||
if( iter2.Done() ) // it wasn't, dependency error
|
if( iter2.Done() ) // it wasn't, dependency error
|
||||||
{
|
{
|
||||||
TSTRING arg1, arg2, alias1, alias2;
|
TSTRING arg1, arg2, alias1, alias2;
|
||||||
cCmdLineParser::LookupArgInfo( i->first.first, arg1, alias1 );
|
cCmdLineParser::LookupArgInfo( i->first.first, arg1, alias1 );
|
||||||
cCmdLineParser::LookupArgInfo( i->first.second, arg2, alias2 );
|
cCmdLineParser::LookupArgInfo( i->first.second, arg2, alias2 );
|
||||||
|
|
||||||
// determine in which form the user passed the arguments,
|
// determine in which form the user passed the arguments,
|
||||||
// and construct the error message in the same form
|
// and construct the error message in the same form
|
||||||
if ( iter1.ActualParam().length() == 2 )
|
if ( iter1.ActualParam().length() == 2 )
|
||||||
throw eCmdLineDependency( _T("The switch -") + arg1 + _T(" requires -") + arg2 +_T(".") );
|
throw eCmdLineDependency( _T("The switch -") + arg1 + _T(" requires -") + arg2 +_T(".") );
|
||||||
else
|
else
|
||||||
throw eCmdLineDependency( _T("The switch --") + alias1 + _T(" requires --") + alias2 + _T(".") );
|
throw eCmdLineDependency( _T("The switch --") + alias1 + _T(" requires --") + alias2 + _T(".") );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( i->second )
|
else if( i->second )
|
||||||
// only make this second check if the dependencies are MUTUAL,
|
// only make this second check if the dependencies are MUTUAL,
|
||||||
// as indicated (or not) by the bool value.
|
// as indicated (or not) by the bool value.
|
||||||
{
|
{
|
||||||
iter2.SeekToArg( i->first.second );
|
iter2.SeekToArg( i->first.second );
|
||||||
// the first arg in the pair was not on the command line,
|
// the first arg in the pair was not on the command line,
|
||||||
// so just make sure the second isn't there...
|
// so just make sure the second isn't there...
|
||||||
if( !iter2.Done() )
|
if( !iter2.Done() )
|
||||||
{
|
{
|
||||||
// arg2 appeared without arg1, so dependency error.
|
// arg2 appeared without arg1, so dependency error.
|
||||||
TSTRING arg1, arg2, alias1, alias2;
|
TSTRING arg1, arg2, alias1, alias2;
|
||||||
cCmdLineParser::LookupArgInfo( i->first.first, arg1, alias1 );
|
cCmdLineParser::LookupArgInfo( i->first.first, arg1, alias1 );
|
||||||
cCmdLineParser::LookupArgInfo( i->first.second, arg2, alias2 );
|
cCmdLineParser::LookupArgInfo( i->first.second, arg2, alias2 );
|
||||||
|
|
||||||
// determine in which form the user passed the arguments,
|
// determine in which form the user passed the arguments,
|
||||||
// and construct the error message in the same form
|
// and construct the error message in the same form
|
||||||
if ( iter1.ActualParam().length() == 2 )
|
if ( iter1.ActualParam().length() == 2 )
|
||||||
throw eCmdLineDependency( _T("The switch -") + arg2 + _T(" requires -") + arg1 +_T(".") );
|
throw eCmdLineDependency( _T("The switch -") + arg2 + _T(" requires -") + arg1 +_T(".") );
|
||||||
else
|
else
|
||||||
throw eCmdLineDependency( _T("The switch --") + alias2 + _T(" requires --") + alias1 + _T(".") );
|
throw eCmdLineDependency( _T("The switch --") + alias2 + _T(" requires --") + alias1 + _T(".") );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} //end for
|
} //end for
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -355,10 +355,10 @@ void cCmdLineParser::TestDependency()
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
void cCmdLineParser::AddMutEx(int argId1, int argId2)
|
void cCmdLineParser::AddMutEx(int argId1, int argId2)
|
||||||
{
|
{
|
||||||
// note that I do no checking for duplicates here...
|
// note that I do no checking for duplicates here...
|
||||||
std::pair<int, int> mutEx(argId1, argId2);
|
std::pair<int, int> mutEx(argId1, argId2);
|
||||||
ASSERT(argId1 != argId2);
|
ASSERT(argId1 != argId2);
|
||||||
mMutExList.push_back(mutEx);
|
mMutExList.push_back(mutEx);
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -366,13 +366,13 @@ void cCmdLineParser::AddMutEx(int argId1, int argId2)
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
void cCmdLineParser::AddDependency(int argId1, int argId2, bool mutual )
|
void cCmdLineParser::AddDependency(int argId1, int argId2, bool mutual )
|
||||||
{
|
{
|
||||||
// again, no checking for duplicates... would a set
|
// again, no checking for duplicates... would a set
|
||||||
// prove to be a better container for this operation?
|
// prove to be a better container for this operation?
|
||||||
std::pair< int, int > Args( argId1, argId2 );
|
std::pair< int, int > Args( argId1, argId2 );
|
||||||
std::pair< std::pair< int, int >, bool > Dep( Args, mutual );
|
std::pair< std::pair< int, int >, bool > Dep( Args, mutual );
|
||||||
|
|
||||||
ASSERT(argId1 != argId2);
|
ASSERT(argId1 != argId2);
|
||||||
mDependencyList.push_back( Dep);
|
mDependencyList.push_back( Dep);
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -381,29 +381,29 @@ void cCmdLineParser::AddDependency(int argId1, int argId2, bool mutual )
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
void cCmdLineParser::TraceContents(int dl)
|
void cCmdLineParser::TraceContents(int dl)
|
||||||
{
|
{
|
||||||
cDebug d("cCmdLineParser::TraceContents");
|
cDebug d("cCmdLineParser::TraceContents");
|
||||||
if(dl == -1)
|
if(dl == -1)
|
||||||
dl = cDebug::D_DEBUG;
|
dl = cDebug::D_DEBUG;
|
||||||
|
|
||||||
std::list<cArgData>::const_iterator i;
|
std::list<cArgData>::const_iterator i;
|
||||||
for(i = mArgData.begin(); i != mArgData.end(); i++)
|
for(i = mArgData.begin(); i != mArgData.end(); i++)
|
||||||
{
|
{
|
||||||
d.Trace(dl, "* Item id:%d\n", i->mId);
|
d.Trace(dl, "* Item id:%d\n", i->mId);
|
||||||
for(std::vector<TSTRING>::const_iterator vi = i->mParams.begin(); vi != i->mParams.end(); vi++)
|
for(std::vector<TSTRING>::const_iterator vi = i->mParams.begin(); vi != i->mParams.end(); vi++)
|
||||||
{
|
{
|
||||||
d.Trace(dl, "\t%s\n", vi->c_str());
|
d.Trace(dl, "\t%s\n", vi->c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
d.Trace(dl, "--- Switch id table ---\n");
|
d.Trace(dl, "--- Switch id table ---\n");
|
||||||
|
|
||||||
cHashTableIter<TSTRING, cArgInfo> iter(mArgTable);
|
cHashTableIter<TSTRING, cArgInfo> iter(mArgTable);
|
||||||
for(iter.SeekBegin(); ! iter.Done(); iter.Next())
|
for(iter.SeekBegin(); ! iter.Done(); iter.Next())
|
||||||
{
|
{
|
||||||
d.Trace(dl, "[%d] %s\n", iter.Val().mId, iter.Key().c_str());
|
d.Trace(dl, "[%d] %s\n", iter.Val().mId, iter.Key().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
d.Trace(dl, "[%d] Final Param List\n", mLastArgInfo.mId);
|
d.Trace(dl, "[%d] Final Param List\n", mLastArgInfo.mId);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -412,28 +412,28 @@ void cCmdLineParser::TraceContents(int dl)
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
bool cCmdLineParser::LookupArgInfo(int argId, TSTRING& arg, TSTRING& alias) const
|
bool cCmdLineParser::LookupArgInfo(int argId, TSTRING& arg, TSTRING& alias) const
|
||||||
{
|
{
|
||||||
arg = _T("");
|
arg = _T("");
|
||||||
alias = _T("");
|
alias = _T("");
|
||||||
|
|
||||||
cHashTableIter<TSTRING, cArgInfo> iter(mArgTable);
|
cHashTableIter<TSTRING, cArgInfo> iter(mArgTable);
|
||||||
for(iter.SeekBegin(); ! iter.Done(); iter.Next())
|
for(iter.SeekBegin(); ! iter.Done(); iter.Next())
|
||||||
{
|
{
|
||||||
if(iter.Val().mId == argId)
|
if(iter.Val().mId == argId)
|
||||||
{
|
{
|
||||||
TSTRING str = iter.Key();
|
TSTRING str = iter.Key();
|
||||||
if((str.length() > 0) && (str[0] == _T('-')))
|
if((str.length() > 0) && (str[0] == _T('-')))
|
||||||
{
|
{
|
||||||
// this is the alias!
|
// this is the alias!
|
||||||
alias = (str.c_str() + 1);
|
alias = (str.c_str() + 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// this is the arg...
|
// this is the arg...
|
||||||
arg = str;
|
arg = str;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ((! arg.empty()) || (! alias.empty()));
|
return ((! arg.empty()) || (! alias.empty()));
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -441,13 +441,13 @@ bool cCmdLineParser::LookupArgInfo(int argId, TSTRING& arg, TSTRING& alias) cons
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
bool cCmdLineParser::ArgInList(int argId)
|
bool cCmdLineParser::ArgInList(int argId)
|
||||||
{
|
{
|
||||||
std::list<cArgData>::iterator i;
|
std::list<cArgData>::iterator i;
|
||||||
for( i = mArgData.begin(); i != mArgData.end(); i++ )
|
for( i = mArgData.begin(); i != mArgData.end(); i++ )
|
||||||
{
|
{
|
||||||
if( i->mId == argId )
|
if( i->mId == argId )
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -458,15 +458,15 @@ bool cCmdLineParser::ArgInList(int argId)
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// SeekToArg
|
// SeekToArg
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
bool cCmdLineIter::SeekToArg(int argId) const
|
bool cCmdLineIter::SeekToArg(int argId) const
|
||||||
{
|
{
|
||||||
for(SeekBegin(); ! Done(); Next())
|
for(SeekBegin(); ! Done(); Next())
|
||||||
{
|
{
|
||||||
if(ArgId() == argId)
|
if(ArgId() == argId)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,39 +49,39 @@
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// eCmdLine
|
// eCmdLine
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
TSS_EXCEPTION( eCmdLine, eError )
|
TSS_EXCEPTION( eCmdLine, eError )
|
||||||
TSS_EXCEPTION( eCmdLineInvalidArg, eCmdLine ) // an arg on the command line is not recognized
|
TSS_EXCEPTION( eCmdLineInvalidArg, eCmdLine ) // an arg on the command line is not recognized
|
||||||
TSS_EXCEPTION( eCmdLineBadArgParam, eCmdLine ) // wrong number of parameters to an argument
|
TSS_EXCEPTION( eCmdLineBadArgParam, eCmdLine ) // wrong number of parameters to an argument
|
||||||
TSS_EXCEPTION( eCmdLineBadParam, eCmdLine ) // wrong number of paramters to the executable (not associated with any arguments)
|
TSS_EXCEPTION( eCmdLineBadParam, eCmdLine ) // wrong number of paramters to the executable (not associated with any arguments)
|
||||||
TSS_EXCEPTION( eCmdLineBadSwitchPos,eCmdLine ) // a '-' arg appeared after the final parameter list
|
TSS_EXCEPTION( eCmdLineBadSwitchPos,eCmdLine ) // a '-' arg appeared after the final parameter list
|
||||||
TSS_EXCEPTION( eCmdLineMutEx, eCmdLine ) // a mutual exclusion error has occured
|
TSS_EXCEPTION( eCmdLineMutEx, eCmdLine ) // a mutual exclusion error has occured
|
||||||
TSS_EXCEPTION( eCmdLineDependency, eCmdLine ) // a dependency error has occurred.
|
TSS_EXCEPTION( eCmdLineDependency, eCmdLine ) // a dependency error has occurred.
|
||||||
TSS_EXCEPTION( eCmdLineMultiArg, eCmdLine ) // an arg was found twice in the command line
|
TSS_EXCEPTION( eCmdLineMultiArg, eCmdLine ) // an arg was found twice in the command line
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// cCmdLineParser owns errors 600-699
|
// cCmdLineParser owns errors 600-699
|
||||||
// these can be turned into a string by using cErrorTable
|
// these can be turned into a string by using cErrorTable
|
||||||
enum ErrorType
|
enum ErrorType
|
||||||
{
|
{
|
||||||
ERR_NONE = 601, // no error
|
ERR_NONE = 601, // no error
|
||||||
ERR_INVALID_ARG = 602, // an arg on the command line is not recognized
|
ERR_INVALID_ARG = 602, // an arg on the command line is not recognized
|
||||||
ERR_BAD_ARG_PARAMS = 603, // wrong number of parameters to an argument
|
ERR_BAD_ARG_PARAMS = 603, // wrong number of parameters to an argument
|
||||||
ERR_BAD_PARAMS = 604, // wrong number of paramters to the executable (not associated with any arguments)
|
ERR_BAD_PARAMS = 604, // wrong number of paramters to the executable (not associated with any arguments)
|
||||||
ERR_SWITCH_AFTER_FINAL_LIST = 605, // a '-' arg appeared after the final paramter list
|
ERR_SWITCH_AFTER_FINAL_LIST = 605, // a '-' arg appeared after the final paramter list
|
||||||
ERR_MUTUAL_EXCLUSION = 606, // a mutual exclusion error has occured
|
ERR_MUTUAL_EXCLUSION = 606, // a mutual exclusion error has occured
|
||||||
ERR_MULTIPLE_ARG = 607, // an arg was found twice in the command line
|
ERR_MULTIPLE_ARG = 607, // an arg was found twice in the command line
|
||||||
|
|
||||||
ERR_INVALID // top of enum
|
ERR_INVALID // top of enum
|
||||||
};
|
};
|
||||||
|
|
||||||
// for storing error information
|
// for storing error information
|
||||||
ErrorType mCurError;
|
ErrorType mCurError;
|
||||||
TSTRING mCurErrorString;
|
TSTRING mCurErrorString;
|
||||||
void GetErrorInfo(ErrorType& et, TSTRING& errorData) const;
|
void GetErrorInfo(ErrorType& et, TSTRING& errorData) const;
|
||||||
// returns information on the type of error that occured in a Parse() command. Only
|
// returns information on the type of error that occured in a Parse() command. Only
|
||||||
// returns valid information if Parse() had just been called and returned false. A
|
// returns valid information if Parse() had just been called and returned false. A
|
||||||
// second call to Parse() might alter existing error info
|
// second call to Parse() might alter existing error info
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
@ -90,176 +90,176 @@ TSS_EXCEPTION( eCmdLineMultiArg, eCmdLine ) // an arg was found twice in the com
|
||||||
class cCmdLineParser
|
class cCmdLineParser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cCmdLineParser();
|
cCmdLineParser();
|
||||||
~cCmdLineParser();
|
~cCmdLineParser();
|
||||||
|
|
||||||
enum ParamCount
|
enum ParamCount
|
||||||
{
|
{
|
||||||
PARAM_NONE, // no parameters to arg
|
PARAM_NONE, // no parameters to arg
|
||||||
PARAM_ONE, // one parameter to arg
|
PARAM_ONE, // one parameter to arg
|
||||||
PARAM_MANY, // zero or more paramters to arg
|
PARAM_MANY, // zero or more paramters to arg
|
||||||
|
|
||||||
PARAM_INVALID // top of enum
|
PARAM_INVALID // top of enum
|
||||||
};
|
};
|
||||||
|
|
||||||
void AddArg(int argId, const TSTRING& arg, const TSTRING& alias, ParamCount numParams, bool multipleAllowed = false);
|
void AddArg(int argId, const TSTRING& arg, const TSTRING& alias, ParamCount numParams, bool multipleAllowed = false);
|
||||||
// this method should be called for each argument that can appear on the
|
// this method should be called for each argument that can appear on the
|
||||||
// command line.
|
// command line.
|
||||||
// argId -- a number that uniquely identifies the argument; no two arguments
|
// argId -- a number that uniquely identifies the argument; no two arguments
|
||||||
// may have the same id (ASSERT-enforced)
|
// may have the same id (ASSERT-enforced)
|
||||||
// arg -- string that comes after the '-'. can be _T("") if there is only
|
// arg -- string that comes after the '-'. can be _T("") if there is only
|
||||||
// a string representation
|
// a string representation
|
||||||
// alias -- string that comes after '--' which has the same meaning. Can be _T("")
|
// alias -- string that comes after '--' which has the same meaning. Can be _T("")
|
||||||
// if there is no alias. If both arg and alias are empty strings, then this arg
|
// if there is no alias. If both arg and alias are empty strings, then this arg
|
||||||
// represents the list of arguments that comes at the end of the command line
|
// represents the list of arguments that comes at the end of the command line
|
||||||
// numParams -- number of parameters that this argument needs
|
// numParams -- number of parameters that this argument needs
|
||||||
|
|
||||||
void AddMutEx(int argId1, int argId2);
|
void AddMutEx(int argId1, int argId2);
|
||||||
// this adds a mutual exclusion constraint. When Parse() is called, if argId1 and
|
// this adds a mutual exclusion constraint. When Parse() is called, if argId1 and
|
||||||
// argId2 both exist on the command line, then the parse will fail and the error
|
// argId2 both exist on the command line, then the parse will fail and the error
|
||||||
// value ERR_MUTUAL_EXCLUSION will be set.
|
// value ERR_MUTUAL_EXCLUSION will be set.
|
||||||
|
|
||||||
void AddDependency(int argId1, int argId2, bool mutual = false );
|
void AddDependency(int argId1, int argId2, bool mutual = false );
|
||||||
// This adds a dependency constraint. When Parse() is called, if argId1
|
// This adds a dependency constraint. When Parse() is called, if argId1
|
||||||
// exists on the command line independent from argId2, then the parse will fail.
|
// exists on the command line independent from argId2, then the parse will fail.
|
||||||
// If the default param mutual is true, then the command parser will check for
|
// If the default param mutual is true, then the command parser will check for
|
||||||
// argId1 if argId2 is passed. We do this, since it is possible for one arg to
|
// argId1 if argId2 is passed. We do this, since it is possible for one arg to
|
||||||
// depend on another, but have the other arg alone on the command line, legally.
|
// depend on another, but have the other arg alone on the command line, legally.
|
||||||
|
|
||||||
void Parse(int argc, const TCHAR *const * argv); // throw eCmdLine
|
void Parse(int argc, const TCHAR *const * argv); // throw eCmdLine
|
||||||
// after AddArg() has been called for every argument that could be processed by the
|
// after AddArg() has been called for every argument that could be processed by the
|
||||||
// command line, call this to tokenize argv. If the return value is false, then
|
// command line, call this to tokenize argv. If the return value is false, then
|
||||||
// the input was invalid in some way; the actual error can be determined by calling
|
// the input was invalid in some way; the actual error can be determined by calling
|
||||||
// GetErrorInfo() below.
|
// GetErrorInfo() below.
|
||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
// clear out all information that this class contains
|
// clear out all information that this class contains
|
||||||
|
|
||||||
bool LookupArgInfo(int argId, TSTRING& arg, TSTRING& alias) const;
|
bool LookupArgInfo(int argId, TSTRING& arg, TSTRING& alias) const;
|
||||||
// given an argId, fill out the strings with the argument and alias strings. Returns false
|
// given an argId, fill out the strings with the argument and alias strings. Returns false
|
||||||
// if the argId cannot be found. This method is not very fast, so don't use it often.
|
// if the argId cannot be found. This method is not very fast, so don't use it often.
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
void TraceContents(int dl = -1) ;
|
void TraceContents(int dl = -1) ;
|
||||||
#endif
|
#endif
|
||||||
private:
|
private:
|
||||||
void TestMutEx();
|
void TestMutEx();
|
||||||
// tests for mutual exclusion violations; if it fails, the current error is set and false
|
// tests for mutual exclusion violations; if it fails, the current error is set and false
|
||||||
// is returned.
|
// is returned.
|
||||||
void TestDependency();
|
void TestDependency();
|
||||||
// tests for all dependency violations.
|
// tests for all dependency violations.
|
||||||
bool ArgInList(int argId);
|
bool ArgInList(int argId);
|
||||||
// returns true if an argument with the specified id already exists in the list; this is used
|
// returns true if an argument with the specified id already exists in the list; this is used
|
||||||
// to make sure the same arg doesn't appear >1 time on the command line
|
// to make sure the same arg doesn't appear >1 time on the command line
|
||||||
|
|
||||||
// for storing information on paramers
|
// for storing information on paramers
|
||||||
struct cArgInfo
|
struct cArgInfo
|
||||||
{
|
{
|
||||||
int mId;
|
int mId;
|
||||||
ParamCount mNumParams;
|
ParamCount mNumParams;
|
||||||
|
|
||||||
cArgInfo(int i = -1, ParamCount p = PARAM_INVALID) : mId(i), mNumParams(p) {}
|
cArgInfo(int i = -1, ParamCount p = PARAM_INVALID) : mId(i), mNumParams(p) {}
|
||||||
};
|
};
|
||||||
// for storing parsed argv information
|
// for storing parsed argv information
|
||||||
struct cArgData
|
struct cArgData
|
||||||
{
|
{
|
||||||
int mId;
|
int mId;
|
||||||
std::vector<TSTRING> mParams;
|
std::vector<TSTRING> mParams;
|
||||||
TSTRING mActualParam; // a string representation of what was actually on the command line
|
TSTRING mActualParam; // a string representation of what was actually on the command line
|
||||||
|
|
||||||
cArgData(int id = -1, const TSTRING& actualParam = TSTRING(_T(""))) : mId(id), mActualParam(actualParam) {}
|
cArgData(int id = -1, const TSTRING& actualParam = TSTRING(_T(""))) : mId(id), mActualParam(actualParam) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
cHashTable<TSTRING, cArgInfo> mArgTable;
|
cHashTable<TSTRING, cArgInfo> mArgTable;
|
||||||
cArgInfo mLastArgInfo; // info on the argument that comes at the end of the command line (with no associated '-x' or '--x')
|
cArgInfo mLastArgInfo; // info on the argument that comes at the end of the command line (with no associated '-x' or '--x')
|
||||||
std::list<cArgData> mArgData;
|
std::list<cArgData> mArgData;
|
||||||
std::list<std::pair<int,int> > mMutExList; // all of the mutual exclusions
|
std::list<std::pair<int,int> > mMutExList; // all of the mutual exclusions
|
||||||
std::list< std::pair < std::pair<int,int>, bool > > mDependencyList; // all of the dependencies
|
std::list< std::pair < std::pair<int,int>, bool > > mDependencyList; // all of the dependencies
|
||||||
std::set< int > mMultipleAllowed;
|
std::set< int > mMultipleAllowed;
|
||||||
|
|
||||||
friend class cCmdLineIter;
|
friend class cCmdLineIter;
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// cCmdLineIter -- used to iterate over the tokenized command line parameters;
|
// cCmdLineIter -- used to iterate over the tokenized command line parameters;
|
||||||
// is only useful after cCmdLineParser::Parse() has been called.
|
// is only useful after cCmdLineParser::Parse() has been called.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
class cCmdLineIter
|
class cCmdLineIter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cCmdLineIter(const cCmdLineParser& parser);
|
cCmdLineIter(const cCmdLineParser& parser);
|
||||||
|
|
||||||
// iteration
|
// iteration
|
||||||
void SeekBegin() const;
|
void SeekBegin() const;
|
||||||
bool Done() const;
|
bool Done() const;
|
||||||
bool IsEmpty() const;
|
bool IsEmpty() const;
|
||||||
void Next() const;
|
void Next() const;
|
||||||
|
|
||||||
bool SeekToArg(int argId) const;
|
bool SeekToArg(int argId) const;
|
||||||
// seeks to the argument with the given argId. returns
|
// seeks to the argument with the given argId. returns
|
||||||
// false and Done() == true if it couldn't find it.
|
// false and Done() == true if it couldn't find it.
|
||||||
|
|
||||||
// access to the argument data
|
// access to the argument data
|
||||||
int ArgId() const;
|
int ArgId() const;
|
||||||
// returns the id of this arg; ASSERTs if Done() == true
|
// returns the id of this arg; ASSERTs if Done() == true
|
||||||
int NumParams() const;
|
int NumParams() const;
|
||||||
// returns the number of parameters this argument has
|
// returns the number of parameters this argument has
|
||||||
const TSTRING& ActualParam() const;
|
const TSTRING& ActualParam() const;
|
||||||
// returns exactly what was passed on the command line (ie -- what the user typed)
|
// returns exactly what was passed on the command line (ie -- what the user typed)
|
||||||
const TSTRING& ParamAt(int index) const;
|
const TSTRING& ParamAt(int index) const;
|
||||||
// returns the parameter at the specified index. ASSERTs if
|
// returns the parameter at the specified index. ASSERTs if
|
||||||
// the index is out of range.
|
// the index is out of range.
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const std::list<cCmdLineParser::cArgData>& mList;
|
const std::list<cCmdLineParser::cArgData>& mList;
|
||||||
mutable std::list<cCmdLineParser::cArgData>::const_iterator mIter;
|
mutable std::list<cCmdLineParser::cArgData>::const_iterator mIter;
|
||||||
};
|
};
|
||||||
|
|
||||||
//#############################################################################
|
//#############################################################################
|
||||||
// inline implementation
|
// inline implementation
|
||||||
//#############################################################################
|
//#############################################################################
|
||||||
inline cCmdLineIter::cCmdLineIter(const cCmdLineParser& parser) :
|
inline cCmdLineIter::cCmdLineIter(const cCmdLineParser& parser) :
|
||||||
mList(parser.mArgData)
|
mList(parser.mArgData)
|
||||||
{
|
{
|
||||||
SeekBegin();
|
SeekBegin();
|
||||||
}
|
}
|
||||||
inline void cCmdLineIter::SeekBegin() const
|
inline void cCmdLineIter::SeekBegin() const
|
||||||
{
|
{
|
||||||
mIter = mList.begin();
|
mIter = mList.begin();
|
||||||
}
|
}
|
||||||
inline bool cCmdLineIter::Done() const
|
inline bool cCmdLineIter::Done() const
|
||||||
{
|
{
|
||||||
return (mIter == mList.end());
|
return (mIter == mList.end());
|
||||||
}
|
}
|
||||||
inline bool cCmdLineIter::IsEmpty() const
|
inline bool cCmdLineIter::IsEmpty() const
|
||||||
{
|
{
|
||||||
return (mList.size() == 0);
|
return (mList.size() == 0);
|
||||||
}
|
}
|
||||||
inline void cCmdLineIter::Next() const
|
inline void cCmdLineIter::Next() const
|
||||||
{
|
{
|
||||||
mIter++;
|
mIter++;
|
||||||
}
|
}
|
||||||
inline int cCmdLineIter::ArgId() const
|
inline int cCmdLineIter::ArgId() const
|
||||||
{
|
{
|
||||||
ASSERT(! Done());
|
ASSERT(! Done());
|
||||||
return mIter->mId;
|
return mIter->mId;
|
||||||
}
|
}
|
||||||
inline int cCmdLineIter::NumParams() const
|
inline int cCmdLineIter::NumParams() const
|
||||||
{
|
{
|
||||||
ASSERT(! Done());
|
ASSERT(! Done());
|
||||||
return mIter->mParams.size();
|
return mIter->mParams.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const TSTRING& cCmdLineIter::ActualParam() const
|
inline const TSTRING& cCmdLineIter::ActualParam() const
|
||||||
{
|
{
|
||||||
ASSERT(! Done());
|
ASSERT(! Done());
|
||||||
return mIter->mActualParam;
|
return mIter->mActualParam;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const TSTRING& cCmdLineIter::ParamAt(int index) const
|
inline const TSTRING& cCmdLineIter::ParamAt(int index) const
|
||||||
{
|
{
|
||||||
ASSERT((index >= 0) && (index < NumParams()));
|
ASSERT((index >= 0) && (index < NumParams()));
|
||||||
return mIter->mParams[index];
|
return mIter->mParams[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ TSS_ImplementPackage( cCore )
|
||||||
|
|
||||||
cCore::cCore()
|
cCore::cCore()
|
||||||
{
|
{
|
||||||
TSS_REGISTER_PKG_ERRORS( core );
|
TSS_REGISTER_PKG_ERRORS( core );
|
||||||
|
|
||||||
// NOTE: Initialize code converter when cCore is a dependency
|
// NOTE: Initialize code converter when cCore is a dependency
|
||||||
// of another package (created on first call to GetInstance(),
|
// of another package (created on first call to GetInstance(),
|
||||||
|
|
|
@ -43,17 +43,17 @@
|
||||||
|
|
||||||
//--Requirements
|
//--Requirements
|
||||||
|
|
||||||
#include "package.h" // for: Packaging Abstraction
|
#include "package.h" // for: Packaging Abstraction
|
||||||
|
|
||||||
//--Classes
|
//--Classes
|
||||||
|
|
||||||
TSS_BeginPackage( cCore )
|
TSS_BeginPackage( cCore )
|
||||||
|
|
||||||
TSS_DECLARE_STRINGTABLE;
|
TSS_DECLARE_STRINGTABLE;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
cCore();
|
cCore();
|
||||||
|
|
||||||
TSS_EndPackage( cCore )
|
TSS_EndPackage( cCore )
|
||||||
|
|
||||||
|
|
|
@ -68,34 +68,34 @@ TSS_REGISTER_ERROR( eBadCmdLine(), _T("Command line error.") );
|
||||||
|
|
||||||
/// Archive
|
/// Archive
|
||||||
|
|
||||||
TSS_REGISTER_ERROR( eArchive(), _T("Archive error.") )
|
TSS_REGISTER_ERROR( eArchive(), _T("Archive error.") )
|
||||||
TSS_REGISTER_ERROR( eArchiveOpen(), _T("File could not be opened.") )
|
TSS_REGISTER_ERROR( eArchiveOpen(), _T("File could not be opened.") )
|
||||||
TSS_REGISTER_ERROR( eArchiveWrite(), _T("File could not be written.") )
|
TSS_REGISTER_ERROR( eArchiveWrite(), _T("File could not be written.") )
|
||||||
TSS_REGISTER_ERROR( eArchiveRead(), _T("File could not be read.") )
|
TSS_REGISTER_ERROR( eArchiveRead(), _T("File could not be read.") )
|
||||||
TSS_REGISTER_ERROR( eArchiveEOF(), _T("End of file reached.") )
|
TSS_REGISTER_ERROR( eArchiveEOF(), _T("End of file reached.") )
|
||||||
TSS_REGISTER_ERROR( eArchiveSeek(), _T("File seek failed.") )
|
TSS_REGISTER_ERROR( eArchiveSeek(), _T("File seek failed.") )
|
||||||
TSS_REGISTER_ERROR( eArchiveMemmap(), _T("Memory mapped archive file invalid.") )
|
TSS_REGISTER_ERROR( eArchiveMemmap(), _T("Memory mapped archive file invalid.") )
|
||||||
TSS_REGISTER_ERROR( eArchiveOutOfMem(), _T("Archive ran out of memory.") )
|
TSS_REGISTER_ERROR( eArchiveOutOfMem(), _T("Archive ran out of memory.") )
|
||||||
TSS_REGISTER_ERROR( eArchiveInvalidOp(),_T("Archive logic error.") )
|
TSS_REGISTER_ERROR( eArchiveInvalidOp(),_T("Archive logic error.") )
|
||||||
TSS_REGISTER_ERROR( eArchiveFormat(), _T("Archive file format invalid.") )
|
TSS_REGISTER_ERROR( eArchiveFormat(), _T("Archive file format invalid.") )
|
||||||
TSS_REGISTER_ERROR( eArchiveNotRegularFile(), _T("File is not a regular file.") )
|
TSS_REGISTER_ERROR( eArchiveNotRegularFile(), _T("File is not a regular file.") )
|
||||||
TSS_REGISTER_ERROR( eArchiveCrypto(), _T("File could not be decrypted.") )
|
TSS_REGISTER_ERROR( eArchiveCrypto(), _T("File could not be decrypted.") )
|
||||||
TSS_REGISTER_ERROR( eArchiveStringTooLong(), _T("String was too long.") )
|
TSS_REGISTER_ERROR( eArchiveStringTooLong(), _T("String was too long.") )
|
||||||
|
|
||||||
|
|
||||||
/// File
|
/// File
|
||||||
|
|
||||||
TSS_REGISTER_ERROR( eFile(), _T("File error.") )
|
TSS_REGISTER_ERROR( eFile(), _T("File error.") )
|
||||||
TSS_REGISTER_ERROR( eFileOpen(), _T("File could not be opened.") )
|
TSS_REGISTER_ERROR( eFileOpen(), _T("File could not be opened.") )
|
||||||
TSS_REGISTER_ERROR( eFileWrite(), _T("File could not be written.") )
|
TSS_REGISTER_ERROR( eFileWrite(), _T("File could not be written.") )
|
||||||
TSS_REGISTER_ERROR( eFileRead(), _T("File could not be read.") )
|
TSS_REGISTER_ERROR( eFileRead(), _T("File could not be read.") )
|
||||||
TSS_REGISTER_ERROR( eFileEOF(), _T("End of file reached.") )
|
TSS_REGISTER_ERROR( eFileEOF(), _T("End of file reached.") )
|
||||||
TSS_REGISTER_ERROR( eFileSeek(), _T("File seek failed.") )
|
TSS_REGISTER_ERROR( eFileSeek(), _T("File seek failed.") )
|
||||||
TSS_REGISTER_ERROR( eFileInvalidOp(), _T("File logic error.") )
|
TSS_REGISTER_ERROR( eFileInvalidOp(), _T("File logic error.") )
|
||||||
TSS_REGISTER_ERROR( eFileTrunc(), _T("File could not be truncated.") )
|
TSS_REGISTER_ERROR( eFileTrunc(), _T("File could not be truncated.") )
|
||||||
TSS_REGISTER_ERROR( eFileClose(), _T("File could not be closed.") )
|
TSS_REGISTER_ERROR( eFileClose(), _T("File could not be closed.") )
|
||||||
TSS_REGISTER_ERROR( eFileFlush(), _T("File could not be flushed.") )
|
TSS_REGISTER_ERROR( eFileFlush(), _T("File could not be flushed.") )
|
||||||
TSS_REGISTER_ERROR( eFileRewind(), _T("File could not be rewound.") )
|
TSS_REGISTER_ERROR( eFileRewind(), _T("File could not be rewound.") )
|
||||||
|
|
||||||
|
|
||||||
/// Win32
|
/// Win32
|
||||||
|
@ -106,32 +106,32 @@ TSS_REGISTER_ERROR(eUnix(), _T("Unix API failure.") )
|
||||||
|
|
||||||
/// FSServices
|
/// FSServices
|
||||||
|
|
||||||
TSS_REGISTER_ERROR( eFSServices(), _T("File system error.") )
|
TSS_REGISTER_ERROR( eFSServices(), _T("File system error.") )
|
||||||
TSS_REGISTER_ERROR( eFSServicesGeneric(),_T("File system error.") )
|
TSS_REGISTER_ERROR( eFSServicesGeneric(),_T("File system error.") )
|
||||||
|
|
||||||
|
|
||||||
/// Serializer
|
/// Serializer
|
||||||
|
|
||||||
TSS_REGISTER_ERROR( eSerializerUnknownType(), _T("Unknown type encountered in file.\nFile format may not be valid for this platform.") )
|
TSS_REGISTER_ERROR( eSerializerUnknownType(), _T("Unknown type encountered in file.\nFile format may not be valid for this platform.") )
|
||||||
TSS_REGISTER_ERROR( eSerializerInputStreamFmt(), _T("Invalid input stream format.") )
|
TSS_REGISTER_ERROR( eSerializerInputStreamFmt(), _T("Invalid input stream format.") )
|
||||||
TSS_REGISTER_ERROR( eSerializerOutputStreamFmt(), _T("Invalid output stream format.") )
|
TSS_REGISTER_ERROR( eSerializerOutputStreamFmt(), _T("Invalid output stream format.") )
|
||||||
TSS_REGISTER_ERROR( eSerializerInputStremTypeArray(), _T("A bad index was encountered in file.") )
|
TSS_REGISTER_ERROR( eSerializerInputStremTypeArray(), _T("A bad index was encountered in file.") )
|
||||||
TSS_REGISTER_ERROR( eSerializerArchive(), _T("File read encountered an archive error.") )
|
TSS_REGISTER_ERROR( eSerializerArchive(), _T("File read encountered an archive error.") )
|
||||||
TSS_REGISTER_ERROR( eSerializerVersionMismatch(), _T("File version mismatch.") )
|
TSS_REGISTER_ERROR( eSerializerVersionMismatch(), _T("File version mismatch.") )
|
||||||
TSS_REGISTER_ERROR( eSerializerEncryption(), _T("File encryption error.") )
|
TSS_REGISTER_ERROR( eSerializerEncryption(), _T("File encryption error.") )
|
||||||
TSS_REGISTER_ERROR( eSerializer(), _T("File format error.") )
|
TSS_REGISTER_ERROR( eSerializer(), _T("File format error.") )
|
||||||
|
|
||||||
|
|
||||||
/// Command Line
|
/// Command Line
|
||||||
|
|
||||||
TSS_REGISTER_ERROR( eCmdLine(), _T("Command line parsing error.") )
|
TSS_REGISTER_ERROR( eCmdLine(), _T("Command line parsing error.") )
|
||||||
TSS_REGISTER_ERROR( eCmdLineInvalidArg(), _T("Invalid argument passed on command line.") )
|
TSS_REGISTER_ERROR( eCmdLineInvalidArg(), _T("Invalid argument passed on command line.") )
|
||||||
TSS_REGISTER_ERROR( eCmdLineBadArgParam(), _T("Incorrect number of parameters to a command line argument.") )
|
TSS_REGISTER_ERROR( eCmdLineBadArgParam(), _T("Incorrect number of parameters to a command line argument.") )
|
||||||
TSS_REGISTER_ERROR( eCmdLineBadParam(), _T("Incorrect number of parameters on command line.") )
|
TSS_REGISTER_ERROR( eCmdLineBadParam(), _T("Incorrect number of parameters on command line.") )
|
||||||
TSS_REGISTER_ERROR( eCmdLineBadSwitchPos(), _T("Switch appears after final command line parameter.") )
|
TSS_REGISTER_ERROR( eCmdLineBadSwitchPos(), _T("Switch appears after final command line parameter.") )
|
||||||
TSS_REGISTER_ERROR( eCmdLineMutEx(), _T("Specified command line switches are mutually exclusive.") )
|
TSS_REGISTER_ERROR( eCmdLineMutEx(), _T("Specified command line switches are mutually exclusive.") )
|
||||||
TSS_REGISTER_ERROR( eCmdLineDependency(), _T("Command line parameter missing.") )
|
TSS_REGISTER_ERROR( eCmdLineDependency(), _T("Command line parameter missing.") )
|
||||||
TSS_REGISTER_ERROR( eCmdLineMultiArg(), _T("Command line argument specified more than once.") )
|
TSS_REGISTER_ERROR( eCmdLineMultiArg(), _T("Command line argument specified more than once.") )
|
||||||
|
|
||||||
|
|
||||||
/// TWLocale
|
/// TWLocale
|
||||||
|
|
|
@ -51,11 +51,11 @@ TSS_BeginStringtable( cCore )
|
||||||
TSS_StringEntry( core::STR_ERROR_CONTINUING, _T("Continuing...") ),
|
TSS_StringEntry( core::STR_ERROR_CONTINUING, _T("Continuing...") ),
|
||||||
TSS_StringEntry( core::STR_ERR2_FILENAME, _T("Filename: ") ),
|
TSS_StringEntry( core::STR_ERR2_FILENAME, _T("Filename: ") ),
|
||||||
TSS_StringEntry( core::STR_ERROR_FILENAME, _T("Filename: ") ),
|
TSS_StringEntry( core::STR_ERROR_FILENAME, _T("Filename: ") ),
|
||||||
TSS_StringEntry( core::STR_UNKNOWN, _T("Unknown") ),
|
TSS_StringEntry( core::STR_UNKNOWN, _T("Unknown") ),
|
||||||
TSS_StringEntry( core::STR_NUMBER_TOO_BIG, _T("Number too big") ),
|
TSS_StringEntry( core::STR_NUMBER_TOO_BIG, _T("Number too big") ),
|
||||||
TSS_StringEntry( core::STR_SIGNAL, _T("Software interrupt forced exit:") ),
|
TSS_StringEntry( core::STR_SIGNAL, _T("Software interrupt forced exit:") ),
|
||||||
TSS_StringEntry( core::STR_NEWLINE, _T("\n") ),
|
TSS_StringEntry( core::STR_NEWLINE, _T("\n") ),
|
||||||
TSS_StringEntry( core::STR_MEMARCHIVE_FILENAME, _T("Error occured in internal memory file") ),
|
TSS_StringEntry( core::STR_MEMARCHIVE_FILENAME, _T("Error occured in internal memory file") ),
|
||||||
TSS_StringEntry( core::STR_MEMARCHIVE_ERRSTR, _T("") ),
|
TSS_StringEntry( core::STR_MEMARCHIVE_ERRSTR, _T("") ),
|
||||||
TSS_StringEntry( core::STR_ENDOFTIME, _T("Tripwire is not designed to run past the year 2038.\nNow exiting...") ),
|
TSS_StringEntry( core::STR_ENDOFTIME, _T("Tripwire is not designed to run past the year 2038.\nNow exiting...") ),
|
||||||
TSS_StringEntry( core::STR_UNKNOWN_TIME, _T("Unknown time") ),
|
TSS_StringEntry( core::STR_UNKNOWN_TIME, _T("Unknown time") ),
|
||||||
|
|
|
@ -59,7 +59,7 @@ TSS_BeginStringIds( core )
|
||||||
STR_ERROR_FILENAME,
|
STR_ERROR_FILENAME,
|
||||||
STR_NUMBER_TOO_BIG,
|
STR_NUMBER_TOO_BIG,
|
||||||
STR_UNKNOWN,
|
STR_UNKNOWN,
|
||||||
STR_SIGNAL,
|
STR_SIGNAL,
|
||||||
STR_NEWLINE,
|
STR_NEWLINE,
|
||||||
STR_MEMARCHIVE_FILENAME,
|
STR_MEMARCHIVE_FILENAME,
|
||||||
STR_MEMARCHIVE_ERRSTR,
|
STR_MEMARCHIVE_ERRSTR,
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Copyright (c) 1991, 1993
|
* Copyright (c) 1991, 1993
|
||||||
* The Regents of the University of California. All rights reserved.
|
* The Regents of the University of California. All rights reserved.
|
||||||
*
|
*
|
||||||
* This code is derived from software contributed to Berkeley by
|
* This code is derived from software contributed to Berkeley by
|
||||||
* James W. Williams of NASA Goddard Space Flight Center.
|
* James W. Williams of NASA Goddard Space Flight Center.
|
||||||
|
@ -48,8 +48,8 @@
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* 3. All advertising materials mentioning features or use of this software
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
* must display the following acknowledgement:
|
* must display the following acknowledgement:
|
||||||
* This product includes software developed by the University of
|
* This product includes software developed by the University of
|
||||||
* California, Berkeley and its contributors.
|
* California, Berkeley and its contributors.
|
||||||
* 4. Neither the name of the University nor the names of its contributors
|
* 4. Neither the name of the University nor the names of its contributors
|
||||||
* may be used to endorse or promote products derived from this software
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
|
@ -85,58 +85,58 @@
|
||||||
#define BUFSIZE 4096
|
#define BUFSIZE 4096
|
||||||
|
|
||||||
static uint32 crctab[] = {
|
static uint32 crctab[] = {
|
||||||
0x0,
|
0x0,
|
||||||
0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
|
0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
|
||||||
0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6,
|
0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6,
|
||||||
0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
|
0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
|
||||||
0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac,
|
0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac,
|
||||||
0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f,
|
0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f,
|
||||||
0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a,
|
0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a,
|
||||||
0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
|
0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
|
||||||
0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58,
|
0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58,
|
||||||
0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033,
|
0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033,
|
||||||
0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe,
|
0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe,
|
||||||
0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
|
0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
|
||||||
0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4,
|
0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4,
|
||||||
0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
|
0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
|
||||||
0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5,
|
0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5,
|
||||||
0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
|
0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
|
||||||
0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07,
|
0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07,
|
||||||
0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c,
|
0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c,
|
||||||
0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1,
|
0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1,
|
||||||
0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
|
0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
|
||||||
0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b,
|
0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b,
|
||||||
0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698,
|
0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698,
|
||||||
0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d,
|
0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d,
|
||||||
0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
|
0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
|
||||||
0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f,
|
0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f,
|
||||||
0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
|
0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
|
||||||
0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80,
|
0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80,
|
||||||
0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
|
0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
|
||||||
0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a,
|
0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a,
|
||||||
0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629,
|
0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629,
|
||||||
0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c,
|
0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c,
|
||||||
0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
|
0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
|
||||||
0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e,
|
0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e,
|
||||||
0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65,
|
0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65,
|
||||||
0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8,
|
0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8,
|
||||||
0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
|
0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
|
||||||
0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2,
|
0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2,
|
||||||
0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
|
0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
|
||||||
0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74,
|
0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74,
|
||||||
0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
|
0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
|
||||||
0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21,
|
0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21,
|
||||||
0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a,
|
0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a,
|
||||||
0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087,
|
0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087,
|
||||||
0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
|
0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
|
||||||
0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d,
|
0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d,
|
||||||
0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce,
|
0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce,
|
||||||
0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb,
|
0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb,
|
||||||
0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
|
0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
|
||||||
0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09,
|
0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09,
|
||||||
0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
|
0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
|
||||||
0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf,
|
0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf,
|
||||||
0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
|
0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -145,8 +145,8 @@ static uint32 crctab[] = {
|
||||||
* locations to store the crc and the number of bytes read. It returns 0 on
|
* locations to store the crc and the number of bytes read. It returns 0 on
|
||||||
* success and 1 on failure. Errno is set on failure.
|
* success and 1 on failure. Errno is set on failure.
|
||||||
*/
|
*/
|
||||||
#define COMPUTE(var, ch) (var) = ((var) << 8) ^ \
|
#define COMPUTE(var, ch) (var) = ((var) << 8) ^ \
|
||||||
crctab[0xff & (unsigned)((var) >> 24 ^ (ch))]
|
crctab[0xff & (unsigned)((var) >> 24 ^ (ch))]
|
||||||
|
|
||||||
void crcInit( CRC_INFO& crcInfo )
|
void crcInit( CRC_INFO& crcInfo )
|
||||||
{
|
{
|
||||||
|
@ -156,22 +156,22 @@ void crcInit( CRC_INFO& crcInfo )
|
||||||
|
|
||||||
void crcUpdate( CRC_INFO& crcInfo, const uint8* pbData, int cbDataLen )
|
void crcUpdate( CRC_INFO& crcInfo, const uint8* pbData, int cbDataLen )
|
||||||
{
|
{
|
||||||
for( int i = 0; i < cbDataLen; i++, pbData++ )
|
for( int i = 0; i < cbDataLen; i++, pbData++ )
|
||||||
{
|
{
|
||||||
COMPUTE( crcInfo.crc, *pbData );
|
COMPUTE( crcInfo.crc, *pbData );
|
||||||
}
|
}
|
||||||
|
|
||||||
crcInfo.cbTotalLen += cbDataLen;
|
crcInfo.cbTotalLen += cbDataLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
void crcFinit( CRC_INFO& crcInfo )
|
void crcFinit( CRC_INFO& crcInfo )
|
||||||
{
|
{
|
||||||
// include the length
|
// include the length
|
||||||
//
|
//
|
||||||
uint32 len = crcInfo.cbTotalLen;
|
uint32 len = crcInfo.cbTotalLen;
|
||||||
for(; len != 0; len >>= 8)
|
for(; len != 0; len >>= 8)
|
||||||
COMPUTE( crcInfo.crc, len & 0xff );
|
COMPUTE( crcInfo.crc, len & 0xff );
|
||||||
|
|
||||||
crcInfo.crc = ~(crcInfo.crc) & 0xFFFFFFFF;
|
crcInfo.crc = ~(crcInfo.crc) & 0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ void crcUpdate( CRC_INFO& crcInfo, const uint8* pbData, int cbDataLen );
|
||||||
void crcFinit ( CRC_INFO& crcInfo );
|
void crcFinit ( CRC_INFO& crcInfo );
|
||||||
|
|
||||||
|
|
||||||
// calculates the crc for len bytes starting at pBuf
|
// calculates the crc for len bytes starting at pBuf
|
||||||
//Wrapper function for CRC32 in crc32.cpp
|
//Wrapper function for CRC32 in crc32.cpp
|
||||||
#endif //__CRC32_H
|
#endif //__CRC32_H
|
||||||
|
|
||||||
|
|
|
@ -44,10 +44,10 @@
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
int cDebug::mDebugLevel(10);
|
int cDebug::mDebugLevel(10);
|
||||||
uint32 cDebug::mOutMask(cDebug::OUT_TRACE);
|
uint32 cDebug::mOutMask(cDebug::OUT_TRACE);
|
||||||
std::ofstream cDebug::logfile;
|
std::ofstream cDebug::logfile;
|
||||||
//mDebugLevel default == 10, mOutMask default == OUT_TRACE.
|
//mDebugLevel default == 10, mOutMask default == OUT_TRACE.
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// Constructors and Destructor
|
// Constructors and Destructor
|
||||||
|
@ -63,13 +63,13 @@ cDebug::cDebug(const char* label)
|
||||||
|
|
||||||
cDebug::cDebug(const cDebug &rhs)
|
cDebug::cDebug(const cDebug &rhs)
|
||||||
{
|
{
|
||||||
strcpy(mLabel, rhs.mLabel);
|
strcpy(mLabel, rhs.mLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
cDebug::~cDebug()
|
cDebug::~cDebug()
|
||||||
{
|
{
|
||||||
if(logfile)
|
if(logfile)
|
||||||
logfile.close();
|
logfile.close();
|
||||||
}
|
}
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -79,38 +79,38 @@ cDebug::~cDebug()
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
void cDebug::Trace(int levelNum, const char* format, ...)
|
void cDebug::Trace(int levelNum, const char* format, ...)
|
||||||
{
|
{
|
||||||
if (levelNum > mDebugLevel)
|
if (levelNum > mDebugLevel)
|
||||||
return;
|
return;
|
||||||
// create the output buffer
|
// create the output buffer
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
DoTrace(format, args);
|
DoTrace(format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDebug::Trace(int levelNum, const wchar_t* format, ...)
|
void cDebug::Trace(int levelNum, const wchar_t* format, ...)
|
||||||
{
|
{
|
||||||
if (levelNum > mDebugLevel)
|
if (levelNum > mDebugLevel)
|
||||||
return;
|
return;
|
||||||
// create the output buffer
|
// create the output buffer
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
DoTrace(format, args);
|
DoTrace(format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// DoTrace()
|
// DoTrace()
|
||||||
// internal helper function -- does the actual printing to logfile,
|
// internal helper function -- does the actual printing to logfile,
|
||||||
// console, etc...
|
// console, etc...
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void cDebug::DoTrace(const char *format, va_list &args)
|
void cDebug::DoTrace(const char *format, va_list &args)
|
||||||
{
|
{
|
||||||
size_t guard1 = 0xBABABABA;
|
size_t guard1 = 0xBABABABA;
|
||||||
char out[2048];
|
char out[2048];
|
||||||
size_t guard2 = 0xBABABABA;
|
size_t guard2 = 0xBABABABA;
|
||||||
|
|
||||||
vsprintf(out, format, args);
|
vsprintf(out, format, args);
|
||||||
|
@ -118,32 +118,32 @@ void cDebug::DoTrace(const char *format, va_list &args)
|
||||||
ASSERT(guard1 == 0xBABABABA && guard2 == 0xBABABABA); // string was too long
|
ASSERT(guard1 == 0xBABABABA && guard2 == 0xBABABABA); // string was too long
|
||||||
ASSERT(strlen(out) < 1024);
|
ASSERT(strlen(out) < 1024);
|
||||||
|
|
||||||
std::ostringstream ostr;
|
std::ostringstream ostr;
|
||||||
ostr.setf(std::ios::left);
|
ostr.setf(std::ios::left);
|
||||||
ostr.width(40);
|
ostr.width(40);
|
||||||
ostr << mLabel;
|
ostr << mLabel;
|
||||||
ostr.width(0);
|
ostr.width(0);
|
||||||
ostr << out;
|
ostr << out;
|
||||||
|
|
||||||
|
|
||||||
if ((mOutMask & OUT_STDOUT) != 0)
|
if ((mOutMask & OUT_STDOUT) != 0)
|
||||||
{
|
{
|
||||||
std::cout << ostr.str().c_str();
|
std::cout << ostr.str().c_str();
|
||||||
std::cout.flush();
|
std::cout.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
//make it output to log file!
|
//make it output to log file!
|
||||||
//
|
//
|
||||||
if ((mOutMask & OUT_FILE) != 0)
|
if ((mOutMask & OUT_FILE) != 0)
|
||||||
{
|
{
|
||||||
// the logfile is narrow chars only...
|
// the logfile is narrow chars only...
|
||||||
logfile.setf(std::ios::left);
|
logfile.setf(std::ios::left);
|
||||||
logfile.width(40);
|
logfile.width(40);
|
||||||
logfile << mLabel;
|
logfile << mLabel;
|
||||||
logfile.width(0);
|
logfile.width(0);
|
||||||
logfile << out;
|
logfile << out;
|
||||||
logfile.flush();
|
logfile.flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,42 +156,42 @@ void cDebug::DoTrace(const wchar_t *format, va_list &args)
|
||||||
#else
|
#else
|
||||||
|
|
||||||
size_t guard1 = 0xBABABABA;
|
size_t guard1 = 0xBABABABA;
|
||||||
wchar_t out[2048];
|
wchar_t out[2048];
|
||||||
size_t guard2 = 0xBABABABA;
|
size_t guard2 = 0xBABABABA;
|
||||||
|
|
||||||
vswprintf(out, format, args);
|
vswprintf(out, format, args);
|
||||||
|
|
||||||
ASSERT(guard1 == 0xBABABABA && guard2 == 0xBABABABA); // string was too long
|
ASSERT(guard1 == 0xBABABABA && guard2 == 0xBABABABA); // string was too long
|
||||||
char nout[1024];
|
char nout[1024];
|
||||||
if (wcstombs(nout, out, 1024) == -1)
|
if (wcstombs(nout, out, 1024) == -1)
|
||||||
strcpy(nout, "XXX Unconvertable wide char detected in cDebug::DoTrace()\n");
|
strcpy(nout, "XXX Unconvertable wide char detected in cDebug::DoTrace()\n");
|
||||||
|
|
||||||
std::ostringstream ostr;
|
std::ostringstream ostr;
|
||||||
ostr.setf(std::ios::left);
|
ostr.setf(std::ios::left);
|
||||||
ostr.width(40);
|
ostr.width(40);
|
||||||
ostr << mLabel;
|
ostr << mLabel;
|
||||||
ostr.width(0);
|
ostr.width(0);
|
||||||
ostr << nout;
|
ostr << nout;
|
||||||
|
|
||||||
|
|
||||||
if ((mOutMask & OUT_STDOUT) != 0)
|
if ((mOutMask & OUT_STDOUT) != 0)
|
||||||
{
|
{
|
||||||
std::cout << ostr.str().c_str();
|
std::cout << ostr.str().c_str();
|
||||||
std::cout.flush();
|
std::cout.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
//make it output to log file!
|
//make it output to log file!
|
||||||
//
|
//
|
||||||
if ((mOutMask & OUT_FILE) != 0)
|
if ((mOutMask & OUT_FILE) != 0)
|
||||||
{
|
{
|
||||||
// the logfile is narrow chars only...
|
// the logfile is narrow chars only...
|
||||||
logfile.setf(std::ios::left);
|
logfile.setf(std::ios::left);
|
||||||
logfile.width(40);
|
logfile.width(40);
|
||||||
logfile << mLabel;
|
logfile << mLabel;
|
||||||
logfile.width(0);
|
logfile.width(0);
|
||||||
logfile << out;
|
logfile << out;
|
||||||
logfile.flush();
|
logfile.flush();
|
||||||
}
|
}
|
||||||
#endif // IS_UNIX
|
#endif // IS_UNIX
|
||||||
}
|
}
|
||||||
|
@ -200,151 +200,151 @@ void cDebug::DoTrace(const wchar_t *format, va_list &args)
|
||||||
|
|
||||||
//
|
//
|
||||||
// wrappers around Trace() that requires less typing
|
// wrappers around Trace() that requires less typing
|
||||||
// TODO: this is quick and dirty, but lets me check in all these files right away. --ghk
|
// TODO: this is quick and dirty, but lets me check in all these files right away. --ghk
|
||||||
//
|
//
|
||||||
|
|
||||||
void cDebug::TraceAlways(const char *format, ...)
|
void cDebug::TraceAlways(const char *format, ...)
|
||||||
{
|
{
|
||||||
if (D_ALWAYS > mDebugLevel)
|
if (D_ALWAYS > mDebugLevel)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// fill up arglist, and pass to printing routine
|
// fill up arglist, and pass to printing routine
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
DoTrace(format, args);
|
DoTrace(format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDebug::TraceError(const char *format, ...)
|
void cDebug::TraceError(const char *format, ...)
|
||||||
{
|
{
|
||||||
if (D_ERROR > mDebugLevel)
|
if (D_ERROR > mDebugLevel)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// fill up arglist, and pass to printing routine
|
// fill up arglist, and pass to printing routine
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
DoTrace(format, args);
|
DoTrace(format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDebug::TraceWarning(const char *format, ...)
|
void cDebug::TraceWarning(const char *format, ...)
|
||||||
{
|
{
|
||||||
if (D_WARNING > mDebugLevel)
|
if (D_WARNING > mDebugLevel)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// fill up arglist, and pass to printing routine
|
// fill up arglist, and pass to printing routine
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
DoTrace(format, args);
|
DoTrace(format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDebug::TraceDebug(const char *format, ...)
|
void cDebug::TraceDebug(const char *format, ...)
|
||||||
{
|
{
|
||||||
if (D_DEBUG > mDebugLevel)
|
if (D_DEBUG > mDebugLevel)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// fill up arglist, and pass to printing routine
|
// fill up arglist, and pass to printing routine
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
DoTrace(format, args);
|
DoTrace(format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDebug::TraceDetail(const char *format, ...)
|
void cDebug::TraceDetail(const char *format, ...)
|
||||||
{
|
{
|
||||||
if (D_DETAIL > mDebugLevel)
|
if (D_DETAIL > mDebugLevel)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// fill up arglist, and pass to printing routine
|
// fill up arglist, and pass to printing routine
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
DoTrace(format, args);
|
DoTrace(format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDebug::TraceNever(const char *format, ...)
|
void cDebug::TraceNever(const char *format, ...)
|
||||||
{
|
{
|
||||||
if (D_NEVER > mDebugLevel)
|
if (D_NEVER > mDebugLevel)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// fill up arglist, and pass to printing routine
|
// fill up arglist, and pass to printing routine
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
DoTrace(format, args);
|
DoTrace(format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDebug::TraceAlways(const wchar_t *format, ...)
|
void cDebug::TraceAlways(const wchar_t *format, ...)
|
||||||
{
|
{
|
||||||
if (D_ALWAYS > mDebugLevel)
|
if (D_ALWAYS > mDebugLevel)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// fill up arglist, and pass to printing routine
|
// fill up arglist, and pass to printing routine
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
DoTrace(format, args);
|
DoTrace(format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDebug::TraceError(const wchar_t *format, ...)
|
void cDebug::TraceError(const wchar_t *format, ...)
|
||||||
{
|
{
|
||||||
if (D_ERROR > mDebugLevel)
|
if (D_ERROR > mDebugLevel)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// fill up arglist, and pass to printing routine
|
// fill up arglist, and pass to printing routine
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
DoTrace(format, args);
|
DoTrace(format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDebug::TraceWarning(const wchar_t *format, ...)
|
void cDebug::TraceWarning(const wchar_t *format, ...)
|
||||||
{
|
{
|
||||||
if (D_WARNING > mDebugLevel)
|
if (D_WARNING > mDebugLevel)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// fill up arglist, and pass to printing routine
|
// fill up arglist, and pass to printing routine
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
DoTrace(format, args);
|
DoTrace(format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDebug::TraceDebug(const wchar_t *format, ...)
|
void cDebug::TraceDebug(const wchar_t *format, ...)
|
||||||
{
|
{
|
||||||
if (D_DEBUG > mDebugLevel)
|
if (D_DEBUG > mDebugLevel)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// fill up arglist, and pass to printing routine
|
// fill up arglist, and pass to printing routine
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
DoTrace(format, args);
|
DoTrace(format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDebug::TraceDetail(const wchar_t *format, ...)
|
void cDebug::TraceDetail(const wchar_t *format, ...)
|
||||||
{
|
{
|
||||||
if (D_DETAIL > mDebugLevel)
|
if (D_DETAIL > mDebugLevel)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// fill up arglist, and pass to printing routine
|
// fill up arglist, and pass to printing routine
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
DoTrace(format, args);
|
DoTrace(format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDebug::TraceNever(const wchar_t *format, ...)
|
void cDebug::TraceNever(const wchar_t *format, ...)
|
||||||
{
|
{
|
||||||
if (D_NEVER > mDebugLevel)
|
if (D_NEVER > mDebugLevel)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// fill up arglist, and pass to printing routine
|
// fill up arglist, and pass to printing routine
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
DoTrace(format, args);
|
DoTrace(format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDebug::TraceVaArgs( int iDebugLevel, const char *format, va_list &args )
|
void cDebug::TraceVaArgs( int iDebugLevel, const char *format, va_list &args )
|
||||||
|
@ -367,15 +367,15 @@ void cDebug::TraceVaArgs( int iDebugLevel, const wchar_t *format, va_list &args
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
bool cDebug::AddOutTarget(OutTarget target)
|
bool cDebug::AddOutTarget(OutTarget target)
|
||||||
{
|
{
|
||||||
if (target == OUT_STDOUT)
|
if (target == OUT_STDOUT)
|
||||||
mOutMask |= OUT_STDOUT;
|
mOutMask |= OUT_STDOUT;
|
||||||
if (target == OUT_TRACE)
|
if (target == OUT_TRACE)
|
||||||
mOutMask |= OUT_TRACE;
|
mOutMask |= OUT_TRACE;
|
||||||
if (target == OUT_FILE) {
|
if (target == OUT_FILE) {
|
||||||
mOutMask |= OUT_FILE;
|
mOutMask |= OUT_FILE;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -383,15 +383,15 @@ bool cDebug::AddOutTarget(OutTarget target)
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
bool cDebug::RemoveOutTarget(OutTarget target)
|
bool cDebug::RemoveOutTarget(OutTarget target)
|
||||||
{
|
{
|
||||||
if (!HasOutTarget(target))
|
if (!HasOutTarget(target))
|
||||||
return true;
|
return true;
|
||||||
if (target == OUT_STDOUT)
|
if (target == OUT_STDOUT)
|
||||||
mOutMask ^= OUT_STDOUT;
|
mOutMask ^= OUT_STDOUT;
|
||||||
if (target == OUT_TRACE)
|
if (target == OUT_TRACE)
|
||||||
mOutMask ^= OUT_TRACE;
|
mOutMask ^= OUT_TRACE;
|
||||||
if (target == OUT_FILE)
|
if (target == OUT_FILE)
|
||||||
mOutMask ^= OUT_FILE;
|
mOutMask ^= OUT_FILE;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -400,14 +400,14 @@ bool cDebug::RemoveOutTarget(OutTarget target)
|
||||||
bool cDebug::HasOutTarget(OutTarget target)
|
bool cDebug::HasOutTarget(OutTarget target)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (target == OUT_STDOUT)
|
if (target == OUT_STDOUT)
|
||||||
return ((mOutMask & OUT_STDOUT) != 0);
|
return ((mOutMask & OUT_STDOUT) != 0);
|
||||||
else if (target == OUT_TRACE)
|
else if (target == OUT_TRACE)
|
||||||
return ((mOutMask & OUT_TRACE) != 0);
|
return ((mOutMask & OUT_TRACE) != 0);
|
||||||
else if (target == OUT_FILE)
|
else if (target == OUT_FILE)
|
||||||
return ((mOutMask & OUT_FILE) != 0);
|
return ((mOutMask & OUT_FILE) != 0);
|
||||||
else //ambiguous input, or too many bits set in target
|
else //ambiguous input, or too many bits set in target
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -416,22 +416,22 @@ bool cDebug::HasOutTarget(OutTarget target)
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
bool cDebug::SetOutputFile(const char* filename)
|
bool cDebug::SetOutputFile(const char* filename)
|
||||||
{
|
{
|
||||||
// TODO -- make sure this does the right thing if a log file is
|
// TODO -- make sure this does the right thing if a log file is
|
||||||
// already open!
|
// already open!
|
||||||
// TODO -- make this work with wide chars
|
// TODO -- make this work with wide chars
|
||||||
if (!logfile)
|
if (!logfile)
|
||||||
logfile.open(filename, std::ios_base::out | std::ios_base::ate | std::ios_base::app);
|
logfile.open(filename, std::ios_base::out | std::ios_base::ate | std::ios_base::app);
|
||||||
else
|
else
|
||||||
logfile.setf(std::ios_base::hex, std::ios_base::basefield);
|
logfile.setf(std::ios_base::hex, std::ios_base::basefield);
|
||||||
//make sure info. will not be clobbered.
|
//make sure info. will not be clobbered.
|
||||||
|
|
||||||
//Should be open now- if not, abort.
|
//Should be open now- if not, abort.
|
||||||
if (!logfile) {
|
if (!logfile) {
|
||||||
mOutMask ^= OUT_FILE;
|
mOutMask ^= OUT_FILE;
|
||||||
return false;
|
return false;
|
||||||
} else
|
} else
|
||||||
mOutMask |= OUT_FILE;
|
mOutMask |= OUT_FILE;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -440,7 +440,7 @@ bool cDebug::SetOutputFile(const char* filename)
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
void cDebug::DebugOut( const char* lpOutputString, ... )
|
void cDebug::DebugOut( const char* lpOutputString, ... )
|
||||||
{
|
{
|
||||||
char buf[2048];
|
char buf[2048];
|
||||||
// create the output buffer
|
// create the output buffer
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, lpOutputString);
|
va_start(args, lpOutputString);
|
||||||
|
@ -449,25 +449,25 @@ void cDebug::DebugOut( const char* lpOutputString, ... )
|
||||||
|
|
||||||
#ifdef _UNICODE
|
#ifdef _UNICODE
|
||||||
wchar_t wbuf[2048];
|
wchar_t wbuf[2048];
|
||||||
if (mbstowcs(wbuf, buf, strlen(buf)+1) == -1)
|
if (mbstowcs(wbuf, buf, strlen(buf)+1) == -1)
|
||||||
wcscpy(wbuf, _T("XXX Unconvertable mb character detected in cDebug::DebugOut()\n") );
|
wcscpy(wbuf, _T("XXX Unconvertable mb character detected in cDebug::DebugOut()\n") );
|
||||||
|
|
||||||
#if !USE_OUTPUT_DEBUG_STRING
|
#if !USE_OUTPUT_DEBUG_STRING
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
TCERR << wbuf;
|
TCERR << wbuf;
|
||||||
#endif //_DEBUG
|
#endif //_DEBUG
|
||||||
#else // USE_OUTPUT_DEBUG_STRING
|
#else // USE_OUTPUT_DEBUG_STRING
|
||||||
::OutputDebugString(wbuf);
|
::OutputDebugString(wbuf);
|
||||||
#endif // USE_OUTPUT_DEBUG_STRING
|
#endif // USE_OUTPUT_DEBUG_STRING
|
||||||
#else // _UNICODE
|
#else // _UNICODE
|
||||||
#if !USE_OUTPUT_DEBUG_STRING
|
#if !USE_OUTPUT_DEBUG_STRING
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
TCERR << buf;
|
TCERR << buf;
|
||||||
#endif //_DEBUG
|
#endif //_DEBUG
|
||||||
#else // USE_OUTPUT_DEBUG_STRING
|
#else // USE_OUTPUT_DEBUG_STRING
|
||||||
::OutputDebugString(buf);
|
::OutputDebugString(buf);
|
||||||
#endif // USE_OUTPUT_DEBUG_STRING
|
#endif // USE_OUTPUT_DEBUG_STRING
|
||||||
#endif // _UNICODE
|
#endif // _UNICODE
|
||||||
|
|
||||||
TCOUT.flush();
|
TCOUT.flush();
|
||||||
}
|
}
|
||||||
|
@ -480,7 +480,7 @@ void cDebug::DebugOut( const wchar_t* lpOutputString, ... )
|
||||||
#if IS_UNIX
|
#if IS_UNIX
|
||||||
char mbformatbuf[1024];
|
char mbformatbuf[1024];
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
// if (wcstombs(mbformatbuf, lpOutputString, wcslen(lpOutputString)) == -1)
|
// if (wcstombs(mbformatbuf, lpOutputString, wcslen(lpOutputString)) == -1)
|
||||||
// strcpy(mbformatbuf, "XXX Unconvertable wide char detected in cDebug::DebugOut()\n");
|
// strcpy(mbformatbuf, "XXX Unconvertable wide char detected in cDebug::DebugOut()\n");
|
||||||
|
|
||||||
vsprintf(buf, mbformatbuf, args);
|
vsprintf(buf, mbformatbuf, args);
|
||||||
|
@ -495,26 +495,26 @@ void cDebug::DebugOut( const wchar_t* lpOutputString, ... )
|
||||||
#if !USE_OUTPUT_DEBUG_STRING
|
#if !USE_OUTPUT_DEBUG_STRING
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
TCERR << buf;
|
TCERR << buf;
|
||||||
#endif //_DEBUG
|
#endif //_DEBUG
|
||||||
#else // USE_OUTPUT_DEBUG_STRING
|
#else // USE_OUTPUT_DEBUG_STRING
|
||||||
::OutputDebugString(buf);
|
::OutputDebugString(buf);
|
||||||
#endif // USE_OUTPUT_DEBUG_STRING
|
#endif // USE_OUTPUT_DEBUG_STRING
|
||||||
#else
|
#else
|
||||||
char nbuf[1024];
|
char nbuf[1024];
|
||||||
#if IS_UNIX
|
#if IS_UNIX
|
||||||
strcpy(nbuf, buf);
|
strcpy(nbuf, buf);
|
||||||
#else
|
#else
|
||||||
if (wcstombs(nbuf, buf, wcslen(buf)+1) == -1)
|
if (wcstombs(nbuf, buf, wcslen(buf)+1) == -1)
|
||||||
strcpy(nbuf, "XXX Unconvertable wide char detected in cDebug::DebugOut()\n");
|
strcpy(nbuf, "XXX Unconvertable wide char detected in cDebug::DebugOut()\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !USE_OUTPUT_DEBUG_STRING
|
#if !USE_OUTPUT_DEBUG_STRING
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
TCERR << nbuf;
|
TCERR << nbuf;
|
||||||
#endif //_DEBUG
|
#endif //_DEBUG
|
||||||
#else // USE_OUTPUT_DEBUG_STRING
|
#else // USE_OUTPUT_DEBUG_STRING
|
||||||
::OutputDebugString(nbuf);
|
::OutputDebugString(nbuf);
|
||||||
#endif // USE_OUTPUT_DEBUG_STRING
|
#endif // USE_OUTPUT_DEBUG_STRING
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TCOUT.flush();
|
TCOUT.flush();
|
||||||
|
|
176
src/core/debug.h
176
src/core/debug.h
|
@ -61,7 +61,7 @@
|
||||||
// When compiling with MFC, these are already defined and we get error msgs
|
// When compiling with MFC, these are already defined and we get error msgs
|
||||||
// every time this file is included. Since these behave the same as the MFC
|
// every time this file is included. Since these behave the same as the MFC
|
||||||
// version, it is OK to always undef them here....
|
// version, it is OK to always undef them here....
|
||||||
// -- 20 Aug 99 mdb
|
// -- 20 Aug 99 mdb
|
||||||
//
|
//
|
||||||
#undef ASSERT
|
#undef ASSERT
|
||||||
#undef TRACE
|
#undef TRACE
|
||||||
|
@ -78,90 +78,90 @@
|
||||||
class cDebug
|
class cDebug
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum OutTarget
|
enum OutTarget
|
||||||
{
|
{
|
||||||
OUT_STDOUT = 1,
|
OUT_STDOUT = 1,
|
||||||
OUT_TRACE = 2,
|
OUT_TRACE = 2,
|
||||||
OUT_FILE = 4
|
OUT_FILE = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
enum DebugLevel
|
enum DebugLevel
|
||||||
{
|
{
|
||||||
D_ALWAYS = 0,
|
D_ALWAYS = 0,
|
||||||
D_ERROR = 1,
|
D_ERROR = 1,
|
||||||
D_WARNING = 4,
|
D_WARNING = 4,
|
||||||
D_DEBUG = 8,
|
D_DEBUG = 8,
|
||||||
D_DETAIL = 16,
|
D_DETAIL = 16,
|
||||||
D_NEVER = 1000
|
D_NEVER = 1000
|
||||||
};
|
};
|
||||||
|
|
||||||
cDebug(const char* pLabel);
|
cDebug(const char* pLabel);
|
||||||
~cDebug();
|
~cDebug();
|
||||||
cDebug(const cDebug& rhs);
|
cDebug(const cDebug& rhs);
|
||||||
|
|
||||||
// These are the preferred tracing interfaces, because you don't need to know
|
// These are the preferred tracing interfaces, because you don't need to know
|
||||||
// the DebugLevel enums.
|
// the DebugLevel enums.
|
||||||
// Wide/Narrow Chars Issues: If you include a %s in your format string and you
|
// Wide/Narrow Chars Issues: If you include a %s in your format string and you
|
||||||
// wish to print out a TCHAR (which might be a natural thing to do) you should
|
// wish to print out a TCHAR (which might be a natural thing to do) you should
|
||||||
// encompas the format string with a _T("") macro, i.e. make it a TSTRING.
|
// encompas the format string with a _T("") macro, i.e. make it a TSTRING.
|
||||||
// The wide character overloads of these functions will expect wide strings
|
// The wide character overloads of these functions will expect wide strings
|
||||||
// for %s options.
|
// for %s options.
|
||||||
//
|
//
|
||||||
void TraceAlways (const char *format, ...);
|
void TraceAlways (const char *format, ...);
|
||||||
void TraceError (const char *format, ...);
|
void TraceError (const char *format, ...);
|
||||||
void TraceWarning (const char *format, ...);
|
void TraceWarning (const char *format, ...);
|
||||||
void TraceDebug (const char *format, ...);
|
void TraceDebug (const char *format, ...);
|
||||||
void TraceDetail (const char *format, ...);
|
void TraceDetail (const char *format, ...);
|
||||||
void TraceNever (const char *format, ...);
|
void TraceNever (const char *format, ...);
|
||||||
void TraceAlways (const wchar_t *format, ...);
|
void TraceAlways (const wchar_t *format, ...);
|
||||||
void TraceError (const wchar_t *format, ...);
|
void TraceError (const wchar_t *format, ...);
|
||||||
void TraceWarning (const wchar_t *format, ...);
|
void TraceWarning (const wchar_t *format, ...);
|
||||||
void TraceDebug (const wchar_t *format, ...);
|
void TraceDebug (const wchar_t *format, ...);
|
||||||
void TraceDetail (const wchar_t *format, ...);
|
void TraceDetail (const wchar_t *format, ...);
|
||||||
void TraceNever (const wchar_t *format, ...);
|
void TraceNever (const wchar_t *format, ...);
|
||||||
|
|
||||||
// these are of use if you are inside a function with a "..." as an argument
|
// these are of use if you are inside a function with a "..." as an argument
|
||||||
// and you want to trace those args
|
// and you want to trace those args
|
||||||
void TraceVaArgs (int iDebugLevel, const char *format, va_list &args);
|
void TraceVaArgs (int iDebugLevel, const char *format, va_list &args);
|
||||||
void TraceVaArgs (int iDebugLevel, const wchar_t *format, va_list &args);
|
void TraceVaArgs (int iDebugLevel, const wchar_t *format, va_list &args);
|
||||||
|
|
||||||
// ...but you can still choose to use this interface...
|
// ...but you can still choose to use this interface...
|
||||||
|
|
||||||
void Trace(int levelNum, const char* format, ...);
|
void Trace(int levelNum, const char* format, ...);
|
||||||
void Trace(int levelNum, const wchar_t* format, ...);
|
void Trace(int levelNum, const wchar_t* format, ...);
|
||||||
// Outputs based on levelnum. If levelnum <= global debug, print.
|
// Outputs based on levelnum. If levelnum <= global debug, print.
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static bool AddOutTarget (OutTarget target);
|
static bool AddOutTarget (OutTarget target);
|
||||||
static bool RemoveOutTarget (OutTarget target);
|
static bool RemoveOutTarget (OutTarget target);
|
||||||
// used to specify the out target....
|
// used to specify the out target....
|
||||||
static bool HasOutTarget (OutTarget target);
|
static bool HasOutTarget (OutTarget target);
|
||||||
|
|
||||||
static bool SetOutputFile (const char* filename);
|
static bool SetOutputFile (const char* filename);
|
||||||
// specifies the output file name used when OUT_FILE is set
|
// specifies the output file name used when OUT_FILE is set
|
||||||
static void SetDebugLevel (int level);
|
static void SetDebugLevel (int level);
|
||||||
static int GetDebugLevel (void);
|
static int GetDebugLevel (void);
|
||||||
// gets and sets the global debug level. Trace output at or below this
|
// gets and sets the global debug level. Trace output at or below this
|
||||||
// level will be output.
|
// level will be output.
|
||||||
|
|
||||||
static void DebugOut ( const char* lpOutputString, ... );
|
static void DebugOut ( const char* lpOutputString, ... );
|
||||||
static void DebugOut ( const wchar_t* lpOutputString, ... );
|
static void DebugOut ( const wchar_t* lpOutputString, ... );
|
||||||
// Works just like TRACE
|
// Works just like TRACE
|
||||||
// note: there is an internal buffer size of 1024; traces larger
|
// note: there is an internal buffer size of 1024; traces larger
|
||||||
// than that will have unpredictable and probably bad results
|
// than that will have unpredictable and probably bad results
|
||||||
private:
|
private:
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
enum { MAX_LABEL = 128 };
|
enum { MAX_LABEL = 128 };
|
||||||
|
|
||||||
static int mDebugLevel;
|
static int mDebugLevel;
|
||||||
static uint32 mOutMask;
|
static uint32 mOutMask;
|
||||||
static std::ofstream logfile;
|
static std::ofstream logfile;
|
||||||
char mLabel[MAX_LABEL];
|
char mLabel[MAX_LABEL];
|
||||||
|
|
||||||
// helper functions
|
// helper functions
|
||||||
void DoTrace(const char *format, va_list &args);
|
void DoTrace(const char *format, va_list &args);
|
||||||
void DoTrace(const wchar_t *format, va_list &args);
|
void DoTrace(const wchar_t *format, va_list &args);
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -180,12 +180,12 @@ private:
|
||||||
|
|
||||||
inline void cDebug::SetDebugLevel(int level)
|
inline void cDebug::SetDebugLevel(int level)
|
||||||
{
|
{
|
||||||
mDebugLevel = level;
|
mDebugLevel = level;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int cDebug::GetDebugLevel()
|
inline int cDebug::GetDebugLevel()
|
||||||
{
|
{
|
||||||
return mDebugLevel;
|
return mDebugLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // DEBUG
|
#else // DEBUG
|
||||||
|
@ -193,30 +193,30 @@ inline int cDebug::GetDebugLevel()
|
||||||
inline cDebug::cDebug (const char *) {}
|
inline cDebug::cDebug (const char *) {}
|
||||||
inline cDebug::~cDebug () {}
|
inline cDebug::~cDebug () {}
|
||||||
inline cDebug::cDebug (const cDebug&) {}
|
inline cDebug::cDebug (const cDebug&) {}
|
||||||
inline void cDebug::TraceAlways (const char *, ...) {}
|
inline void cDebug::TraceAlways (const char *, ...) {}
|
||||||
inline void cDebug::TraceError (const char *, ...) {}
|
inline void cDebug::TraceError (const char *, ...) {}
|
||||||
inline void cDebug::TraceWarning (const char *, ...) {}
|
inline void cDebug::TraceWarning (const char *, ...) {}
|
||||||
inline void cDebug::TraceDebug (const char *, ...) {}
|
inline void cDebug::TraceDebug (const char *, ...) {}
|
||||||
inline void cDebug::TraceDetail (const char *, ...) {}
|
inline void cDebug::TraceDetail (const char *, ...) {}
|
||||||
inline void cDebug::TraceNever (const char *, ...) {}
|
inline void cDebug::TraceNever (const char *, ...) {}
|
||||||
inline void cDebug::TraceAlways (const wchar_t *, ...) {}
|
inline void cDebug::TraceAlways (const wchar_t *, ...) {}
|
||||||
inline void cDebug::TraceError (const wchar_t *, ...) {}
|
inline void cDebug::TraceError (const wchar_t *, ...) {}
|
||||||
inline void cDebug::TraceWarning (const wchar_t *, ...) {}
|
inline void cDebug::TraceWarning (const wchar_t *, ...) {}
|
||||||
inline void cDebug::TraceDebug (const wchar_t *, ...) {}
|
inline void cDebug::TraceDebug (const wchar_t *, ...) {}
|
||||||
inline void cDebug::TraceDetail (const wchar_t *, ...) {}
|
inline void cDebug::TraceDetail (const wchar_t *, ...) {}
|
||||||
inline void cDebug::TraceNever (const wchar_t *, ...) {}
|
inline void cDebug::TraceNever (const wchar_t *, ...) {}
|
||||||
inline void cDebug::TraceVaArgs (int, const char *, va_list &) {}
|
inline void cDebug::TraceVaArgs (int, const char *, va_list &) {}
|
||||||
inline void cDebug::TraceVaArgs (int, const wchar_t *, va_list &) {}
|
inline void cDebug::TraceVaArgs (int, const wchar_t *, va_list &) {}
|
||||||
inline void cDebug::Trace (int, const char*, ...) {}
|
inline void cDebug::Trace (int, const char*, ...) {}
|
||||||
inline void cDebug::Trace (int, const wchar_t*, ...) {}
|
inline void cDebug::Trace (int, const wchar_t*, ...) {}
|
||||||
inline bool cDebug::AddOutTarget (OutTarget) { return false; }
|
inline bool cDebug::AddOutTarget (OutTarget) { return false; }
|
||||||
inline bool cDebug::RemoveOutTarget (OutTarget) { return false; }
|
inline bool cDebug::RemoveOutTarget (OutTarget) { return false; }
|
||||||
inline bool cDebug::HasOutTarget (OutTarget) { return false; }
|
inline bool cDebug::HasOutTarget (OutTarget) { return false; }
|
||||||
inline bool cDebug::SetOutputFile (const char*) { return false; }
|
inline bool cDebug::SetOutputFile (const char*) { return false; }
|
||||||
inline void cDebug::SetDebugLevel (int) {}
|
inline void cDebug::SetDebugLevel (int) {}
|
||||||
inline int cDebug::GetDebugLevel (void) { return 0; }
|
inline int cDebug::GetDebugLevel (void) { return 0; }
|
||||||
inline void cDebug::DebugOut ( const char*, ... ) {}
|
inline void cDebug::DebugOut ( const char*, ... ) {}
|
||||||
inline void cDebug::DebugOut ( const wchar_t*, ... ) {}
|
inline void cDebug::DebugOut ( const wchar_t*, ... ) {}
|
||||||
|
|
||||||
#endif // DEBUG
|
#endif // DEBUG
|
||||||
|
|
||||||
|
@ -229,9 +229,9 @@ inline void cDebug::DebugOut ( const wchar_t*, ... ) {}
|
||||||
|
|
||||||
#if IS_UNIX
|
#if IS_UNIX
|
||||||
|
|
||||||
#define ASSERTMSG( exp, s ) assert( (exp) != 0 )
|
#define ASSERTMSG( exp, s ) assert( (exp) != 0 )
|
||||||
#define ASSERT( exp ) assert( (exp) != 0 )
|
#define ASSERT( exp ) assert( (exp) != 0 )
|
||||||
// if we are not windows we will just use the standard assert()
|
// if we are not windows we will just use the standard assert()
|
||||||
#define TSS_DebugBreak() ASSERT( false );
|
#define TSS_DebugBreak() ASSERT( false );
|
||||||
|
|
||||||
#endif// IS_UNIX
|
#endif// IS_UNIX
|
||||||
|
|
|
@ -829,7 +829,7 @@ bool cEncoder::OnlyOneCatagoryPerChar() const
|
||||||
ach[0] = ch;
|
ach[0] = ch;
|
||||||
for( sack_type::const_iterator atE = m_encodings.begin(); atE != m_encodings.end(); atE++ )
|
for( sack_type::const_iterator atE = m_encodings.begin(); atE != m_encodings.end(); atE++ )
|
||||||
{
|
{
|
||||||
if( (*atE)->NeedsEncoding( ach.begin(), ach.end() ) )
|
if( (*atE)->NeedsEncoding( ach.begin(), ach.end() ) )
|
||||||
{
|
{
|
||||||
if( fFailedATest )
|
if( fFailedATest )
|
||||||
return false; // each char can only fail one test
|
return false; // each char can only fail one test
|
||||||
|
|
|
@ -41,11 +41,11 @@
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
uint32 eError::CalcHash( const char* name )
|
uint32 eError::CalcHash( const char* name )
|
||||||
{
|
{
|
||||||
CRC_INFO crc;
|
CRC_INFO crc;
|
||||||
crcInit( crc );
|
crcInit( crc );
|
||||||
crcUpdate( crc, (const uint8*)name, strlen( name ) );
|
crcUpdate( crc, (const uint8*)name, strlen( name ) );
|
||||||
crcFinit( crc );
|
crcFinit( crc );
|
||||||
return crc.crc;
|
return crc.crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
182
src/core/error.h
182
src/core/error.h
|
@ -43,55 +43,55 @@ class eError
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
// Construction and Assignment
|
// Construction and Assignment
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
eError( const TSTRING& msg, uint32 flags = 0 );
|
eError( const TSTRING& msg, uint32 flags = 0 );
|
||||||
explicit eError( const eError& rhs );
|
explicit eError( const eError& rhs );
|
||||||
explicit eError();
|
explicit eError();
|
||||||
void operator=( const eError& rhs );
|
void operator=( const eError& rhs );
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
// Destruction
|
// Destruction
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
virtual ~eError();
|
virtual ~eError();
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
// Data Access
|
// Data Access
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
virtual uint32 GetID() const = 0;
|
virtual uint32 GetID() const = 0;
|
||||||
// returns a system wide unique identifier for this exception. See the
|
// returns a system wide unique identifier for this exception. See the
|
||||||
// macro below for the typical implementation of this method.
|
// macro below for the typical implementation of this method.
|
||||||
// This is used to associate the error with a string description of the
|
// This is used to associate the error with a string description of the
|
||||||
// error via the global error table.
|
// error via the global error table.
|
||||||
|
|
||||||
virtual TSTRING GetMsg() const;
|
virtual TSTRING GetMsg() const;
|
||||||
// returns specific information about the error that occured. Provides
|
// returns specific information about the error that occured. Provides
|
||||||
// additional information about the error described by GetID(). It should
|
// additional information about the error described by GetID(). It should
|
||||||
// not provide any information redundant with GetID().
|
// not provide any information redundant with GetID().
|
||||||
//
|
//
|
||||||
// The string passed to the constructor should be formated properly to
|
// The string passed to the constructor should be formated properly to
|
||||||
// be displayed as the "Second" part of an error message, or the derived
|
// be displayed as the "Second" part of an error message, or the derived
|
||||||
// class should override GetMsg() and return a string appropriate for display.
|
// class should override GetMsg() and return a string appropriate for display.
|
||||||
|
|
||||||
uint32 GetFlags() const;
|
uint32 GetFlags() const;
|
||||||
// Flags are defined below. Currently, these only have an impact on how errors are
|
// Flags are defined below. Currently, these only have an impact on how errors are
|
||||||
// displayed.
|
// displayed.
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
// Flags
|
// Flags
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
enum Flag
|
enum Flag
|
||||||
{
|
{
|
||||||
NON_FATAL = 0x00000001, // displays "Error" or "Warning" ?
|
NON_FATAL = 0x00000001, // displays "Error" or "Warning" ?
|
||||||
SUPRESS_THIRD_MSG = 0x00000002 // supresses the "continuing" or "exiting" message
|
SUPRESS_THIRD_MSG = 0x00000002 // supresses the "continuing" or "exiting" message
|
||||||
};
|
};
|
||||||
|
|
||||||
void SetFlags( uint32 flags );
|
void SetFlags( uint32 flags );
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
// Flag Convenience Methods
|
// Flag Convenience Methods
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
void SetFatality(bool fatal);
|
void SetFatality(bool fatal);
|
||||||
bool IsFatal() const;
|
bool IsFatal() const;
|
||||||
// Fatality is set to true by default when eError is constructed. But when an error
|
// Fatality is set to true by default when eError is constructed. But when an error
|
||||||
|
@ -101,19 +101,19 @@ public:
|
||||||
void SetSupressThird(bool supressThird);
|
void SetSupressThird(bool supressThird);
|
||||||
bool SupressThird() const;
|
bool SupressThird() const;
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
// Utility Methods
|
// Utility Methods
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
static uint32 CalcHash( const char* name );
|
static uint32 CalcHash( const char* name );
|
||||||
// calculates the CRC32 of the string passed in as name. This methods
|
// calculates the CRC32 of the string passed in as name. This methods
|
||||||
// asserts that name is non null. This is used to generate unique IDs
|
// asserts that name is non null. This is used to generate unique IDs
|
||||||
// for errors.
|
// for errors.
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
// Private Implementation
|
// Private Implementation
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
protected:
|
protected:
|
||||||
TSTRING mMsg;
|
TSTRING mMsg;
|
||||||
uint32 mFlags;
|
uint32 mFlags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ protected:
|
||||||
// TSS_BEGIN_EXCEPTION / TSS_END_EXCEPTION
|
// TSS_BEGIN_EXCEPTION / TSS_END_EXCEPTION
|
||||||
//
|
//
|
||||||
// Serves the same purpose as TSS_EXCEPTION but allows custom data and methods
|
// Serves the same purpose as TSS_EXCEPTION but allows custom data and methods
|
||||||
// to be added to the exception class.
|
// to be added to the exception class.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#if HAVE_GCC
|
#if HAVE_GCC
|
||||||
|
@ -135,22 +135,22 @@ protected:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TSS_BEGIN_EXCEPTION( except, base ) \
|
#define TSS_BEGIN_EXCEPTION( except, base ) \
|
||||||
class except : public base \
|
class except : public base \
|
||||||
{\
|
{\
|
||||||
public:\
|
public:\
|
||||||
except( const TSTRING& msg, uint32 flags = 0 ) \
|
except( const TSTRING& msg, uint32 flags = 0 ) \
|
||||||
: base( msg, flags ) {} \
|
: base( msg, flags ) {} \
|
||||||
TSS_BEGIN_EXCEPTION_EXPLICIT except( const except& rhs ) \
|
TSS_BEGIN_EXCEPTION_EXPLICIT except( const except& rhs ) \
|
||||||
: base( rhs ) {} \
|
: base( rhs ) {} \
|
||||||
explicit except() : base() {} \
|
explicit except() : base() {} \
|
||||||
\
|
\
|
||||||
virtual uint32 GetID() const \
|
virtual uint32 GetID() const \
|
||||||
{\
|
{\
|
||||||
return CalcHash( #except ); \
|
return CalcHash( #except ); \
|
||||||
}\
|
}\
|
||||||
|
|
||||||
#define TSS_END_EXCEPTION( ) \
|
#define TSS_END_EXCEPTION( ) \
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// TSS_BEGIN_EXCEPTION_NO_CTOR
|
// TSS_BEGIN_EXCEPTION_NO_CTOR
|
||||||
|
@ -158,29 +158,29 @@ protected:
|
||||||
// Same as TSS_BEGIN_EXCEPTION, but doesn't define any ctors.
|
// Same as TSS_BEGIN_EXCEPTION, but doesn't define any ctors.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
#define TSS_BEGIN_EXCEPTION_NO_CTOR( except, base ) \
|
#define TSS_BEGIN_EXCEPTION_NO_CTOR( except, base ) \
|
||||||
class except : public base \
|
class except : public base \
|
||||||
{\
|
{\
|
||||||
public:\
|
public:\
|
||||||
explicit except() : base() {} \
|
explicit except() : base() {} \
|
||||||
\
|
\
|
||||||
virtual uint32 GetID() const \
|
virtual uint32 GetID() const \
|
||||||
{\
|
{\
|
||||||
return CalcHash( #except ); \
|
return CalcHash( #except ); \
|
||||||
}\
|
}\
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// TSS_EXCEPTION
|
// TSS_EXCEPTION
|
||||||
//
|
//
|
||||||
// This is a convenience define for quickly defining an exception class. After
|
// This is a convenience define for quickly defining an exception class. After
|
||||||
// defining a new exception, don't forget to add it to the package's error
|
// defining a new exception, don't forget to add it to the package's error
|
||||||
// string file!
|
// string file!
|
||||||
//
|
//
|
||||||
// TODO (mdb) -- do we want to cache the CRC? if we store it in a class static
|
// TODO (mdb) -- do we want to cache the CRC? if we store it in a class static
|
||||||
// variable, then we will need to define it in the cpp file as well ...
|
// variable, then we will need to define it in the cpp file as well ...
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
#define TSS_EXCEPTION( except, base ) \
|
#define TSS_EXCEPTION( except, base ) \
|
||||||
TSS_BEGIN_EXCEPTION( except, base ) \
|
TSS_BEGIN_EXCEPTION( except, base ) \
|
||||||
TSS_END_EXCEPTION()
|
TSS_END_EXCEPTION()
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Inline Implementation
|
// Inline Implementation
|
||||||
|
@ -190,8 +190,8 @@ protected:
|
||||||
// eError
|
// eError
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
inline eError::eError( const TSTRING& msg, uint32 flags )
|
inline eError::eError( const TSTRING& msg, uint32 flags )
|
||||||
: mMsg ( msg ),
|
: mMsg ( msg ),
|
||||||
mFlags ( flags )
|
mFlags ( flags )
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -200,8 +200,8 @@ inline eError::eError( const TSTRING& msg, uint32 flags )
|
||||||
// eError
|
// eError
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
inline eError::eError( const eError& rhs )
|
inline eError::eError( const eError& rhs )
|
||||||
: mMsg ( rhs.mMsg ),
|
: mMsg ( rhs.mMsg ),
|
||||||
mFlags ( rhs.mFlags )
|
mFlags ( rhs.mFlags )
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -210,8 +210,8 @@ inline eError::eError( const eError& rhs )
|
||||||
// eError
|
// eError
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
inline eError::eError( )
|
inline eError::eError( )
|
||||||
: mMsg ( _T("") ),
|
: mMsg ( _T("") ),
|
||||||
mFlags ( 0 )
|
mFlags ( 0 )
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -222,8 +222,8 @@ inline eError::eError( )
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
inline void eError::operator=( const eError& rhs )
|
inline void eError::operator=( const eError& rhs )
|
||||||
{
|
{
|
||||||
mMsg = rhs.mMsg;
|
mMsg = rhs.mMsg;
|
||||||
mFlags = rhs.mFlags;
|
mFlags = rhs.mFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -239,7 +239,7 @@ inline eError::~eError()
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
inline TSTRING eError::GetMsg() const
|
inline TSTRING eError::GetMsg() const
|
||||||
{
|
{
|
||||||
return mMsg;
|
return mMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -247,7 +247,7 @@ inline TSTRING eError::GetMsg() const
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
inline uint32 eError::GetFlags() const
|
inline uint32 eError::GetFlags() const
|
||||||
{
|
{
|
||||||
return mFlags;
|
return mFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -255,7 +255,7 @@ inline uint32 eError::GetFlags() const
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
inline void eError::SetFlags( uint32 flags )
|
inline void eError::SetFlags( uint32 flags )
|
||||||
{
|
{
|
||||||
mFlags = flags;
|
mFlags = flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -47,32 +47,32 @@ class eError;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// cErrorBucket -- contains an interface that handles error reporting, and
|
// cErrorBucket -- contains an interface that handles error reporting, and
|
||||||
// contains a link to a child bucket. Each concrete implementation of the
|
// contains a link to a child bucket. Each concrete implementation of the
|
||||||
// cErrorBucket interface will perform its own specific task related to the
|
// cErrorBucket interface will perform its own specific task related to the
|
||||||
// error's occurence (print to stderr, store in a queue, etc) and then forward
|
// error's occurence (print to stderr, store in a queue, etc) and then forward
|
||||||
// the error on to its child link. The parent bucket does not own the destruction
|
// the error on to its child link. The parent bucket does not own the destruction
|
||||||
// of the pointer to the child bucket.
|
// of the pointer to the child bucket.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
class cErrorBucket
|
class cErrorBucket
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cErrorBucket();
|
cErrorBucket();
|
||||||
virtual ~cErrorBucket() {}
|
virtual ~cErrorBucket() {}
|
||||||
|
|
||||||
virtual void AddError(const eError& error);
|
virtual void AddError(const eError& error);
|
||||||
// add an error to the bucket
|
// add an error to the bucket
|
||||||
|
|
||||||
cErrorBucket* GetChild();
|
cErrorBucket* GetChild();
|
||||||
// returns the bucket that the current bucket is chained to, or
|
// returns the bucket that the current bucket is chained to, or
|
||||||
// NULL if nothing is attached to it.
|
// NULL if nothing is attached to it.
|
||||||
cErrorBucket* SetChild(cErrorBucket* pNewChild);
|
cErrorBucket* SetChild(cErrorBucket* pNewChild);
|
||||||
// sets the child link of this bucket; returns the old link value
|
// sets the child link of this bucket; returns the old link value
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void HandleError(const eError& error) = 0;
|
virtual void HandleError(const eError& error) = 0;
|
||||||
// override this to implement error handling functionality specific to
|
// override this to implement error handling functionality specific to
|
||||||
// the derived class
|
// the derived class
|
||||||
cErrorBucket* mpChild;
|
cErrorBucket* mpChild;
|
||||||
};
|
};
|
||||||
|
|
||||||
//#############################################################################
|
//#############################################################################
|
||||||
|
@ -82,20 +82,20 @@ protected:
|
||||||
// cErrorBucket
|
// cErrorBucket
|
||||||
///////////////////
|
///////////////////
|
||||||
inline cErrorBucket::cErrorBucket() :
|
inline cErrorBucket::cErrorBucket() :
|
||||||
mpChild(0)
|
mpChild(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
inline cErrorBucket* cErrorBucket::GetChild()
|
inline cErrorBucket* cErrorBucket::GetChild()
|
||||||
{
|
{
|
||||||
return mpChild;
|
return mpChild;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline cErrorBucket* cErrorBucket::SetChild(cErrorBucket* pNewChild)
|
inline cErrorBucket* cErrorBucket::SetChild(cErrorBucket* pNewChild)
|
||||||
{
|
{
|
||||||
cErrorBucket* pOldChild = mpChild;
|
cErrorBucket* pOldChild = mpChild;
|
||||||
mpChild = pNewChild;
|
mpChild = pNewChild;
|
||||||
return pOldChild;
|
return pOldChild;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -42,9 +42,9 @@
|
||||||
//#############################################################################
|
//#############################################################################
|
||||||
void cErrorBucket::AddError(const eError& error)
|
void cErrorBucket::AddError(const eError& error)
|
||||||
{
|
{
|
||||||
HandleError(error);
|
HandleError(error);
|
||||||
if(mpChild)
|
if(mpChild)
|
||||||
mpChild->AddError(error);
|
mpChild->AddError(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
//#############################################################################
|
//#############################################################################
|
||||||
|
@ -55,14 +55,14 @@ void cErrorReporter::PrintErrorMsg(const eError& error, const TSTRING& strExtra)
|
||||||
cDisplayEncoder e(
|
cDisplayEncoder e(
|
||||||
(cDisplayEncoder::Flags) ( cDisplayEncoder::NON_ROUNDTRIP |
|
(cDisplayEncoder::Flags) ( cDisplayEncoder::NON_ROUNDTRIP |
|
||||||
cDisplayEncoder::ALLOW_WHITESPACE ) );
|
cDisplayEncoder::ALLOW_WHITESPACE ) );
|
||||||
TSTRING errStr;
|
TSTRING errStr;
|
||||||
|
|
||||||
//
|
//
|
||||||
// if the ID is zero, just return.
|
// if the ID is zero, just return.
|
||||||
// this should only occur at the top level of a program (ie -- twcmdline.cpp) and
|
// this should only occur at the top level of a program (ie -- twcmdline.cpp) and
|
||||||
// indicates that an error occurred and an error message has already been printed out.
|
// indicates that an error occurred and an error message has already been printed out.
|
||||||
// Therefore, we will do nothing here but return.
|
// Therefore, we will do nothing here but return.
|
||||||
//
|
//
|
||||||
|
|
||||||
// TODO: Having an error with an ID of 0 is legacy. The only place it happens at this
|
// TODO: Having an error with an ID of 0 is legacy. The only place it happens at this
|
||||||
// point is when we throw ePoly() with no constructor arguments. At some point we want
|
// point is when we throw ePoly() with no constructor arguments. At some point we want
|
||||||
|
@ -70,8 +70,8 @@ void cErrorReporter::PrintErrorMsg(const eError& error, const TSTRING& strExtra)
|
||||||
// But we don't want to break any release code, thus we return on the next line - June 2, 1999 DMB.
|
// But we don't want to break any release code, thus we return on the next line - June 2, 1999 DMB.
|
||||||
ASSERT( error.GetID() != 0 );
|
ASSERT( error.GetID() != 0 );
|
||||||
|
|
||||||
if( error.GetID() == 0 )
|
if( error.GetID() == 0 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// "First Part" header
|
// "First Part" header
|
||||||
errStr = TSS_GetString( cCore, error.IsFatal() ? core::STR_ERROR_ERROR
|
errStr = TSS_GetString( cCore, error.IsFatal() ? core::STR_ERROR_ERROR
|
||||||
|
@ -94,7 +94,7 @@ void cErrorReporter::PrintErrorMsg(const eError& error, const TSTRING& strExtra)
|
||||||
// #pragma message("errorbucketimpl.cpp needs a little help in the mb arena, with the findfirst/last and such")
|
// #pragma message("errorbucketimpl.cpp needs a little help in the mb arena, with the findfirst/last and such")
|
||||||
|
|
||||||
errStr = cErrorTable::GetInstance()->Get( error.GetID() );
|
errStr = cErrorTable::GetInstance()->Get( error.GetID() );
|
||||||
if(! errStr.empty())
|
if(! errStr.empty())
|
||||||
{
|
{
|
||||||
// If the first part has a '\n' in it, we take everything following and prepend it to the
|
// If the first part has a '\n' in it, we take everything following and prepend it to the
|
||||||
// second part. This was added to allow specifing a verbose string as the second part
|
// second part. This was added to allow specifing a verbose string as the second part
|
||||||
|
@ -109,7 +109,7 @@ void cErrorReporter::PrintErrorMsg(const eError& error, const TSTRING& strExtra)
|
||||||
ASSERT(errStr.length() + len + 6 < 80); // line too big for terminal?
|
ASSERT(errStr.length() + len + 6 < 80); // line too big for terminal?
|
||||||
// Add 6 to account for "### ' and ': '
|
// Add 6 to account for "### ' and ': '
|
||||||
TCERR << TSS_GetString( cCore, core::STR_ERROR_COLON ) << _T(" ") << errStr;
|
TCERR << TSS_GetString( cCore, core::STR_ERROR_COLON ) << _T(" ") << errStr;
|
||||||
TCERR << std::endl;
|
TCERR << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// "Second Part" error string
|
// "Second Part" error string
|
||||||
|
@ -160,22 +160,22 @@ void cErrorReporter::PrintErrorMsg(const eError& error, const TSTRING& strExtra)
|
||||||
}
|
}
|
||||||
|
|
||||||
// "Third Part" print 'exiting' or 'continuing'
|
// "Third Part" print 'exiting' or 'continuing'
|
||||||
// note that we supress this part if the appropriate flag is set...
|
// note that we supress this part if the appropriate flag is set...
|
||||||
//
|
//
|
||||||
if( (error.GetFlags() & eError::SUPRESS_THIRD_MSG) == 0 )
|
if( (error.GetFlags() & eError::SUPRESS_THIRD_MSG) == 0 )
|
||||||
{
|
{
|
||||||
TCERR << TSS_GetString( cCore, core::STR_ERROR_HEADER)
|
TCERR << TSS_GetString( cCore, core::STR_ERROR_HEADER)
|
||||||
<< TSS_GetString(
|
<< TSS_GetString(
|
||||||
cCore,
|
cCore,
|
||||||
error.IsFatal()
|
error.IsFatal()
|
||||||
? core::STR_ERROR_EXITING
|
? core::STR_ERROR_EXITING
|
||||||
: core::STR_ERROR_CONTINUING ) << std::endl;
|
: core::STR_ERROR_CONTINUING ) << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cErrorReporter::HandleError(const eError& error)
|
void cErrorReporter::HandleError(const eError& error)
|
||||||
{
|
{
|
||||||
PrintErrorMsg(error);
|
PrintErrorMsg(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
//#############################################################################
|
//#############################################################################
|
||||||
|
@ -183,11 +183,11 @@ void cErrorReporter::HandleError(const eError& error)
|
||||||
//#############################################################################
|
//#############################################################################
|
||||||
void cErrorTracer::HandleError(const eError& error)
|
void cErrorTracer::HandleError(const eError& error)
|
||||||
{
|
{
|
||||||
cDebug d("cErrorTracer::HandleError");
|
cDebug d("cErrorTracer::HandleError");
|
||||||
|
|
||||||
d.TraceError( _T("%s : %s\n"),
|
d.TraceError( _T("%s : %s\n"),
|
||||||
cErrorTable::GetInstance()->Get( error.GetID() ).c_str(),
|
cErrorTable::GetInstance()->Get( error.GetID() ).c_str(),
|
||||||
error.GetMsg().c_str() );
|
error.GetMsg().c_str() );
|
||||||
}
|
}
|
||||||
|
|
||||||
//#############################################################################
|
//#############################################################################
|
||||||
|
@ -197,51 +197,51 @@ IMPLEMENT_TYPEDSERIALIZABLE(cErrorQueue, _T("cErrorQueue"), 0, 1);
|
||||||
|
|
||||||
void cErrorQueue::Clear()
|
void cErrorQueue::Clear()
|
||||||
{
|
{
|
||||||
mList.clear();
|
mList.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
int cErrorQueue::GetNumErrors() const
|
int cErrorQueue::GetNumErrors() const
|
||||||
{
|
{
|
||||||
return mList.size();
|
return mList.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void cErrorQueue::HandleError(const eError& error)
|
void cErrorQueue::HandleError(const eError& error)
|
||||||
{
|
{
|
||||||
mList.push_back( ePoly( error ) );
|
mList.push_back( ePoly( error ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
cErrorQueueIter::cErrorQueueIter(cErrorQueue& queue) :
|
cErrorQueueIter::cErrorQueueIter(cErrorQueue& queue) :
|
||||||
mList(queue.mList)
|
mList(queue.mList)
|
||||||
{
|
{
|
||||||
SeekBegin();
|
SeekBegin();
|
||||||
}
|
}
|
||||||
|
|
||||||
cErrorQueueIter::cErrorQueueIter(const cErrorQueue& queue)
|
cErrorQueueIter::cErrorQueueIter(const cErrorQueue& queue)
|
||||||
: mList( ((cErrorQueue*)&queue)->mList )
|
: mList( ((cErrorQueue*)&queue)->mList )
|
||||||
{
|
{
|
||||||
SeekBegin();
|
SeekBegin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void cErrorQueueIter::SeekBegin()
|
void cErrorQueueIter::SeekBegin()
|
||||||
{
|
{
|
||||||
mIter = mList.begin();
|
mIter = mList.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
void cErrorQueueIter::Next()
|
void cErrorQueueIter::Next()
|
||||||
{
|
{
|
||||||
++mIter;
|
++mIter;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cErrorQueueIter::Done() const
|
bool cErrorQueueIter::Done() const
|
||||||
{
|
{
|
||||||
return (mIter == mList.end());
|
return (mIter == mList.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
const ePoly& cErrorQueueIter::GetError() const
|
const ePoly& cErrorQueueIter::GetError() const
|
||||||
{
|
{
|
||||||
ASSERT(! Done());
|
ASSERT(! Done());
|
||||||
return (*mIter);
|
return (*mIter);
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -249,24 +249,24 @@ const ePoly& cErrorQueueIter::GetError() const
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
void cErrorQueue::Read(iSerializer* pSerializer, int32 version)
|
void cErrorQueue::Read(iSerializer* pSerializer, int32 version)
|
||||||
{
|
{
|
||||||
if (version > Version())
|
if (version > Version())
|
||||||
ThrowAndAssert(eSerializerVersionMismatch(_T("ErrorQueue Read")));
|
ThrowAndAssert(eSerializerVersionMismatch(_T("ErrorQueue Read")));
|
||||||
|
|
||||||
int32 size;
|
int32 size;
|
||||||
mList.clear();
|
mList.clear();
|
||||||
pSerializer->ReadInt32(size);
|
pSerializer->ReadInt32(size);
|
||||||
for(int i = 0; i < size; ++i)
|
for(int i = 0; i < size; ++i)
|
||||||
{
|
{
|
||||||
int32 errorNumber;
|
int32 errorNumber;
|
||||||
TSTRING errorString;
|
TSTRING errorString;
|
||||||
int32 flags;
|
int32 flags;
|
||||||
|
|
||||||
pSerializer->ReadInt32 (errorNumber);
|
pSerializer->ReadInt32 (errorNumber);
|
||||||
pSerializer->ReadString (errorString);
|
pSerializer->ReadString (errorString);
|
||||||
pSerializer->ReadInt32 (flags);
|
pSerializer->ReadInt32 (flags);
|
||||||
|
|
||||||
mList.push_back( ePoly( errorNumber, errorString, flags ) );
|
mList.push_back( ePoly( errorNumber, errorString, flags ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,14 +275,14 @@ void cErrorQueue::Read(iSerializer* pSerializer, int32 version)
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
void cErrorQueue::Write(iSerializer* pSerializer) const
|
void cErrorQueue::Write(iSerializer* pSerializer) const
|
||||||
{
|
{
|
||||||
pSerializer->WriteInt32(mList.size());
|
pSerializer->WriteInt32(mList.size());
|
||||||
ListType::const_iterator i;
|
ListType::const_iterator i;
|
||||||
for( i = mList.begin(); i != mList.end(); ++i)
|
for( i = mList.begin(); i != mList.end(); ++i)
|
||||||
{
|
{
|
||||||
pSerializer->WriteInt32 ((*i).GetID());
|
pSerializer->WriteInt32 ((*i).GetID());
|
||||||
pSerializer->WriteString((*i).GetMsg());
|
pSerializer->WriteString((*i).GetMsg());
|
||||||
pSerializer->WriteInt32 ((*i).GetFlags());
|
pSerializer->WriteInt32 ((*i).GetFlags());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,15 +292,15 @@ void cErrorQueue::Write(iSerializer* pSerializer) const
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
void cErrorQueue::TraceContents(int dl) const
|
void cErrorQueue::TraceContents(int dl) const
|
||||||
{
|
{
|
||||||
if(dl < 0)
|
if(dl < 0)
|
||||||
dl = cDebug::D_DEBUG;
|
dl = cDebug::D_DEBUG;
|
||||||
|
|
||||||
cDebug d("cFCOErrorQueue::TraceContents");
|
cDebug d("cFCOErrorQueue::TraceContents");
|
||||||
ListType::const_iterator i;
|
ListType::const_iterator i;
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
for(i = mList.begin(); i != mList.end(); i++, counter++)
|
for(i = mList.begin(); i != mList.end(); i++, counter++)
|
||||||
{
|
{
|
||||||
d.Trace(dl, _T("Error[%d]: num = %x string = %s\n") , counter, (*i).GetID(), (*i).GetMsg().c_str());
|
d.Trace(dl, _T("Error[%d]: num = %x string = %s\n") , counter, (*i).GetID(), (*i).GetMsg().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,111 +61,111 @@
|
||||||
|
|
||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
// cErrorReporter -- sends all error messages to
|
// cErrorReporter -- sends all error messages to
|
||||||
// stderr
|
// stderr
|
||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
class cErrorReporter : public cErrorBucket
|
class cErrorReporter : public cErrorBucket
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void PrintErrorMsg(const eError& error, const TSTRING& strExtra = _T(""));
|
static void PrintErrorMsg(const eError& error, const TSTRING& strExtra = _T(""));
|
||||||
// function that HandleError() uses to print the error messages to stderr.
|
// function that HandleError() uses to print the error messages to stderr.
|
||||||
// this function uses the current authoritative format for error reporting, so
|
// this function uses the current authoritative format for error reporting, so
|
||||||
// other functions needing to display errors to the user should use this.
|
// other functions needing to display errors to the user should use this.
|
||||||
//
|
//
|
||||||
|
|
||||||
// NOTE:bam 5/7/99 -- I don't think the below is true anymore?
|
// NOTE:bam 5/7/99 -- I don't think the below is true anymore?
|
||||||
// NOTE:mdb -- if the error has an ID of zero, nothing will be printed. This
|
// NOTE:mdb -- if the error has an ID of zero, nothing will be printed. This
|
||||||
// is a way to throw a fatal error where the error reporting has already
|
// is a way to throw a fatal error where the error reporting has already
|
||||||
// occurred.
|
// occurred.
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void HandleError(const eError& error);
|
virtual void HandleError(const eError& error);
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
// cErrorTracer -- traces all errors with the D_ERROR debug
|
// cErrorTracer -- traces all errors with the D_ERROR debug
|
||||||
// level
|
// level
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
class cErrorTracer : public cErrorBucket
|
class cErrorTracer : public cErrorBucket
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
virtual void HandleError(const eError& error);
|
virtual void HandleError(const eError& error);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
// cErrorQueue -- keeps track of all the errors that
|
// cErrorQueue -- keeps track of all the errors that
|
||||||
// are reported to it, providing an interface for
|
// are reported to it, providing an interface for
|
||||||
// retrieving them at a later time
|
// retrieving them at a later time
|
||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
class cErrorQueue : public cErrorBucket, public iTypedSerializable
|
class cErrorQueue : public cErrorBucket, public iTypedSerializable
|
||||||
{
|
{
|
||||||
friend class cErrorQueueIter;
|
friend class cErrorQueueIter;
|
||||||
public:
|
public:
|
||||||
void Clear();
|
void Clear();
|
||||||
// remove all errors from the queue
|
// remove all errors from the queue
|
||||||
int GetNumErrors() const;
|
int GetNumErrors() const;
|
||||||
// returns how many errors are in the queue
|
// returns how many errors are in the queue
|
||||||
|
|
||||||
//
|
//
|
||||||
// iSerializable interface
|
// iSerializable interface
|
||||||
//
|
//
|
||||||
virtual void Read (iSerializer* pSerializer, int32 version = 0); // throw (eSerializer, eArchive)
|
virtual void Read (iSerializer* pSerializer, int32 version = 0); // throw (eSerializer, eArchive)
|
||||||
virtual void Write(iSerializer* pSerializer) const; // throw (eSerializer, eArchive)
|
virtual void Write(iSerializer* pSerializer) const; // throw (eSerializer, eArchive)
|
||||||
|
|
||||||
//
|
//
|
||||||
// Debugging
|
// Debugging
|
||||||
//
|
//
|
||||||
void TraceContents(int dl = -1) const;
|
void TraceContents(int dl = -1) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void HandleError(const eError& error);
|
virtual void HandleError(const eError& error);
|
||||||
private:
|
private:
|
||||||
typedef std::list<ePoly> ListType;
|
typedef std::list<ePoly> ListType;
|
||||||
ListType mList;
|
ListType mList;
|
||||||
|
|
||||||
DECLARE_TYPEDSERIALIZABLE()
|
DECLARE_TYPEDSERIALIZABLE()
|
||||||
};
|
};
|
||||||
|
|
||||||
class cErrorQueueIter
|
class cErrorQueueIter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cErrorQueueIter(cErrorQueue& queue);
|
cErrorQueueIter(cErrorQueue& queue);
|
||||||
cErrorQueueIter(const cErrorQueue& queue);
|
cErrorQueueIter(const cErrorQueue& queue);
|
||||||
~cErrorQueueIter() {}
|
~cErrorQueueIter() {}
|
||||||
|
|
||||||
// iteration methods
|
// iteration methods
|
||||||
void SeekBegin();
|
void SeekBegin();
|
||||||
void Next();
|
void Next();
|
||||||
bool Done() const;
|
bool Done() const;
|
||||||
|
|
||||||
// access to the error
|
// access to the error
|
||||||
const ePoly& GetError() const;
|
const ePoly& GetError() const;
|
||||||
// both of these return results are undefined if the iterator
|
// both of these return results are undefined if the iterator
|
||||||
// is not valid (ie - IsDone() == true)
|
// is not valid (ie - IsDone() == true)
|
||||||
private:
|
private:
|
||||||
cErrorQueue::ListType& mList;
|
cErrorQueue::ListType& mList;
|
||||||
cErrorQueue::ListType::iterator mIter;
|
cErrorQueue::ListType::iterator mIter;
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
// cErrorBucketNull -- an error bucket that plays the
|
// cErrorBucketNull -- an error bucket that plays the
|
||||||
// role of /dev/null
|
// role of /dev/null
|
||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
class cErrorBucketNull : public cErrorBucket
|
class cErrorBucketNull : public cErrorBucket
|
||||||
{
|
{
|
||||||
virtual void AddError(const eError& ) {}
|
virtual void AddError(const eError& ) {}
|
||||||
protected:
|
protected:
|
||||||
virtual void HandleError(const eError& ) {}
|
virtual void HandleError(const eError& ) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
// cErrorBucketPassThru -- does nothing with errors;
|
// cErrorBucketPassThru -- does nothing with errors;
|
||||||
// just passes them on to its children
|
// just passes them on to its children
|
||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
class cErrorBucketPassThru : public cErrorBucket
|
class cErrorBucketPassThru : public cErrorBucket
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
virtual void HandleError(const eError& ) {}
|
virtual void HandleError(const eError& ) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -45,8 +45,8 @@
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
cErrorTable* cErrorTable::GetInstance()
|
cErrorTable* cErrorTable::GetInstance()
|
||||||
{
|
{
|
||||||
static cErrorTable gErrorTable;
|
static cErrorTable gErrorTable;
|
||||||
return &gErrorTable;
|
return &gErrorTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -34,8 +34,8 @@
|
||||||
// Date: 30 April 99
|
// Date: 30 April 99
|
||||||
// Creator: mdb
|
// Creator: mdb
|
||||||
//
|
//
|
||||||
// cErrorTable -- singleton derived from Resource_<> that serves as the global
|
// cErrorTable -- singleton derived from Resource_<> that serves as the global
|
||||||
// error id to string mapping
|
// error id to string mapping
|
||||||
//
|
//
|
||||||
#ifndef __ERRORTABLE_H
|
#ifndef __ERRORTABLE_H
|
||||||
#define __ERRORTABLE_H
|
#define __ERRORTABLE_H
|
||||||
|
@ -54,16 +54,16 @@ class eError;
|
||||||
class cErrorTable : public cMessages_<uint32, TCHAR>
|
class cErrorTable : public cMessages_<uint32, TCHAR>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef cMessages_<uint32, TCHAR> inherited;
|
typedef cMessages_<uint32, TCHAR> inherited;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Convenience Methods
|
// Convenience Methods
|
||||||
//
|
//
|
||||||
void Put( const eError& e, const TCHAR* msg );
|
void Put( const eError& e, const TCHAR* msg );
|
||||||
//
|
//
|
||||||
// Singleton Interface
|
// Singleton Interface
|
||||||
//
|
//
|
||||||
static cErrorTable* GetInstance();
|
static cErrorTable* GetInstance();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
|
@ -85,55 +85,55 @@ inline void cErrorTable::Put( const eError& e, const TCHAR* msg )
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// These macros make it easy for a module to register errors with the global
|
// These macros make it easy for a module to register errors with the global
|
||||||
// error table. Them like this:
|
// error table. Them like this:
|
||||||
//
|
//
|
||||||
// // animalerrors.h
|
// // animalerrors.h
|
||||||
// //
|
// //
|
||||||
// TSS_DECLARE_ERROR_REGISTRATION( animal )
|
// TSS_DECLARE_ERROR_REGISTRATION( animal )
|
||||||
//
|
//
|
||||||
// // animalerrors.cpp
|
// // animalerrors.cpp
|
||||||
// //
|
// //
|
||||||
// TSS_BEGIN_ERROR_REGISTRATION( animal )
|
// TSS_BEGIN_ERROR_REGISTRATION( animal )
|
||||||
// TSS_REGISTER_ERROR( eDog, _T("Dog error") )
|
// TSS_REGISTER_ERROR( eDog, _T("Dog error") )
|
||||||
// TSS_REGISTER_ERROR( eDogBark, _T("Barking error") )
|
// TSS_REGISTER_ERROR( eDogBark, _T("Barking error") )
|
||||||
// TSS_END_ERROR_REGISTRATION()
|
// TSS_END_ERROR_REGISTRATION()
|
||||||
//
|
//
|
||||||
// // pkg.h
|
// // pkg.h
|
||||||
// TSS_DeclarePackage( cWorld )
|
// TSS_DeclarePackage( cWorld )
|
||||||
//
|
//
|
||||||
// // pkg.cpp
|
// // pkg.cpp
|
||||||
// cWorld::cWorld()
|
// cWorld::cWorld()
|
||||||
// {
|
// {
|
||||||
// TSS_REGISTER_PKG_ERRORS( animal )
|
// TSS_REGISTER_PKG_ERRORS( animal )
|
||||||
//
|
//
|
||||||
//===================
|
//===================
|
||||||
// cpp file macros
|
// cpp file macros
|
||||||
//===================
|
//===================
|
||||||
#define TSS_BEGIN_ERROR_REGISTRATION( pkgName ) \
|
#define TSS_BEGIN_ERROR_REGISTRATION( pkgName ) \
|
||||||
RegisterErrors##pkgName::RegisterErrors##pkgName() \
|
RegisterErrors##pkgName::RegisterErrors##pkgName() \
|
||||||
{
|
{
|
||||||
|
|
||||||
#define TSS_REGISTER_ERROR( err, str ) \
|
#define TSS_REGISTER_ERROR( err, str ) \
|
||||||
cErrorTable::GetInstance()->Put \
|
cErrorTable::GetInstance()->Put \
|
||||||
( err, str );
|
( err, str );
|
||||||
|
|
||||||
#define TSS_END_ERROR_REGISTRATION() \
|
#define TSS_END_ERROR_REGISTRATION() \
|
||||||
}
|
}
|
||||||
|
|
||||||
//===================
|
//===================
|
||||||
// h file macros
|
// h file macros
|
||||||
//===================
|
//===================
|
||||||
#define TSS_DECLARE_ERROR_REGISTRATION( pkgName ) \
|
#define TSS_DECLARE_ERROR_REGISTRATION( pkgName ) \
|
||||||
struct RegisterErrors##pkgName \
|
struct RegisterErrors##pkgName \
|
||||||
{\
|
{\
|
||||||
RegisterErrors##pkgName(); \
|
RegisterErrors##pkgName(); \
|
||||||
};
|
};
|
||||||
|
|
||||||
//===================
|
//===================
|
||||||
// package init macros
|
// package init macros
|
||||||
//===================
|
//===================
|
||||||
#define TSS_REGISTER_PKG_ERRORS( pkgName ) \
|
#define TSS_REGISTER_PKG_ERRORS( pkgName ) \
|
||||||
RegisterErrors##pkgName register##pkgName;
|
RegisterErrors##pkgName register##pkgName;
|
||||||
|
|
||||||
|
|
||||||
#endif //__ERRORTABLE_H
|
#endif //__ERRORTABLE_H
|
||||||
|
|
|
@ -43,11 +43,11 @@
|
||||||
#if IS_UNIX
|
#if IS_UNIX
|
||||||
namespace //unique
|
namespace //unique
|
||||||
{
|
{
|
||||||
TCHAR* tw_itot( int value, TCHAR* string, int radix)
|
TCHAR* tw_itot( int value, TCHAR* string, int radix)
|
||||||
{
|
{
|
||||||
_stprintf( string, "%d", value );
|
_stprintf( string, "%d", value );
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define tw_itot _itot
|
#define tw_itot _itot
|
||||||
|
@ -73,7 +73,7 @@ eInternal::eInternal(TCHAR* sourceFile, int lineNum)
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
TSTRING cErrorUtil::MakeFileError( const TSTRING& msg, const TSTRING& fileName )
|
TSTRING cErrorUtil::MakeFileError( const TSTRING& msg, const TSTRING& fileName )
|
||||||
{
|
{
|
||||||
TSTRING ret;
|
TSTRING ret;
|
||||||
ret = TSS_GetString( cCore, core::STR_ERR2_FILENAME );
|
ret = TSS_GetString( cCore, core::STR_ERR2_FILENAME );
|
||||||
ret.append( fileName );
|
ret.append( fileName );
|
||||||
ret.append( 1, _T('\n') );
|
ret.append( 1, _T('\n') );
|
||||||
|
@ -83,6 +83,6 @@ TSTRING cErrorUtil::MakeFileError( const TSTRING& msg, const TSTRING& fileName )
|
||||||
ret.append(msg);
|
ret.append(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,9 +36,9 @@
|
||||||
// Company: TSS
|
// Company: TSS
|
||||||
// Desc: contains useful eError derived classes
|
// Desc: contains useful eError derived classes
|
||||||
//
|
//
|
||||||
// eInternal -- internal logic errors ( ie -- programming mistakes )
|
// eInternal -- internal logic errors ( ie -- programming mistakes )
|
||||||
// ePoly -- "polymorphic" error that takes its ID as input instead
|
// ePoly -- "polymorphic" error that takes its ID as input instead
|
||||||
// of from its class name
|
// of from its class name
|
||||||
// ThrowAndAssert -- asserts false and throws the specified exception
|
// ThrowAndAssert -- asserts false and throws the specified exception
|
||||||
//
|
//
|
||||||
#ifndef __ERRORUTIL_H
|
#ifndef __ERRORUTIL_H
|
||||||
|
@ -55,22 +55,22 @@
|
||||||
class ePoly : public eError
|
class ePoly : public eError
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
// Construction and Assignment
|
// Construction and Assignment
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
ePoly( uint32 id, const TSTRING& msg, uint32 flags = 0 );
|
ePoly( uint32 id, const TSTRING& msg, uint32 flags = 0 );
|
||||||
explicit ePoly( const eError& rhs );
|
explicit ePoly( const eError& rhs );
|
||||||
explicit ePoly();
|
explicit ePoly();
|
||||||
void operator=( const eError& rhs );
|
void operator=( const eError& rhs );
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
// ID manipulation
|
// ID manipulation
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
virtual uint32 GetID() const;
|
virtual uint32 GetID() const;
|
||||||
void SetID( uint32 id );
|
void SetID( uint32 id );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32 mID;
|
uint32 mID;
|
||||||
};
|
};
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -78,7 +78,7 @@ private:
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
TSS_BEGIN_EXCEPTION( eInternal, eError )
|
TSS_BEGIN_EXCEPTION( eInternal, eError )
|
||||||
public:
|
public:
|
||||||
eInternal( TCHAR* file, int lineNum );
|
eInternal( TCHAR* file, int lineNum );
|
||||||
TSS_END_EXCEPTION()
|
TSS_END_EXCEPTION()
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -87,11 +87,11 @@ TSS_END_EXCEPTION()
|
||||||
class cErrorUtil
|
class cErrorUtil
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static TSTRING MakeFileError( const TSTRING& msg, const TSTRING& fileName );
|
static TSTRING MakeFileError( const TSTRING& msg, const TSTRING& fileName );
|
||||||
// constructs an error message of the form:
|
// constructs an error message of the form:
|
||||||
// File: <fileName> \n <msg>
|
// File: <fileName> \n <msg>
|
||||||
// This is useful for constructing strings to pass as the msg parameter
|
// This is useful for constructing strings to pass as the msg parameter
|
||||||
// to eError constructors.
|
// to eError constructors.
|
||||||
};
|
};
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -99,15 +99,15 @@ public:
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// NOTE -- we require the developer to supply the file name instead of using
|
// NOTE -- we require the developer to supply the file name instead of using
|
||||||
// __FILE__ because that includes the full path to the file, which we
|
// __FILE__ because that includes the full path to the file, which we
|
||||||
// would not like to display to the user.
|
// would not like to display to the user.
|
||||||
//
|
//
|
||||||
#define INTERNAL_ERROR(filename) eInternal((TCHAR*)_T(filename), __LINE__)
|
#define INTERNAL_ERROR(filename) eInternal((TCHAR*)_T(filename), __LINE__)
|
||||||
#define THROW_INTERNAL(filename) throw eInternal((TCHAR*)_T(filename), __LINE__)
|
#define THROW_INTERNAL(filename) throw eInternal((TCHAR*)_T(filename), __LINE__)
|
||||||
|
|
||||||
|
|
||||||
// TODO: ASSERT is always fatal in Unix, perhaps we could #ifdef the ASSERT
|
// TODO: ASSERT is always fatal in Unix, perhaps we could #ifdef the ASSERT
|
||||||
// to echo to cout the line number the exception occured at?
|
// to echo to cout the line number the exception occured at?
|
||||||
#define ThrowAndAssert(exception) { ASSERT(false); throw exception; }
|
#define ThrowAndAssert(exception) { ASSERT(false); throw exception; }
|
||||||
|
|
||||||
|
|
||||||
|
@ -119,8 +119,8 @@ public:
|
||||||
// ePoly
|
// ePoly
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
inline ePoly::ePoly( uint32 id, const TSTRING& msg, uint32 flags )
|
inline ePoly::ePoly( uint32 id, const TSTRING& msg, uint32 flags )
|
||||||
: eError( msg, flags ),
|
: eError( msg, flags ),
|
||||||
mID( id )
|
mID( id )
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -137,8 +137,8 @@ inline ePoly::ePoly( const eError& rhs )
|
||||||
// ePoly
|
// ePoly
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
inline ePoly::ePoly()
|
inline ePoly::ePoly()
|
||||||
: eError( _T("") ),
|
: eError( _T("") ),
|
||||||
mID( 0 )
|
mID( 0 )
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -150,7 +150,7 @@ inline void ePoly::operator=( const eError& rhs )
|
||||||
{
|
{
|
||||||
mMsg = rhs.GetMsg();
|
mMsg = rhs.GetMsg();
|
||||||
mFlags = rhs.GetFlags();
|
mFlags = rhs.GetFlags();
|
||||||
mID = rhs.GetID();
|
mID = rhs.GetID();
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -158,7 +158,7 @@ inline void ePoly::operator=( const eError& rhs )
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
inline uint32 ePoly::GetID() const
|
inline uint32 ePoly::GetID() const
|
||||||
{
|
{
|
||||||
return mID;
|
return mID;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -166,7 +166,7 @@ inline uint32 ePoly::GetID() const
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
inline void ePoly::SetID( uint32 id )
|
inline void ePoly::SetID( uint32 id )
|
||||||
{
|
{
|
||||||
mID = id;
|
mID = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //__ERRORUTIL_H
|
#endif //__ERRORUTIL_H
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
// info@tripwire.org or www.tripwire.org.
|
// info@tripwire.org or www.tripwire.org.
|
||||||
//
|
//
|
||||||
// file.h : Interface for cFile class, which abstracts file operations across
|
// file.h : Interface for cFile class, which abstracts file operations across
|
||||||
// different platforms (currently just Windows and Unix...)
|
// different platforms (currently just Windows and Unix...)
|
||||||
|
|
||||||
#ifndef __FILE_H
|
#ifndef __FILE_H
|
||||||
#define __FILE_H
|
#define __FILE_H
|
||||||
|
@ -55,17 +55,17 @@
|
||||||
// eFile exception class
|
// eFile exception class
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
TSS_FILE_EXCEPTION( eFile, eFileError );
|
TSS_FILE_EXCEPTION( eFile, eFileError );
|
||||||
TSS_FILE_EXCEPTION( eFileOpen, eFile );
|
TSS_FILE_EXCEPTION( eFileOpen, eFile );
|
||||||
TSS_FILE_EXCEPTION( eFileWrite, eFile );
|
TSS_FILE_EXCEPTION( eFileWrite, eFile );
|
||||||
TSS_FILE_EXCEPTION( eFileRead, eFile );
|
TSS_FILE_EXCEPTION( eFileRead, eFile );
|
||||||
TSS_FILE_EXCEPTION( eFileEOF, eFile ); // never used!
|
TSS_FILE_EXCEPTION( eFileEOF, eFile ); // never used!
|
||||||
TSS_FILE_EXCEPTION( eFileSeek, eFile );
|
TSS_FILE_EXCEPTION( eFileSeek, eFile );
|
||||||
TSS_FILE_EXCEPTION( eFileInvalidOp, eFile ); // never used!
|
TSS_FILE_EXCEPTION( eFileInvalidOp, eFile ); // never used!
|
||||||
TSS_FILE_EXCEPTION( eFileTrunc, eFile );
|
TSS_FILE_EXCEPTION( eFileTrunc, eFile );
|
||||||
TSS_FILE_EXCEPTION( eFileClose, eFile ); // never used!
|
TSS_FILE_EXCEPTION( eFileClose, eFile ); // never used!
|
||||||
TSS_FILE_EXCEPTION( eFileFlush, eFile );
|
TSS_FILE_EXCEPTION( eFileFlush, eFile );
|
||||||
TSS_FILE_EXCEPTION( eFileRewind, eFile );
|
TSS_FILE_EXCEPTION( eFileRewind, eFile );
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// cFile
|
// cFile
|
||||||
|
@ -81,64 +81,64 @@ public:
|
||||||
|
|
||||||
#endif // IS_UNIX
|
#endif // IS_UNIX
|
||||||
|
|
||||||
enum SeekFrom
|
enum SeekFrom
|
||||||
{
|
{
|
||||||
SEEK_BEGIN = 0,
|
SEEK_BEGIN = 0,
|
||||||
SEEK_CURRENT,
|
SEEK_CURRENT,
|
||||||
SEEK_EOF
|
SEEK_EOF
|
||||||
};
|
};
|
||||||
|
|
||||||
enum OpenFlags
|
enum OpenFlags
|
||||||
{
|
{
|
||||||
// note that reading from the file is implicit
|
// note that reading from the file is implicit
|
||||||
OPEN_READ = 0x00000001, // not needed, but makes calls nice...
|
OPEN_READ = 0x00000001, // not needed, but makes calls nice...
|
||||||
OPEN_WRITE = 0x00000002, // we will be writing to the file
|
OPEN_WRITE = 0x00000002, // we will be writing to the file
|
||||||
OPEN_LOCKED_TEMP = 0x00000004, // the file should not be readable by other processes and should be removed when closed
|
OPEN_LOCKED_TEMP = 0x00000004, // the file should not be readable by other processes and should be removed when closed
|
||||||
OPEN_TRUNCATE = 0x00000008, // opens an empty file. creates it if it doesn't exist. Doesn't make much sense without OF_WRITE
|
OPEN_TRUNCATE = 0x00000008, // opens an empty file. creates it if it doesn't exist. Doesn't make much sense without OF_WRITE
|
||||||
OPEN_CREATE = 0x00000010, // create the file if it doesn't exist; this is implicit if OF_TRUNCATE is set
|
OPEN_CREATE = 0x00000010, // create the file if it doesn't exist; this is implicit if OF_TRUNCATE is set
|
||||||
OPEN_TEXT = 0x00000020,
|
OPEN_TEXT = 0x00000020,
|
||||||
OPEN_EXCLUSIVE = 0x00000040, // Use O_CREAT | O_EXCL
|
OPEN_EXCLUSIVE = 0x00000040, // Use O_CREAT | O_EXCL
|
||||||
OPEN_NONBLOCKING = 0x00000080, // Use non-blocking i/o [Unix]
|
OPEN_NONBLOCKING = 0x00000080, // Use non-blocking i/o [Unix]
|
||||||
};
|
};
|
||||||
|
|
||||||
//Ctor, Dtor, CpyCtor, Operator=:
|
//Ctor, Dtor, CpyCtor, Operator=:
|
||||||
cFile ( void );
|
cFile ( void );
|
||||||
~cFile ( void );
|
~cFile ( void );
|
||||||
|
|
||||||
/************ User Interface **************************/
|
/************ User Interface **************************/
|
||||||
|
|
||||||
// Both Open methods ALWAYS open files in BINARY mode!
|
// Both Open methods ALWAYS open files in BINARY mode!
|
||||||
void Open ( const TSTRING& sFileName, uint32 flags = OPEN_READ ); //throw(eFile)
|
void Open ( const TSTRING& sFileName, uint32 flags = OPEN_READ ); //throw(eFile)
|
||||||
void Close ( void ); //throw(eFile)
|
void Close ( void ); //throw(eFile)
|
||||||
bool IsOpen ( void ) const;
|
bool IsOpen ( void ) const;
|
||||||
|
|
||||||
File_t Seek ( File_t offset, SeekFrom From ) const; //throw(eFile)
|
File_t Seek ( File_t offset, SeekFrom From ) const; //throw(eFile)
|
||||||
// Seek returns the current offset after completion
|
// Seek returns the current offset after completion
|
||||||
File_t Read ( void* buffer, File_t nBytes ) const; //throw(eFile)
|
File_t Read ( void* buffer, File_t nBytes ) const; //throw(eFile)
|
||||||
// Read returns the number of bytes that are actually read. If the nBytes
|
// Read returns the number of bytes that are actually read. If the nBytes
|
||||||
// parameter is 0, 0 bytes will be read and buffer will remain untouched.
|
// parameter is 0, 0 bytes will be read and buffer will remain untouched.
|
||||||
// If the read head is at EOF, no bytes will be read and 0 will be returned.
|
// If the read head is at EOF, no bytes will be read and 0 will be returned.
|
||||||
File_t Write ( const void* buffer, File_t nBytes ); //throw(eFile)
|
File_t Write ( const void* buffer, File_t nBytes ); //throw(eFile)
|
||||||
// Write returns the number of bytes that are actually written.
|
// Write returns the number of bytes that are actually written.
|
||||||
File_t Tell ( void ) const;
|
File_t Tell ( void ) const;
|
||||||
// Tell returns the current offset.
|
// Tell returns the current offset.
|
||||||
bool Flush ( void ); //throw(eFile)
|
bool Flush ( void ); //throw(eFile)
|
||||||
// Flush returns 0 if the currently defined stream is successfully flushed.
|
// Flush returns 0 if the currently defined stream is successfully flushed.
|
||||||
void Rewind ( void ) const; //throw(eFile)
|
void Rewind ( void ) const; //throw(eFile)
|
||||||
// Sets the offset to 0.
|
// Sets the offset to 0.
|
||||||
File_t GetSize ( void ) const;
|
File_t GetSize ( void ) const;
|
||||||
// Returns the size of the current file in bytes. Returns -1 if no file is defined.
|
// Returns the size of the current file in bytes. Returns -1 if no file is defined.
|
||||||
void Truncate ( File_t offset ); // throw(eFile)
|
void Truncate ( File_t offset ); // throw(eFile)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
cFile ( const cFile& rhs ); //not impl.
|
cFile ( const cFile& rhs ); //not impl.
|
||||||
cFile& operator= ( const cFile& rhs); //not impl.
|
cFile& operator= ( const cFile& rhs); //not impl.
|
||||||
|
|
||||||
//Pointer to the insulated implementation
|
//Pointer to the insulated implementation
|
||||||
cFile_i* mpData;
|
cFile_i* mpData;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool isWritable;
|
bool isWritable;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -146,8 +146,8 @@ public:
|
||||||
class cArosPath
|
class cArosPath
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static TSTRING AsPosix(const TSTRING& in);
|
static TSTRING AsPosix(const TSTRING& in);
|
||||||
static TSTRING AsNative(const TSTRING& in);
|
static TSTRING AsNative(const TSTRING& in);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -56,14 +56,14 @@
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
/*static TSTRING util_GetErrnoString()
|
/*static TSTRING util_GetErrnoString()
|
||||||
{
|
{
|
||||||
TSTRING ret;
|
TSTRING ret;
|
||||||
char* pErrorStr = strerror(errno);
|
char* pErrorStr = strerror(errno);
|
||||||
#ifdef _UNICODE
|
#ifdef _UNICODE
|
||||||
#error We dont currently support unicode on unix
|
#error We dont currently support unicode on unix
|
||||||
#else
|
#else
|
||||||
ret = pErrorStr;
|
ret = pErrorStr;
|
||||||
#endif
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -73,26 +73,26 @@
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
struct cFile_i
|
struct cFile_i
|
||||||
{
|
{
|
||||||
cFile_i();
|
cFile_i();
|
||||||
~cFile_i();
|
~cFile_i();
|
||||||
|
|
||||||
FILE* mpCurrStream; //currently defined file stream
|
FILE* mpCurrStream; //currently defined file stream
|
||||||
TSTRING mFileName; //the name of the file we are currently referencing.
|
TSTRING mFileName; //the name of the file we are currently referencing.
|
||||||
};
|
};
|
||||||
|
|
||||||
//Ctor
|
//Ctor
|
||||||
cFile_i::cFile_i() :
|
cFile_i::cFile_i() :
|
||||||
mpCurrStream(NULL)
|
mpCurrStream(NULL)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//Dtor
|
//Dtor
|
||||||
cFile_i::~cFile_i()
|
cFile_i::~cFile_i()
|
||||||
{
|
{
|
||||||
if (mpCurrStream != NULL)
|
if (mpCurrStream != NULL)
|
||||||
fclose( mpCurrStream );
|
fclose( mpCurrStream );
|
||||||
mpCurrStream = NULL;
|
mpCurrStream = NULL;
|
||||||
|
|
||||||
mFileName.empty();
|
mFileName.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -102,18 +102,18 @@ cFile_i::~cFile_i()
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
cFile::cFile() :
|
cFile::cFile() :
|
||||||
mpData(NULL), isWritable(false)
|
mpData(NULL), isWritable(false)
|
||||||
{
|
{
|
||||||
mpData = new cFile_i;
|
mpData = new cFile_i;
|
||||||
}
|
}
|
||||||
|
|
||||||
cFile::~cFile()
|
cFile::~cFile()
|
||||||
{
|
{
|
||||||
if( mpData != NULL)
|
if( mpData != NULL)
|
||||||
{
|
{
|
||||||
delete mpData;
|
delete mpData;
|
||||||
mpData = NULL;
|
mpData = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -126,44 +126,44 @@ void cFile::Open( const TSTRING& sFileName, uint32 flags )
|
||||||
#else
|
#else
|
||||||
void cFile::Open( const TSTRING& sFileNameC, uint32 flags )
|
void cFile::Open( const TSTRING& sFileNameC, uint32 flags )
|
||||||
{
|
{
|
||||||
TSTRING sFileName = cArosPath::AsNative(sFileNameC);
|
TSTRING sFileName = cArosPath::AsNative(sFileNameC);
|
||||||
#endif
|
#endif
|
||||||
mode_t openmode = 0664;
|
mode_t openmode = 0664;
|
||||||
if ( mpData->mpCurrStream != NULL )
|
if ( mpData->mpCurrStream != NULL )
|
||||||
Close();
|
Close();
|
||||||
|
|
||||||
//
|
//
|
||||||
// set up the sopen permissions
|
// set up the sopen permissions
|
||||||
//
|
//
|
||||||
int perm = 0;
|
int perm = 0;
|
||||||
|
|
||||||
TSTRING mode;
|
TSTRING mode;
|
||||||
|
|
||||||
if( flags & OPEN_WRITE )
|
if( flags & OPEN_WRITE )
|
||||||
{
|
{
|
||||||
perm |= O_RDWR;
|
perm |= O_RDWR;
|
||||||
isWritable = true;
|
isWritable = true;
|
||||||
mode = _T("rb");
|
mode = _T("rb");
|
||||||
if( flags & OPEN_TRUNCATE )
|
if( flags & OPEN_TRUNCATE )
|
||||||
{
|
{
|
||||||
perm |= O_TRUNC;
|
perm |= O_TRUNC;
|
||||||
perm |= O_CREAT;
|
perm |= O_CREAT;
|
||||||
mode = _T("w+b");
|
mode = _T("w+b");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mode = _T("r+b");
|
mode = _T("r+b");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
perm |= O_RDONLY;
|
perm |= O_RDONLY;
|
||||||
isWritable = false;
|
isWritable = false;
|
||||||
mode = _T("rb");
|
mode = _T("rb");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( flags & OPEN_EXCLUSIVE ) {
|
if ( flags & OPEN_EXCLUSIVE ) {
|
||||||
perm |= O_CREAT | O_EXCL;
|
perm |= O_CREAT | O_EXCL;
|
||||||
openmode = (mode_t) 0600; // Make sure only root can read the file
|
openmode = (mode_t) 0600; // Make sure only root can read the file
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( flags & OPEN_CREATE )
|
if ( flags & OPEN_CREATE )
|
||||||
perm |= O_CREAT;
|
perm |= O_CREAT;
|
||||||
|
@ -172,83 +172,83 @@ void cFile::Open( const TSTRING& sFileNameC, uint32 flags )
|
||||||
if( flags & OPEN_NONBLOCKING )
|
if( flags & OPEN_NONBLOCKING )
|
||||||
perm |= O_NONBLOCK;
|
perm |= O_NONBLOCK;
|
||||||
#endif
|
#endif
|
||||||
//
|
//
|
||||||
// actually open the file
|
// actually open the file
|
||||||
//
|
//
|
||||||
int fh = _topen( sFileName.c_str(), perm, openmode );
|
int fh = _topen( sFileName.c_str(), perm, openmode );
|
||||||
if( fh == -1 )
|
if( fh == -1 )
|
||||||
{
|
{
|
||||||
throw( eFileOpen( sFileName, iFSServices::GetInstance()->GetErrString() ) );
|
throw( eFileOpen( sFileName, iFSServices::GetInstance()->GetErrString() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef __AROS__
|
#ifndef __AROS__
|
||||||
if( flags & OPEN_LOCKED_TEMP )
|
if( flags & OPEN_LOCKED_TEMP )
|
||||||
{
|
{
|
||||||
// unlink this file
|
// unlink this file
|
||||||
if( 0 != unlink( sFileName.c_str() ) )
|
if( 0 != unlink( sFileName.c_str() ) )
|
||||||
{
|
{
|
||||||
// we weren't able to unlink file, so close handle and fail
|
// we weren't able to unlink file, so close handle and fail
|
||||||
close( fh );
|
close( fh );
|
||||||
throw( eFileOpen( sFileName, iFSServices::GetInstance()->GetErrString() ) );
|
throw( eFileOpen( sFileName, iFSServices::GetInstance()->GetErrString() ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// turn the file handle into a FILE*
|
// turn the file handle into a FILE*
|
||||||
//
|
//
|
||||||
mpData->mpCurrStream = _tfdopen(fh, mode.c_str());
|
mpData->mpCurrStream = _tfdopen(fh, mode.c_str());
|
||||||
|
|
||||||
mpData->mFileName = sFileName; //Set mFileName to the newly opened file.
|
mpData->mFileName = sFileName; //Set mFileName to the newly opened file.
|
||||||
|
|
||||||
cFile::Rewind();
|
cFile::Rewind();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Close -- Closes mpCurrStream and sets the pointer to NULL
|
// Close -- Closes mpCurrStream and sets the pointer to NULL
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
void cFile::Close() //throw(eFile)
|
void cFile::Close() //throw(eFile)
|
||||||
{
|
{
|
||||||
if(mpData->mpCurrStream != NULL)
|
if(mpData->mpCurrStream != NULL)
|
||||||
{
|
{
|
||||||
fclose( mpData->mpCurrStream );
|
fclose( mpData->mpCurrStream );
|
||||||
mpData->mpCurrStream = NULL;
|
mpData->mpCurrStream = NULL;
|
||||||
}
|
}
|
||||||
mpData->mFileName.empty();
|
mpData->mFileName.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cFile::IsOpen( void ) const
|
bool cFile::IsOpen( void ) const
|
||||||
{
|
{
|
||||||
return( mpData->mpCurrStream != NULL );
|
return( mpData->mpCurrStream != NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Seek -- Positions the read/write offset in mpCurrStream. Returns the
|
// Seek -- Positions the read/write offset in mpCurrStream. Returns the
|
||||||
// current offset upon completion. Returns 0 if no stream is defined.
|
// current offset upon completion. Returns 0 if no stream is defined.
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
cFile::File_t cFile::Seek( File_t offset, SeekFrom From) const //throw(eFile)
|
cFile::File_t cFile::Seek( File_t offset, SeekFrom From) const //throw(eFile)
|
||||||
{
|
{
|
||||||
//Check to see if a file as been opened yet...
|
//Check to see if a file as been opened yet...
|
||||||
ASSERT( mpData->mpCurrStream != 0);
|
ASSERT( mpData->mpCurrStream != 0);
|
||||||
|
|
||||||
int apiFrom;
|
int apiFrom;
|
||||||
|
|
||||||
switch( From )
|
switch( From )
|
||||||
{
|
{
|
||||||
case cFile::SEEK_BEGIN:
|
case cFile::SEEK_BEGIN:
|
||||||
apiFrom = SEEK_SET;
|
apiFrom = SEEK_SET;
|
||||||
break;
|
break;
|
||||||
case cFile::SEEK_CURRENT:
|
case cFile::SEEK_CURRENT:
|
||||||
apiFrom = SEEK_CUR;
|
apiFrom = SEEK_CUR;
|
||||||
break;
|
break;
|
||||||
case cFile::SEEK_EOF:
|
case cFile::SEEK_EOF:
|
||||||
apiFrom = SEEK_END;
|
apiFrom = SEEK_END;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
//An invalid SeekFrom parameter was passed.
|
//An invalid SeekFrom parameter was passed.
|
||||||
throw( eInternal( _T("file_unix") ) );
|
throw( eInternal( _T("file_unix") ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is a hack to simulate running out of disk space
|
// this is a hack to simulate running out of disk space
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -276,98 +276,98 @@ cFile::File_t cFile::Seek( File_t offset, SeekFrom From) const //throw(eFile)
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Read -- Returns the actual bytes read from mpCurrStream. Returns 0 if
|
// Read -- Returns the actual bytes read from mpCurrStream. Returns 0 if
|
||||||
// mpCurrStream is undefined.
|
// mpCurrStream is undefined.
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
cFile::File_t cFile::Read( void* buffer, File_t nBytes ) const //throw(eFile)
|
cFile::File_t cFile::Read( void* buffer, File_t nBytes ) const //throw(eFile)
|
||||||
{
|
{
|
||||||
File_t iBytesRead;
|
File_t iBytesRead;
|
||||||
|
|
||||||
// Has a file been opened?
|
// Has a file been opened?
|
||||||
ASSERT( mpData->mpCurrStream != NULL );
|
ASSERT( mpData->mpCurrStream != NULL );
|
||||||
|
|
||||||
// Is the nBytes parameter 0? If so, return without touching buffer:
|
// Is the nBytes parameter 0? If so, return without touching buffer:
|
||||||
if( nBytes == 0 )
|
if( nBytes == 0 )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
iBytesRead = fread( buffer, sizeof(byte), nBytes, mpData->mpCurrStream );
|
iBytesRead = fread( buffer, sizeof(byte), nBytes, mpData->mpCurrStream );
|
||||||
|
|
||||||
if( ferror( mpData->mpCurrStream ) != 0 )
|
if( ferror( mpData->mpCurrStream ) != 0 )
|
||||||
throw eFileRead( mpData->mFileName, iFSServices::GetInstance()->GetErrString() ) ;
|
throw eFileRead( mpData->mFileName, iFSServices::GetInstance()->GetErrString() ) ;
|
||||||
else
|
else
|
||||||
return iBytesRead;
|
return iBytesRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Write -- Returns the actual number of bytes written to mpCurrStream
|
// Write -- Returns the actual number of bytes written to mpCurrStream
|
||||||
// Returns 0 if no file has been opened.
|
// Returns 0 if no file has been opened.
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
cFile::File_t cFile::Write( const void* buffer, File_t nBytes ) //throw(eFile)
|
cFile::File_t cFile::Write( const void* buffer, File_t nBytes ) //throw(eFile)
|
||||||
{
|
{
|
||||||
File_t actual_count = 0;
|
File_t actual_count = 0;
|
||||||
|
|
||||||
// Has a file been opened? Is it writable?
|
// Has a file been opened? Is it writable?
|
||||||
ASSERT( mpData->mpCurrStream != NULL );
|
ASSERT( mpData->mpCurrStream != NULL );
|
||||||
ASSERT( isWritable );
|
ASSERT( isWritable );
|
||||||
|
|
||||||
if( ( actual_count = fwrite( buffer, sizeof(byte), nBytes, mpData->mpCurrStream ) ) < nBytes )
|
if( ( actual_count = fwrite( buffer, sizeof(byte), nBytes, mpData->mpCurrStream ) ) < nBytes )
|
||||||
throw eFileWrite( mpData->mFileName, iFSServices::GetInstance()->GetErrString() );
|
throw eFileWrite( mpData->mFileName, iFSServices::GetInstance()->GetErrString() );
|
||||||
else
|
else
|
||||||
return actual_count;
|
return actual_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Tell -- Returns the current file offset. Returns 0 if no file has been
|
// Tell -- Returns the current file offset. Returns 0 if no file has been
|
||||||
// opened.
|
// opened.
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
cFile::File_t cFile::Tell() const
|
cFile::File_t cFile::Tell() const
|
||||||
{
|
{
|
||||||
ASSERT( mpData->mpCurrStream != 0);
|
ASSERT( mpData->mpCurrStream != 0);
|
||||||
|
|
||||||
return ftell( mpData->mpCurrStream );
|
return ftell( mpData->mpCurrStream );
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Flush -- Flushes the current stream.
|
// Flush -- Flushes the current stream.
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
bool cFile::Flush() //throw(eFile)
|
bool cFile::Flush() //throw(eFile)
|
||||||
{
|
{
|
||||||
if ( mpData->mpCurrStream == NULL )
|
if ( mpData->mpCurrStream == NULL )
|
||||||
throw eFileFlush( mpData->mFileName, iFSServices::GetInstance()->GetErrString() );
|
throw eFileFlush( mpData->mFileName, iFSServices::GetInstance()->GetErrString() );
|
||||||
|
|
||||||
return ( fflush( mpData->mpCurrStream) == 0 );
|
return ( fflush( mpData->mpCurrStream) == 0 );
|
||||||
}
|
}
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Rewind -- Sets the offset to the beginning of the file. If mpCurrStream
|
// Rewind -- Sets the offset to the beginning of the file. If mpCurrStream
|
||||||
// is NULL, this method returns false. If the rewind operation fails,
|
// is NULL, this method returns false. If the rewind operation fails,
|
||||||
// an exception is thrown.
|
// an exception is thrown.
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
void cFile::Rewind() const //throw(eFile)
|
void cFile::Rewind() const //throw(eFile)
|
||||||
{
|
{
|
||||||
ASSERT( mpData->mpCurrStream != 0);
|
ASSERT( mpData->mpCurrStream != 0);
|
||||||
|
|
||||||
rewind( mpData->mpCurrStream );
|
rewind( mpData->mpCurrStream );
|
||||||
if( ftell( mpData->mpCurrStream ) != 0 )
|
if( ftell( mpData->mpCurrStream ) != 0 )
|
||||||
throw( eFileRewind( mpData->mFileName, iFSServices::GetInstance()->GetErrString() ) );
|
throw( eFileRewind( mpData->mFileName, iFSServices::GetInstance()->GetErrString() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// GetSize -- Returns the size of the current stream, if one has been
|
// GetSize -- Returns the size of the current stream, if one has been
|
||||||
// opened. If no stream has been opened, returns -1.
|
// opened. If no stream has been opened, returns -1.
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
cFile::File_t cFile::GetSize() const
|
cFile::File_t cFile::GetSize() const
|
||||||
{
|
{
|
||||||
File_t vCurrentOffset = Tell(); //for saving the current offset
|
File_t vCurrentOffset = Tell(); //for saving the current offset
|
||||||
File_t ret;
|
File_t ret;
|
||||||
|
|
||||||
//Has a file been opened? If not, return -1
|
//Has a file been opened? If not, return -1
|
||||||
if( mpData->mpCurrStream == NULL )
|
if( mpData->mpCurrStream == NULL )
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = Seek( 0, cFile::SEEK_EOF );
|
ret = Seek( 0, cFile::SEEK_EOF );
|
||||||
Seek( vCurrentOffset, cFile::SEEK_BEGIN );
|
Seek( vCurrentOffset, cFile::SEEK_BEGIN );
|
||||||
//return the offset to it's position prior to GetSize call.
|
//return the offset to it's position prior to GetSize call.
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -375,39 +375,39 @@ cFile::File_t cFile::GetSize() const
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
void cFile::Truncate( File_t offset ) // throw(eFile)
|
void cFile::Truncate( File_t offset ) // throw(eFile)
|
||||||
{
|
{
|
||||||
ASSERT( mpData->mpCurrStream != 0);
|
ASSERT( mpData->mpCurrStream != 0);
|
||||||
ASSERT( isWritable );
|
ASSERT( isWritable );
|
||||||
|
|
||||||
ftruncate( fileno(mpData->mpCurrStream), offset );
|
ftruncate( fileno(mpData->mpCurrStream), offset );
|
||||||
if( GetSize() != offset )
|
if( GetSize() != offset )
|
||||||
throw( eFileTrunc( mpData->mFileName, iFSServices::GetInstance()->GetErrString() ) );
|
throw( eFileTrunc( mpData->mFileName, iFSServices::GetInstance()->GetErrString() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef __AROS__
|
#ifdef __AROS__
|
||||||
TSTRING cArosPath::AsPosix( const TSTRING& in )
|
TSTRING cArosPath::AsPosix( const TSTRING& in )
|
||||||
{
|
{
|
||||||
if (in[0] == '/')
|
if (in[0] == '/')
|
||||||
return in;
|
return in;
|
||||||
|
|
||||||
TSTRING out = '/' + in;
|
TSTRING out = '/' + in;
|
||||||
std::replace(out.begin(), out.end(), ':', '/');
|
std::replace(out.begin(), out.end(), ':', '/');
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
TSTRING cArosPath::AsNative( const TSTRING& in )
|
TSTRING cArosPath::AsNative( const TSTRING& in )
|
||||||
{
|
{
|
||||||
if (in[0] != '/')
|
if (in[0] != '/')
|
||||||
return in;
|
return in;
|
||||||
|
|
||||||
int x;
|
int x;
|
||||||
for (x=1; in[x] == '/' && x<in.length(); x++);
|
for (x=1; in[x] == '/' && x<in.length(); x++);
|
||||||
|
|
||||||
TSTRING out = in.substr(x);
|
TSTRING out = in.substr(x);
|
||||||
TSTRING::size_type t = out.find_first_of('/');
|
TSTRING::size_type t = out.find_first_of('/');
|
||||||
out[t] = ':';
|
out[t] = ':';
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -40,37 +40,37 @@
|
||||||
eFileError::eFileError( const TSTRING& filename, const TSTRING& description, uint32 flags )
|
eFileError::eFileError( const TSTRING& filename, const TSTRING& description, uint32 flags )
|
||||||
: eError( _T(""), flags )
|
: eError( _T(""), flags )
|
||||||
{
|
{
|
||||||
mFilename = filename;
|
mFilename = filename;
|
||||||
mMsg = description;
|
mMsg = description;
|
||||||
}
|
}
|
||||||
|
|
||||||
TSTRING eFileError::GetFilename() const
|
TSTRING eFileError::GetFilename() const
|
||||||
{
|
{
|
||||||
return mFilename;
|
return mFilename;
|
||||||
}
|
}
|
||||||
|
|
||||||
TSTRING eFileError::GetDescription() const
|
TSTRING eFileError::GetDescription() const
|
||||||
{
|
{
|
||||||
return mMsg;
|
return mMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* virtual */ TSTRING eFileError::GetMsg() const
|
/* virtual */ TSTRING eFileError::GetMsg() const
|
||||||
{
|
{
|
||||||
TSTRING ret;
|
TSTRING ret;
|
||||||
|
|
||||||
if( ! mFilename.empty() )
|
if( ! mFilename.empty() )
|
||||||
{
|
{
|
||||||
ret = TSS_GetString( cCore, core::STR_ERROR_FILENAME ) + mFilename;
|
ret = TSS_GetString( cCore, core::STR_ERROR_FILENAME ) + mFilename;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ! mMsg.empty() )
|
if( ! mMsg.empty() )
|
||||||
{
|
{
|
||||||
if ( ! mFilename.empty() )
|
if ( ! mFilename.empty() )
|
||||||
ret += _T("\n");
|
ret += _T("\n");
|
||||||
|
|
||||||
ret += mMsg;
|
ret += mMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,28 +53,28 @@
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
TSS_BEGIN_EXCEPTION_NO_CTOR( eFileError, eError )
|
TSS_BEGIN_EXCEPTION_NO_CTOR( eFileError, eError )
|
||||||
private:
|
private:
|
||||||
TSTRING mFilename;
|
TSTRING mFilename;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
eFileError( const TSTRING& filename, const TSTRING& description, uint32 flags = 0 );
|
eFileError( const TSTRING& filename, const TSTRING& description, uint32 flags = 0 );
|
||||||
|
|
||||||
explicit eFileError( const eFileError& rhs )
|
explicit eFileError( const eFileError& rhs )
|
||||||
: eError( rhs ) { mFilename = rhs.mFilename; }
|
: eError( rhs ) { mFilename = rhs.mFilename; }
|
||||||
eFileError( const TSTRING& msg, uint32 flags = 0 )
|
eFileError( const TSTRING& msg, uint32 flags = 0 )
|
||||||
: eError( msg, flags ) {}
|
: eError( msg, flags ) {}
|
||||||
|
|
||||||
|
|
||||||
TSTRING GetFilename() const;
|
TSTRING GetFilename() const;
|
||||||
TSTRING GetDescription() const;
|
TSTRING GetDescription() const;
|
||||||
virtual TSTRING GetMsg() const;
|
virtual TSTRING GetMsg() const;
|
||||||
|
|
||||||
TSS_END_EXCEPTION()
|
TSS_END_EXCEPTION()
|
||||||
|
|
||||||
#define TSS_FILE_EXCEPTION( except, base ) \
|
#define TSS_FILE_EXCEPTION( except, base ) \
|
||||||
TSS_BEGIN_EXCEPTION( except, base ) \
|
TSS_BEGIN_EXCEPTION( except, base ) \
|
||||||
except( const TSTRING& filename, const TSTRING& msg, uint32 flags = 0 ) \
|
except( const TSTRING& filename, const TSTRING& msg, uint32 flags = 0 ) \
|
||||||
: base( filename, msg, flags ) {} \
|
: base( filename, msg, flags ) {} \
|
||||||
TSS_END_EXCEPTION()
|
TSS_END_EXCEPTION()
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -110,17 +110,17 @@ int cFileHeaderID::operator==( const cFileHeaderID& rhs ) const
|
||||||
( ::memcmp( mID, rhs.mID, mIDLen * sizeof(char) ) == 0 );
|
( ::memcmp( mID, rhs.mID, mIDLen * sizeof(char) ) == 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
void cFileHeaderID::Read(iSerializer* pSerializer, int32 /*version*/ ) // throw (eSerializer, eArchive)
|
void cFileHeaderID::Read(iSerializer* pSerializer, int32 /*version*/ ) // throw (eSerializer, eArchive)
|
||||||
{
|
{
|
||||||
int16 len;
|
int16 len;
|
||||||
pSerializer->ReadInt16( len );
|
pSerializer->ReadInt16( len );
|
||||||
if ( (len < 0) || (len >= cFileHeaderID::MAXBYTES ))
|
if ( (len < 0) || (len >= cFileHeaderID::MAXBYTES ))
|
||||||
{
|
{
|
||||||
// this is invalid!
|
// this is invalid!
|
||||||
throw eSerializerInputStreamFmt( _T("File Header ID invalid") );
|
throw eSerializerInputStreamFmt( _T("File Header ID invalid") );
|
||||||
}
|
}
|
||||||
pSerializer->ReadBlob(mID, len * sizeof(char));
|
pSerializer->ReadBlob(mID, len * sizeof(char));
|
||||||
mIDLen = len;
|
mIDLen = len;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cFileHeaderID::Write(iSerializer* pSerializer) const // throw (eSerializer, eArchive)
|
void cFileHeaderID::Write(iSerializer* pSerializer) const // throw (eSerializer, eArchive)
|
||||||
|
|
|
@ -59,8 +59,8 @@ public:
|
||||||
int operator == (const cFileHeaderID& rhs) const;
|
int operator == (const cFileHeaderID& rhs) const;
|
||||||
int operator != (const cFileHeaderID& rhs) const;
|
int operator != (const cFileHeaderID& rhs) const;
|
||||||
|
|
||||||
virtual void Read (iSerializer* pSerializer, int32 version = 0); // throw (eSerializer, eArchive)
|
virtual void Read (iSerializer* pSerializer, int32 version = 0); // throw (eSerializer, eArchive)
|
||||||
virtual void Write(iSerializer* pSerializer) const; // throw (eSerializer, eArchive)
|
virtual void Write(iSerializer* pSerializer) const; // throw (eSerializer, eArchive)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// For now we will store the id as a string.
|
// For now we will store the id as a string.
|
||||||
|
@ -127,8 +127,8 @@ public:
|
||||||
cMemoryArchive& GetBaggage();
|
cMemoryArchive& GetBaggage();
|
||||||
const cMemoryArchive& GetBaggage() const;
|
const cMemoryArchive& GetBaggage() const;
|
||||||
|
|
||||||
virtual void Read (iSerializer* pSerializer, int32 version = 0); // throw (eSerializer, eArchive)
|
virtual void Read (iSerializer* pSerializer, int32 version = 0); // throw (eSerializer, eArchive)
|
||||||
virtual void Write(iSerializer* pSerializer) const; // throw (eSerializer, eArchive)
|
virtual void Write(iSerializer* pSerializer) const; // throw (eSerializer, eArchive)
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
cFileHeaderID mID;
|
cFileHeaderID mID;
|
||||||
|
|
|
@ -45,26 +45,26 @@
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// cGrowHeap -- a heap that can grow but never shrink
|
// cGrowHeap -- a heap that can grow but never shrink
|
||||||
// All items alloced should be well below growBy in size
|
// All items alloced should be well below growBy in size
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
class cGrowHeap_i;
|
class cGrowHeap_i;
|
||||||
|
|
||||||
class cGrowHeap
|
class cGrowHeap
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cGrowHeap( size_t initialSize, size_t growby, const TCHAR* name );
|
cGrowHeap( size_t initialSize, size_t growby, const TCHAR* name );
|
||||||
// creates a heap that is initially initialSize big, and increases the
|
// creates a heap that is initially initialSize big, and increases the
|
||||||
// size by growBy every time there is no more room.
|
// size by growBy every time there is no more room.
|
||||||
// initialSize and growby must be a multiple of BYTE_ALIGN
|
// initialSize and growby must be a multiple of BYTE_ALIGN
|
||||||
~cGrowHeap();
|
~cGrowHeap();
|
||||||
|
|
||||||
void* Malloc( size_t size );
|
void* Malloc( size_t size );
|
||||||
void Clear();
|
void Clear();
|
||||||
// resets the grow heap's state.
|
// resets the grow heap's state.
|
||||||
size_t TotalMemUsage() const;
|
size_t TotalMemUsage() const;
|
||||||
// returns the total memory usage of this heap
|
// returns the total memory usage of this heap
|
||||||
private:
|
private:
|
||||||
cGrowHeap_i* mpData;
|
cGrowHeap_i* mpData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
// operator overloaded in order for this to work. TSTRINGS will always
|
// operator overloaded in order for this to work. TSTRINGS will always
|
||||||
// work as the key value because of the overloaded-template-function
|
// work as the key value because of the overloaded-template-function
|
||||||
//
|
//
|
||||||
// Note: Any overloaded const byte*() operator must return an
|
// Note: Any overloaded const byte*() operator must return an
|
||||||
// length of key as well. see cDefaultConvert
|
// length of key as well. see cDefaultConvert
|
||||||
//
|
//
|
||||||
// IMPORTANT -- cDefaultConvert only works for pointers to objects
|
// IMPORTANT -- cDefaultConvert only works for pointers to objects
|
||||||
|
@ -63,18 +63,18 @@
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// Comparison function objects ... these are used by the hash table to determine
|
// Comparison function objects ... these are used by the hash table to determine
|
||||||
// equality. The one defined should work for objects that use op== to define
|
// equality. The one defined should work for objects that use op== to define
|
||||||
// equality. There is also a specialization for TSTRINGS. If neither of these
|
// equality. There is also a specialization for TSTRINGS. If neither of these
|
||||||
// fit your needs, you must pass the hash table your own fn pointer or class
|
// fit your needs, you must pass the hash table your own fn pointer or class
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
template<class T>
|
template<class T>
|
||||||
class cDefaultCompare
|
class cDefaultCompare
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool operator()(const T& lhs, const T& rhs)
|
bool operator()(const T& lhs, const T& rhs)
|
||||||
{
|
{
|
||||||
return lhs == rhs;
|
return lhs == rhs;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
/////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////
|
||||||
// specialization for TSTRINGS
|
// specialization for TSTRINGS
|
||||||
|
@ -82,24 +82,24 @@ public:
|
||||||
template<>
|
template<>
|
||||||
inline bool cDefaultCompare<TSTRING>::operator()(const TSTRING& lhs, const TSTRING& rhs)
|
inline bool cDefaultCompare<TSTRING>::operator()(const TSTRING& lhs, const TSTRING& rhs)
|
||||||
{
|
{
|
||||||
return (lhs.compare(rhs) == 0);
|
return (lhs.compare(rhs) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// Conversion function objects ... used by the hash table to locate the key in KEY_TYPE
|
// Conversion function objects ... used by the hash table to locate the key in KEY_TYPE
|
||||||
// into a byte* and a key length (for hashing purposes). The default implementation
|
// into a byte* and a key length (for hashing purposes). The default implementation
|
||||||
// just does a cast. A specialization is also provided for TSTRINGs.
|
// just does a cast. A specialization is also provided for TSTRINGs.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
template<class T>
|
template<class T>
|
||||||
class cDefaultConvert
|
class cDefaultConvert
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
const byte* operator()(const T& obj, int* const pcbKeyLen)
|
const byte* operator()(const T& obj, int* const pcbKeyLen)
|
||||||
{
|
{
|
||||||
// HACK! TODO: in the interest of time, I've left this as it is.....
|
// HACK! TODO: in the interest of time, I've left this as it is.....
|
||||||
*pcbKeyLen = sizeof(TCHAR) * _tcslen(obj);
|
*pcbKeyLen = sizeof(TCHAR) * _tcslen(obj);
|
||||||
return (byte*)obj;
|
return (byte*)obj;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
/////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////
|
||||||
// specialization for TSTRINGS
|
// specialization for TSTRINGS
|
||||||
|
@ -108,27 +108,27 @@ template<>
|
||||||
inline const byte* cDefaultConvert<TSTRING>::operator()(const TSTRING& obj, int* const pcbKeyLen )
|
inline const byte* cDefaultConvert<TSTRING>::operator()(const TSTRING& obj, int* const pcbKeyLen )
|
||||||
{
|
{
|
||||||
*pcbKeyLen = sizeof(TCHAR) * obj.length();
|
*pcbKeyLen = sizeof(TCHAR) * obj.length();
|
||||||
return (byte*)obj.c_str();
|
return (byte*)obj.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// cHashTable<KEY, VAL, CMP, CONVERTER>
|
// cHashTable<KEY, VAL, CMP, CONVERTER>
|
||||||
// KEY -- the key you are hashing on
|
// KEY -- the key you are hashing on
|
||||||
// VAL -- the value you want associated with that key
|
// VAL -- the value you want associated with that key
|
||||||
// CMP -- a function object that takes (KEY, KEY) and returns true if they
|
// CMP -- a function object that takes (KEY, KEY) and returns true if they
|
||||||
// are equal.
|
// are equal.
|
||||||
// CONVERTER -- function object that takes (KEY, int* pcbKeyLen) and returns a const byte*
|
// CONVERTER -- function object that takes (KEY, int* pcbKeyLen) and returns a const byte*
|
||||||
// ( points to start of key ) and a byte length (in pcbKeyLen) that tells the hashtable
|
// ( points to start of key ) and a byte length (in pcbKeyLen) that tells the hashtable
|
||||||
// how long the key is
|
// how long the key is
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// these were moved outside of the class because it sucks to have to name the class with template parameters
|
// these were moved outside of the class because it sucks to have to name the class with template parameters
|
||||||
// ie -- mTable(cHashTable<TSTRING, int>::MEDIUM
|
// ie -- mTable(cHashTable<TSTRING, int>::MEDIUM
|
||||||
enum cHashTable_TableSize {
|
enum cHashTable_TableSize {
|
||||||
HASH_VERY_SMALL = 17,
|
HASH_VERY_SMALL = 17,
|
||||||
HASH_SMALL = 2007,
|
HASH_SMALL = 2007,
|
||||||
HASH_MEDIUM = 6007,
|
HASH_MEDIUM = 6007,
|
||||||
HASH_LARGE = 13007,
|
HASH_LARGE = 13007,
|
||||||
HASH_VERY_LARGE = 49999
|
HASH_VERY_LARGE = 49999
|
||||||
};
|
};
|
||||||
|
|
||||||
// forward declaration
|
// forward declaration
|
||||||
|
@ -141,48 +141,48 @@ class cHashTable
|
||||||
{
|
{
|
||||||
friend class cHashTableIter<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>;
|
friend class cHashTableIter<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>;
|
||||||
public:
|
public:
|
||||||
//structure for hash table nodes.
|
//structure for hash table nodes.
|
||||||
struct node {
|
struct node {
|
||||||
KEY_TYPE nKey;
|
KEY_TYPE nKey;
|
||||||
VAL_TYPE nData;
|
VAL_TYPE nData;
|
||||||
node* next;
|
node* next;
|
||||||
};
|
};
|
||||||
|
|
||||||
cHashTable(int tblSize = HASH_MEDIUM);
|
cHashTable(int tblSize = HASH_MEDIUM);
|
||||||
~cHashTable();
|
~cHashTable();
|
||||||
|
|
||||||
bool Insert(KEY_TYPE key, VAL_TYPE data_in);
|
bool Insert(KEY_TYPE key, VAL_TYPE data_in);
|
||||||
// The pointer, data_in, is stored in a node based on string_in's hashing.
|
// The pointer, data_in, is stored in a node based on string_in's hashing.
|
||||||
//
|
//
|
||||||
// if (key) already exists in the table, then it's value is replaced by (data_in)
|
// if (key) already exists in the table, then it's value is replaced by (data_in)
|
||||||
// returns true if (key) already existed in table. otherwise, returns false
|
// returns true if (key) already existed in table. otherwise, returns false
|
||||||
|
|
||||||
bool Lookup(KEY_TYPE key, VAL_TYPE& data_out) const;
|
bool Lookup(KEY_TYPE key, VAL_TYPE& data_out) const;
|
||||||
//bool Lookup(TSTRING key, VAL_TYPE& data_out) const;
|
//bool Lookup(TSTRING key, VAL_TYPE& data_out) const;
|
||||||
//Lookup returns true if a match is found for string_check. A reference
|
//Lookup returns true if a match is found for string_check. A reference
|
||||||
//to the node in the table that matches string_check is passed back (by ref).
|
//to the node in the table that matches string_check is passed back (by ref).
|
||||||
bool Remove(KEY_TYPE key);
|
bool Remove(KEY_TYPE key);
|
||||||
//The node that matches string_out is de-allocated.
|
//The node that matches string_out is de-allocated.
|
||||||
|
|
||||||
bool Clear(void);
|
bool Clear(void);
|
||||||
//Clears the entire table and sets all node pointers to NULL
|
//Clears the entire table and sets all node pointers to NULL
|
||||||
bool IsEmpty(void) const;
|
bool IsEmpty(void) const;
|
||||||
uint32 Hash( const KEY_TYPE& key ) const;
|
uint32 Hash( const KEY_TYPE& key ) const;
|
||||||
//The hashing function, taken from old Tripwire
|
//The hashing function, taken from old Tripwire
|
||||||
int32 GetNumValues() const { return mValuesInTable; };
|
int32 GetNumValues() const { return mValuesInTable; };
|
||||||
// returns number of table entries filled
|
// returns number of table entries filled
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
void TraceDiagnostics() const;
|
void TraceDiagnostics() const;
|
||||||
// traces hash table statistics
|
// traces hash table statistics
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
cHashTable(const cHashTable& rhs); // not impl
|
cHashTable(const cHashTable& rhs); // not impl
|
||||||
void operator=(const cHashTable& rhs); // not impl
|
void operator=(const cHashTable& rhs); // not impl
|
||||||
|
|
||||||
node** mTable;
|
node** mTable;
|
||||||
int mTableSize;
|
int mTableSize;
|
||||||
int32 mValuesInTable;
|
int32 mValuesInTable;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -194,23 +194,23 @@ template <class KEY_TYPE, class VAL_TYPE, class COMPARE_OP, class CONVERTER>
|
||||||
class cHashTableIter
|
class cHashTableIter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cHashTableIter(const cHashTable<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>& hashTbl);
|
cHashTableIter(const cHashTable<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>& hashTbl);
|
||||||
|
|
||||||
void SeekBegin() const;
|
void SeekBegin() const;
|
||||||
bool Done() const;
|
bool Done() const;
|
||||||
void Next() const;
|
void Next() const;
|
||||||
|
|
||||||
const KEY_TYPE& Key() const;
|
const KEY_TYPE& Key() const;
|
||||||
const VAL_TYPE& Val() const;
|
const VAL_TYPE& Val() const;
|
||||||
VAL_TYPE& Val();
|
VAL_TYPE& Val();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable int mCurIndex;
|
mutable int mCurIndex;
|
||||||
mutable typename cHashTable<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::node* mpCurNode;
|
mutable typename cHashTable<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::node* mpCurNode;
|
||||||
const cHashTable<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>& mHashTable;
|
const cHashTable<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>& mHashTable;
|
||||||
|
|
||||||
// helper function
|
// helper function
|
||||||
void SeekNextValid() const;
|
void SeekNextValid() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -223,61 +223,61 @@ private:
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
template <class KEY_TYPE, class VAL_TYPE, class COMPARE_OP, class CONVERTER>
|
template <class KEY_TYPE, class VAL_TYPE, class COMPARE_OP, class CONVERTER>
|
||||||
inline cHashTableIter<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::cHashTableIter( const cHashTable<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>& hashTbl) :
|
inline cHashTableIter<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::cHashTableIter( const cHashTable<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>& hashTbl) :
|
||||||
mHashTable(hashTbl)
|
mHashTable(hashTbl)
|
||||||
{
|
{
|
||||||
SeekBegin();
|
SeekBegin();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class KEY_TYPE, class VAL_TYPE, class COMPARE_OP, class CONVERTER>
|
template <class KEY_TYPE, class VAL_TYPE, class COMPARE_OP, class CONVERTER>
|
||||||
inline void cHashTableIter<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::SeekBegin() const
|
inline void cHashTableIter<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::SeekBegin() const
|
||||||
{
|
{
|
||||||
mCurIndex = 0;
|
mCurIndex = 0;
|
||||||
mpCurNode = mHashTable.mTable[0];
|
mpCurNode = mHashTable.mTable[0];
|
||||||
if(! mpCurNode)
|
if(! mpCurNode)
|
||||||
SeekNextValid();
|
SeekNextValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class KEY_TYPE, class VAL_TYPE, class COMPARE_OP, class CONVERTER>
|
template <class KEY_TYPE, class VAL_TYPE, class COMPARE_OP, class CONVERTER>
|
||||||
inline bool cHashTableIter<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::Done() const
|
inline bool cHashTableIter<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::Done() const
|
||||||
{
|
{
|
||||||
return ((mCurIndex < 0) || (mCurIndex >= mHashTable.mTableSize));
|
return ((mCurIndex < 0) || (mCurIndex >= mHashTable.mTableSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class KEY_TYPE, class VAL_TYPE, class COMPARE_OP, class CONVERTER>
|
template <class KEY_TYPE, class VAL_TYPE, class COMPARE_OP, class CONVERTER>
|
||||||
inline void cHashTableIter<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::Next() const
|
inline void cHashTableIter<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::Next() const
|
||||||
{
|
{
|
||||||
SeekNextValid();
|
SeekNextValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class KEY_TYPE, class VAL_TYPE, class COMPARE_OP, class CONVERTER>
|
template <class KEY_TYPE, class VAL_TYPE, class COMPARE_OP, class CONVERTER>
|
||||||
inline void cHashTableIter<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::SeekNextValid() const
|
inline void cHashTableIter<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::SeekNextValid() const
|
||||||
{
|
{
|
||||||
if(mpCurNode)
|
if(mpCurNode)
|
||||||
mpCurNode = mpCurNode->next;
|
mpCurNode = mpCurNode->next;
|
||||||
//mCurIndex++;
|
//mCurIndex++;
|
||||||
while((! mpCurNode) && (mCurIndex < mHashTable.mTableSize))
|
while((! mpCurNode) && (mCurIndex < mHashTable.mTableSize))
|
||||||
{
|
{
|
||||||
mpCurNode = mHashTable.mTable[++mCurIndex];
|
mpCurNode = mHashTable.mTable[++mCurIndex];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class KEY_TYPE, class VAL_TYPE, class COMPARE_OP, class CONVERTER>
|
template <class KEY_TYPE, class VAL_TYPE, class COMPARE_OP, class CONVERTER>
|
||||||
inline const KEY_TYPE& cHashTableIter<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::Key() const
|
inline const KEY_TYPE& cHashTableIter<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::Key() const
|
||||||
{
|
{
|
||||||
ASSERT(! Done());
|
ASSERT(! Done());
|
||||||
return mpCurNode->nKey;
|
return mpCurNode->nKey;
|
||||||
}
|
}
|
||||||
template <class KEY_TYPE, class VAL_TYPE, class COMPARE_OP, class CONVERTER>
|
template <class KEY_TYPE, class VAL_TYPE, class COMPARE_OP, class CONVERTER>
|
||||||
inline const VAL_TYPE& cHashTableIter<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::Val() const
|
inline const VAL_TYPE& cHashTableIter<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::Val() const
|
||||||
{
|
{
|
||||||
ASSERT(! Done());
|
ASSERT(! Done());
|
||||||
return mpCurNode->nData;
|
return mpCurNode->nData;
|
||||||
}
|
}
|
||||||
template <class KEY_TYPE, class VAL_TYPE, class COMPARE_OP, class CONVERTER>
|
template <class KEY_TYPE, class VAL_TYPE, class COMPARE_OP, class CONVERTER>
|
||||||
inline VAL_TYPE& cHashTableIter<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::Val()
|
inline VAL_TYPE& cHashTableIter<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::Val()
|
||||||
{
|
{
|
||||||
ASSERT(! Done());
|
ASSERT(! Done());
|
||||||
return mpCurNode->nData;
|
return mpCurNode->nData;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -289,98 +289,98 @@ template <class KEY_TYPE, class VAL_TYPE, class COMPARE_OP, class CONVERTER>
|
||||||
cHashTable<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::cHashTable(int tblSize)
|
cHashTable<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::cHashTable(int tblSize)
|
||||||
{
|
{
|
||||||
mValuesInTable = 0;
|
mValuesInTable = 0;
|
||||||
mTableSize = tblSize;
|
mTableSize = tblSize;
|
||||||
mTable = new node*[mTableSize];
|
mTable = new node*[mTableSize];
|
||||||
|
|
||||||
for (int i=0; i < mTableSize; ++i)
|
for (int i=0; i < mTableSize; ++i)
|
||||||
mTable[i] = NULL;
|
mTable[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Destructor steps through table and deallocates all dynamic memory
|
//Destructor steps through table and deallocates all dynamic memory
|
||||||
template <class KEY_TYPE, class VAL_TYPE, class COMPARE_OP, class CONVERTER>
|
template <class KEY_TYPE, class VAL_TYPE, class COMPARE_OP, class CONVERTER>
|
||||||
cHashTable<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::~cHashTable()
|
cHashTable<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::~cHashTable()
|
||||||
{
|
{
|
||||||
for (int i=0; i<mTableSize; ++i)
|
for (int i=0; i<mTableSize; ++i)
|
||||||
{
|
{
|
||||||
if (mTable[i] != NULL)
|
if (mTable[i] != NULL)
|
||||||
{
|
{
|
||||||
//delete the entire chain:
|
//delete the entire chain:
|
||||||
node* curr = mTable[i];
|
node* curr = mTable[i];
|
||||||
node* del;
|
node* del;
|
||||||
while(curr != NULL)
|
while(curr != NULL)
|
||||||
{
|
{
|
||||||
del = curr;
|
del = curr;
|
||||||
curr=curr->next;
|
curr=curr->next;
|
||||||
|
|
||||||
delete del;
|
delete del;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Insert -- Hashes a const TCHAR* to a new index. Collisions are resolved
|
// Insert -- Hashes a const TCHAR* to a new index. Collisions are resolved
|
||||||
// using seperate chaining (link lists).
|
// using seperate chaining (link lists).
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// General Version:
|
// General Version:
|
||||||
template <class KEY_TYPE, class VAL_TYPE, class COMPARE_OP, class CONVERTER>
|
template <class KEY_TYPE, class VAL_TYPE, class COMPARE_OP, class CONVERTER>
|
||||||
bool cHashTable<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::Insert(KEY_TYPE key, VAL_TYPE d_in)
|
bool cHashTable<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::Insert(KEY_TYPE key, VAL_TYPE d_in)
|
||||||
{
|
{
|
||||||
COMPARE_OP compare;
|
COMPARE_OP compare;
|
||||||
|
|
||||||
int hindex = Hash( key );
|
int hindex = Hash( key );
|
||||||
if (mTable[hindex] == NULL) {
|
if (mTable[hindex] == NULL) {
|
||||||
//open index, perform insert
|
//open index, perform insert
|
||||||
mTable[hindex] = new node;
|
mTable[hindex] = new node;
|
||||||
(mTable[hindex])->nKey = key;
|
(mTable[hindex])->nKey = key;
|
||||||
(mTable[hindex])->next = NULL;
|
(mTable[hindex])->next = NULL;
|
||||||
(mTable[hindex])->nData = d_in;
|
(mTable[hindex])->nData = d_in;
|
||||||
mValuesInTable++;
|
mValuesInTable++;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else //collision, do linked list insert
|
else //collision, do linked list insert
|
||||||
{
|
{
|
||||||
// case 1: key already exists in list -- replace existing one
|
// case 1: key already exists in list -- replace existing one
|
||||||
// case 2: key does not exist -- add to end of list
|
// case 2: key does not exist -- add to end of list
|
||||||
|
|
||||||
node* nodeptr = mTable[hindex];
|
node* nodeptr = mTable[hindex];
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if ( compare(nodeptr->nKey, key))
|
if ( compare(nodeptr->nKey, key))
|
||||||
{
|
{
|
||||||
// we found a duplicate!
|
// we found a duplicate!
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// break if this is the last node in the list
|
// break if this is the last node in the list
|
||||||
if(! nodeptr->next)
|
if(! nodeptr->next)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// otherwise, keep traversing
|
// otherwise, keep traversing
|
||||||
nodeptr = nodeptr->next;
|
nodeptr = nodeptr->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add a node if the key was not found
|
// add a node if the key was not found
|
||||||
if (! found)
|
if (! found)
|
||||||
{
|
{
|
||||||
node *prev = nodeptr;
|
node *prev = nodeptr;
|
||||||
nodeptr = new node;
|
nodeptr = new node;
|
||||||
nodeptr->nKey = key;
|
nodeptr->nKey = key;
|
||||||
nodeptr->next = NULL;
|
nodeptr->next = NULL;
|
||||||
prev->next = nodeptr;
|
prev->next = nodeptr;
|
||||||
|
|
||||||
mValuesInTable++;
|
mValuesInTable++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// whether it is a new node or not, set the data to this new value
|
// whether it is a new node or not, set the data to this new value
|
||||||
nodeptr->nData = d_in;
|
nodeptr->nData = d_in;
|
||||||
|
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -391,60 +391,60 @@ template <class KEY_TYPE, class VAL_TYPE, class COMPARE_OP, class CONVERTER>
|
||||||
bool
|
bool
|
||||||
cHashTable<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::Lookup(KEY_TYPE key, VAL_TYPE& d_out) const
|
cHashTable<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::Lookup(KEY_TYPE key, VAL_TYPE& d_out) const
|
||||||
{
|
{
|
||||||
COMPARE_OP compare;
|
COMPARE_OP compare;
|
||||||
|
|
||||||
int hindex = Hash( key );
|
int hindex = Hash( key );
|
||||||
if (mTable[hindex] == NULL)
|
if (mTable[hindex] == NULL)
|
||||||
return false;
|
return false;
|
||||||
else {
|
else {
|
||||||
node* nodeptr = mTable[hindex];
|
node* nodeptr = mTable[hindex];
|
||||||
while (nodeptr != NULL)
|
while (nodeptr != NULL)
|
||||||
{
|
{
|
||||||
if( compare(nodeptr->nKey, key)) {
|
if( compare(nodeptr->nKey, key)) {
|
||||||
d_out = nodeptr->nData;
|
d_out = nodeptr->nData;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
nodeptr = nodeptr->next;
|
nodeptr = nodeptr->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false; //mTable entries exhausted without a match
|
return false; //mTable entries exhausted without a match
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Remove -- Removes a single entry from the hash table. Returns false if
|
// Remove -- Removes a single entry from the hash table. Returns false if
|
||||||
// the nKey is not found in the table.
|
// the nKey is not found in the table.
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// General Version -
|
// General Version -
|
||||||
template <class KEY_TYPE, class VAL_TYPE, class COMPARE_OP, class CONVERTER>
|
template <class KEY_TYPE, class VAL_TYPE, class COMPARE_OP, class CONVERTER>
|
||||||
bool
|
bool
|
||||||
cHashTable<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::Remove(KEY_TYPE key)
|
cHashTable<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::Remove(KEY_TYPE key)
|
||||||
{
|
{
|
||||||
COMPARE_OP compare;
|
COMPARE_OP compare;
|
||||||
|
|
||||||
int hindex = Hash( key );
|
int hindex = Hash( key );
|
||||||
if (mTable[hindex] == NULL) {
|
if (mTable[hindex] == NULL) {
|
||||||
delete (mTable[hindex]);
|
delete (mTable[hindex]);
|
||||||
mTable[hindex] = NULL;
|
mTable[hindex] = NULL;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
node* nodeptr = mTable[hindex];
|
node* nodeptr = mTable[hindex];
|
||||||
node* prev;
|
node* prev;
|
||||||
while(nodeptr != NULL) {
|
while(nodeptr != NULL) {
|
||||||
prev = nodeptr;
|
prev = nodeptr;
|
||||||
if(compare(mTable[hindex]->nKey, key))
|
if(compare(mTable[hindex]->nKey, key))
|
||||||
{
|
{
|
||||||
prev->next = nodeptr->next;
|
prev->next = nodeptr->next;
|
||||||
delete nodeptr;
|
delete nodeptr;
|
||||||
if (nodeptr == mTable[hindex])
|
if (nodeptr == mTable[hindex])
|
||||||
mTable[hindex] = NULL;
|
mTable[hindex] = NULL;
|
||||||
nodeptr = NULL;
|
nodeptr = NULL;
|
||||||
return true;
|
return true;
|
||||||
}//end if
|
}//end if
|
||||||
nodeptr = nodeptr->next;
|
nodeptr = nodeptr->next;
|
||||||
}//end while
|
}//end while
|
||||||
}//end else
|
}//end else
|
||||||
return false; //match was not found, no node deleted
|
return false; //match was not found, no node deleted
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -454,23 +454,23 @@ template <class KEY_TYPE, class VAL_TYPE, class COMPARE_OP, class CONVERTER>
|
||||||
bool
|
bool
|
||||||
cHashTable<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::Clear(void)
|
cHashTable<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::Clear(void)
|
||||||
{
|
{
|
||||||
for (int i=0; i<mTableSize; ++i)
|
for (int i=0; i<mTableSize; ++i)
|
||||||
{
|
{
|
||||||
if (mTable[i] != NULL) {
|
if (mTable[i] != NULL) {
|
||||||
node* curr = mTable[i];
|
node* curr = mTable[i];
|
||||||
node* del;
|
node* del;
|
||||||
while(curr != NULL) {
|
while(curr != NULL) {
|
||||||
del = curr;
|
del = curr;
|
||||||
curr=curr->next;
|
curr=curr->next;
|
||||||
delete del;
|
delete del;
|
||||||
if (del == mTable[i])
|
if (del == mTable[i])
|
||||||
mTable[i] = NULL;
|
mTable[i] = NULL;
|
||||||
del = NULL;
|
del = NULL;
|
||||||
|
|
||||||
}//end delete chain loop
|
}//end delete chain loop
|
||||||
}//end if mTable[i]!= NULL
|
}//end if mTable[i]!= NULL
|
||||||
}//end for
|
}//end for
|
||||||
return (IsEmpty());
|
return (IsEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -480,10 +480,10 @@ template <class KEY_TYPE, class VAL_TYPE, class COMPARE_OP, class CONVERTER>
|
||||||
bool
|
bool
|
||||||
cHashTable<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::IsEmpty(void) const
|
cHashTable<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::IsEmpty(void) const
|
||||||
{
|
{
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
for(int i=0; i< mTableSize; ++i)
|
for(int i=0; i< mTableSize; ++i)
|
||||||
ret &= (mTable[i] == NULL);
|
ret &= (mTable[i] == NULL);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -495,10 +495,10 @@ uint32 cHashTable<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::Hash( const KEY_TY
|
||||||
CONVERTER converter;
|
CONVERTER converter;
|
||||||
int len;
|
int len;
|
||||||
const byte* pb = converter( key, &len ); //locates key
|
const byte* pb = converter( key, &len ); //locates key
|
||||||
uint32 hindex;
|
uint32 hindex;
|
||||||
|
|
||||||
hindex = *pb;
|
hindex = *pb;
|
||||||
while (len-- > 0)
|
while (len-- > 0)
|
||||||
hindex = ((hindex << 9) ^ *pb++) % mTableSize;
|
hindex = ((hindex << 9) ^ *pb++) % mTableSize;
|
||||||
return hindex;
|
return hindex;
|
||||||
}
|
}
|
||||||
|
@ -508,34 +508,34 @@ uint32 cHashTable<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::Hash( const KEY_TY
|
||||||
template <class KEY_TYPE, class VAL_TYPE, class COMPARE_OP, class CONVERTER>
|
template <class KEY_TYPE, class VAL_TYPE, class COMPARE_OP, class CONVERTER>
|
||||||
void cHashTable<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::TraceDiagnostics() const
|
void cHashTable<KEY_TYPE, VAL_TYPE, COMPARE_OP, CONVERTER>::TraceDiagnostics() const
|
||||||
{
|
{
|
||||||
cDebug d("cHashTable::Diagnostics");
|
cDebug d("cHashTable::Diagnostics");
|
||||||
|
|
||||||
int slotsFilled = 0, numItems = 0, numMultiSlot = 0;
|
int slotsFilled = 0, numItems = 0, numMultiSlot = 0;
|
||||||
node* pNode;
|
node* pNode;
|
||||||
|
|
||||||
for(int i=0; i < mTableSize; i++)
|
for(int i=0; i < mTableSize; i++)
|
||||||
{
|
{
|
||||||
if(mTable[i] != NULL)
|
if(mTable[i] != NULL)
|
||||||
{
|
{
|
||||||
slotsFilled++;
|
slotsFilled++;
|
||||||
numItems++;
|
numItems++;
|
||||||
pNode = (mTable[i])->next;
|
pNode = (mTable[i])->next;
|
||||||
if(pNode != NULL)
|
if(pNode != NULL)
|
||||||
numMultiSlot++;
|
numMultiSlot++;
|
||||||
while(pNode)
|
while(pNode)
|
||||||
{
|
{
|
||||||
numItems++;
|
numItems++;
|
||||||
pNode = pNode->next;
|
pNode = pNode->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
d.TraceDebug("---------------Hash Table Statisics---------------\n");
|
d.TraceDebug("---------------Hash Table Statisics---------------\n");
|
||||||
d.TraceDebug("-- Number of slots: %d\n", mTableSize);
|
d.TraceDebug("-- Number of slots: %d\n", mTableSize);
|
||||||
d.TraceDebug("-- Number of items: %d\n", numItems);
|
d.TraceDebug("-- Number of items: %d\n", numItems);
|
||||||
d.TraceDebug("-- Slots filled: %d (%lf %%)\n",slotsFilled, ((double)slotsFilled / (double)mTableSize) * 100.0);
|
d.TraceDebug("-- Slots filled: %d (%lf %%)\n",slotsFilled, ((double)slotsFilled / (double)mTableSize) * 100.0);
|
||||||
d.TraceDebug("-- Slots with >1 item: %d (%lf %%)\n",numMultiSlot, ((double)numMultiSlot / (double)slotsFilled) * 100.0);
|
d.TraceDebug("-- Slots with >1 item: %d (%lf %%)\n",numMultiSlot, ((double)numMultiSlot / (double)slotsFilled) * 100.0);
|
||||||
d.TraceDebug("--------------------------------------------------\n");
|
d.TraceDebug("--------------------------------------------------\n");
|
||||||
}
|
}
|
||||||
#endif // _DEBUG
|
#endif // _DEBUG
|
||||||
|
|
||||||
|
|
|
@ -71,10 +71,10 @@
|
||||||
/*
|
/*
|
||||||
* Some comments on getting Haval into Tripwire:
|
* Some comments on getting Haval into Tripwire:
|
||||||
*
|
*
|
||||||
* - all #elif directives replaced by ugly #if/#else/#endif sequences.
|
* - all #elif directives replaced by ugly #if/#else/#endif sequences.
|
||||||
* not all compilers support #elif (an ANSI construct).
|
* not all compilers support #elif (an ANSI construct).
|
||||||
* - byte-order is discovered at compile time. we use the information
|
* - byte-order is discovered at compile time. we use the information
|
||||||
* in "../../include/byteorder.h" to get this information.
|
* in "../../include/byteorder.h" to get this information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma GCC diagnostic ignored "-Wparentheses"
|
#pragma GCC diagnostic ignored "-Wparentheses"
|
||||||
|
@ -90,7 +90,7 @@
|
||||||
#include "haval.h"
|
#include "haval.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#define HAVAL_VERSION 1 /* current version number */
|
#define HAVAL_VERSION 1 /* current version number */
|
||||||
|
|
||||||
/* Do not remove this line. Protyping depends on it! */
|
/* Do not remove this line. Protyping depends on it! */
|
||||||
#if defined(__STDC__) || defined(__cplusplus)
|
#if defined(__STDC__) || defined(__cplusplus)
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -95,41 +95,41 @@ int echild();
|
||||||
/*
|
/*
|
||||||
* define error codes
|
* define error codes
|
||||||
*/
|
*/
|
||||||
#define SE_NONE 0 /* no error */
|
#define SE_NONE 0 /* no error */
|
||||||
#define SE_NOMEM -1 /* no memory */
|
#define SE_NOMEM -1 /* no memory */
|
||||||
#define SE_NOPIPE -2 /* no pipes */
|
#define SE_NOPIPE -2 /* no pipes */
|
||||||
#define SE_NOVAR -3 /* variable not defined */
|
#define SE_NOVAR -3 /* variable not defined */
|
||||||
#define SE_BADFD -4 /* invalid file descriptor */
|
#define SE_BADFD -4 /* invalid file descriptor */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* default security settings
|
* default security settings
|
||||||
*/
|
*/
|
||||||
#ifndef DEF_UMASK
|
#ifndef DEF_UMASK
|
||||||
# define DEF_UMASK 077 /* only owner has privileges */
|
# define DEF_UMASK 077 /* only owner has privileges */
|
||||||
#endif
|
#endif
|
||||||
#ifndef UID_RESET
|
#ifndef UID_RESET
|
||||||
# define UID_RESET -2 /* reset EUID to RUID */
|
# define UID_RESET -2 /* reset EUID to RUID */
|
||||||
#endif
|
#endif
|
||||||
#ifndef GID_RESET
|
#ifndef GID_RESET
|
||||||
# define GID_RESET -2 /* reset EGID to RGID */
|
# define GID_RESET -2 /* reset EGID to RGID */
|
||||||
#endif
|
#endif
|
||||||
#ifndef DEF_PATH
|
#ifndef DEF_PATH
|
||||||
# ifdef __FreeBSD_cc_version
|
# ifdef __FreeBSD_cc_version
|
||||||
# define DEF_PATH "PATH=/sbin:/usr/sbin:/bin:/usr/bin" /* default search path */
|
# define DEF_PATH "PATH=/sbin:/usr/sbin:/bin:/usr/bin" /* default search path */
|
||||||
# else
|
# else
|
||||||
# define DEF_PATH "PATH=/bin:/usr/bin:/usr/ucb" /* default search path */
|
# define DEF_PATH "PATH=/bin:/usr/bin:/usr/ucb" /* default search path */
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#ifndef DEF_SHELL
|
#ifndef DEF_SHELL
|
||||||
# define DEF_SHELL "SHELL=/bin/sh" /* default shell */
|
# define DEF_SHELL "SHELL=/bin/sh" /* default shell */
|
||||||
#endif
|
#endif
|
||||||
#ifndef DEF_IFS
|
#ifndef DEF_IFS
|
||||||
# define DEF_IFS "IFS= \t\n" /* default IFS */
|
# define DEF_IFS "IFS= \t\n" /* default IFS */
|
||||||
#endif
|
#endif
|
||||||
#ifndef DEF_TZ
|
#ifndef DEF_TZ
|
||||||
# define DEF_TZ "TZ" /* default TZ */
|
# define DEF_TZ "TZ" /* default TZ */
|
||||||
#endif
|
#endif
|
||||||
#ifndef NOSHELL
|
#ifndef NOSHELL
|
||||||
# define NOSHELL "/bin/sh" /* use this if no shell */
|
# define NOSHELL "/bin/sh" /* use this if no shell */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -40,10 +40,10 @@
|
||||||
class cBlockLink
|
class cBlockLink
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cBlockLink(cBlockLink* pNext) : mpNext(pNext) {}
|
cBlockLink(cBlockLink* pNext) : mpNext(pNext) {}
|
||||||
cBlockLink* Next() { return mpNext; }
|
cBlockLink* Next() { return mpNext; }
|
||||||
private:
|
private:
|
||||||
cBlockLink* mpNext; // pointer to the next link, or NULL
|
cBlockLink* mpNext; // pointer to the next link, or NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,13 +55,13 @@ private:
|
||||||
// ctor, dtor
|
// ctor, dtor
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
cBlockList::cBlockList() :
|
cBlockList::cBlockList() :
|
||||||
mpBlocks(0)
|
mpBlocks(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
cBlockList::~cBlockList()
|
cBlockList::~cBlockList()
|
||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -69,9 +69,9 @@ cBlockList::~cBlockList()
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
void* cBlockList::Allocate(int size)
|
void* cBlockList::Allocate(int size)
|
||||||
{
|
{
|
||||||
char* mem = new char[size + sizeof(cBlockLink)];
|
char* mem = new char[size + sizeof(cBlockLink)];
|
||||||
mpBlocks = new(mem) cBlockLink(mpBlocks);
|
mpBlocks = new(mem) cBlockLink(mpBlocks);
|
||||||
return mem + sizeof(cBlockLink);
|
return mem + sizeof(cBlockLink);
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -79,13 +79,13 @@ void* cBlockList::Allocate(int size)
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
void cBlockList::Clear()
|
void cBlockList::Clear()
|
||||||
{
|
{
|
||||||
while(mpBlocks)
|
while(mpBlocks)
|
||||||
{
|
{
|
||||||
cBlockLink* pLink = mpBlocks;
|
cBlockLink* pLink = mpBlocks;
|
||||||
mpBlocks = mpBlocks->Next();
|
mpBlocks = mpBlocks->Next();
|
||||||
pLink->~cBlockLink();
|
pLink->~cBlockLink();
|
||||||
delete [] (char*)(pLink);
|
delete [] (char*)(pLink);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -96,16 +96,16 @@ void cBlockList::Clear()
|
||||||
// ctor, dtor
|
// ctor, dtor
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
cObjectPoolBase::cObjectPoolBase(int objSize, int chunkSize) :
|
cObjectPoolBase::cObjectPoolBase(int objSize, int chunkSize) :
|
||||||
mObjectSize(objSize),
|
mObjectSize(objSize),
|
||||||
mChunkSize(chunkSize),
|
mChunkSize(chunkSize),
|
||||||
mpNextFree(0)
|
mpNextFree(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
cObjectPoolBase::~cObjectPoolBase()
|
cObjectPoolBase::~cObjectPoolBase()
|
||||||
{
|
{
|
||||||
//TODO -- assert that the number of instances left are 0.
|
//TODO -- assert that the number of instances left are 0.
|
||||||
Clear();
|
Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -113,19 +113,19 @@ cObjectPoolBase::~cObjectPoolBase()
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
void cObjectPoolBase::AllocNewChunk()
|
void cObjectPoolBase::AllocNewChunk()
|
||||||
{
|
{
|
||||||
ASSERT(mpNextFree == 0);
|
ASSERT(mpNextFree == 0);
|
||||||
|
|
||||||
int size = mObjectSize * mChunkSize;
|
int size = mObjectSize * mChunkSize;
|
||||||
char* pBlock = (char*)mBlockList.Allocate(size);
|
char* pBlock = (char*)mBlockList.Allocate(size);
|
||||||
|
|
||||||
char* pLast = pBlock + size - mObjectSize;
|
char* pLast = pBlock + size - mObjectSize;
|
||||||
for(char* pc = pBlock; pc < pLast; pc += mObjectSize)
|
for(char* pc = pBlock; pc < pLast; pc += mObjectSize)
|
||||||
{
|
{
|
||||||
((cLink*)pc)->mpNext = (cLink*)(pc + mObjectSize);
|
((cLink*)pc)->mpNext = (cLink*)(pc + mObjectSize);
|
||||||
}
|
}
|
||||||
((cLink*)pLast)->mpNext = 0;
|
((cLink*)pLast)->mpNext = 0;
|
||||||
|
|
||||||
mpNextFree = (cLink*)pBlock;
|
mpNextFree = (cLink*)pBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -32,8 +32,8 @@
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// objectpool.h
|
// objectpool.h
|
||||||
//
|
//
|
||||||
// cBlockList -- a linked list of blocks of memory
|
// cBlockList -- a linked list of blocks of memory
|
||||||
// cObjectPoolBase -- a pool of equal-sized objects; constant time allocation
|
// cObjectPoolBase -- a pool of equal-sized objects; constant time allocation
|
||||||
#ifndef __OBJECTPOOL_H
|
#ifndef __OBJECTPOOL_H
|
||||||
#define __OBJECTPOOL_H
|
#define __OBJECTPOOL_H
|
||||||
|
|
||||||
|
@ -45,13 +45,13 @@ class cBlockLink;
|
||||||
class cBlockList
|
class cBlockList
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cBlockList();
|
cBlockList();
|
||||||
~cBlockList();
|
~cBlockList();
|
||||||
|
|
||||||
void* Allocate(int size);
|
void* Allocate(int size);
|
||||||
void Clear(); // releases everything in the block list
|
void Clear(); // releases everything in the block list
|
||||||
private:
|
private:
|
||||||
cBlockLink* mpBlocks; // linked list of blocks
|
cBlockLink* mpBlocks; // linked list of blocks
|
||||||
};
|
};
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -60,44 +60,44 @@ private:
|
||||||
class cObjectPoolBase
|
class cObjectPoolBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cObjectPoolBase(int objSize, int chunkSize);
|
cObjectPoolBase(int objSize, int chunkSize);
|
||||||
~cObjectPoolBase();
|
~cObjectPoolBase();
|
||||||
// NOTE -- dtor is not virtual; therefore it is potentially dangerous to delete a pointer to
|
// NOTE -- dtor is not virtual; therefore it is potentially dangerous to delete a pointer to
|
||||||
// this class unless you know for sure the dynamic class type has nothing to clean up.
|
// this class unless you know for sure the dynamic class type has nothing to clean up.
|
||||||
|
|
||||||
void* Alloc ();
|
void* Alloc ();
|
||||||
void Free (void* pObj);
|
void Free (void* pObj);
|
||||||
void Clear ();
|
void Clear ();
|
||||||
//TODO -- add IsPointerValid()
|
//TODO -- add IsPointerValid()
|
||||||
private:
|
private:
|
||||||
void AllocNewChunk(); // get another chunk to use...
|
void AllocNewChunk(); // get another chunk to use...
|
||||||
|
|
||||||
struct cLink
|
struct cLink
|
||||||
{
|
{
|
||||||
cLink* mpNext;
|
cLink* mpNext;
|
||||||
};
|
};
|
||||||
|
|
||||||
cBlockList mBlockList;
|
cBlockList mBlockList;
|
||||||
const int mObjectSize; // how big are the objects?
|
const int mObjectSize; // how big are the objects?
|
||||||
const int mChunkSize; // how big are the chunks we are allocating?
|
const int mChunkSize; // how big are the chunks we are allocating?
|
||||||
cLink* mpNextFree; // the next free object
|
cLink* mpNextFree; // the next free object
|
||||||
//int mInstanceCount; // number of objects that are currently allocated but not freed.
|
//int mInstanceCount; // number of objects that are currently allocated but not freed.
|
||||||
};
|
};
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// cObjectPool
|
// cObjectPool
|
||||||
// Note -- this template only works for classes that are constructed with their
|
// Note -- this template only works for classes that are constructed with their
|
||||||
// default ctor; I don't know how to extend this model to work for non-default
|
// default ctor; I don't know how to extend this model to work for non-default
|
||||||
// ctors...
|
// ctors...
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
template <class T>
|
template <class T>
|
||||||
class cObjectPool : public cObjectPoolBase
|
class cObjectPool : public cObjectPoolBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cObjectPool(int chunkSize) : cObjectPoolBase(sizeof(T), chunkSize) {}
|
cObjectPool(int chunkSize) : cObjectPoolBase(sizeof(T), chunkSize) {}
|
||||||
|
|
||||||
T* New () { return new(cObjectPoolBase::Alloc()) T(); }
|
T* New () { return new(cObjectPoolBase::Alloc()) T(); }
|
||||||
void Delete (T* pObj) { pObj->~T(); Free(pObj); }
|
void Delete (T* pObj) { pObj->~T(); Free(pObj); }
|
||||||
};
|
};
|
||||||
|
|
||||||
//#############################################################################
|
//#############################################################################
|
||||||
|
@ -108,12 +108,12 @@ public:
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
inline void* cObjectPoolBase::Alloc()
|
inline void* cObjectPoolBase::Alloc()
|
||||||
{
|
{
|
||||||
if(! mpNextFree)
|
if(! mpNextFree)
|
||||||
AllocNewChunk();
|
AllocNewChunk();
|
||||||
|
|
||||||
cLink* pRtn = mpNextFree;
|
cLink* pRtn = mpNextFree;
|
||||||
mpNextFree = mpNextFree->mpNext;
|
mpNextFree = mpNextFree->mpNext;
|
||||||
return pRtn;
|
return pRtn;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -121,9 +121,9 @@ inline void* cObjectPoolBase::Alloc()
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
inline void cObjectPoolBase::Free(void* pObj)
|
inline void cObjectPoolBase::Free(void* pObj)
|
||||||
{
|
{
|
||||||
cLink* pNew = (cLink*)pObj;
|
cLink* pNew = (cLink*)pObj;
|
||||||
pNew->mpNext = mpNextFree;
|
pNew->mpNext = mpNextFree;
|
||||||
mpNextFree = pNew;
|
mpNextFree = pNew;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -131,8 +131,8 @@ inline void cObjectPoolBase::Free(void* pObj)
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
inline void cObjectPoolBase::Clear()
|
inline void cObjectPoolBase::Clear()
|
||||||
{
|
{
|
||||||
mBlockList.Clear();
|
mBlockList.Clear();
|
||||||
mpNextFree = 0;
|
mpNextFree = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -91,8 +91,8 @@
|
||||||
|
|
||||||
//--PACKAGE Helpers
|
//--PACKAGE Helpers
|
||||||
|
|
||||||
#define TSS_Package( pkg ) \
|
#define TSS_Package( pkg ) \
|
||||||
pkg::GetInstance() // Access "the" Package obj
|
pkg::GetInstance() // Access "the" Package obj
|
||||||
|
|
||||||
#define TSS_Dependency( pkg ) \
|
#define TSS_Dependency( pkg ) \
|
||||||
TSS_Package( pkg ) // Declare a Package Depend.
|
TSS_Package( pkg ) // Declare a Package Depend.
|
||||||
|
@ -100,7 +100,7 @@
|
||||||
|
|
||||||
|
|
||||||
#define TSS_BeginPackage( pkg ) \
|
#define TSS_BeginPackage( pkg ) \
|
||||||
class pkg : public cPackageBase_< TCHAR > \
|
class pkg : public cPackageBase_< TCHAR > \
|
||||||
{ \
|
{ \
|
||||||
public: \
|
public: \
|
||||||
static pkg& GetInstance();
|
static pkg& GetInstance();
|
||||||
|
@ -128,34 +128,34 @@
|
||||||
//--STRINGTABLE Helperfs
|
//--STRINGTABLE Helperfs
|
||||||
|
|
||||||
#define TSS_GetString( pkg, id ) \
|
#define TSS_GetString( pkg, id ) \
|
||||||
TSS_Package( pkg ).GetString( id ) // Access the Message String
|
TSS_Package( pkg ).GetString( id ) // Access the Message String
|
||||||
|
|
||||||
|
|
||||||
#define TSS_DECLARE_STRINGTABLE \
|
#define TSS_DECLARE_STRINGTABLE \
|
||||||
public: \
|
public: \
|
||||||
Messages::String \
|
Messages::String \
|
||||||
GetString( \
|
GetString( \
|
||||||
Messages::ConstKeyRef id ) const { \
|
Messages::ConstKeyRef id ) const { \
|
||||||
return m_messages.Get( id ); } \
|
return m_messages.Get( id ); } \
|
||||||
void LoadStrings(); \
|
void LoadStrings(); \
|
||||||
private: \
|
private: \
|
||||||
Messages m_messages // Decare a Stringtable
|
Messages m_messages // Decare a Stringtable
|
||||||
|
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
#define TSS_BeginStringtable( pkg ) \
|
#define TSS_BeginStringtable( pkg ) \
|
||||||
void pkg::LoadStrings() \
|
void pkg::LoadStrings() \
|
||||||
{ cDebug d( #pkg "::LoadStrings()" ); \
|
{ cDebug d( #pkg "::LoadStrings()" ); \
|
||||||
d.TraceDebug("Loading strings for " #pkg " package.\n"); \
|
d.TraceDebug("Loading strings for " #pkg " package.\n"); \
|
||||||
Messages::Pair astr[] = { // Define a Stringtable
|
Messages::Pair astr[] = { // Define a Stringtable
|
||||||
#else // _DEBUG
|
#else // _DEBUG
|
||||||
#define TSS_BeginStringtable( pkg ) \
|
#define TSS_BeginStringtable( pkg ) \
|
||||||
void pkg::LoadStrings() \
|
void pkg::LoadStrings() \
|
||||||
{ Messages::Pair astr[] = { // Define a Stringtable
|
{ Messages::Pair astr[] = { // Define a Stringtable
|
||||||
#endif // _DEBUG
|
#endif // _DEBUG
|
||||||
|
|
||||||
#define TSS_EndStringtable( pkg ) \
|
#define TSS_EndStringtable( pkg ) \
|
||||||
}; m_messages.Put( \
|
}; m_messages.Put( \
|
||||||
astr, astr + countof(astr) ); } // End define Strintable
|
astr, astr + countof(astr) ); } // End define Strintable
|
||||||
|
|
||||||
|
|
||||||
|
@ -175,7 +175,7 @@
|
||||||
// cPackageBase_<CharT> -- Base class for all Package Resources
|
// cPackageBase_<CharT> -- Base class for all Package Resources
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// SYNOPSIS:
|
// SYNOPSIS:
|
||||||
// This class is the base class for all package representations
|
// This class is the base class for all package representations
|
||||||
// and, thus, establishes the package contract. It's interface
|
// and, thus, establishes the package contract. It's interface
|
||||||
// is relied on by the Package singleton wrapper, TSS_Package.
|
// is relied on by the Package singleton wrapper, TSS_Package.
|
||||||
// Since part of its contract is that there is only one package
|
// Since part of its contract is that there is only one package
|
||||||
|
@ -197,9 +197,9 @@
|
||||||
template< class CharT >
|
template< class CharT >
|
||||||
class cPackageBase_
|
class cPackageBase_
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef cMessages_< int, CharT > Messages;
|
typedef cMessages_< int, CharT > Messages;
|
||||||
|
|
||||||
void LoadStrings()
|
void LoadStrings()
|
||||||
{
|
{
|
||||||
|
|
|
@ -46,23 +46,23 @@
|
||||||
// For each of these "enumerations" we create unique integers identifying each
|
// For each of these "enumerations" we create unique integers identifying each
|
||||||
// variation. We group similar items together, such as OS_REDHAT and OS_SLACKWARE
|
// variation. We group similar items together, such as OS_REDHAT and OS_SLACKWARE
|
||||||
|
|
||||||
#define OS_UNKNOWN 0
|
#define OS_UNKNOWN 0
|
||||||
#define OS_WIN32 0x0101
|
#define OS_WIN32 0x0101
|
||||||
#define OS_AIX 0x0401
|
#define OS_AIX 0x0401
|
||||||
#define OS_HPUX 0x0501
|
#define OS_HPUX 0x0501
|
||||||
#define OS_IRIX 0x0601
|
#define OS_IRIX 0x0601
|
||||||
#define OS_OSF1 0x0701
|
#define OS_OSF1 0x0701
|
||||||
|
|
||||||
#define COMP_UNKNOWN 0
|
#define COMP_UNKNOWN 0
|
||||||
#define COMP_MSVC 0x0101
|
#define COMP_MSVC 0x0101
|
||||||
#define COMP_KAI_GCC 0x0201
|
#define COMP_KAI_GCC 0x0201
|
||||||
#define COMP_KAI_SUNPRO 0x0202
|
#define COMP_KAI_SUNPRO 0x0202
|
||||||
#define COMP_KAI_GLIBC 0x0203
|
#define COMP_KAI_GLIBC 0x0203
|
||||||
#define COMP_KAI_VISUALAGE 0x0204
|
#define COMP_KAI_VISUALAGE 0x0204
|
||||||
#define COMP_KAI_HPANSIC 0x0205
|
#define COMP_KAI_HPANSIC 0x0205
|
||||||
#define COMP_KAI_IRIX 0x0206
|
#define COMP_KAI_IRIX 0x0206
|
||||||
#define COMP_KAI_OSF1ALPHA 0x0207
|
#define COMP_KAI_OSF1ALPHA 0x0207
|
||||||
#define COMP_SUNPRO 0x0301
|
#define COMP_SUNPRO 0x0301
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// Platform detection
|
// Platform detection
|
||||||
|
@ -93,34 +93,34 @@
|
||||||
#define COMP COMP_KAI_IRIX
|
#define COMP COMP_KAI_IRIX
|
||||||
|
|
||||||
#elif defined(_ALPHA)
|
#elif defined(_ALPHA)
|
||||||
#define OS OS_OSF1
|
#define OS OS_OSF1
|
||||||
#define COMP COMP_KAI_OSF1ALPHA
|
#define COMP COMP_KAI_OSF1ALPHA
|
||||||
|
|
||||||
#elif defined (_HPUX)
|
#elif defined (_HPUX)
|
||||||
#define OS OS_HPUX
|
#define OS OS_HPUX
|
||||||
#define COMP COMP_KAI_HPANSIC
|
#define COMP COMP_KAI_HPANSIC
|
||||||
|
|
||||||
#else
|
#else
|
||||||
// OK for OS not to resolve, it's being phased out.
|
// OK for OS not to resolve, it's being phased out.
|
||||||
// #error Unknown OS
|
// #error Unknown OS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(OS)
|
#if !defined(OS)
|
||||||
// OK for OS not to resolve, it's being phased out.
|
// OK for OS not to resolve, it's being phased out.
|
||||||
// #error OS definition did not resolve. Check "platform.h".
|
// #error OS definition did not resolve. Check "platform.h".
|
||||||
#endif
|
#endif
|
||||||
/* XXX: COMP may now not resolve, because autoconf may
|
/* XXX: COMP may now not resolve, because autoconf may
|
||||||
* detect GCC. This is done in the hopes that all
|
* detect GCC. This is done in the hopes that all
|
||||||
* COMP detections, and indeed both OS & COMP detechtions
|
* COMP detections, and indeed both OS & COMP detechtions
|
||||||
* will eventualy be done automatically.
|
* will eventualy be done automatically.
|
||||||
*
|
*
|
||||||
* This means, the former "#if !defined(COMP)" will
|
* This means, the former "#if !defined(COMP)" will
|
||||||
* temporarily have to also check the HAVE_[compiler]
|
* temporarily have to also check the HAVE_[compiler]
|
||||||
* #defines until all compilers are checked by autoconf,
|
* #defines until all compilers are checked by autoconf,
|
||||||
* at which point this can be removed completely.
|
* at which point this can be removed completely.
|
||||||
*
|
*
|
||||||
* PH - 20010311
|
* PH - 20010311
|
||||||
*/
|
*/
|
||||||
#if !defined(COMP) && !defined(HAVE_GCC)
|
#if !defined(COMP) && !defined(HAVE_GCC)
|
||||||
#error COMP definition did not resolve. Check "platform.h".
|
#error COMP definition did not resolve. Check "platform.h".
|
||||||
#endif
|
#endif
|
||||||
|
@ -153,10 +153,10 @@
|
||||||
// OS detection
|
// OS detection
|
||||||
// Note: Avoid using these if possible (see above)
|
// Note: Avoid using these if possible (see above)
|
||||||
#define IS_WIN32 (OS == OS_WIN32)
|
#define IS_WIN32 (OS == OS_WIN32)
|
||||||
#define IS_AIX (OS == OS_AIX)
|
#define IS_AIX (OS == OS_AIX)
|
||||||
#define IS_HPUX (OS == OS_HPUX)
|
#define IS_HPUX (OS == OS_HPUX)
|
||||||
#define IS_IRIX (OS == OS_IRIX)
|
#define IS_IRIX (OS == OS_IRIX)
|
||||||
#define IS_OSF1 (OS == OS_OSF1)
|
#define IS_OSF1 (OS == OS_OSF1)
|
||||||
|
|
||||||
// complier detection
|
// complier detection
|
||||||
#define IS_KAI (COMP == COMP_KAI_GCC || COMP == COMP_KAI_SUNPRO || COMP == COMP_KAI_GLIBC || COMP == COMP_KAI_VISUALAGE || COMP == COMP_KAI_HPANSIC || COMP == COMP_KAI_IRIX || COMP == COMP_KAI_OSF1ALPHA)
|
#define IS_KAI (COMP == COMP_KAI_GCC || COMP == COMP_KAI_SUNPRO || COMP == COMP_KAI_GLIBC || COMP == COMP_KAI_VISUALAGE || COMP == COMP_KAI_HPANSIC || COMP == COMP_KAI_IRIX || COMP == COMP_KAI_OSF1ALPHA)
|
||||||
|
@ -179,8 +179,8 @@
|
||||||
|
|
||||||
// Threading API
|
// Threading API
|
||||||
// TODO:mdb -- this is not complete or rigorous on the unix side!!!
|
// TODO:mdb -- this is not complete or rigorous on the unix side!!!
|
||||||
#define SUPPORTS_WIN32_THREADS IS_WIN32
|
#define SUPPORTS_WIN32_THREADS IS_WIN32
|
||||||
#define SUPPORTS_POSIX_THREADS (!SUPPORTS_WIN32_THREADS)
|
#define SUPPORTS_POSIX_THREADS (!SUPPORTS_WIN32_THREADS)
|
||||||
|
|
||||||
// Miscellaneous
|
// Miscellaneous
|
||||||
#define FSEEK_TAKES_INT32 IS_UNIX // True if fseek takes 32-bit offsets
|
#define FSEEK_TAKES_INT32 IS_UNIX // True if fseek takes 32-bit offsets
|
||||||
|
|
|
@ -54,18 +54,18 @@ RefSet* gpRefCountObj_Objects = 0;
|
||||||
// a way to see what hasn't been accounted for....
|
// a way to see what hasn't been accounted for....
|
||||||
struct cRefCountObj_Debug
|
struct cRefCountObj_Debug
|
||||||
{
|
{
|
||||||
~cRefCountObj_Debug()
|
~cRefCountObj_Debug()
|
||||||
{
|
{
|
||||||
RefSet::iterator i;
|
RefSet::iterator i;
|
||||||
cDebug d("cRefCountObj_Debug");
|
cDebug d("cRefCountObj_Debug");
|
||||||
if(gpRefCountObj_Objects)
|
if(gpRefCountObj_Objects)
|
||||||
{
|
{
|
||||||
for(i = gpRefCountObj_Objects->begin(); i != gpRefCountObj_Objects->end(); i++)
|
for(i = gpRefCountObj_Objects->begin(); i != gpRefCountObj_Objects->end(); i++)
|
||||||
{
|
{
|
||||||
d.TraceNever("Refrence Counted Object %p still exists\n", *i);
|
d.TraceNever("Refrence Counted Object %p still exists\n", *i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} gRefCountObj_Debug;
|
} gRefCountObj_Debug;
|
||||||
|
|
||||||
#endif // _DEBUG
|
#endif // _DEBUG
|
||||||
|
@ -80,12 +80,12 @@ cRefCountObj::cRefCountObj()
|
||||||
++objectCounter;
|
++objectCounter;
|
||||||
++referenceCounter;
|
++referenceCounter;
|
||||||
|
|
||||||
cDebug d("cRefCountObj::cRefCountObj");
|
cDebug d("cRefCountObj::cRefCountObj");
|
||||||
d.TraceNever("Object Created[%p] %s\n", this, typeid(*this).name());
|
d.TraceNever("Object Created[%p] %s\n", this, typeid(*this).name());
|
||||||
|
|
||||||
if(! gpRefCountObj_Objects)
|
if(! gpRefCountObj_Objects)
|
||||||
gpRefCountObj_Objects = new RefSet;
|
gpRefCountObj_Objects = new RefSet;
|
||||||
gpRefCountObj_Objects->insert(this);
|
gpRefCountObj_Objects->insert(this);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,20 +97,20 @@ cRefCountObj::~cRefCountObj()
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
--objectCounter;
|
--objectCounter;
|
||||||
cDebug d("cRefCountObj::~cRefCountObj");
|
cDebug d("cRefCountObj::~cRefCountObj");
|
||||||
d.TraceNever("Object Destroyed[%p] %s Objects Left = %d\n", this, typeid(*this).name(), objectCounter);
|
d.TraceNever("Object Destroyed[%p] %s Objects Left = %d\n", this, typeid(*this).name(), objectCounter);
|
||||||
if(objectCounter == 0)
|
if(objectCounter == 0)
|
||||||
{
|
|
||||||
d.TraceDebug("****** All Reference Counted Objects Destroyed! ******\n") ;
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT(gpRefCountObj_Objects);
|
|
||||||
RefSet::const_iterator i = gpRefCountObj_Objects->find(this);
|
|
||||||
ASSERT(i != gpRefCountObj_Objects->end());
|
|
||||||
gpRefCountObj_Objects->erase(this);
|
|
||||||
if(gpRefCountObj_Objects->size() == 0)
|
|
||||||
{
|
{
|
||||||
delete gpRefCountObj_Objects;
|
d.TraceDebug("****** All Reference Counted Objects Destroyed! ******\n") ;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(gpRefCountObj_Objects);
|
||||||
|
RefSet::const_iterator i = gpRefCountObj_Objects->find(this);
|
||||||
|
ASSERT(i != gpRefCountObj_Objects->end());
|
||||||
|
gpRefCountObj_Objects->erase(this);
|
||||||
|
if(gpRefCountObj_Objects->size() == 0)
|
||||||
|
{
|
||||||
|
delete gpRefCountObj_Objects;
|
||||||
gpRefCountObj_Objects = 0;
|
gpRefCountObj_Objects = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ void cRefCountObj::AddRef() const
|
||||||
|
|
||||||
void cRefCountObj::Release() const
|
void cRefCountObj::Release() const
|
||||||
{
|
{
|
||||||
if (this == 0)
|
if (this == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (--mRefCount == 0)
|
if (--mRefCount == 0)
|
||||||
|
@ -150,6 +150,6 @@ void cRefCountObj::Release() const
|
||||||
|
|
||||||
void cRefCountObj::Delete() const
|
void cRefCountObj::Delete() const
|
||||||
{
|
{
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,13 +67,13 @@ public:
|
||||||
virtual void AddRef() const;
|
virtual void AddRef() const;
|
||||||
virtual void Release() const;
|
virtual void Release() const;
|
||||||
|
|
||||||
int GetRefCount() const { return mRefCount; }
|
int GetRefCount() const { return mRefCount; }
|
||||||
// sometimes it is useful to know an object's refrence
|
// sometimes it is useful to know an object's refrence
|
||||||
protected:
|
protected:
|
||||||
virtual ~cRefCountObj();
|
virtual ~cRefCountObj();
|
||||||
|
|
||||||
virtual void Delete() const;
|
virtual void Delete() const;
|
||||||
// override this if you don't want to be destroyed by "delete this"!
|
// override this if you don't want to be destroyed by "delete this"!
|
||||||
private:
|
private:
|
||||||
mutable int mRefCount;
|
mutable int mRefCount;
|
||||||
|
|
||||||
|
|
|
@ -425,7 +425,7 @@ Message_Class::GetWide( ConstKeyRef id ) const
|
||||||
// cMessages_<char & wchar_t> -- Specializations
|
// cMessages_<char & wchar_t> -- Specializations
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// SYNOPSIS:
|
// SYNOPSIS:
|
||||||
// MSVC does not yet support specializations. As a compromise, we fully
|
// MSVC does not yet support specializations. As a compromise, we fully
|
||||||
// specialize on TCHR but assume a key type of "const int".
|
// specialize on TCHR but assume a key type of "const int".
|
||||||
//
|
//
|
||||||
|
|
||||||
|
@ -456,7 +456,7 @@ class cMessages_<ENUM_TYPE, char> :
|
||||||
{
|
{
|
||||||
Value msg = Resources::Get( id );
|
Value msg = Resources::Get( id );
|
||||||
return ( msg != DefaultValueRef() )
|
return ( msg != DefaultValueRef() )
|
||||||
? String( msg )
|
? String( msg )
|
||||||
: String();
|
: String();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,9 +78,9 @@ class iSerializer;
|
||||||
class iSerializable
|
class iSerializable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void Read (iSerializer* pSerializer, int32 version = 0) = 0; // throw (eSerializer, eArchive)
|
virtual void Read (iSerializer* pSerializer, int32 version = 0) = 0; // throw (eSerializer, eArchive)
|
||||||
virtual void Write(iSerializer* pSerializer) const = 0; // throw (eSerializer, eArchive)
|
virtual void Write(iSerializer* pSerializer) const = 0; // throw (eSerializer, eArchive)
|
||||||
// objects implement these methods to read and write themselves to a serializer.
|
// objects implement these methods to read and write themselves to a serializer.
|
||||||
|
|
||||||
virtual ~iSerializable() {}
|
virtual ~iSerializable() {}
|
||||||
};
|
};
|
||||||
|
@ -88,16 +88,16 @@ public:
|
||||||
class iTypedSerializable : public iTyped, public iSerializable
|
class iTypedSerializable : public iTyped, public iSerializable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef iTypedSerializable* (*CreateFunc)();
|
typedef iTypedSerializable* (*CreateFunc)();
|
||||||
// Pointer to a function that creates an empty version of each typed serializable object
|
// Pointer to a function that creates an empty version of each typed serializable object
|
||||||
|
|
||||||
virtual int32 Version() const = 0;
|
virtual int32 Version() const = 0;
|
||||||
// Return the current version of that this serializable object writes.
|
// Return the current version of that this serializable object writes.
|
||||||
// As a convention version number should be (major_version << 16) | minor_version.
|
// As a convention version number should be (major_version << 16) | minor_version.
|
||||||
|
|
||||||
static int32 MkVersion(int16 major, int16 minor) { return (int32)(((uint32)major << 16) | (uint32)minor); }
|
static int32 MkVersion(int16 major, int16 minor) { return (int32)(((uint32)major << 16) | (uint32)minor); }
|
||||||
static int16 MajorVersion(int32 version) { return (int16)((uint32)version >> 16); }
|
static int16 MajorVersion(int32 version) { return (int16)((uint32)version >> 16); }
|
||||||
static int16 MinorVersion(int32 version) { return (int16)version; }
|
static int16 MinorVersion(int32 version) { return (int16)version; }
|
||||||
|
|
||||||
virtual ~iTypedSerializable() {}
|
virtual ~iTypedSerializable() {}
|
||||||
};
|
};
|
||||||
|
@ -105,21 +105,21 @@ public:
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
// convenience macros
|
// convenience macros
|
||||||
#define DECLARE_TYPEDSERIALIZABLE() \
|
#define DECLARE_TYPEDSERIALIZABLE() \
|
||||||
DECLARE_TYPED() \
|
DECLARE_TYPED() \
|
||||||
public: \
|
public: \
|
||||||
static iTypedSerializable* Create(); \
|
static iTypedSerializable* Create(); \
|
||||||
virtual int32 Version() const;
|
virtual int32 Version() const;
|
||||||
|
|
||||||
#define IMPLEMENT_TYPEDSERIALIZABLE(CLASS, TYPEDSTRING, VERSION_MAJOR, VERSION_MINOR) \
|
#define IMPLEMENT_TYPEDSERIALIZABLE(CLASS, TYPEDSTRING, VERSION_MAJOR, VERSION_MINOR) \
|
||||||
IMPLEMENT_TYPED(CLASS, TYPEDSTRING) \
|
IMPLEMENT_TYPED(CLASS, TYPEDSTRING) \
|
||||||
iTypedSerializable* CLASS::Create() \
|
iTypedSerializable* CLASS::Create() \
|
||||||
{ \
|
{ \
|
||||||
return new CLASS; \
|
return new CLASS; \
|
||||||
} \
|
} \
|
||||||
int32 CLASS::Version() const \
|
int32 CLASS::Version() const \
|
||||||
{ \
|
{ \
|
||||||
return iTypedSerializable::MkVersion(VERSION_MAJOR, VERSION_MINOR); \
|
return iTypedSerializable::MkVersion(VERSION_MAJOR, VERSION_MINOR); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __SERIALIZABLE_H
|
#endif // __SERIALIZABLE_H
|
||||||
|
|
||||||
|
|
|
@ -45,78 +45,78 @@
|
||||||
// eSerializer::GetMsg -- Overloaded method for returning an error message.
|
// eSerializer::GetMsg -- Overloaded method for returning an error message.
|
||||||
/*virtual*/ TSTRING eSerializer::GetMsg() const
|
/*virtual*/ TSTRING eSerializer::GetMsg() const
|
||||||
{
|
{
|
||||||
TSTRING ret;
|
TSTRING ret;
|
||||||
|
|
||||||
if( !eSerializer::mDataSource.empty() )
|
if( !eSerializer::mDataSource.empty() )
|
||||||
{
|
{
|
||||||
ret = mMsg;
|
ret = mMsg;
|
||||||
|
|
||||||
switch( eSerializer::mSourceType )
|
switch( eSerializer::mSourceType )
|
||||||
{
|
{
|
||||||
case TY_UNDEFINED:
|
case TY_UNDEFINED:
|
||||||
ret.append( mDataSource );
|
ret.append( mDataSource );
|
||||||
break;
|
break;
|
||||||
case TY_FILE:
|
case TY_FILE:
|
||||||
ret.append( _T("\nFile: ") );
|
ret.append( _T("\nFile: ") );
|
||||||
ret.append( mDataSource );
|
ret.append( mDataSource );
|
||||||
break;
|
break;
|
||||||
case TY_TEMPFILE:
|
case TY_TEMPFILE:
|
||||||
ret.append( _T("\nTemporary File: ") );
|
ret.append( _T("\nTemporary File: ") );
|
||||||
ret.append( mDataSource );
|
ret.append( mDataSource );
|
||||||
break;
|
break;
|
||||||
case TY_MEMORY:
|
case TY_MEMORY:
|
||||||
ret.append( _T("\nMemory Block: ") ); //uhhh...??
|
ret.append( _T("\nMemory Block: ") ); //uhhh...??
|
||||||
ret.append( mDataSource );
|
ret.append( mDataSource );
|
||||||
break;
|
break;
|
||||||
case TY_PIPE:
|
case TY_PIPE:
|
||||||
ret.append( _T("\nNamed Pipe: "));
|
ret.append( _T("\nNamed Pipe: "));
|
||||||
ret.append( mDataSource );
|
ret.append( mDataSource );
|
||||||
break;
|
break;
|
||||||
case TY_SOCKET:
|
case TY_SOCKET:
|
||||||
ret.append( _T("\nNetwork Socket: "));
|
ret.append( _T("\nNetwork Socket: "));
|
||||||
ret.append( mDataSource );
|
ret.append( mDataSource );
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ret.append( _T("\n"));
|
ret.append( _T("\n"));
|
||||||
ret.append( mDataSource );
|
ret.append( mDataSource );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Just use the base class method...
|
// Just use the base class method...
|
||||||
ret = eError::GetMsg();
|
ret = eError::GetMsg();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
eSerializer::eSerializer(ErrorNum errNum, const TSTRING& msg) :
|
eSerializer::eSerializer(ErrorNum errNum, const TSTRING& msg) :
|
||||||
eError(errNum, msg)
|
eError(errNum, msg)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
const TSTRING& eSerializer::GetMsg() const
|
const TSTRING& eSerializer::GetMsg() const
|
||||||
{
|
{
|
||||||
if((mErrorNum < 0) || (mErrorNum >= E_NUMITEMS))
|
if((mErrorNum < 0) || (mErrorNum >= E_NUMITEMS))
|
||||||
{
|
{
|
||||||
// I don't know what this error number is; just use the base class implementation
|
// I don't know what this error number is; just use the base class implementation
|
||||||
return eError::GetMsg();
|
return eError::GetMsg();
|
||||||
}
|
}
|
||||||
|
|
||||||
static TSTRING message;
|
static TSTRING message;
|
||||||
static const TCHAR* reasonStrings[] = { _T("The serializer encountered an unknown type"),
|
static const TCHAR* reasonStrings[] = { _T("The serializer encountered an unknown type"),
|
||||||
_T("Invlaid input stream format for serializer"),
|
_T("Invlaid input stream format for serializer"),
|
||||||
_T("Archive error"),
|
_T("Archive error"),
|
||||||
_T("Version Mismatch"),
|
_T("Version Mismatch"),
|
||||||
_T("Invalid Reason") };
|
_T("Invalid Reason") };
|
||||||
|
|
||||||
message = reasonStrings[mErrorNum];
|
message = reasonStrings[mErrorNum];
|
||||||
message += _T(" : ");
|
message += _T(" : ");
|
||||||
message += mMsg;
|
message += mMsg;
|
||||||
|
|
||||||
return message;
|
return message;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,29 +47,29 @@ class iSerializable;
|
||||||
// Serializer Base Exception
|
// Serializer Base Exception
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
TSS_BEGIN_EXCEPTION_NO_CTOR( eSerializer, eError )
|
TSS_BEGIN_EXCEPTION_NO_CTOR( eSerializer, eError )
|
||||||
// TODO: What else to add to this enumeration? Locked File? Temp file?
|
// TODO: What else to add to this enumeration? Locked File? Temp file?
|
||||||
enum DataSourceType {
|
enum DataSourceType {
|
||||||
TY_UNDEFINED = 0,
|
TY_UNDEFINED = 0,
|
||||||
TY_FILE,
|
TY_FILE,
|
||||||
TY_TEMPFILE,
|
TY_TEMPFILE,
|
||||||
TY_MEMORY,
|
TY_MEMORY,
|
||||||
TY_PIPE,
|
TY_PIPE,
|
||||||
TY_SOCKET
|
TY_SOCKET
|
||||||
};
|
};
|
||||||
|
|
||||||
eSerializer( const TSTRING& msg, const TSTRING& dataSource = _T(""), DataSourceType paramType = TY_UNDEFINED )
|
eSerializer( const TSTRING& msg, const TSTRING& dataSource = _T(""), DataSourceType paramType = TY_UNDEFINED )
|
||||||
: eError( msg ),
|
: eError( msg ),
|
||||||
mDataSource( dataSource ),
|
mDataSource( dataSource ),
|
||||||
mSourceType( paramType )
|
mSourceType( paramType )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual TSTRING GetMsg() const;
|
virtual TSTRING GetMsg() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TSTRING mDataSource;
|
TSTRING mDataSource;
|
||||||
// TSTRING indentifier of the datasource associated with a particular error
|
// TSTRING indentifier of the datasource associated with a particular error
|
||||||
// (if one exists) EX: a filename.
|
// (if one exists) EX: a filename.
|
||||||
DataSourceType mSourceType;
|
DataSourceType mSourceType;
|
||||||
TSS_END_EXCEPTION();
|
TSS_END_EXCEPTION();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
@ -94,67 +94,67 @@ TSS_SERIALIZER_EXCEPTION( eSerializerVersionMismatch );
|
||||||
TSS_SERIALIZER_EXCEPTION( eSerializerEncryption );
|
TSS_SERIALIZER_EXCEPTION( eSerializerEncryption );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
E_UNKNOWN_TYPE = 700,
|
E_UNKNOWN_TYPE = 700,
|
||||||
E_INPUT_STREAM_FORMAT = 701,
|
E_INPUT_STREAM_FORMAT = 701,
|
||||||
E_OUTPUT_STREAM_FORMAT = 706,
|
E_OUTPUT_STREAM_FORMAT = 706,
|
||||||
E_INPUT_STR_TYPEARRAY = 702, // bad index in to type array
|
E_INPUT_STR_TYPEARRAY = 702, // bad index in to type array
|
||||||
E_ARCHIVE = 703,
|
E_ARCHIVE = 703,
|
||||||
E_VERSION_MISMATCH = 704,
|
E_VERSION_MISMATCH = 704,
|
||||||
E_ENCRYPTION_ERROR = 705,
|
E_ENCRYPTION_ERROR = 705,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class iSerializer
|
class iSerializer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Initializing and closing the archive
|
// Initializing and closing the archive
|
||||||
virtual void Init() = 0; // throw eSerializer
|
virtual void Init() = 0; // throw eSerializer
|
||||||
// initializes the serializer; must be called before any reading or writing is done
|
// initializes the serializer; must be called before any reading or writing is done
|
||||||
virtual void Finit() = 0;
|
virtual void Finit() = 0;
|
||||||
// called after a session of serialization is done; called implicitely by the destructor
|
// called after a session of serialization is done; called implicitely by the destructor
|
||||||
// if not called explicitely before destruction
|
// if not called explicitely before destruction
|
||||||
|
|
||||||
//Reading and writing objects Init() should have already been called or all these will fail.
|
//Reading and writing objects Init() should have already been called or all these will fail.
|
||||||
virtual void WriteObjectDynCreate(const iTypedSerializable* pObj) = 0; // throw (eSerializer, eArchive)
|
virtual void WriteObjectDynCreate(const iTypedSerializable* pObj) = 0; // throw (eSerializer, eArchive)
|
||||||
// writes an object such that it can be dynamically created when read back in with
|
// writes an object such that it can be dynamically created when read back in with
|
||||||
// ReadObject.
|
// ReadObject.
|
||||||
virtual iTypedSerializable* ReadObjectDynCreate() = 0; // throw (eSerializer, eArchive);
|
virtual iTypedSerializable* ReadObjectDynCreate() = 0; // throw (eSerializer, eArchive);
|
||||||
// reads an object from the archive, returning a pointer to it. The caller is responsible for
|
// reads an object from the archive, returning a pointer to it. The caller is responsible for
|
||||||
// deleteing or Release()ing it when done.
|
// deleteing or Release()ing it when done.
|
||||||
virtual void WriteObject(const iTypedSerializable* pObj) = 0; // throw (eSerializer, eArchive)
|
virtual void WriteObject(const iTypedSerializable* pObj) = 0; // throw (eSerializer, eArchive)
|
||||||
// writes an object to the archive that will not be dynamically created
|
// writes an object to the archive that will not be dynamically created
|
||||||
virtual void ReadObject(iTypedSerializable* pObj) = 0; // throw (eSerializer, eArchive)
|
virtual void ReadObject(iTypedSerializable* pObj) = 0; // throw (eSerializer, eArchive)
|
||||||
// reads an object that was written with WriteObject()
|
// reads an object that was written with WriteObject()
|
||||||
|
|
||||||
|
|
||||||
// writing interface
|
// writing interface
|
||||||
// all of these can throw eArchive
|
// all of these can throw eArchive
|
||||||
virtual void ReadInt16(int16& ret) = 0;
|
virtual void ReadInt16(int16& ret) = 0;
|
||||||
virtual void ReadInt32(int32& ret) = 0;
|
virtual void ReadInt32(int32& ret) = 0;
|
||||||
virtual void ReadInt64(int64& ret) = 0;
|
virtual void ReadInt64(int64& ret) = 0;
|
||||||
virtual void ReadString(TSTRING& ret) = 0;
|
virtual void ReadString(TSTRING& ret) = 0;
|
||||||
virtual int ReadBlob(void* pBlob, int count) = 0;
|
virtual int ReadBlob(void* pBlob, int count) = 0;
|
||||||
virtual void WriteInt16(int16 i) = 0;
|
virtual void WriteInt16(int16 i) = 0;
|
||||||
virtual void WriteInt32(int32 i) = 0;
|
virtual void WriteInt32(int32 i) = 0;
|
||||||
virtual void WriteInt64(int64 i) = 0;
|
virtual void WriteInt64(int64 i) = 0;
|
||||||
virtual void WriteString(const TSTRING& s) = 0;
|
virtual void WriteString(const TSTRING& s) = 0;
|
||||||
virtual void WriteBlob(const void* pBlob, int count) = 0;
|
virtual void WriteBlob(const void* pBlob, int count) = 0;
|
||||||
|
|
||||||
virtual TSTRING GetFileName() const { return _T(""); }
|
virtual TSTRING GetFileName() const { return _T(""); }
|
||||||
// derived classes can implement this to return the file name associated with the serializer.
|
// derived classes can implement this to return the file name associated with the serializer.
|
||||||
// it is only used in error reporting.
|
// it is only used in error reporting.
|
||||||
|
|
||||||
// the error enumeration: 700-799
|
// the error enumeration: 700-799
|
||||||
enum ErrorNum
|
enum ErrorNum
|
||||||
{
|
{
|
||||||
E_UNKNOWN_TYPE = 700,
|
E_UNKNOWN_TYPE = 700,
|
||||||
E_INPUT_STREAM_FORMAT = 701,
|
E_INPUT_STREAM_FORMAT = 701,
|
||||||
E_INPUT_STR_TYPEARRAY = 702, // bad index in to type array
|
E_INPUT_STR_TYPEARRAY = 702, // bad index in to type array
|
||||||
E_ARCHIVE = 703,
|
E_ARCHIVE = 703,
|
||||||
E_VERSION_MISMATCH = 704,
|
E_VERSION_MISMATCH = 704,
|
||||||
E_ENCRYPTION_ERROR = 705,
|
E_ENCRYPTION_ERROR = 705,
|
||||||
E_OUTPUT_STREAM_FORMAT = 706,
|
E_OUTPUT_STREAM_FORMAT = 706,
|
||||||
E_NUMITEMS
|
E_NUMITEMS
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual ~iSerializer() {}
|
virtual ~iSerializer() {}
|
||||||
};
|
};
|
||||||
|
|
|
@ -38,24 +38,24 @@
|
||||||
#include "crc32.h"
|
#include "crc32.h"
|
||||||
|
|
||||||
// static members
|
// static members
|
||||||
cSerializerImpl::SerMap cSerializerImpl::mSerCreateMap ;
|
cSerializerImpl::SerMap cSerializerImpl::mSerCreateMap ;
|
||||||
cSerializerImpl::SerRefCountMap cSerializerImpl::mSerRefCountCreateMap ;
|
cSerializerImpl::SerRefCountMap cSerializerImpl::mSerRefCountCreateMap ;
|
||||||
|
|
||||||
|
|
||||||
// RAD:09/01/99 -- No longer needed!
|
// RAD:09/01/99 -- No longer needed!
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// util_TstrToStr -- converts the passed in tstring into a narrow string. maxSize
|
// util_TstrToStr -- converts the passed in tstring into a narrow string. maxSize
|
||||||
// indicates the size of the narrow buffer
|
// indicates the size of the narrow buffer
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// static inline void util_TstrToStr(char* pStr, const TCHAR* pTstr, int maxSize)
|
// static inline void util_TstrToStr(char* pStr, const TCHAR* pTstr, int maxSize)
|
||||||
// {
|
// {
|
||||||
// #ifdef _UNICODE
|
// #ifdef _UNICODE
|
||||||
// ASSERT( maxSize >= wcstombs( 0, pTstr
|
// ASSERT( maxSize >= wcstombs( 0, pTstr
|
||||||
// wcstombs(pStr, pTstr, maxSize);
|
// wcstombs(pStr, pTstr, maxSize);
|
||||||
// #else
|
// #else
|
||||||
// strncpy( pStr, pTstr, maxSize );
|
// strncpy( pStr, pTstr, maxSize );
|
||||||
// #endif
|
// #endif
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
|
@ -64,9 +64,9 @@ cSerializerImpl::SerRefCountMap cSerializerImpl::mSerRefCountCreateMap ;
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
static uint32 util_GetCRC( const cType& type )
|
static uint32 util_GetCRC( const cType& type )
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// convert this to narrow...
|
// convert this to narrow...
|
||||||
//
|
//
|
||||||
|
|
||||||
// NOTE:RAD -- Fixed bug when going from TCHAR is Wide to Multibyte
|
// NOTE:RAD -- Fixed bug when going from TCHAR is Wide to Multibyte
|
||||||
// 09/01/99 - Increased performance by returning byte len instead of
|
// 09/01/99 - Increased performance by returning byte len instead of
|
||||||
|
@ -77,7 +77,7 @@ static uint32 util_GetCRC( const cType& type )
|
||||||
#ifdef _UNICODE
|
#ifdef _UNICODE
|
||||||
|
|
||||||
char sz[256];
|
char sz[256];
|
||||||
const uint8* pszType = (const uint8*)(&sz[0]);
|
const uint8* pszType = (const uint8*)(&sz[0]);
|
||||||
const wchar_t* wsz = type.AsString();
|
const wchar_t* wsz = type.AsString();
|
||||||
|
|
||||||
ASSERT( countof(sz) >= ::wcstombs( 0, wsz, size_t(-1) ) );
|
ASSERT( countof(sz) >= ::wcstombs( 0, wsz, size_t(-1) ) );
|
||||||
|
@ -102,24 +102,24 @@ static uint32 util_GetCRC( const cType& type )
|
||||||
ASSERT( pszType && *pszType );
|
ASSERT( pszType && *pszType );
|
||||||
|
|
||||||
//
|
//
|
||||||
// calculate the crc...
|
// calculate the crc...
|
||||||
//
|
//
|
||||||
CRC_INFO crc;
|
CRC_INFO crc;
|
||||||
crcInit( crc );
|
crcInit( crc );
|
||||||
crcUpdate( crc, pszType, nBytes );
|
crcUpdate( crc, pszType, nBytes );
|
||||||
crcFinit( crc );
|
crcFinit( crc );
|
||||||
|
|
||||||
return crc.crc;
|
return crc.crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
//#############################################################################
|
//#############################################################################
|
||||||
// class cSerializerImpl
|
// class cSerializerImpl
|
||||||
//#############################################################################
|
//#############################################################################
|
||||||
cSerializerImpl::cSerializerImpl(cArchive& archive, Mode action, const TSTRING& fileName) :
|
cSerializerImpl::cSerializerImpl(cArchive& archive, Mode action, const TSTRING& fileName) :
|
||||||
mpArchive(&archive),
|
mpArchive(&archive),
|
||||||
mMode(action),
|
mMode(action),
|
||||||
mbInit(false),
|
mbInit(false),
|
||||||
mFileName( fileName )
|
mFileName( fileName )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,13 +129,13 @@ cSerializerImpl::~cSerializerImpl()
|
||||||
|
|
||||||
bool cSerializerImpl::IsWriting() const
|
bool cSerializerImpl::IsWriting() const
|
||||||
{
|
{
|
||||||
return (mMode == S_WRITE);
|
return (mMode == S_WRITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// static object registration functions; Exactly one of these should be called for
|
// static object registration functions; Exactly one of these should be called for
|
||||||
// every object that is to be serialized.
|
// every object that is to be serialized.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// TODO:dmb - following line doesn't do anything???
|
// TODO:dmb - following line doesn't do anything???
|
||||||
|
@ -143,49 +143,49 @@ bool cSerializerImpl::IsWriting() const
|
||||||
|
|
||||||
void cSerializerImpl::RegisterSerializable(const cType& type, iTypedSerializable::CreateFunc pFunc)
|
void cSerializerImpl::RegisterSerializable(const cType& type, iTypedSerializable::CreateFunc pFunc)
|
||||||
{
|
{
|
||||||
uint32 crc = util_GetCRC( type );
|
uint32 crc = util_GetCRC( type );
|
||||||
|
|
||||||
if( cSerializerImpl::mSerCreateMap.find( crc ) != cSerializerImpl::mSerCreateMap.end() )
|
if( cSerializerImpl::mSerCreateMap.find( crc ) != cSerializerImpl::mSerCreateMap.end() )
|
||||||
{
|
{
|
||||||
// duplicate entry!
|
// duplicate entry!
|
||||||
//
|
//
|
||||||
ASSERT( false );
|
ASSERT( false );
|
||||||
TOSTRINGSTREAM str;
|
TOSTRINGSTREAM str;
|
||||||
str << _T("Duplicate entry in type table: ") << type.AsString() << std::endl;
|
str << _T("Duplicate entry in type table: ") << type.AsString() << std::endl;
|
||||||
throw eInternal(str.str());
|
throw eInternal(str.str());
|
||||||
}
|
}
|
||||||
cSerializerImpl::mSerCreateMap[crc] = pFunc;
|
cSerializerImpl::mSerCreateMap[crc] = pFunc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSerializerImpl::RegisterSerializableRefCt(const cType& type, iSerRefCountObj::CreateFunc pFunc)
|
void cSerializerImpl::RegisterSerializableRefCt(const cType& type, iSerRefCountObj::CreateFunc pFunc)
|
||||||
{
|
{
|
||||||
uint32 crc = util_GetCRC( type );
|
uint32 crc = util_GetCRC( type );
|
||||||
|
|
||||||
if( cSerializerImpl::mSerRefCountCreateMap.find( crc ) != cSerializerImpl::mSerRefCountCreateMap.end() )
|
if( cSerializerImpl::mSerRefCountCreateMap.find( crc ) != cSerializerImpl::mSerRefCountCreateMap.end() )
|
||||||
{
|
{
|
||||||
// duplicate entry!
|
// duplicate entry!
|
||||||
//
|
//
|
||||||
ASSERT( false );
|
ASSERT( false );
|
||||||
TOSTRINGSTREAM str;
|
TOSTRINGSTREAM str;
|
||||||
str << _T("Duplicate entry in type table: ") << type.AsString() << std::ends;
|
str << _T("Duplicate entry in type table: ") << type.AsString() << std::ends;
|
||||||
throw eInternal(str.str());
|
throw eInternal(str.str());
|
||||||
}
|
}
|
||||||
cSerializerImpl::mSerRefCountCreateMap[crc] = pFunc;
|
cSerializerImpl::mSerRefCountCreateMap[crc] = pFunc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// Init -- the job of init is to clear out the RefCountObj table, fill out the
|
// Init -- the job of init is to clear out the RefCountObj table, fill out the
|
||||||
// mTypeArray, and and write the header information
|
// mTypeArray, and and write the header information
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
void cSerializerImpl::Init()
|
void cSerializerImpl::Init()
|
||||||
{
|
{
|
||||||
cDebug d("cSerializerImpl::Init");
|
cDebug d("cSerializerImpl::Init");
|
||||||
d.TraceDetail("Entering; IsWriting = %s\n", IsWriting() ? "true" : "false");
|
d.TraceDetail("Entering; IsWriting = %s\n", IsWriting() ? "true" : "false");
|
||||||
|
|
||||||
mRefCtObjTbl.Clear();
|
mRefCtObjTbl.Clear();
|
||||||
|
|
||||||
mbInit = true;
|
mbInit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -193,9 +193,9 @@ void cSerializerImpl::Init()
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
void cSerializerImpl::Finit()
|
void cSerializerImpl::Finit()
|
||||||
{
|
{
|
||||||
cDebug d("cSerializerImpl::Finit");
|
cDebug d("cSerializerImpl::Finit");
|
||||||
d.TraceDetail("Exiting; IsWriting = %s\n", IsWriting() ? "true" : "false");
|
d.TraceDetail("Exiting; IsWriting = %s\n", IsWriting() ? "true" : "false");
|
||||||
mbInit = false;
|
mbInit = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -203,168 +203,168 @@ void cSerializerImpl::Finit()
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
void cSerializerImpl::WriteObjectDynCreate(const iTypedSerializable* pObj)
|
void cSerializerImpl::WriteObjectDynCreate(const iTypedSerializable* pObj)
|
||||||
{
|
{
|
||||||
ASSERT(mbInit);
|
ASSERT(mbInit);
|
||||||
ASSERT(IsWriting());
|
ASSERT(IsWriting());
|
||||||
cDebug d("cSerializerImpl::WriteObjectDynCreate");
|
cDebug d("cSerializerImpl::WriteObjectDynCreate");
|
||||||
// CurrentPos() only works with bidir archive
|
// CurrentPos() only works with bidir archive
|
||||||
//d.TraceDetail("Entering... Archive Offset = %d\n", mpArchive->CurrentPos());
|
//d.TraceDetail("Entering... Archive Offset = %d\n", mpArchive->CurrentPos());
|
||||||
d.TraceDetail(_T(" Object Type = %s\n"), pObj->GetType().AsString());
|
d.TraceDetail(_T(" Object Type = %s\n"), pObj->GetType().AsString());
|
||||||
// first, we write out the header, which consists of the following:
|
// first, we write out the header, which consists of the following:
|
||||||
// uint32 crc of the object's type
|
// uint32 crc of the object's type
|
||||||
// int32 version of stored data
|
// int32 version of stored data
|
||||||
// int32 size of the chunk (counting from this point; not including the previous int32
|
// int32 size of the chunk (counting from this point; not including the previous int32
|
||||||
// int32 index into mRefCountObjTbl, or 0 if it isn't refrence counted.
|
// int32 index into mRefCountObjTbl, or 0 if it isn't refrence counted.
|
||||||
// if the index already exists, then no data follows; a refrence
|
// if the index already exists, then no data follows; a refrence
|
||||||
// should just be added to the existing object.
|
// should just be added to the existing object.
|
||||||
ASSERT(mpArchive != 0);
|
ASSERT(mpArchive != 0);
|
||||||
|
|
||||||
// get the ident for this class type
|
// get the ident for this class type
|
||||||
//
|
//
|
||||||
uint32 crc = util_GetCRC( pObj->GetType() );
|
uint32 crc = util_GetCRC( pObj->GetType() );
|
||||||
|
|
||||||
//
|
//
|
||||||
// make sure this type is registered, and figure out if it is refrence counted
|
// make sure this type is registered, and figure out if it is refrence counted
|
||||||
//
|
//
|
||||||
SerRefCountMap::iterator i = mSerRefCountCreateMap.find( crc );
|
SerRefCountMap::iterator i = mSerRefCountCreateMap.find( crc );
|
||||||
bool bRefCount = true;
|
bool bRefCount = true;
|
||||||
if( i == mSerRefCountCreateMap.end() )
|
if( i == mSerRefCountCreateMap.end() )
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// maybe it is not refrence counted...
|
// maybe it is not refrence counted...
|
||||||
//
|
//
|
||||||
SerMap::iterator si = mSerCreateMap.find( crc );
|
SerMap::iterator si = mSerCreateMap.find( crc );
|
||||||
if( si == mSerCreateMap.end() )
|
if( si == mSerCreateMap.end() )
|
||||||
{
|
{
|
||||||
d.TraceError("Attempt to serialize unregistered type : %s\n", pObj->GetType().AsString());
|
d.TraceError("Attempt to serialize unregistered type : %s\n", pObj->GetType().AsString());
|
||||||
ThrowAndAssert(eSerializerUnknownType( pObj->GetType().AsString(), mFileName, eSerializer::TY_FILE ));
|
ThrowAndAssert(eSerializerUnknownType( pObj->GetType().AsString(), mFileName, eSerializer::TY_FILE ));
|
||||||
}
|
}
|
||||||
bRefCount = false;
|
bRefCount = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
mpArchive->WriteInt32(crc);
|
mpArchive->WriteInt32(crc);
|
||||||
mpArchive->WriteInt32(pObj->Version());
|
mpArchive->WriteInt32(pObj->Version());
|
||||||
// write a placeholder for the size; we will come back and fill in the right value later...
|
// write a placeholder for the size; we will come back and fill in the right value later...
|
||||||
mpArchive->WriteInt32(0xffffffff);
|
mpArchive->WriteInt32(0xffffffff);
|
||||||
|
|
||||||
if(bRefCount)
|
if(bRefCount)
|
||||||
{
|
{
|
||||||
// see if the object has already been serialized...
|
// see if the object has already been serialized...
|
||||||
int idx;
|
int idx;
|
||||||
if((idx = mRefCtObjTbl.Lookup(static_cast<const iSerRefCountObj*>(pObj))) == 0)
|
if((idx = mRefCtObjTbl.Lookup(static_cast<const iSerRefCountObj*>(pObj))) == 0)
|
||||||
{
|
{
|
||||||
// it is not in the table yet; add it and serialize the object
|
// it is not in the table yet; add it and serialize the object
|
||||||
idx = mRefCtObjTbl.Add(static_cast<const iSerRefCountObj*>(pObj));
|
idx = mRefCtObjTbl.Add(static_cast<const iSerRefCountObj*>(pObj));
|
||||||
d.TraceDetail("Object [%d] written for first time...\n", idx);
|
d.TraceDetail("Object [%d] written for first time...\n", idx);
|
||||||
mpArchive->WriteInt32(idx);
|
mpArchive->WriteInt32(idx);
|
||||||
pObj->Write(this);
|
pObj->Write(this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// since it is already in the table, just write the index number
|
// since it is already in the table, just write the index number
|
||||||
d.TraceDetail("Object [%d] already serialized; incrementing refrence count.\n", idx);
|
d.TraceDetail("Object [%d] already serialized; incrementing refrence count.\n", idx);
|
||||||
mpArchive->WriteInt32(idx);
|
mpArchive->WriteInt32(idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// not reference counted ... just write 0
|
// not reference counted ... just write 0
|
||||||
mpArchive->WriteInt32(0);
|
mpArchive->WriteInt32(0);
|
||||||
// ... then write the object.
|
// ... then write the object.
|
||||||
pObj->Write(this);
|
pObj->Write(this);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// ReadObjectDynCreate
|
// ReadObjectDynCreate
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
iTypedSerializable* cSerializerImpl::ReadObjectDynCreate()
|
iTypedSerializable* cSerializerImpl::ReadObjectDynCreate()
|
||||||
{
|
{
|
||||||
cDebug d("cSerializerImpl::ReadObjectDynCreate");
|
cDebug d("cSerializerImpl::ReadObjectDynCreate");
|
||||||
//d.TraceDetail("Entering... archive offset = %d\n", mpArchive->CurrentPos());
|
//d.TraceDetail("Entering... archive offset = %d\n", mpArchive->CurrentPos());
|
||||||
|
|
||||||
int32 size, objIdx;
|
int32 size, objIdx;
|
||||||
uint32 crc;
|
uint32 crc;
|
||||||
// first, get the type...
|
// first, get the type...
|
||||||
mpArchive->ReadInt32(reinterpret_cast<int32&>(crc));
|
mpArchive->ReadInt32(reinterpret_cast<int32&>(crc));
|
||||||
|
|
||||||
// read in the version
|
// read in the version
|
||||||
int32 version;
|
int32 version;
|
||||||
mpArchive->ReadInt32(version);
|
mpArchive->ReadInt32(version);
|
||||||
|
|
||||||
// read in the size and the index...
|
// read in the size and the index...
|
||||||
mpArchive->ReadInt32(size);
|
mpArchive->ReadInt32(size);
|
||||||
|
|
||||||
// Save the position so we can seek correctly later on
|
// Save the position so we can seek correctly later on
|
||||||
//int64 sizePos = mpArchive->CurrentPos();
|
//int64 sizePos = mpArchive->CurrentPos();
|
||||||
|
|
||||||
mpArchive->ReadInt32(objIdx);
|
mpArchive->ReadInt32(objIdx);
|
||||||
if(objIdx == 0)
|
if(objIdx == 0)
|
||||||
{
|
{
|
||||||
// the object is not reference counted; create and read in the object
|
// the object is not reference counted; create and read in the object
|
||||||
// first, we need to create the object.
|
// first, we need to create the object.
|
||||||
SerMap::iterator si;
|
SerMap::iterator si;
|
||||||
si = mSerCreateMap.find(crc);
|
si = mSerCreateMap.find(crc);
|
||||||
if(si == mSerCreateMap.end())
|
if(si == mSerCreateMap.end())
|
||||||
{
|
{
|
||||||
// unable to find the creation function...
|
// unable to find the creation function...
|
||||||
d.TraceError("Unable to find creation function for non-ref counted object %d\n", crc);
|
d.TraceError("Unable to find creation function for non-ref counted object %d\n", crc);
|
||||||
TOSTRINGSTREAM str;
|
TOSTRINGSTREAM str;
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
// Let's only report the actual crc in debug mode
|
// Let's only report the actual crc in debug mode
|
||||||
str << (int32)crc << std::ends;
|
str << (int32)crc << std::ends;
|
||||||
#endif
|
#endif
|
||||||
ThrowAndAssert(eSerializerUnknownType(str.str(), mFileName, eSerializer::TY_FILE));
|
ThrowAndAssert(eSerializerUnknownType(str.str(), mFileName, eSerializer::TY_FILE));
|
||||||
}
|
}
|
||||||
iTypedSerializable* pObj = ((*si).second)();
|
iTypedSerializable* pObj = ((*si).second)();
|
||||||
d.TraceDetail("Created non-ref counted object %s(%p)\n", pObj->GetType().AsString(), pObj);
|
d.TraceDetail("Created non-ref counted object %s(%p)\n", pObj->GetType().AsString(), pObj);
|
||||||
pObj->Read(this, version);
|
pObj->Read(this, version);
|
||||||
|
|
||||||
// seek past this object in case filepos is not correct!
|
// seek past this object in case filepos is not correct!
|
||||||
//mpArchive->Seek(sizePos + size, cBidirArchive::BEGINNING);
|
//mpArchive->Seek(sizePos + size, cBidirArchive::BEGINNING);
|
||||||
|
|
||||||
return pObj;
|
return pObj;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// refrence counted...
|
// refrence counted...
|
||||||
iSerRefCountObj* pObj;
|
iSerRefCountObj* pObj;
|
||||||
pObj = mRefCtObjTbl.Lookup(objIdx);
|
pObj = mRefCtObjTbl.Lookup(objIdx);
|
||||||
if(pObj == NULL)
|
if(pObj == NULL)
|
||||||
{
|
{
|
||||||
// not in table yet...first find the creation function
|
// not in table yet...first find the creation function
|
||||||
SerRefCountMap::iterator rci;
|
SerRefCountMap::iterator rci;
|
||||||
rci = mSerRefCountCreateMap.find(crc);
|
rci = mSerRefCountCreateMap.find(crc);
|
||||||
if(rci == mSerRefCountCreateMap.end())
|
if(rci == mSerRefCountCreateMap.end())
|
||||||
{
|
{
|
||||||
// unable to find the creation function...
|
// unable to find the creation function...
|
||||||
d.TraceError("Unable to find creation function for ref counted object %d\n", crc);
|
d.TraceError("Unable to find creation function for ref counted object %d\n", crc);
|
||||||
TOSTRINGSTREAM str;
|
TOSTRINGSTREAM str;
|
||||||
str << (int32)crc << std::ends;
|
str << (int32)crc << std::ends;
|
||||||
ThrowAndAssert(eSerializerUnknownType(str.str(), mFileName, eSerializer::TY_FILE));
|
ThrowAndAssert(eSerializerUnknownType(str.str(), mFileName, eSerializer::TY_FILE));
|
||||||
}
|
}
|
||||||
pObj = ((*rci).second)();
|
pObj = ((*rci).second)();
|
||||||
d.TraceDetail("Creating Ref-Coutnted object [%d] %s(%p)\n", objIdx, pObj->GetType().AsString(), pObj);
|
d.TraceDetail("Creating Ref-Coutnted object [%d] %s(%p)\n", objIdx, pObj->GetType().AsString(), pObj);
|
||||||
pObj->Read(this);
|
pObj->Read(this);
|
||||||
mRefCtObjTbl.Add(pObj, objIdx);
|
mRefCtObjTbl.Add(pObj, objIdx);
|
||||||
|
|
||||||
// seek past this object in case filepos is not correct!
|
// seek past this object in case filepos is not correct!
|
||||||
//mpArchive->Seek(sizePos + size, cBidirArchive::BEGINNING);
|
//mpArchive->Seek(sizePos + size, cBidirArchive::BEGINNING);
|
||||||
|
|
||||||
return pObj;
|
return pObj;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// already serialized; just return this object.
|
// already serialized; just return this object.
|
||||||
d.TraceDetail("Adding refrence to previously serialized object [%d] %s(%p)\n", objIdx, pObj->GetType().AsString(), pObj);
|
d.TraceDetail("Adding refrence to previously serialized object [%d] %s(%p)\n", objIdx, pObj->GetType().AsString(), pObj);
|
||||||
pObj->AddRef();
|
pObj->AddRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
// seek past this object in case filepos is not correct!
|
// seek past this object in case filepos is not correct!
|
||||||
//mpArchive->Seek(sizePos + size, cBidirArchive::BEGINNING);
|
//mpArchive->Seek(sizePos + size, cBidirArchive::BEGINNING);
|
||||||
|
|
||||||
return pObj;
|
return pObj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -372,102 +372,102 @@ iTypedSerializable* cSerializerImpl::ReadObjectDynCreate()
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
void cSerializerImpl::WriteObject(const iTypedSerializable* pObj)
|
void cSerializerImpl::WriteObject(const iTypedSerializable* pObj)
|
||||||
{
|
{
|
||||||
ASSERT(pObj != 0);
|
ASSERT(pObj != 0);
|
||||||
//ASSERT(mbInit); // this isn't needed if we are not writing the type array
|
//ASSERT(mbInit); // this isn't needed if we are not writing the type array
|
||||||
ASSERT(IsWriting());
|
ASSERT(IsWriting());
|
||||||
cDebug d("cSerializerImpl::WriteObject");
|
cDebug d("cSerializerImpl::WriteObject");
|
||||||
//d.TraceDetail("Entering... Archive Offset = %d\n", mpArchive->CurrentPos());
|
//d.TraceDetail("Entering... Archive Offset = %d\n", mpArchive->CurrentPos());
|
||||||
d.TraceDetail(" Object Type = %s\n", pObj->GetType().AsString());
|
d.TraceDetail(" Object Type = %s\n", pObj->GetType().AsString());
|
||||||
// first, we write out the header, which consists of the following:
|
// first, we write out the header, which consists of the following:
|
||||||
// int32 refrence into mTypeArray, indicating the object's type
|
// int32 refrence into mTypeArray, indicating the object's type
|
||||||
// int32 version of stored data
|
// int32 version of stored data
|
||||||
// int32 size of the chunk (counting from this point; not including the previous int32
|
// int32 size of the chunk (counting from this point; not including the previous int32
|
||||||
// data the object data
|
// data the object data
|
||||||
ASSERT(mpArchive != 0);
|
ASSERT(mpArchive != 0);
|
||||||
|
|
||||||
|
|
||||||
// 5Nov 98 mdb -- I am removing the read and write of type info for this method; it is never used, since
|
// 5Nov 98 mdb -- I am removing the read and write of type info for this method; it is never used, since
|
||||||
// the object is already created when ReadObject() happens. The only good it might serve is in asserting that
|
// the object is already created when ReadObject() happens. The only good it might serve is in asserting that
|
||||||
// the input stream is valid, but I can do that with the 0xffffffff size below (asserting that it is the same
|
// the input stream is valid, but I can do that with the 0xffffffff size below (asserting that it is the same
|
||||||
// when it is read back in)
|
// when it is read back in)
|
||||||
/* int i = 0;
|
/* int i = 0;
|
||||||
for(; i < mTypeArray.size(); i++)
|
for(; i < mTypeArray.size(); i++)
|
||||||
{
|
{
|
||||||
if(pObj->GetType() == *mTypeArray[i])
|
if(pObj->GetType() == *mTypeArray[i])
|
||||||
{
|
{
|
||||||
// aha! this is it!
|
// aha! this is it!
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(i == mTypeArray.size())
|
if(i == mTypeArray.size())
|
||||||
{
|
{
|
||||||
// the type was not registered;
|
// the type was not registered;
|
||||||
// a debate exists in my mind as to whether this should be an exception or an assertion -- mdb
|
// a debate exists in my mind as to whether this should be an exception or an assertion -- mdb
|
||||||
d.TraceError("Attempt to serialize unregistered type : %s\n", pObj->GetType().AsString());
|
d.TraceError("Attempt to serialize unregistered type : %s\n", pObj->GetType().AsString());
|
||||||
ThrowAndAssert(eSerializerUnknownType(pObj->GetType().AsString()));
|
ThrowAndAssert(eSerializerUnknownType(pObj->GetType().AsString()));
|
||||||
}
|
}
|
||||||
mpArchive->WriteInt32(i);
|
mpArchive->WriteInt32(i);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
mpArchive->WriteInt32(0); // place holder for type array index
|
mpArchive->WriteInt32(0); // place holder for type array index
|
||||||
mpArchive->WriteInt32(pObj->Version());
|
mpArchive->WriteInt32(pObj->Version());
|
||||||
// write a placeholder for the size; we will come back and fill in the right value later...
|
// write a placeholder for the size; we will come back and fill in the right value later...
|
||||||
//int64 sizePos = mpArchive->CurrentPos();
|
//int64 sizePos = mpArchive->CurrentPos();
|
||||||
mpArchive->WriteInt32(0xffffffff);
|
mpArchive->WriteInt32(0xffffffff);
|
||||||
|
|
||||||
// write out the object!
|
// write out the object!
|
||||||
pObj->Write(this);
|
pObj->Write(this);
|
||||||
|
|
||||||
// finally, we need to go back and patch up the size...
|
// finally, we need to go back and patch up the size...
|
||||||
//int64 returnPos = mpArchive->CurrentPos();
|
//int64 returnPos = mpArchive->CurrentPos();
|
||||||
//mpArchive->Seek(sizePos, cBidirArchive::BEGINNING);
|
//mpArchive->Seek(sizePos, cBidirArchive::BEGINNING);
|
||||||
//mpArchive->WriteInt32((int32)(returnPos - sizePos - sizeof(int32)));
|
//mpArchive->WriteInt32((int32)(returnPos - sizePos - sizeof(int32)));
|
||||||
//mpArchive->Seek(returnPos, cBidirArchive::BEGINNING);
|
//mpArchive->Seek(returnPos, cBidirArchive::BEGINNING);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSerializerImpl::ReadObject(iTypedSerializable* pObj)
|
void cSerializerImpl::ReadObject(iTypedSerializable* pObj)
|
||||||
{
|
{
|
||||||
cDebug d("cSerializerImpl::ReadObjectDynCreate");
|
cDebug d("cSerializerImpl::ReadObjectDynCreate");
|
||||||
//d.TraceDetail("Entering... archive offset = %d\n", mpArchive->CurrentPos());
|
//d.TraceDetail("Entering... archive offset = %d\n", mpArchive->CurrentPos());
|
||||||
|
|
||||||
// NOTE -- type index stuff is gone; see the comment in WriteObject()
|
// NOTE -- type index stuff is gone; see the comment in WriteObject()
|
||||||
int32 /*typeIdx,*/ size;
|
int32 /*typeIdx,*/ size;
|
||||||
// first, get the type...
|
// first, get the type...
|
||||||
/*
|
/*
|
||||||
mpArchive->ReadInt32(typeIdx);
|
mpArchive->ReadInt32(typeIdx);
|
||||||
if((typeIdx < 0) || (typeIdx >= mTypeArray.size()))
|
if((typeIdx < 0) || (typeIdx >= mTypeArray.size()))
|
||||||
{
|
{
|
||||||
// unknown type index!
|
// unknown type index!
|
||||||
d.TraceError("Encountered bad index into TypeArray: %d\n", typeIdx);
|
d.TraceError("Encountered bad index into TypeArray: %d\n", typeIdx);
|
||||||
ThrowAndAssert(eSerializerInputStremTypeArray());
|
ThrowAndAssert(eSerializerInputStremTypeArray());
|
||||||
}
|
}
|
||||||
const cType* pType = mTypeArray[typeIdx];
|
const cType* pType = mTypeArray[typeIdx];
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// read in the version
|
// read in the version
|
||||||
int32 dummy, version;
|
int32 dummy, version;
|
||||||
mpArchive->ReadInt32(dummy); // old type array index
|
mpArchive->ReadInt32(dummy); // old type array index
|
||||||
mpArchive->ReadInt32(version);
|
mpArchive->ReadInt32(version);
|
||||||
|
|
||||||
// read in the size and the index...
|
// read in the size and the index...
|
||||||
mpArchive->ReadInt32(size);
|
mpArchive->ReadInt32(size);
|
||||||
|
|
||||||
// use the size to assert that the file format is correct
|
// use the size to assert that the file format is correct
|
||||||
if(size != (int)0xffffffff)
|
if(size != (int)0xffffffff)
|
||||||
{
|
{
|
||||||
// unknown type index!
|
// unknown type index!
|
||||||
d.TraceError("Encountered bad size: %d\n", size);
|
d.TraceError("Encountered bad size: %d\n", size);
|
||||||
ThrowAndAssert(eSerializerInputStremTypeArray(_T(""), mFileName, eSerializer::TY_FILE));
|
ThrowAndAssert(eSerializerInputStremTypeArray(_T(""), mFileName, eSerializer::TY_FILE));
|
||||||
}
|
}
|
||||||
|
|
||||||
// remember current position
|
// remember current position
|
||||||
//int64 sizePos = mpArchive->CurrentPos();
|
//int64 sizePos = mpArchive->CurrentPos();
|
||||||
|
|
||||||
// read in the object!
|
// read in the object!
|
||||||
pObj->Read(this, version);
|
pObj->Read(this, version);
|
||||||
|
|
||||||
// seek past this object in case filepos is not correct!
|
// seek past this object in case filepos is not correct!
|
||||||
//mpArchive->Seek(sizePos + size, cBidirArchive::BEGINNING);
|
//mpArchive->Seek(sizePos + size, cBidirArchive::BEGINNING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -476,52 +476,52 @@ void cSerializerImpl::ReadObject(iTypedSerializable* pObj)
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
void cSerializerImpl::ReadInt16(int16& ret)
|
void cSerializerImpl::ReadInt16(int16& ret)
|
||||||
{
|
{
|
||||||
mpArchive->ReadInt16(ret);
|
mpArchive->ReadInt16(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSerializerImpl::ReadInt32(int32& ret)
|
void cSerializerImpl::ReadInt32(int32& ret)
|
||||||
{
|
{
|
||||||
mpArchive->ReadInt32(ret);
|
mpArchive->ReadInt32(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSerializerImpl::ReadInt64(int64& ret)
|
void cSerializerImpl::ReadInt64(int64& ret)
|
||||||
{
|
{
|
||||||
mpArchive->ReadInt64(ret);
|
mpArchive->ReadInt64(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSerializerImpl::ReadString(TSTRING& ret)
|
void cSerializerImpl::ReadString(TSTRING& ret)
|
||||||
{
|
{
|
||||||
mpArchive->ReadString(ret);
|
mpArchive->ReadString(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
int cSerializerImpl::ReadBlob(void* pBlob, int count)
|
int cSerializerImpl::ReadBlob(void* pBlob, int count)
|
||||||
{
|
{
|
||||||
return mpArchive->ReadBlob(pBlob, count);
|
return mpArchive->ReadBlob(pBlob, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSerializerImpl::WriteInt16(int16 i)
|
void cSerializerImpl::WriteInt16(int16 i)
|
||||||
{
|
{
|
||||||
mpArchive->WriteInt16(i);
|
mpArchive->WriteInt16(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSerializerImpl::WriteInt32(int32 i)
|
void cSerializerImpl::WriteInt32(int32 i)
|
||||||
{
|
{
|
||||||
mpArchive->WriteInt32(i);
|
mpArchive->WriteInt32(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSerializerImpl::WriteInt64(int64 i)
|
void cSerializerImpl::WriteInt64(int64 i)
|
||||||
{
|
{
|
||||||
mpArchive->WriteInt64(i);
|
mpArchive->WriteInt64(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSerializerImpl::WriteString(const TSTRING& s)
|
void cSerializerImpl::WriteString(const TSTRING& s)
|
||||||
{
|
{
|
||||||
mpArchive->WriteString(s);
|
mpArchive->WriteString(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSerializerImpl::WriteBlob(const void* pBlob, int count)
|
void cSerializerImpl::WriteBlob(const void* pBlob, int count)
|
||||||
{
|
{
|
||||||
mpArchive->WriteBlob(pBlob, count);
|
mpArchive->WriteBlob(pBlob, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -529,6 +529,6 @@ void cSerializerImpl::WriteBlob(const void* pBlob, int count)
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
TSTRING cSerializerImpl::GetFileName() const
|
TSTRING cSerializerImpl::GetFileName() const
|
||||||
{
|
{
|
||||||
return mFileName;
|
return mFileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,71 +60,71 @@ class cArchive;
|
||||||
class cSerializerImpl : public iSerializer
|
class cSerializerImpl : public iSerializer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum Mode { S_READ, S_WRITE };
|
enum Mode { S_READ, S_WRITE };
|
||||||
cSerializerImpl (cArchive& archive, Mode action, const TSTRING& fileName = _T("") );
|
cSerializerImpl (cArchive& archive, Mode action, const TSTRING& fileName = _T("") );
|
||||||
// fileName is only used for error reporting purposes
|
// fileName is only used for error reporting purposes
|
||||||
virtual ~cSerializerImpl();
|
virtual ~cSerializerImpl();
|
||||||
|
|
||||||
bool IsWriting() const;
|
bool IsWriting() const;
|
||||||
|
|
||||||
// Initializing and closing the archive
|
// Initializing and closing the archive
|
||||||
virtual void Init(); // throw eSerializer
|
virtual void Init(); // throw eSerializer
|
||||||
// initializes the serializer; must be called before any reading or writing is done
|
// initializes the serializer; must be called before any reading or writing is done
|
||||||
virtual void Finit();
|
virtual void Finit();
|
||||||
// called after a session of serialization is done; called implicitely by the destructor
|
// called after a session of serialization is done; called implicitely by the destructor
|
||||||
// if not called explicitely before destruction
|
// if not called explicitely before destruction
|
||||||
|
|
||||||
//Reading and writing objects Init() should have already been called or all these will fail.
|
//Reading and writing objects Init() should have already been called or all these will fail.
|
||||||
virtual void WriteObjectDynCreate(const iTypedSerializable* pObj); // throw (eSerializer, eArchive)
|
virtual void WriteObjectDynCreate(const iTypedSerializable* pObj); // throw (eSerializer, eArchive)
|
||||||
// writes an object such that it can be dynamically created when read back in with
|
// writes an object such that it can be dynamically created when read back in with
|
||||||
// ReadObject.
|
// ReadObject.
|
||||||
virtual iTypedSerializable* ReadObjectDynCreate(); // throw (eSerializer, eArchive);
|
virtual iTypedSerializable* ReadObjectDynCreate(); // throw (eSerializer, eArchive);
|
||||||
// reads an object from the archive, returning a pointer to it. The caller is responsible for
|
// reads an object from the archive, returning a pointer to it. The caller is responsible for
|
||||||
// deleteing or Release()ing it when done.
|
// deleteing or Release()ing it when done.
|
||||||
virtual void WriteObject(const iTypedSerializable* pObj); // throw (eSerializer, eArchive)
|
virtual void WriteObject(const iTypedSerializable* pObj); // throw (eSerializer, eArchive)
|
||||||
// writes an object to the archive that will not be dynamically created
|
// writes an object to the archive that will not be dynamically created
|
||||||
virtual void ReadObject(iTypedSerializable* pObj); // throw (eSerializer, eArchive)
|
virtual void ReadObject(iTypedSerializable* pObj); // throw (eSerializer, eArchive)
|
||||||
// reads an object that was written with WriteObject()
|
// reads an object that was written with WriteObject()
|
||||||
|
|
||||||
// members for registering classes to be serialized. One of these must be called exactly once
|
// members for registering classes to be serialized. One of these must be called exactly once
|
||||||
// for each class that is to be serialized.
|
// for each class that is to be serialized.
|
||||||
static void RegisterSerializable (const cType& type, iTypedSerializable::CreateFunc pFunc);
|
static void RegisterSerializable (const cType& type, iTypedSerializable::CreateFunc pFunc);
|
||||||
static void RegisterSerializableRefCt (const cType& type, iSerRefCountObj::CreateFunc pFunc);
|
static void RegisterSerializableRefCt (const cType& type, iSerRefCountObj::CreateFunc pFunc);
|
||||||
|
|
||||||
// writing interface
|
// writing interface
|
||||||
// TODO -- I am not sure if I want to keep these or just have the serializer expose the archive. Actually,
|
// TODO -- I am not sure if I want to keep these or just have the serializer expose the archive. Actually,
|
||||||
// I think the best thing might be to have iSerializable only know about the archive
|
// I think the best thing might be to have iSerializable only know about the archive
|
||||||
// Standard data read/write
|
// Standard data read/write
|
||||||
// (All functions can throw eArchave exceptions).
|
// (All functions can throw eArchave exceptions).
|
||||||
virtual void ReadInt16(int16& ret);
|
virtual void ReadInt16(int16& ret);
|
||||||
virtual void ReadInt32(int32& ret);
|
virtual void ReadInt32(int32& ret);
|
||||||
virtual void ReadInt64(int64& ret);
|
virtual void ReadInt64(int64& ret);
|
||||||
virtual void ReadString(TSTRING& ret);
|
virtual void ReadString(TSTRING& ret);
|
||||||
virtual int ReadBlob(void* pBlob, int count);
|
virtual int ReadBlob(void* pBlob, int count);
|
||||||
virtual void WriteInt16(int16 i);
|
virtual void WriteInt16(int16 i);
|
||||||
virtual void WriteInt32(int32 i);
|
virtual void WriteInt32(int32 i);
|
||||||
virtual void WriteInt64(int64 i);
|
virtual void WriteInt64(int64 i);
|
||||||
virtual void WriteString(const TSTRING& s);
|
virtual void WriteString(const TSTRING& s);
|
||||||
virtual void WriteBlob(const void* pBlob, int count);
|
virtual void WriteBlob(const void* pBlob, int count);
|
||||||
|
|
||||||
virtual TSTRING GetFileName() const;
|
virtual TSTRING GetFileName() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
cArchive* mpArchive; // the archive we are serializing to
|
cArchive* mpArchive; // the archive we are serializing to
|
||||||
Mode mMode; // are we writing or reading?
|
Mode mMode; // are we writing or reading?
|
||||||
bool mbInit; // has init been called?
|
bool mbInit; // has init been called?
|
||||||
cSerRefCountTable mRefCtObjTbl; // keeps track of all ref counted objects that
|
cSerRefCountTable mRefCtObjTbl; // keeps track of all ref counted objects that
|
||||||
// have been read or written during serialization
|
// have been read or written during serialization
|
||||||
TSTRING mFileName;
|
TSTRING mFileName;
|
||||||
|
|
||||||
// creation function maps
|
// creation function maps
|
||||||
typedef std::map<uint32, iTypedSerializable::CreateFunc> SerMap;
|
typedef std::map<uint32, iTypedSerializable::CreateFunc> SerMap;
|
||||||
typedef std::map<uint32, iSerRefCountObj::CreateFunc> SerRefCountMap;
|
typedef std::map<uint32, iSerRefCountObj::CreateFunc> SerRefCountMap;
|
||||||
static SerMap mSerCreateMap;
|
static SerMap mSerCreateMap;
|
||||||
static SerRefCountMap mSerRefCountCreateMap;
|
static SerRefCountMap mSerRefCountCreateMap;
|
||||||
|
|
||||||
static void InitSerializableMaps();
|
static void InitSerializableMaps();
|
||||||
static void FinitSerializableMaps();
|
static void FinitSerializableMaps();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -39,35 +39,35 @@ namespace {
|
||||||
template<class FROM, class TO>
|
template<class FROM, class TO>
|
||||||
int64 CopyImpl(TO* pTo, FROM* pFrom, int64 amt)
|
int64 CopyImpl(TO* pTo, FROM* pFrom, int64 amt)
|
||||||
{
|
{
|
||||||
enum { BUF_SIZE = 8192 };
|
enum { BUF_SIZE = 8192 };
|
||||||
int8 buf[BUF_SIZE];
|
int8 buf[BUF_SIZE];
|
||||||
int64 amtLeft = amt;
|
int64 amtLeft = amt;
|
||||||
|
|
||||||
while(amtLeft > 0)
|
while(amtLeft > 0)
|
||||||
{
|
{
|
||||||
// NOTE: We use int's here rather than int64 because iSerializer and cArchive
|
// NOTE: We use int's here rather than int64 because iSerializer and cArchive
|
||||||
// only take int's as their size parameter - dmb
|
// only take int's as their size parameter - dmb
|
||||||
int amtToRead = amtLeft > BUF_SIZE ? BUF_SIZE : (int)amtLeft;
|
int amtToRead = amtLeft > BUF_SIZE ? BUF_SIZE : (int)amtLeft;
|
||||||
int amtRead = pFrom->ReadBlob(buf, amtToRead );
|
int amtRead = pFrom->ReadBlob(buf, amtToRead );
|
||||||
amtLeft -= amtRead;
|
amtLeft -= amtRead;
|
||||||
pTo->WriteBlob(buf, amtRead);
|
pTo->WriteBlob(buf, amtRead);
|
||||||
if(amtRead < amtToRead)
|
if(amtRead < amtToRead)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return the amount copied ...
|
// return the amount copied ...
|
||||||
return (amt - amtLeft);
|
return (amt - amtLeft);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int64 cSerializerUtil::Copy( iSerializer* pDest, cArchive* pSrc, int64 amt )
|
int64 cSerializerUtil::Copy( iSerializer* pDest, cArchive* pSrc, int64 amt )
|
||||||
{
|
{
|
||||||
return CopyImpl( pDest, pSrc, amt );
|
return CopyImpl( pDest, pSrc, amt );
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 cSerializerUtil::Copy( cArchive* pDest, iSerializer* pSrc, int64 amt )
|
int64 cSerializerUtil::Copy( cArchive* pDest, iSerializer* pSrc, int64 amt )
|
||||||
{
|
{
|
||||||
return CopyImpl( pDest, pSrc, amt );
|
return CopyImpl( pDest, pSrc, amt );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,10 +44,10 @@ class iSerializer;
|
||||||
class cSerializerUtil
|
class cSerializerUtil
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static int64 Copy( iSerializer* pDest, cArchive* pSrc, int64 amt ); // throw( eArchvie, eSerilaizer )
|
static int64 Copy( iSerializer* pDest, cArchive* pSrc, int64 amt ); // throw( eArchvie, eSerilaizer )
|
||||||
static int64 Copy( cArchive* pDest, iSerializer* pSrc, int64 amt ); // throw( eArchvie, eSerilaizer )
|
static int64 Copy( cArchive* pDest, iSerializer* pSrc, int64 amt ); // throw( eArchvie, eSerilaizer )
|
||||||
// these two methods copy data from archives to serializers and vice-versa. They
|
// these two methods copy data from archives to serializers and vice-versa. They
|
||||||
// throw exceptions on error; the return value is the amount that was copied.
|
// throw exceptions on error; the return value is the amount that was copied.
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -57,8 +57,8 @@ public:
|
||||||
std::string mString;
|
std::string mString;
|
||||||
|
|
||||||
virtual ~cSerializableNString() {};
|
virtual ~cSerializableNString() {};
|
||||||
virtual void Read (iSerializer* pSerializer, int32 version = 0); // throw (eSerializer, eArchive)
|
virtual void Read (iSerializer* pSerializer, int32 version = 0); // throw (eSerializer, eArchive)
|
||||||
virtual void Write(iSerializer* pSerializer) const; // throw (eSerializer, eArchive)
|
virtual void Write(iSerializer* pSerializer) const; // throw (eSerializer, eArchive)
|
||||||
|
|
||||||
DECLARE_TYPEDSERIALIZABLE()
|
DECLARE_TYPEDSERIALIZABLE()
|
||||||
};
|
};
|
||||||
|
@ -72,8 +72,8 @@ public:
|
||||||
std::string mString;
|
std::string mString;
|
||||||
|
|
||||||
virtual ~cSerializableWString() {};
|
virtual ~cSerializableWString() {};
|
||||||
virtual void Read (iSerializer* pSerializer, int32 version = 0); // throw (eSerializer, eArchive)
|
virtual void Read (iSerializer* pSerializer, int32 version = 0); // throw (eSerializer, eArchive)
|
||||||
virtual void Write(iSerializer* pSerializer) const; // throw (eSerializer, eArchive)
|
virtual void Write(iSerializer* pSerializer) const; // throw (eSerializer, eArchive)
|
||||||
|
|
||||||
DECLARE_TYPEDSERIALIZABLE()
|
DECLARE_TYPEDSERIALIZABLE()
|
||||||
};
|
};
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
/*
|
/*
|
||||||
* sha.c
|
* sha.c
|
||||||
*
|
*
|
||||||
* signature function hook for SHA.
|
* signature function hook for SHA.
|
||||||
*
|
*
|
||||||
* Gene Kim
|
* Gene Kim
|
||||||
* Purdue University
|
* Purdue University
|
||||||
|
@ -175,7 +175,7 @@ void shsTransform(SHS_INFO *shsInfo)
|
||||||
|
|
||||||
/* Step A. Copy the data buffer into the local work buffer */
|
/* Step A. Copy the data buffer into the local work buffer */
|
||||||
for( i = 0; i < 16; i++ )
|
for( i = 0; i < 16; i++ )
|
||||||
W[ i ] = shsInfo->data[ i ];
|
W[ i ] = shsInfo->data[ i ];
|
||||||
|
|
||||||
/* Step B. Expand the 16 words into 64 temporary data words */
|
/* Step B. Expand the 16 words into 64 temporary data words */
|
||||||
expand( 16 ); expand( 17 ); expand( 18 ); expand( 19 ); expand( 20 );
|
expand( 16 ); expand( 17 ); expand( 18 ); expand( 19 ); expand( 20 );
|
||||||
|
@ -244,10 +244,10 @@ static void byteReverse(uint32* buffer, int byteCount)
|
||||||
|
|
||||||
byteCount /= sizeof( uint32 );
|
byteCount /= sizeof( uint32 );
|
||||||
for( count = 0; count < byteCount; count++ )
|
for( count = 0; count < byteCount; count++ )
|
||||||
{
|
{
|
||||||
value = ( buffer[ count ] << 16 ) | ( buffer[ count ] >> 16 );
|
value = ( buffer[ count ] << 16 ) | ( buffer[ count ] >> 16 );
|
||||||
buffer[ count ] = ( ( value & 0xFF00FF00L ) >> 8 ) | ( ( value & 0x00FF00FFL ) << 8 );
|
buffer[ count ] = ( ( value & 0xFF00FF00L ) >> 8 ) | ( ( value & 0x00FF00FFL ) << 8 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* #ifndef WORDS_BIGENDIAN */
|
#endif /* #ifndef WORDS_BIGENDIAN */
|
||||||
|
|
||||||
|
@ -260,21 +260,21 @@ void shsUpdate(SHS_INFO* shsInfo, uint8* buffer, int count)
|
||||||
{
|
{
|
||||||
/* Update bitcount */
|
/* Update bitcount */
|
||||||
if( ( shsInfo->countLo + ( ( uint32 ) count << 3 ) ) < shsInfo->countLo )
|
if( ( shsInfo->countLo + ( ( uint32 ) count << 3 ) ) < shsInfo->countLo )
|
||||||
shsInfo->countHi++; /* Carry from low to high bitCount */
|
shsInfo->countHi++; /* Carry from low to high bitCount */
|
||||||
shsInfo->countLo += ( ( uint32 ) count << 3 );
|
shsInfo->countLo += ( ( uint32 ) count << 3 );
|
||||||
shsInfo->countHi += ( ( uint32 ) count >> 29 );
|
shsInfo->countHi += ( ( uint32 ) count >> 29 );
|
||||||
|
|
||||||
/* Process data in SHS_BLOCKSIZE chunks */
|
/* Process data in SHS_BLOCKSIZE chunks */
|
||||||
while( count >= SHS_BLOCKSIZE )
|
while( count >= SHS_BLOCKSIZE )
|
||||||
{
|
{
|
||||||
memcpy( (char *) shsInfo->data, (char *) buffer, SHS_BLOCKSIZE );
|
memcpy( (char *) shsInfo->data, (char *) buffer, SHS_BLOCKSIZE );
|
||||||
#ifndef WORDS_BIGENDIAN
|
#ifndef WORDS_BIGENDIAN
|
||||||
byteReverse( shsInfo->data, SHS_BLOCKSIZE );
|
byteReverse( shsInfo->data, SHS_BLOCKSIZE );
|
||||||
#endif /* #ifndef WORDS_BIGENDIAN */
|
#endif /* #ifndef WORDS_BIGENDIAN */
|
||||||
shsTransform( shsInfo );
|
shsTransform( shsInfo );
|
||||||
buffer += SHS_BLOCKSIZE;
|
buffer += SHS_BLOCKSIZE;
|
||||||
count -= SHS_BLOCKSIZE;
|
count -= SHS_BLOCKSIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle any remaining bytes of data. This should only happen once
|
/* Handle any remaining bytes of data. This should only happen once
|
||||||
on the final lot of data */
|
on the final lot of data */
|
||||||
|
@ -295,20 +295,20 @@ void shsFinal(SHS_INFO *shsInfo)
|
||||||
|
|
||||||
/* Pad out to 56 mod 64 */
|
/* Pad out to 56 mod 64 */
|
||||||
if( count > 56 )
|
if( count > 56 )
|
||||||
{
|
{
|
||||||
/* Two lots of padding: Pad the first block to 64 bytes */
|
/* Two lots of padding: Pad the first block to 64 bytes */
|
||||||
memset( ( char * ) shsInfo->data + count, 0, 64 - count );
|
memset( ( char * ) shsInfo->data + count, 0, 64 - count );
|
||||||
#ifndef WORDS_BIGENDIAN
|
#ifndef WORDS_BIGENDIAN
|
||||||
byteReverse( shsInfo->data, SHS_BLOCKSIZE );
|
byteReverse( shsInfo->data, SHS_BLOCKSIZE );
|
||||||
#endif /* #ifndef WORDS_BIGENDIAN */
|
#endif /* #ifndef WORDS_BIGENDIAN */
|
||||||
shsTransform( shsInfo );
|
shsTransform( shsInfo );
|
||||||
|
|
||||||
/* Now fill the next block with 56 bytes */
|
/* Now fill the next block with 56 bytes */
|
||||||
memset( (char *) shsInfo->data, 0, 56 );
|
memset( (char *) shsInfo->data, 0, 56 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* Pad block to 56 bytes */
|
/* Pad block to 56 bytes */
|
||||||
memset( ( char * ) shsInfo->data + count, 0, 56 - count );
|
memset( ( char * ) shsInfo->data + count, 0, 56 - count );
|
||||||
#ifndef WORDS_BIGENDIAN
|
#ifndef WORDS_BIGENDIAN
|
||||||
byteReverse( shsInfo->data, SHS_BLOCKSIZE );
|
byteReverse( shsInfo->data, SHS_BLOCKSIZE );
|
||||||
#endif /* #ifndef WORDS_BIGENDIAN */
|
#endif /* #ifndef WORDS_BIGENDIAN */
|
||||||
|
@ -350,14 +350,14 @@ void main()
|
||||||
shsUpdate( &shsInfo, ( uint8 * ) "abc", 3 );
|
shsUpdate( &shsInfo, ( uint8 * ) "abc", 3 );
|
||||||
shsFinal( &shsInfo );
|
shsFinal( &shsInfo );
|
||||||
if( shsInfo.digest[ 0 ] != 0x0164B8A9L ||
|
if( shsInfo.digest[ 0 ] != 0x0164B8A9L ||
|
||||||
shsInfo.digest[ 1 ] != 0x14CD2A5EL ||
|
shsInfo.digest[ 1 ] != 0x14CD2A5EL ||
|
||||||
shsInfo.digest[ 2 ] != 0x74C4F7FFL ||
|
shsInfo.digest[ 2 ] != 0x74C4F7FFL ||
|
||||||
shsInfo.digest[ 3 ] != 0x082C4D97L ||
|
shsInfo.digest[ 3 ] != 0x082C4D97L ||
|
||||||
shsInfo.digest[ 4 ] != 0xF1EDF880L )
|
shsInfo.digest[ 4 ] != 0xF1EDF880L )
|
||||||
{
|
{
|
||||||
puts( "Error in SHS implementation" );
|
puts( "Error in SHS implementation" );
|
||||||
exit( -1 );
|
exit( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now perform time trial, generating MD for 10MB of data. First,
|
/* Now perform time trial, generating MD for 10MB of data. First,
|
||||||
initialize the test data */
|
initialize the test data */
|
||||||
|
@ -370,7 +370,7 @@ void main()
|
||||||
/* Calculate SHS message digest in TEST_BLOCK_SIZE byte blocks */
|
/* Calculate SHS message digest in TEST_BLOCK_SIZE byte blocks */
|
||||||
shsInit( &shsInfo );
|
shsInit( &shsInfo );
|
||||||
for( i = TEST_BLOCKS; i > 0; i-- )
|
for( i = TEST_BLOCKS; i > 0; i-- )
|
||||||
shsUpdate( &shsInfo, data, TEST_BLOCK_SIZE );
|
shsUpdate( &shsInfo, data, TEST_BLOCK_SIZE );
|
||||||
shsFinal( &shsInfo );
|
shsFinal( &shsInfo );
|
||||||
|
|
||||||
/* Get finish time and time difference */
|
/* Get finish time and time difference */
|
||||||
|
|
|
@ -46,10 +46,10 @@
|
||||||
/* The structure for storing SHS info */
|
/* The structure for storing SHS info */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32 digest[ 5 ]; /* Message digest */
|
uint32 digest[ 5 ]; /* Message digest */
|
||||||
uint32 countLo, countHi; /* 64-bit bit count */
|
uint32 countLo, countHi; /* 64-bit bit count */
|
||||||
uint32 data[ 16 ]; /* SHS data buffer */
|
uint32 data[ 16 ]; /* SHS data buffer */
|
||||||
} SHS_INFO;
|
} SHS_INFO;
|
||||||
|
|
||||||
/* Whether the machine is little-endian or not */
|
/* Whether the machine is little-endian or not */
|
||||||
|
|
||||||
|
@ -63,22 +63,22 @@ void shsFinal(SHS_INFO* shsInfo);
|
||||||
* formulation. Bruce Schneier described it thus in a posting to the
|
* formulation. Bruce Schneier described it thus in a posting to the
|
||||||
* Cypherpunks mailing list on June 21, 1994 (as told to us by Steve Bellovin):
|
* Cypherpunks mailing list on June 21, 1994 (as told to us by Steve Bellovin):
|
||||||
*
|
*
|
||||||
* This is the fix to the Secure Hash Standard, NIST FIPS PUB 180:
|
* This is the fix to the Secure Hash Standard, NIST FIPS PUB 180:
|
||||||
*
|
*
|
||||||
* In Section 7 of FIPS 180 (page 9), the line which reads
|
* In Section 7 of FIPS 180 (page 9), the line which reads
|
||||||
*
|
*
|
||||||
* "b) For t=16 to 79 let Wt = Wt-3 XOR Wt-8 XOR Wt-14 XOR
|
* "b) For t=16 to 79 let Wt = Wt-3 XOR Wt-8 XOR Wt-14 XOR
|
||||||
* Wt-16."
|
* Wt-16."
|
||||||
*
|
*
|
||||||
* is to be replaced by
|
* is to be replaced by
|
||||||
*
|
*
|
||||||
* "b) For t=16 to 79 let Wt = S1(Wt-3 XOR Wt-8 XOR Wt-14 XOR
|
* "b) For t=16 to 79 let Wt = S1(Wt-3 XOR Wt-8 XOR Wt-14 XOR
|
||||||
* Wt-16)."
|
* Wt-16)."
|
||||||
*
|
*
|
||||||
* where S1 is a left circular shift by one bit as defined in
|
* where S1 is a left circular shift by one bit as defined in
|
||||||
* Section 3 of FIPS 180 (page 6):
|
* Section 3 of FIPS 180 (page 6):
|
||||||
*
|
*
|
||||||
* S1(X) = (X<<1) OR (X>>31).
|
* S1(X) = (X<<1) OR (X>>31).
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -54,8 +54,8 @@
|
||||||
class iSerRefCountObj : public cRefCountObj, public iTypedSerializable
|
class iSerRefCountObj : public cRefCountObj, public iTypedSerializable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// the creation function
|
// the creation function
|
||||||
typedef iSerRefCountObj* (*CreateFunc)(void);
|
typedef iSerRefCountObj* (*CreateFunc)(void);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~iSerRefCountObj();
|
virtual ~iSerRefCountObj();
|
||||||
|
@ -65,21 +65,21 @@ protected:
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
// convenience macros
|
// convenience macros
|
||||||
#define DECLARE_SERREFCOUNT() \
|
#define DECLARE_SERREFCOUNT() \
|
||||||
DECLARE_TYPED() \
|
DECLARE_TYPED() \
|
||||||
public: \
|
public: \
|
||||||
static iSerRefCountObj* Create(); \
|
static iSerRefCountObj* Create(); \
|
||||||
virtual int32 Version() const;
|
virtual int32 Version() const;
|
||||||
|
|
||||||
#define IMPLEMENT_SERREFCOUNT(CLASS, TYPEDSTRING, VERSION_MAJOR, VERSION_MINOR) \
|
#define IMPLEMENT_SERREFCOUNT(CLASS, TYPEDSTRING, VERSION_MAJOR, VERSION_MINOR) \
|
||||||
IMPLEMENT_TYPED(CLASS, TYPEDSTRING) \
|
IMPLEMENT_TYPED(CLASS, TYPEDSTRING) \
|
||||||
iSerRefCountObj* CLASS::Create() \
|
iSerRefCountObj* CLASS::Create() \
|
||||||
{ \
|
{ \
|
||||||
return new CLASS; \
|
return new CLASS; \
|
||||||
} \
|
} \
|
||||||
int32 CLASS::Version() const \
|
int32 CLASS::Version() const \
|
||||||
{ \
|
{ \
|
||||||
return iTypedSerializable::MkVersion(VERSION_MAJOR, VERSION_MINOR); \
|
return iTypedSerializable::MkVersion(VERSION_MAJOR, VERSION_MINOR); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -54,8 +54,8 @@ cSerRefCountTable::~cSerRefCountTable()
|
||||||
|
|
||||||
void cSerRefCountTable::Clear()
|
void cSerRefCountTable::Clear()
|
||||||
{
|
{
|
||||||
mIDToObjTbl.clear();
|
mIDToObjTbl.clear();
|
||||||
mObjToIdTbl.clear();
|
mObjToIdTbl.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// find the table id for object. returns 0 if not in table.
|
// find the table id for object. returns 0 if not in table.
|
||||||
|
@ -63,8 +63,8 @@ int cSerRefCountTable::Lookup(const iSerRefCountObj* pObj)
|
||||||
{
|
{
|
||||||
std::map<iSerRefCountObj*, int>::iterator itr;
|
std::map<iSerRefCountObj*, int>::iterator itr;
|
||||||
|
|
||||||
// pay no attention to this cast :-)
|
// pay no attention to this cast :-)
|
||||||
itr = mObjToIdTbl.find(const_cast<iSerRefCountObj*>(pObj));
|
itr = mObjToIdTbl.find(const_cast<iSerRefCountObj*>(pObj));
|
||||||
|
|
||||||
return (itr == mObjToIdTbl.end()) ? 0 : itr->second;
|
return (itr == mObjToIdTbl.end()) ? 0 : itr->second;
|
||||||
}
|
}
|
||||||
|
@ -86,8 +86,8 @@ int cSerRefCountTable::Add(iSerRefCountObj* pObj, int id)
|
||||||
{
|
{
|
||||||
if (Lookup(pObj) != 0)
|
if (Lookup(pObj) != 0)
|
||||||
{
|
{
|
||||||
// this should be a programming error, but we will throw just to be safe...
|
// this should be a programming error, but we will throw just to be safe...
|
||||||
ThrowAndAssert(eInternal(_T("cSerRefCountTable::Add() passed object already in table.")));
|
ThrowAndAssert(eInternal(_T("cSerRefCountTable::Add() passed object already in table.")));
|
||||||
}
|
}
|
||||||
if (id == 0)
|
if (id == 0)
|
||||||
{
|
{
|
||||||
|
@ -96,8 +96,8 @@ int cSerRefCountTable::Add(iSerRefCountObj* pObj, int id)
|
||||||
}
|
}
|
||||||
else if (Lookup(id) != NULL)
|
else if (Lookup(id) != NULL)
|
||||||
{
|
{
|
||||||
// this should be a programming error, but we will throw just to be safe...
|
// this should be a programming error, but we will throw just to be safe...
|
||||||
ThrowAndAssert(eInternal(_T("cSerRefCountTable::Add() passed ID already in table.")));
|
ThrowAndAssert(eInternal(_T("cSerRefCountTable::Add() passed ID already in table.")));
|
||||||
}
|
}
|
||||||
|
|
||||||
mIDToObjTbl.insert( MapIDTObj::value_type(id, pObj));
|
mIDToObjTbl.insert( MapIDTObj::value_type(id, pObj));
|
||||||
|
@ -108,8 +108,8 @@ int cSerRefCountTable::Add(iSerRefCountObj* pObj, int id)
|
||||||
|
|
||||||
int cSerRefCountTable::Add(const iSerRefCountObj* pObj, int id)
|
int cSerRefCountTable::Add(const iSerRefCountObj* pObj, int id)
|
||||||
{
|
{
|
||||||
iSerRefCountObj* pNonConst = const_cast<iSerRefCountObj*>(pObj);
|
iSerRefCountObj* pNonConst = const_cast<iSerRefCountObj*>(pObj);
|
||||||
return Add(pNonConst, id);
|
return Add(pNonConst, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -54,17 +54,17 @@ public:
|
||||||
// Add an object to the table, optionally specifying an ID. Returns a
|
// Add an object to the table, optionally specifying an ID. Returns a
|
||||||
// unique ID for the object. ASSERTs and throws exception if object is
|
// unique ID for the object. ASSERTs and throws exception if object is
|
||||||
// already in table or the ID is already taken.
|
// already in table or the ID is already taken.
|
||||||
int Add( iSerRefCountObj* pObj, int id = 0);
|
int Add( iSerRefCountObj* pObj, int id = 0);
|
||||||
int Add(const iSerRefCountObj* pObj, int id = 0);
|
int Add(const iSerRefCountObj* pObj, int id = 0);
|
||||||
// TODO -- Note that this class is not really const-correct in that the const version of
|
// TODO -- Note that this class is not really const-correct in that the const version of
|
||||||
// Add() just casts away the constness. The right thing to do is to make the serializer
|
// Add() just casts away the constness. The right thing to do is to make the serializer
|
||||||
// use different versions of this class (const and non-const) depending on whether it is
|
// use different versions of this class (const and non-const) depending on whether it is
|
||||||
// reading or writing and (maybe?) make this class a template class so that it can map
|
// reading or writing and (maybe?) make this class a template class so that it can map
|
||||||
// to either const or non-const objects.
|
// to either const or non-const objects.
|
||||||
|
|
||||||
|
|
||||||
// clears out the table
|
// clears out the table
|
||||||
void Clear();
|
void Clear();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef std::map<int, iSerRefCountObj*> MapIDTObj;
|
typedef std::map<int, iSerRefCountObj*> MapIDTObj;
|
||||||
|
|
|
@ -88,7 +88,7 @@ public:
|
||||||
const byte* operator()( const wc16_string& s, int* const pcbKeyLen )
|
const byte* operator()( const wc16_string& s, int* const pcbKeyLen )
|
||||||
{
|
{
|
||||||
*pcbKeyLen = sizeof(WCHAR16) * s.length();
|
*pcbKeyLen = sizeof(WCHAR16) * s.length();
|
||||||
return (byte*)s.c_str();
|
return (byte*)s.c_str();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ class tss_hash_key_compare
|
||||||
public:
|
public:
|
||||||
bool operator()( const wc16_string& lhs, const wc16_string& rhs )
|
bool operator()( const wc16_string& lhs, const wc16_string& rhs )
|
||||||
{
|
{
|
||||||
return ( lhs.compare( rhs ) == 0 );
|
return ( lhs.compare( rhs ) == 0 );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -506,12 +506,12 @@ void cMBUCS2Cache::Add(mbchar_t* pMBchar, int mblen, dbchar_t ucs2)
|
||||||
static inline const byte* tss_hash_key_convert()( const TCHAR* psz, int* const pcbKeyLen )
|
static inline const byte* tss_hash_key_convert()( const TCHAR* psz, int* const pcbKeyLen )
|
||||||
{
|
{
|
||||||
*pcbKeyLen = sizeof(TCHAR) * _tcslen( psz );
|
*pcbKeyLen = sizeof(TCHAR) * _tcslen( psz );
|
||||||
return (byte*)psz;
|
return (byte*)psz;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool tss_hash_key_compare()( const TCHAR* lhs, const TCHAR* rhs )
|
static inline bool tss_hash_key_compare()( const TCHAR* lhs, const TCHAR* rhs )
|
||||||
{
|
{
|
||||||
return ( _tcscmp( lhs, rhs ) == 0 );
|
return ( _tcscmp( lhs, rhs ) == 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
cHashTable< dbchar_t*,
|
cHashTable< dbchar_t*,
|
||||||
|
|
|
@ -55,9 +55,9 @@ inline
|
||||||
void TestStringUtil()
|
void TestStringUtil()
|
||||||
{
|
{
|
||||||
#if USING_NTDBS_STUFF
|
#if USING_NTDBS_STUFF
|
||||||
cDebug db("Test std::char_traits<dbchar_t>");
|
cDebug db("Test std::char_traits<dbchar_t>");
|
||||||
|
|
||||||
db.TraceAlways("Entering...\n");
|
db.TraceAlways("Entering...\n");
|
||||||
|
|
||||||
tss::dbstring a;
|
tss::dbstring a;
|
||||||
tss::dbstring b;
|
tss::dbstring b;
|
||||||
|
@ -143,7 +143,7 @@ void TestStringUtil()
|
||||||
//std::string TstrToStr( const TSTRING& tstr );
|
//std::string TstrToStr( const TSTRING& tstr );
|
||||||
//TSTRING StrToTstr( const std::string& str );
|
//TSTRING StrToTstr( const std::string& str );
|
||||||
//TSTRING WstrToTstr( const wc16_string& src );
|
//TSTRING WstrToTstr( const wc16_string& src );
|
||||||
//wc16_string TstrToWstr( const TSTRING& tstr );
|
//wc16_string TstrToWstr( const TSTRING& tstr );
|
||||||
|
|
||||||
// test Null assignments
|
// test Null assignments
|
||||||
singleStr = cStringUtil::TstrToStr( tStrNull );
|
singleStr = cStringUtil::TstrToStr( tStrNull );
|
||||||
|
|
|
@ -54,42 +54,42 @@ template<class TIME_FN, class TIME_TYPE>
|
||||||
class cTaskTimer
|
class cTaskTimer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cTaskTimer(const TSTRING& name) : mName(name), mTotalTime(0), mStartTime(0), mNumStarts(0) {}
|
cTaskTimer(const TSTRING& name) : mName(name), mTotalTime(0), mStartTime(0), mNumStarts(0) {}
|
||||||
~cTaskTimer();
|
~cTaskTimer();
|
||||||
|
|
||||||
void Start();
|
void Start();
|
||||||
void Stop();
|
void Stop();
|
||||||
bool IsRunning() { return (mStartTime != 0); }
|
bool IsRunning() { return (mStartTime != 0); }
|
||||||
void Reset() { mNumStarts = mStartTime = mTotalTime = 0 }
|
void Reset() { mNumStarts = mStartTime = mTotalTime = 0 }
|
||||||
int32 GetTotalTime() const;
|
int32 GetTotalTime() const;
|
||||||
int32 GetNumTimesStarted() const; // returns the number of times start() was called
|
int32 GetNumTimesStarted() const; // returns the number of times start() was called
|
||||||
const std::string& GetName() const;
|
const std::string& GetName() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TSTRING mName;
|
TSTRING mName;
|
||||||
int32 mTotalTime;
|
int32 mTotalTime;
|
||||||
TIME_TYPE mStartTime;
|
TIME_TYPE mStartTime;
|
||||||
int32 mNumStarts;
|
int32 mNumStarts;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#if IS_UNIX
|
#if IS_UNIX
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// cUnixTimeFn -- Unix version, inserts proper function call and overloads
|
// cUnixTimeFn -- Unix version, inserts proper function call and overloads
|
||||||
// operator()
|
// operator()
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
class cUnixTimeFn
|
class cUnixTimeFn
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef uint32 DataType;
|
typedef uint32 DataType;
|
||||||
|
|
||||||
uint32 operator()()
|
uint32 operator()()
|
||||||
{
|
{
|
||||||
return time( &dummy_var );
|
return time( &dummy_var );
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
time_t dummy_var;
|
time_t dummy_var;
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -105,45 +105,45 @@ typedef cUnixTaskTimer cGenericTaskTimer;
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
template<class TIME_FN, class TIME_TYPE>
|
template<class TIME_FN, class TIME_TYPE>
|
||||||
inline void cTaskTimer<TIME_FN, TIME_TYPE>::Start()
|
inline void cTaskTimer<TIME_FN, TIME_TYPE>::Start()
|
||||||
{
|
{
|
||||||
ASSERT(! IsRunning());
|
ASSERT(! IsRunning());
|
||||||
TIME_FN GetTime;
|
TIME_FN GetTime;
|
||||||
mStartTime = GetTime();
|
mStartTime = GetTime();
|
||||||
mNumStarts++;
|
mNumStarts++;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class TIME_FN, class TIME_TYPE>
|
template<class TIME_FN, class TIME_TYPE>
|
||||||
inline void cTaskTimer<TIME_FN, TIME_TYPE>::Stop()
|
inline void cTaskTimer<TIME_FN, TIME_TYPE>::Stop()
|
||||||
{
|
{
|
||||||
ASSERT(IsRunning());
|
ASSERT(IsRunning());
|
||||||
TIME_FN GetTime;
|
TIME_FN GetTime;
|
||||||
mTotalTime += ( GetTime() - mStartTime );
|
mTotalTime += ( GetTime() - mStartTime );
|
||||||
mStartTime = 0;
|
mStartTime = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class TIME_FN, class TIME_TYPE>
|
template<class TIME_FN, class TIME_TYPE>
|
||||||
inline int32 cTaskTimer<TIME_FN, TIME_TYPE>::GetTotalTime() const
|
inline int32 cTaskTimer<TIME_FN, TIME_TYPE>::GetTotalTime() const
|
||||||
{
|
{
|
||||||
return mTotalTime;
|
return mTotalTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class TIME_FN, class TIME_TYPE>
|
template<class TIME_FN, class TIME_TYPE>
|
||||||
inline const std::string& cTaskTimer<TIME_FN, TIME_TYPE>::GetName() const
|
inline const std::string& cTaskTimer<TIME_FN, TIME_TYPE>::GetName() const
|
||||||
{
|
{
|
||||||
return mName
|
return mName
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class TIME_FN, class TIME_TYPE>
|
template<class TIME_FN, class TIME_TYPE>
|
||||||
inline cTaskTimer<TIME_FN, TIME_TYPE>::~cTaskTimer()
|
inline cTaskTimer<TIME_FN, TIME_TYPE>::~cTaskTimer()
|
||||||
{
|
{
|
||||||
// stop the timer if it is currently running
|
// stop the timer if it is currently running
|
||||||
if(IsRunning())
|
if(IsRunning())
|
||||||
Stop();
|
Stop();
|
||||||
|
|
||||||
// trace out the time contents...
|
// trace out the time contents...
|
||||||
cDebug d("cTaskTimer");
|
cDebug d("cTaskTimer");
|
||||||
d.TraceDebug("----- Time to execute %s: %d (started %d times)\n", mName.c_str(), mTotalTime, mNumStarts);
|
d.TraceDebug("----- Time to execute %s: %d (started %d times)\n", mName.c_str(), mTotalTime, mNumStarts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -114,12 +114,12 @@ typedef std::ifstream TIFSTREAM;
|
||||||
#define _tcsncmp strncmp
|
#define _tcsncmp strncmp
|
||||||
|
|
||||||
// other abstractions
|
// other abstractions
|
||||||
#define TUNLINK unlink
|
#define TUNLINK unlink
|
||||||
|
|
||||||
// string representation
|
// string representation
|
||||||
#if defined(_T)
|
#if defined(_T)
|
||||||
// run it right over with a bulldozer, tripwire doesn't seem
|
// run it right over with a bulldozer, tripwire doesn't seem
|
||||||
// to use ctype.h's _T -PH
|
// to use ctype.h's _T -PH
|
||||||
#undef _T
|
#undef _T
|
||||||
#endif
|
#endif
|
||||||
#define _T(x) x
|
#define _T(x) x
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
//
|
//
|
||||||
bool TimeBombExploded()
|
bool TimeBombExploded()
|
||||||
{
|
{
|
||||||
struct tm time_struct;
|
struct tm time_struct;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
memset(&time_struct, 0, sizeof(time_struct));
|
memset(&time_struct, 0, sizeof(time_struct));
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
// METHOD CODE
|
// METHOD CODE
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
|
|
||||||
#define TIME_MAX 2147483647L // largest signed 32 bit number
|
#define TIME_MAX 2147483647L // largest signed 32 bit number
|
||||||
|
|
||||||
#ifdef __AROS__
|
#ifdef __AROS__
|
||||||
#define tzset()
|
#define tzset()
|
||||||
|
|
|
@ -44,36 +44,36 @@ static void tw_psignal( int sig, const TCHAR* s );
|
||||||
|
|
||||||
tw_sighandler_t tw_signal(int sig, tw_sighandler_t pFunc)
|
tw_sighandler_t tw_signal(int sig, tw_sighandler_t pFunc)
|
||||||
{
|
{
|
||||||
return signal(sig, pFunc);
|
return signal(sig, pFunc);
|
||||||
}
|
}
|
||||||
|
|
||||||
int tw_raise(int sig)
|
int tw_raise(int sig)
|
||||||
{
|
{
|
||||||
return raise(sig);
|
return raise(sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
tw_sighandler_t tw_sigign(int sig)
|
tw_sighandler_t tw_sigign(int sig)
|
||||||
{
|
{
|
||||||
return signal(sig, SIG_IGN);
|
return signal(sig, SIG_IGN);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// tw_HandleSignal -- Take a given signal and install a handler for
|
// tw_HandleSignal -- Take a given signal and install a handler for
|
||||||
// it, which will then exit with the supplied exit value
|
// it, which will then exit with the supplied exit value
|
||||||
tw_sighandler_t tw_HandleSignal( int sig )
|
tw_sighandler_t tw_HandleSignal( int sig )
|
||||||
{
|
{
|
||||||
return signal( sig, util_SignalHandler );
|
return signal( sig, util_SignalHandler );
|
||||||
}
|
}
|
||||||
|
|
||||||
void util_SignalHandler( int sig )
|
void util_SignalHandler( int sig )
|
||||||
{
|
{
|
||||||
//If we're on unix, let's print out a nice error message telling
|
//If we're on unix, let's print out a nice error message telling
|
||||||
//the user which signal we've recieved.
|
//the user which signal we've recieved.
|
||||||
#if IS_UNIX
|
#if IS_UNIX
|
||||||
tw_psignal( sig, (TSS_GetString( cCore, core::STR_SIGNAL).c_str() ) );
|
tw_psignal( sig, (TSS_GetString( cCore, core::STR_SIGNAL).c_str() ) );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
exit( 8 );
|
exit( 8 );
|
||||||
}
|
}
|
||||||
|
|
||||||
#if IS_UNIX
|
#if IS_UNIX
|
||||||
|
@ -108,7 +108,7 @@ void tw_psignal(int sig, const TCHAR *str)
|
||||||
_T("Virtual Timer Expired"),
|
_T("Virtual Timer Expired"),
|
||||||
_T("Profiling Timer Expired"),
|
_T("Profiling Timer Expired"),
|
||||||
_T("Pollable Event"),
|
_T("Pollable Event"),
|
||||||
_T("Window Size Change"),
|
_T("Window Size Change"),
|
||||||
_T("Stopped (signal)"),
|
_T("Stopped (signal)"),
|
||||||
_T("Stopped (user)"),
|
_T("Stopped (user)"),
|
||||||
_T("Continued"),
|
_T("Continued"),
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
//
|
//
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// tw_signal.h -- a wrapper around signal(), needed because of linux
|
// tw_signal.h -- a wrapper around signal(), needed because of linux
|
||||||
// build issues
|
// build issues
|
||||||
//
|
//
|
||||||
#ifndef __TW_SIGNAL_H
|
#ifndef __TW_SIGNAL_H
|
||||||
#define __TW_SIGNAL_H
|
#define __TW_SIGNAL_H
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
#ifdef HAVE_SIGNUM_H
|
#ifdef HAVE_SIGNUM_H
|
||||||
#include <signum.h> // the signal number constants
|
#include <signum.h> // the signal number constants
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_BITS_SIGNUM_H
|
#ifdef HAVE_BITS_SIGNUM_H
|
||||||
#include <bits/signum.h>
|
#include <bits/signum.h>
|
||||||
|
@ -50,7 +50,7 @@ typedef void (*tw_sighandler_t)(int);
|
||||||
}
|
}
|
||||||
|
|
||||||
tw_sighandler_t tw_signal(int sig, tw_sighandler_t pFunc);
|
tw_sighandler_t tw_signal(int sig, tw_sighandler_t pFunc);
|
||||||
int tw_raise (int sig);
|
int tw_raise (int sig);
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// tw_sigign -- wrapper around tw_signal(XXX, SIG_IGN)
|
// tw_sigign -- wrapper around tw_signal(XXX, SIG_IGN)
|
||||||
|
|
|
@ -255,8 +255,8 @@ TSTRING& cTWLocale::FormatTime( int64 t, TSTRING& strBuf )
|
||||||
{
|
{
|
||||||
util_FormatTime( ptm, strBuf );
|
util_FormatTime( ptm, strBuf );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
strBuf = TSS_GetString( cCore, core::STR_UNKNOWN_TIME );
|
strBuf = TSS_GetString( cCore, core::STR_UNKNOWN_TIME );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,7 +311,7 @@ TSTRING& util_FormatTimeC( struct tm* ptm, TSTRING& strBuf )
|
||||||
|
|
||||||
TCHAR achTimeBuf[256];
|
TCHAR achTimeBuf[256];
|
||||||
|
|
||||||
/* XXX: This should check (#ifdef) for strftime - PH */
|
/* XXX: This should check (#ifdef) for strftime - PH */
|
||||||
size_t nbWritten = _tcsftime( achTimeBuf, countof( achTimeBuf ),
|
size_t nbWritten = _tcsftime( achTimeBuf, countof( achTimeBuf ),
|
||||||
|
|
||||||
#if IS_MSVC // MSVC uses proprietary '#'
|
#if IS_MSVC // MSVC uses proprietary '#'
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
|
|
||||||
enum Languages
|
enum Languages
|
||||||
{
|
{
|
||||||
LANG_USENGLISH = 1
|
LANG_USENGLISH = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -44,23 +44,23 @@
|
||||||
class cType
|
class cType
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cType(const TCHAR* name);
|
cType(const TCHAR* name);
|
||||||
|
|
||||||
const TCHAR* AsString() const;
|
const TCHAR* AsString() const;
|
||||||
bool operator==(const cType& rhs) const;
|
bool operator==(const cType& rhs) const;
|
||||||
bool operator!=(const cType& rhs) const;
|
bool operator!=(const cType& rhs) const;
|
||||||
private:
|
private:
|
||||||
TSTRING mString;
|
TSTRING mString;
|
||||||
};
|
};
|
||||||
|
|
||||||
class iTyped
|
class iTyped
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual const cType& GetType() const = 0;
|
virtual const cType& GetType() const = 0;
|
||||||
// the type of an FCO; classes that implement this interface need to
|
// the type of an FCO; classes that implement this interface need to
|
||||||
// (a) declare a public static const cType member mType and
|
// (a) declare a public static const cType member mType and
|
||||||
// (b) returning that object in their implementation of GetType()
|
// (b) returning that object in their implementation of GetType()
|
||||||
// You can use the macros below to simplify the process
|
// You can use the macros below to simplify the process
|
||||||
|
|
||||||
virtual ~iTyped() {}
|
virtual ~iTyped() {}
|
||||||
};
|
};
|
||||||
|
@ -72,70 +72,70 @@ public:
|
||||||
public:\
|
public:\
|
||||||
static const cType mType;\
|
static const cType mType;\
|
||||||
virtual const cType& GetType() const;
|
virtual const cType& GetType() const;
|
||||||
// put DECLARE_TYPED in the class definition
|
// put DECLARE_TYPED in the class definition
|
||||||
|
|
||||||
#define IMPLEMENT_TYPED(CLASS, STRING)\
|
#define IMPLEMENT_TYPED(CLASS, STRING)\
|
||||||
const cType CLASS::mType(STRING);\
|
const cType CLASS::mType(STRING);\
|
||||||
const cType& CLASS::GetType() const\
|
const cType& CLASS::GetType() const\
|
||||||
{\
|
{\
|
||||||
return mType;\
|
return mType;\
|
||||||
}
|
}
|
||||||
// put IMPLEMENT_TYPED in the .cpp file where the class is implemented
|
// put IMPLEMENT_TYPED in the .cpp file where the class is implemented
|
||||||
|
|
||||||
#define CLASS_TYPE(CLASS) CLASS::mType
|
#define CLASS_TYPE(CLASS) CLASS::mType
|
||||||
// a convienent way to specify a class's type
|
// a convienent way to specify a class's type
|
||||||
|
|
||||||
///////////////////////////////////////////////
|
///////////////////////////////////////////////
|
||||||
// iTyped Example
|
// iTyped Example
|
||||||
///////////////////////////////////////////////
|
///////////////////////////////////////////////
|
||||||
/*
|
/*
|
||||||
(foo.h)
|
(foo.h)
|
||||||
class cFoo : public iTyped
|
class cFoo : public iTyped
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DECLARE_TYPED()
|
DECLARE_TYPED()
|
||||||
}
|
}
|
||||||
|
|
||||||
(foo.cpp)
|
(foo.cpp)
|
||||||
DECLARE_TYPED(cFoo, "Foo");
|
DECLARE_TYPED(cFoo, "Foo");
|
||||||
|
|
||||||
(main.cpp)
|
(main.cpp)
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
iTyped* pi = Bar(); // returned a cFoo
|
iTyped* pi = Bar(); // returned a cFoo
|
||||||
cout << "Encountered class " << pi->GetType().AsString() << endl;
|
cout << "Encountered class " << pi->GetType().AsString() << endl;
|
||||||
// prints "Encountered class Foo"
|
// prints "Encountered class Foo"
|
||||||
if(pi->GetType() == CLASS_TYPE(cFoo))
|
if(pi->GetType() == CLASS_TYPE(cFoo))
|
||||||
{
|
{
|
||||||
cFoo* pFoo = static_cast<cFoo*>(pi);
|
cFoo* pFoo = static_cast<cFoo*>(pi);
|
||||||
// cast is always safe
|
// cast is always safe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// inline implementation
|
// inline implementation
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
inline cType::cType(const TCHAR* name) :
|
inline cType::cType(const TCHAR* name) :
|
||||||
mString(name)
|
mString(name)
|
||||||
{
|
{
|
||||||
ASSERT(!mString.empty());
|
ASSERT(!mString.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline const TCHAR* cType::AsString() const
|
inline const TCHAR* cType::AsString() const
|
||||||
{
|
{
|
||||||
return mString.c_str();
|
return mString.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool cType::operator==(const cType& rhs) const
|
inline bool cType::operator==(const cType& rhs) const
|
||||||
{
|
{
|
||||||
return (this == &rhs);
|
return (this == &rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool cType::operator!=(const cType& rhs) const
|
inline bool cType::operator!=(const cType& rhs) const
|
||||||
{
|
{
|
||||||
return (this != &rhs);
|
return (this != &rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -40,38 +40,38 @@
|
||||||
// standard TSS types
|
// standard TSS types
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
typedef unsigned char byte ; // platform-independent
|
typedef unsigned char byte ; // platform-independent
|
||||||
|
|
||||||
typedef signed char int8 ;
|
typedef signed char int8 ;
|
||||||
typedef short int16 ;
|
typedef short int16 ;
|
||||||
typedef float float32 ;
|
typedef float float32 ;
|
||||||
typedef double float64 ;
|
typedef double float64 ;
|
||||||
typedef unsigned char uint8 ;
|
typedef unsigned char uint8 ;
|
||||||
typedef unsigned short uint16 ;
|
typedef unsigned short uint16 ;
|
||||||
|
|
||||||
#if SIZEOF_INT == 4
|
#if SIZEOF_INT == 4
|
||||||
typedef int int32 ;
|
typedef int int32 ;
|
||||||
typedef unsigned int uint32 ;
|
typedef unsigned int uint32 ;
|
||||||
#elif SIZEOF_LONG == 4
|
#elif SIZEOF_LONG == 4
|
||||||
typedef long int32 ;
|
typedef long int32 ;
|
||||||
typedef unsigned long uint32 ;
|
typedef unsigned long uint32 ;
|
||||||
#else
|
#else
|
||||||
# error "I don't seem to have a 32-bit integer type on this system."
|
# error "I don't seem to have a 32-bit integer type on this system."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SIZEOF_LONG == 8
|
#if SIZEOF_LONG == 8
|
||||||
typedef long int64 ;
|
typedef long int64 ;
|
||||||
typedef unsigned long uint64 ;
|
typedef unsigned long uint64 ;
|
||||||
#elif SIZEOF_LONG_LONG == 8
|
#elif SIZEOF_LONG_LONG == 8
|
||||||
typedef long long int64 ;
|
typedef long long int64 ;
|
||||||
typedef unsigned long long uint64 ;
|
typedef unsigned long long uint64 ;
|
||||||
#else
|
#else
|
||||||
# error "I don't seem to have a 64-bit integer type on this system."
|
# error "I don't seem to have a 64-bit integer type on this system."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// other Win32 definitions
|
// other Win32 definitions
|
||||||
//typedef uint16 UINT;
|
//typedef uint16 UINT;
|
||||||
//typedef uint32 DWORD;
|
//typedef uint32 DWORD;
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Limits -- should be platform independent, right? ( assumes 2's complement numbers )
|
// Limits -- should be platform independent, right? ( assumes 2's complement numbers )
|
||||||
|
|
|
@ -39,45 +39,45 @@
|
||||||
|
|
||||||
// TODO: JEB: make this look like eFileError
|
// TODO: JEB: make this look like eFileError
|
||||||
eUnix::eUnix( const TCHAR* szFunctionName, const TCHAR* szObjectName, bool fCallGetLastError)
|
eUnix::eUnix( const TCHAR* szFunctionName, const TCHAR* szObjectName, bool fCallGetLastError)
|
||||||
: eError( _T(""))
|
: eError( _T(""))
|
||||||
{
|
{
|
||||||
#if IS_UNIX
|
#if IS_UNIX
|
||||||
ASSERT( szFunctionName || szObjectName || fCallGetLastError );
|
ASSERT( szFunctionName || szObjectName || fCallGetLastError );
|
||||||
//
|
//
|
||||||
// construct the error message:
|
// construct the error message:
|
||||||
//
|
//
|
||||||
// it will be of the form: FuncName() failed for Object: <FormatMessage output>
|
// it will be of the form: FuncName() failed for Object: <FormatMessage output>
|
||||||
//
|
//
|
||||||
if( szFunctionName )
|
if( szFunctionName )
|
||||||
{
|
{
|
||||||
mMsg = szFunctionName;
|
mMsg = szFunctionName;
|
||||||
mMsg += _T(" failed");
|
mMsg += _T(" failed");
|
||||||
|
|
||||||
if( szObjectName )
|
if( szObjectName )
|
||||||
{
|
{
|
||||||
mMsg += _T(" for ");
|
mMsg += _T(" for ");
|
||||||
mMsg += szObjectName;
|
mMsg += szObjectName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( szObjectName )
|
else if( szObjectName )
|
||||||
{
|
{
|
||||||
mMsg = szObjectName;
|
mMsg = szObjectName;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mMsg = _T("Error");
|
mMsg = _T("Error");
|
||||||
}
|
}
|
||||||
|
|
||||||
if( fCallGetLastError )
|
if( fCallGetLastError )
|
||||||
{
|
{
|
||||||
TSTRING strErr = strerror(errno);
|
TSTRING strErr = strerror(errno);
|
||||||
|
|
||||||
if( ! strErr.empty() )
|
if( ! strErr.empty() )
|
||||||
{
|
{
|
||||||
mMsg += _T(": ");
|
mMsg += _T(": ");
|
||||||
mMsg += strErr;
|
mMsg += strErr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // IS_UNIX
|
#endif // IS_UNIX
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,11 +43,11 @@
|
||||||
|
|
||||||
TSS_BEGIN_EXCEPTION( eUnix, eError )
|
TSS_BEGIN_EXCEPTION( eUnix, eError )
|
||||||
|
|
||||||
eUnix( const TCHAR* functionName, const TCHAR* objectName, bool displayErrorNumber = true );
|
eUnix( const TCHAR* functionName, const TCHAR* objectName, bool displayErrorNumber = true );
|
||||||
// construct one of these to indicate a unix api failure. both functionName and
|
// construct one of these to indicate a unix api failure. both functionName and
|
||||||
// objectName can be NULL. This method will construct a string to pass to eError
|
// objectName can be NULL. This method will construct a string to pass to eError
|
||||||
// that contains all of the above information plus whatever errno returns if the dusplayErrorNumber
|
// that contains all of the above information plus whatever errno returns if the dusplayErrorNumber
|
||||||
// parameter is true.
|
// parameter is true.
|
||||||
|
|
||||||
|
|
||||||
TSS_END_EXCEPTION()
|
TSS_END_EXCEPTION()
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
//////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////
|
||||||
// unixfsservices.cpp
|
// unixfsservices.cpp
|
||||||
//
|
//
|
||||||
// Implements cUnixFSServices class in unixfsservices.h
|
// Implements cUnixFSServices class in unixfsservices.h
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "core/stdcore.h"
|
#include "core/stdcore.h"
|
||||||
|
@ -143,18 +143,18 @@ cUnixFSServices::~cUnixFSServices()
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// GetErrString
|
// GetErrString
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
TSTRING cUnixFSServices::GetErrString() const
|
TSTRING cUnixFSServices::GetErrString() const
|
||||||
{
|
{
|
||||||
TSTRING ret;
|
TSTRING ret;
|
||||||
char* pErrorStr = strerror(errno);
|
char* pErrorStr = strerror(errno);
|
||||||
#ifdef _UNICODE
|
#ifdef _UNICODE
|
||||||
wchar_t pBuf[1024];
|
wchar_t pBuf[1024];
|
||||||
mbstowcs(pBuf, pErrorStr, 1024);
|
mbstowcs(pBuf, pErrorStr, 1024);
|
||||||
ret = pBuf;
|
ret = pBuf;
|
||||||
#else
|
#else
|
||||||
ret = pErrorStr;
|
ret = pErrorStr;
|
||||||
#endif
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -186,71 +186,71 @@ void cUnixFSServices::ReadDir(const TSTRING& strFilename, std::vector<TSTRING> &
|
||||||
#else
|
#else
|
||||||
void cUnixFSServices::ReadDir(const TSTRING& strFilenameC, std::vector<TSTRING>& v, bool bFullPaths) const throw(eFSServices)
|
void cUnixFSServices::ReadDir(const TSTRING& strFilenameC, std::vector<TSTRING>& v, bool bFullPaths) const throw(eFSServices)
|
||||||
{
|
{
|
||||||
TSTRING strFilename = cArosPath::AsNative(strFilenameC);
|
TSTRING strFilename = cArosPath::AsNative(strFilenameC);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//Get all the filenames
|
//Get all the filenames
|
||||||
DIR* dp;
|
DIR* dp;
|
||||||
dp = opendir( strFilename.c_str() );
|
dp = opendir( strFilename.c_str() );
|
||||||
|
|
||||||
if (dp == NULL)
|
if (dp == NULL)
|
||||||
{
|
{
|
||||||
throw eFSServicesGeneric( strFilename, iFSServices::GetInstance()->GetErrString() );
|
throw eFSServicesGeneric( strFilename, iFSServices::GetInstance()->GetErrString() );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dirent* d;
|
struct dirent* d;
|
||||||
|
|
||||||
while ((d = readdir(dp)) != NULL)
|
while ((d = readdir(dp)) != NULL)
|
||||||
{
|
{
|
||||||
if ((strcmp(d->d_name, _T(".")) != 0) && (strcmp(d->d_name, _T("..")) != 0))
|
if ((strcmp(d->d_name, _T(".")) != 0) && (strcmp(d->d_name, _T("..")) != 0))
|
||||||
{
|
{
|
||||||
if( bFullPaths )
|
if( bFullPaths )
|
||||||
{
|
{
|
||||||
//Create the full pathname
|
//Create the full pathname
|
||||||
TSTRING strNewName = strFilename;
|
TSTRING strNewName = strFilename;
|
||||||
|
|
||||||
// get full path of dir entry
|
// get full path of dir entry
|
||||||
util_TrailingSep( strNewName, true );
|
util_TrailingSep( strNewName, true );
|
||||||
strNewName += d->d_name;
|
strNewName += d->d_name;
|
||||||
|
|
||||||
// save full path name
|
// save full path name
|
||||||
v.push_back( strNewName );
|
v.push_back( strNewName );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
v.push_back( d->d_name );
|
v.push_back( d->d_name );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Close the directory
|
//Close the directory
|
||||||
closedir( dp );
|
closedir( dp );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* needs to and with S_IFMT, check EQUALITY with S_*, and return more types
|
/* needs to and with S_IFMT, check EQUALITY with S_*, and return more types
|
||||||
cFSStatArgs::FileType cUnixFSServices::GetFileType(const cFCOName &filename) throw(eFSServices)
|
cFSStatArgs::FileType cUnixFSServices::GetFileType(const cFCOName &filename) throw(eFSServices)
|
||||||
{
|
{
|
||||||
cFSStatArgs stat;
|
cFSStatArgs stat;
|
||||||
Stat(filename, stat);
|
Stat(filename, stat);
|
||||||
return stat.mFileType;
|
return stat.mFileType;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void cUnixFSServices::GetCurrentDir( TSTRING& strCurDir ) const throw(eFSServices)
|
void cUnixFSServices::GetCurrentDir( TSTRING& strCurDir ) const throw(eFSServices)
|
||||||
{
|
{
|
||||||
TCHAR pathname[iFSServices::TW_MAX_PATH];
|
TCHAR pathname[iFSServices::TW_MAX_PATH];
|
||||||
pathname[0] = '\0';
|
pathname[0] = '\0';
|
||||||
TCHAR* ret = getcwd(pathname, sizeof(TCHAR)*iFSServices::TW_MAX_PATH);
|
TCHAR* ret = getcwd(pathname, sizeof(TCHAR)*iFSServices::TW_MAX_PATH);
|
||||||
|
|
||||||
if (ret == NULL)
|
if (ret == NULL)
|
||||||
throw eFSServicesGeneric( strCurDir, iFSServices::GetInstance()->GetErrString() );
|
throw eFSServicesGeneric( strCurDir, iFSServices::GetInstance()->GetErrString() );
|
||||||
|
|
||||||
strCurDir = pathname;
|
strCurDir = pathname;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cUnixFSServices::ChangeDir( const TSTRING& strDir ) const throw(eFSServices)
|
void cUnixFSServices::ChangeDir( const TSTRING& strDir ) const throw(eFSServices)
|
||||||
{
|
{
|
||||||
if( chdir( strDir.c_str() ) < 0 )
|
if( chdir( strDir.c_str() ) < 0 )
|
||||||
throw eFSServicesGeneric( strDir, iFSServices::GetInstance()->GetErrString() );
|
throw eFSServicesGeneric( strDir, iFSServices::GetInstance()->GetErrString() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -303,25 +303,25 @@ TSTRING& cUnixFSServices::MakeTempFilename( TSTRING& strName ) const throw(eFSSe
|
||||||
// So I'll always attempt to delete it -bam
|
// So I'll always attempt to delete it -bam
|
||||||
FileDelete( strName );
|
FileDelete( strName );
|
||||||
|
|
||||||
return( strName );
|
return( strName );
|
||||||
}
|
}
|
||||||
|
|
||||||
void cUnixFSServices::Mkdir( const TSTRING& strName ) const throw ( eFSServices )
|
void cUnixFSServices::Mkdir( const TSTRING& strName ) const throw ( eFSServices )
|
||||||
{
|
{
|
||||||
if( 0 != _tmkdir( strName.c_str(), 0777 ) )
|
if( 0 != _tmkdir( strName.c_str(), 0777 ) )
|
||||||
{
|
{
|
||||||
// if mkdir failed because the dir existed, that's OK
|
// if mkdir failed because the dir existed, that's OK
|
||||||
if( errno != EEXIST )
|
if( errno != EEXIST )
|
||||||
throw eFSServicesGeneric( strName, iFSServices::GetInstance()->GetErrString() );
|
throw eFSServicesGeneric( strName, iFSServices::GetInstance()->GetErrString() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cUnixFSServices::Rmdir( const TSTRING& strName ) const
|
bool cUnixFSServices::Rmdir( const TSTRING& strName ) const
|
||||||
{
|
{
|
||||||
if( 0 == rmdir( strName.c_str() ) )
|
if( 0 == rmdir( strName.c_str() ) )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cUnixFSServices::GetTempDirName( TSTRING& strName ) const throw(eFSServices)
|
void cUnixFSServices::GetTempDirName( TSTRING& strName ) const throw(eFSServices)
|
||||||
|
@ -341,19 +341,19 @@ void cUnixFSServices::Stat( const TSTRING& strName, cFSStatArgs &stat ) const th
|
||||||
#else
|
#else
|
||||||
void cUnixFSServices::Stat( const TSTRING& strNameC, cFSStatArgs& stat) const throw(eFSServices)
|
void cUnixFSServices::Stat( const TSTRING& strNameC, cFSStatArgs& stat) const throw(eFSServices)
|
||||||
{
|
{
|
||||||
TSTRING strName = cArosPath::AsNative(strNameC);
|
TSTRING strName = cArosPath::AsNative(strNameC);
|
||||||
#endif
|
#endif
|
||||||
//local variable for obtaining info on file.
|
//local variable for obtaining info on file.
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
ret = lstat( strName.c_str(), &statbuf );
|
ret = lstat( strName.c_str(), &statbuf );
|
||||||
|
|
||||||
cDebug d( "cUnixFSServices::Stat" );
|
cDebug d( "cUnixFSServices::Stat" );
|
||||||
d.TraceDetail( "Executing on file %s (result=%d)\n", strName.c_str(), ret );
|
d.TraceDetail( "Executing on file %s (result=%d)\n", strName.c_str(), ret );
|
||||||
|
|
||||||
if( ret < 0 )
|
if( ret < 0 )
|
||||||
throw eFSServicesGeneric( strName, iFSServices::GetInstance()->GetErrString() );
|
throw eFSServicesGeneric( strName, iFSServices::GetInstance()->GetErrString() );
|
||||||
|
|
||||||
// new stuff 7/17/99 - BAM
|
// new stuff 7/17/99 - BAM
|
||||||
// if the file is not a device set rdev to zero by hand (most OSs will
|
// if the file is not a device set rdev to zero by hand (most OSs will
|
||||||
|
@ -365,46 +365,46 @@ void cUnixFSServices::Stat( const TSTRING& strNameC, cFSStatArgs& stat) const th
|
||||||
util_ZeroMemory( statbuf.st_rdev );
|
util_ZeroMemory( statbuf.st_rdev );
|
||||||
}
|
}
|
||||||
|
|
||||||
//copy information returned by lstat call into the structure passed in
|
//copy information returned by lstat call into the structure passed in
|
||||||
stat.gid = statbuf.st_gid;
|
stat.gid = statbuf.st_gid;
|
||||||
stat.atime = statbuf.st_atime;
|
stat.atime = statbuf.st_atime;
|
||||||
stat.ctime = statbuf.st_ctime;
|
stat.ctime = statbuf.st_ctime;
|
||||||
stat.mtime = statbuf.st_mtime;
|
stat.mtime = statbuf.st_mtime;
|
||||||
stat.dev = statbuf.st_dev;
|
stat.dev = statbuf.st_dev;
|
||||||
stat.rdev = statbuf.st_rdev;
|
stat.rdev = statbuf.st_rdev;
|
||||||
stat.ino = statbuf.st_ino;
|
stat.ino = statbuf.st_ino;
|
||||||
stat.mode = statbuf.st_mode;
|
stat.mode = statbuf.st_mode;
|
||||||
stat.nlink = statbuf.st_nlink;
|
stat.nlink = statbuf.st_nlink;
|
||||||
stat.size = statbuf.st_size;
|
stat.size = statbuf.st_size;
|
||||||
stat.uid = statbuf.st_uid;
|
stat.uid = statbuf.st_uid;
|
||||||
stat.blksize = statbuf.st_blksize;
|
stat.blksize = statbuf.st_blksize;
|
||||||
stat.blocks = statbuf.st_blocks;
|
stat.blocks = statbuf.st_blocks;
|
||||||
|
|
||||||
// set the file type
|
// set the file type
|
||||||
if(S_ISREG(statbuf.st_mode)) stat.mFileType = cFSStatArgs::TY_FILE;
|
if(S_ISREG(statbuf.st_mode)) stat.mFileType = cFSStatArgs::TY_FILE;
|
||||||
else if(S_ISDIR(statbuf.st_mode)) stat.mFileType = cFSStatArgs::TY_DIR;
|
else if(S_ISDIR(statbuf.st_mode)) stat.mFileType = cFSStatArgs::TY_DIR;
|
||||||
else if(S_ISLNK(statbuf.st_mode)) stat.mFileType = cFSStatArgs::TY_SYMLINK;
|
else if(S_ISLNK(statbuf.st_mode)) stat.mFileType = cFSStatArgs::TY_SYMLINK;
|
||||||
else if(S_ISBLK(statbuf.st_mode)) stat.mFileType = cFSStatArgs::TY_BLOCKDEV;
|
else if(S_ISBLK(statbuf.st_mode)) stat.mFileType = cFSStatArgs::TY_BLOCKDEV;
|
||||||
else if(S_ISCHR(statbuf.st_mode)) stat.mFileType = cFSStatArgs::TY_CHARDEV;
|
else if(S_ISCHR(statbuf.st_mode)) stat.mFileType = cFSStatArgs::TY_CHARDEV;
|
||||||
else if(S_ISFIFO(statbuf.st_mode)) stat.mFileType = cFSStatArgs::TY_FIFO;
|
else if(S_ISFIFO(statbuf.st_mode)) stat.mFileType = cFSStatArgs::TY_FIFO;
|
||||||
else if(S_ISSOCK(statbuf.st_mode)) stat.mFileType = cFSStatArgs::TY_SOCK;
|
else if(S_ISSOCK(statbuf.st_mode)) stat.mFileType = cFSStatArgs::TY_SOCK;
|
||||||
#ifdef S_IFDOOR
|
#ifdef S_IFDOOR
|
||||||
else if(S_ISDOOR(statbuf.st_mode)) stat.mFileType = cFSStatArgs::TY_DOOR;
|
else if(S_ISDOOR(statbuf.st_mode)) stat.mFileType = cFSStatArgs::TY_DOOR;
|
||||||
#endif
|
#endif
|
||||||
#ifdef S_IFPORT
|
#ifdef S_IFPORT
|
||||||
else if(S_ISPORT(statbuf.st_mode)) stat.mFileType = cFSStatArgs::TY_PORT;
|
else if(S_ISPORT(statbuf.st_mode)) stat.mFileType = cFSStatArgs::TY_PORT;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
else stat.mFileType = cFSStatArgs::TY_INVALID;
|
else stat.mFileType = cFSStatArgs::TY_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cUnixFSServices::GetMachineName( TSTRING& strName ) const throw( eFSServices )
|
void cUnixFSServices::GetMachineName( TSTRING& strName ) const throw( eFSServices )
|
||||||
{
|
{
|
||||||
struct utsname namebuf;
|
struct utsname namebuf;
|
||||||
if( uname( &namebuf ) == -1 )
|
if( uname( &namebuf ) == -1 )
|
||||||
throw eFSServicesGeneric( strName );
|
throw eFSServicesGeneric( strName );
|
||||||
else
|
else
|
||||||
strName = namebuf.nodename;
|
strName = namebuf.nodename;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cUnixFSServices::GetMachineNameFullyQualified( TSTRING& strName ) const
|
void cUnixFSServices::GetMachineNameFullyQualified( TSTRING& strName ) const
|
||||||
|
@ -455,7 +455,7 @@ bool cUnixFSServices::GetCurrentUserName( TSTRING& strName ) const
|
||||||
fSuccess = true;
|
fSuccess = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
strName = _T("");
|
strName = _T("");
|
||||||
|
|
||||||
return( fSuccess );
|
return( fSuccess );
|
||||||
}
|
}
|
||||||
|
@ -506,17 +506,17 @@ bool cUnixFSServices::GetIPAddress( uint32& uiIPAddress )
|
||||||
|
|
||||||
bool cUnixFSServices::IsCaseSensitive() const
|
bool cUnixFSServices::IsCaseSensitive() const
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool cUnixFSServices::GetOwnerForFile( const TSTRING& tstrFilename, TSTRING& tstrUser ) const
|
bool cUnixFSServices::GetOwnerForFile( const TSTRING& tstrFilename, TSTRING& tstrUser ) const
|
||||||
{
|
{
|
||||||
bool fSuccess = true;
|
bool fSuccess = true;
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
|
|
||||||
int ret = lstat(tstrFilename.c_str(), &statbuf);
|
int ret = lstat(tstrFilename.c_str(), &statbuf);
|
||||||
if(ret < 0)
|
if(ret < 0)
|
||||||
{
|
{
|
||||||
fSuccess = false;
|
fSuccess = false;
|
||||||
}
|
}
|
||||||
|
@ -525,11 +525,11 @@ bool cUnixFSServices::GetOwnerForFile( const TSTRING& tstrFilename, TSTRING& tst
|
||||||
{
|
{
|
||||||
struct passwd* pp = getpwuid( statbuf.st_uid );
|
struct passwd* pp = getpwuid( statbuf.st_uid );
|
||||||
//ASSERT( pp );
|
//ASSERT( pp );
|
||||||
// We shouldn't assert this, because it might be the case that a file
|
// We shouldn't assert this, because it might be the case that a file
|
||||||
// is associated with some old user that no longer exists... we should
|
// is associated with some old user that no longer exists... we should
|
||||||
// not fail this case. Instead, the method will just return false per
|
// not fail this case. Instead, the method will just return false per
|
||||||
// the test below.
|
// the test below.
|
||||||
if( pp == NULL )
|
if( pp == NULL )
|
||||||
{
|
{
|
||||||
fSuccess = false;
|
fSuccess = false;
|
||||||
}
|
}
|
||||||
|
@ -545,10 +545,10 @@ bool cUnixFSServices::GetOwnerForFile( const TSTRING& tstrFilename, TSTRING& tst
|
||||||
bool cUnixFSServices::GetGroupForFile( const TSTRING& tstrFilename, TSTRING& tstrGroup ) const
|
bool cUnixFSServices::GetGroupForFile( const TSTRING& tstrFilename, TSTRING& tstrGroup ) const
|
||||||
{
|
{
|
||||||
bool fSuccess = true;
|
bool fSuccess = true;
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
|
|
||||||
int ret = lstat(tstrFilename.c_str(), &statbuf);
|
int ret = lstat(tstrFilename.c_str(), &statbuf);
|
||||||
if(ret < 0)
|
if(ret < 0)
|
||||||
{
|
{
|
||||||
fSuccess = false;
|
fSuccess = false;
|
||||||
}
|
}
|
||||||
|
@ -558,7 +558,7 @@ bool cUnixFSServices::GetGroupForFile( const TSTRING& tstrFilename, TSTRING& tst
|
||||||
struct group* pg = getgrgid( statbuf.st_gid );
|
struct group* pg = getgrgid( statbuf.st_gid );
|
||||||
//ASSERT( pg ); this assert stops everything in debug mode if we can't lookup a groupid
|
//ASSERT( pg ); this assert stops everything in debug mode if we can't lookup a groupid
|
||||||
|
|
||||||
if( pg == NULL )
|
if( pg == NULL )
|
||||||
{
|
{
|
||||||
fSuccess = false;
|
fSuccess = false;
|
||||||
tstrGroup = TSS_GetString(cCore, core::STR_UNKNOWN);
|
tstrGroup = TSS_GetString(cCore, core::STR_UNKNOWN);
|
||||||
|
@ -571,8 +571,8 @@ bool cUnixFSServices::GetGroupForFile( const TSTRING& tstrFilename, TSTRING& tst
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
// Function name : cUnixFSServices::ConvertModeToString
|
// Function name : cUnixFSServices::ConvertModeToString
|
||||||
// Description : takes a TSTRING and fills it with an "ls -l" representation
|
// Description : takes a TSTRING and fills it with an "ls -l" representation
|
||||||
// of the object's permission bits ( e.g. "drwxr-x--x" ).
|
// of the object's permission bits ( e.g. "drwxr-x--x" ).
|
||||||
//
|
//
|
||||||
// Returns : void -- no errors are reported
|
// Returns : void -- no errors are reported
|
||||||
|
@ -583,95 +583,95 @@ bool cUnixFSServices::GetGroupForFile( const TSTRING& tstrFilename, TSTRING& tst
|
||||||
void cUnixFSServices::ConvertModeToString( uint64 perm, TSTRING& tstrPerm ) const
|
void cUnixFSServices::ConvertModeToString( uint64 perm, TSTRING& tstrPerm ) const
|
||||||
{
|
{
|
||||||
TCHAR szPerm[11]; //10 permission bits plus the NULL
|
TCHAR szPerm[11]; //10 permission bits plus the NULL
|
||||||
_tcscpy( szPerm, _T("----------") );
|
_tcscpy( szPerm, _T("----------") );
|
||||||
|
|
||||||
ASSERT( sizeof(unsigned short) <= sizeof(uint32) );
|
ASSERT( sizeof(unsigned short) <= sizeof(uint32) );
|
||||||
// We do this in case an "unsigned short" is ever larger than the
|
// We do this in case an "unsigned short" is ever larger than the
|
||||||
// value we are switching on, since the size of the mode parameter
|
// value we are switching on, since the size of the mode parameter
|
||||||
// will be unsigned short (whatever that means, for the given platform...)
|
// will be unsigned short (whatever that means, for the given platform...)
|
||||||
|
|
||||||
// check file type
|
// check file type
|
||||||
switch ((uint32)perm & S_IFMT) //some versions of Unix don't like to switch on
|
switch ((uint32)perm & S_IFMT) //some versions of Unix don't like to switch on
|
||||||
//64 bit values.
|
//64 bit values.
|
||||||
{
|
{
|
||||||
case S_IFDIR:
|
case S_IFDIR:
|
||||||
szPerm[0] = _T('d');
|
szPerm[0] = _T('d');
|
||||||
break;
|
break;
|
||||||
case S_IFCHR:
|
case S_IFCHR:
|
||||||
szPerm[0] = _T('c');
|
szPerm[0] = _T('c');
|
||||||
break;
|
break;
|
||||||
case S_IFBLK:
|
case S_IFBLK:
|
||||||
szPerm[0] = _T('b');
|
szPerm[0] = _T('b');
|
||||||
break;
|
break;
|
||||||
case S_IFIFO:
|
case S_IFIFO:
|
||||||
szPerm[0] = _T('p');
|
szPerm[0] = _T('p');
|
||||||
break;
|
break;
|
||||||
case S_IFLNK:
|
case S_IFLNK:
|
||||||
szPerm[0] = _T('l');
|
szPerm[0] = _T('l');
|
||||||
break;
|
break;
|
||||||
#ifdef S_IFDOOR
|
#ifdef S_IFDOOR
|
||||||
case S_IFDOOR:
|
case S_IFDOOR:
|
||||||
szPerm[0] = _T('D');
|
szPerm[0] = _T('D');
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef S_IFPORT
|
#ifdef S_IFPORT
|
||||||
case S_IFPORT:
|
case S_IFPORT:
|
||||||
szPerm[0] = _T('P');
|
szPerm[0] = _T('P');
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check owner read and write
|
// check owner read and write
|
||||||
if (perm & S_IRUSR)
|
if (perm & S_IRUSR)
|
||||||
szPerm[1] = _T('r');
|
szPerm[1] = _T('r');
|
||||||
if (perm & S_IWUSR)
|
if (perm & S_IWUSR)
|
||||||
szPerm[2] = _T('w');
|
szPerm[2] = _T('w');
|
||||||
|
|
||||||
// check owner execute
|
// check owner execute
|
||||||
if (perm & S_ISUID && perm & S_IXUSR)
|
if (perm & S_ISUID && perm & S_IXUSR)
|
||||||
szPerm[3] = _T('s');
|
szPerm[3] = _T('s');
|
||||||
else if (perm & S_IXUSR)
|
else if (perm & S_IXUSR)
|
||||||
szPerm[3] = _T('x');
|
szPerm[3] = _T('x');
|
||||||
else if (perm & S_ISUID)
|
else if (perm & S_ISUID)
|
||||||
szPerm[3] = _T('S');
|
szPerm[3] = _T('S');
|
||||||
|
|
||||||
// check group read and write
|
// check group read and write
|
||||||
if (perm & S_IRGRP)
|
if (perm & S_IRGRP)
|
||||||
szPerm[4] = _T('r');
|
szPerm[4] = _T('r');
|
||||||
if (perm & S_IWGRP)
|
if (perm & S_IWGRP)
|
||||||
szPerm[5] = _T('w');
|
szPerm[5] = _T('w');
|
||||||
|
|
||||||
// check group execute
|
// check group execute
|
||||||
if (perm & S_ISGID && perm & S_IXGRP)
|
if (perm & S_ISGID && perm & S_IXGRP)
|
||||||
szPerm[6] = _T('s');
|
szPerm[6] = _T('s');
|
||||||
else if (perm & S_IXGRP)
|
else if (perm & S_IXGRP)
|
||||||
szPerm[6] = _T('x');
|
szPerm[6] = _T('x');
|
||||||
else if (perm & S_ISGID)
|
else if (perm & S_ISGID)
|
||||||
szPerm[6] = _T('l');
|
szPerm[6] = _T('l');
|
||||||
|
|
||||||
// check other read and write
|
// check other read and write
|
||||||
if (perm & S_IROTH)
|
if (perm & S_IROTH)
|
||||||
szPerm[7] = _T('r');
|
szPerm[7] = _T('r');
|
||||||
if (perm & S_IWOTH)
|
if (perm & S_IWOTH)
|
||||||
szPerm[8] = _T('w');
|
szPerm[8] = _T('w');
|
||||||
|
|
||||||
// check other execute
|
// check other execute
|
||||||
if (perm & S_ISVTX && perm & S_IXOTH)
|
if (perm & S_ISVTX && perm & S_IXOTH)
|
||||||
szPerm[9] = _T('t');
|
szPerm[9] = _T('t');
|
||||||
else if (perm & S_IXOTH)
|
else if (perm & S_IXOTH)
|
||||||
szPerm[9] = _T('x');
|
szPerm[9] = _T('x');
|
||||||
else if (perm & S_ISVTX)
|
else if (perm & S_ISVTX)
|
||||||
szPerm[9] = _T('T');
|
szPerm[9] = _T('T');
|
||||||
|
|
||||||
tstrPerm = szPerm;
|
tstrPerm = szPerm;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
// Function name : cUnixFSServices::Rename
|
// Function name : cUnixFSServices::Rename
|
||||||
// Description : Rename a file. Overwrites newname if it exists.and overwrite is true
|
// Description : Rename a file. Overwrites newname if it exists.and overwrite is true
|
||||||
//
|
//
|
||||||
// Returns : false if failure, true on success
|
// Returns : false if failure, true on success
|
||||||
bool cUnixFSServices::Rename(const TSTRING& strOldName, const TSTRING& strNewName, bool overwrite) const
|
bool cUnixFSServices::Rename(const TSTRING& strOldName, const TSTRING& strNewName, bool overwrite) const
|
||||||
|
@ -728,16 +728,16 @@ bool cUnixFSServices::GetExecutableFilename( TSTRING& strFullPath, const TSTRING
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// Function name : cUnixFSServices::FullPath
|
// Function name : cUnixFSServices::FullPath
|
||||||
// Description :
|
// Description :
|
||||||
//
|
//
|
||||||
// Return type : bool
|
// Return type : bool
|
||||||
// Argument : TSTRING& strFullPath
|
// Argument : TSTRING& strFullPath
|
||||||
// Argument : const TSTRING& strRelPathC
|
// Argument : const TSTRING& strRelPathC
|
||||||
// Argument : const TSTRING& pathRelFromC
|
// Argument : const TSTRING& pathRelFromC
|
||||||
//
|
//
|
||||||
// TODO -- is throwing an exception the more appropriate alternative to returning
|
// TODO -- is throwing an exception the more appropriate alternative to returning
|
||||||
// a bool? I think it is ... mdb
|
// a bool? I think it is ... mdb
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
bool cUnixFSServices::FullPath( TSTRING& strFullPath, const TSTRING& strRelPathC, const TSTRING& pathRelFromC ) const
|
bool cUnixFSServices::FullPath( TSTRING& strFullPath, const TSTRING& strRelPathC, const TSTRING& pathRelFromC ) const
|
||||||
{
|
{
|
||||||
|
@ -755,7 +755,7 @@ bool cUnixFSServices::FullPath( TSTRING& strFullPath, const TSTRING& strRelPathC
|
||||||
//
|
//
|
||||||
|
|
||||||
if( strRelPath[0] == TW_SLASH ) // if is absolute path
|
if( strRelPath[0] == TW_SLASH ) // if is absolute path
|
||||||
{
|
{
|
||||||
if( IsRoot( strRelPath ) ) // if it's root, don't monkey with it, just return it.
|
if( IsRoot( strRelPath ) ) // if it's root, don't monkey with it, just return it.
|
||||||
{
|
{
|
||||||
strFullPath = strRelPath;
|
strFullPath = strRelPath;
|
||||||
|
@ -763,26 +763,26 @@ bool cUnixFSServices::FullPath( TSTRING& strFullPath, const TSTRING& strRelPathC
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
strFullPath = _T(""); // push root, then add path elements from strRelPathC
|
strFullPath = _T(""); // push root, then add path elements from strRelPathC
|
||||||
// one by one (in while loop below)
|
// one by one (in while loop below)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // is a relative path, so check pathRelFromC
|
else // is a relative path, so check pathRelFromC
|
||||||
{
|
{
|
||||||
if( pathRelFromC.empty() ) // if we're relative to CWD...
|
if( pathRelFromC.empty() ) // if we're relative to CWD...
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// get the current working directory
|
// get the current working directory
|
||||||
//
|
//
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
GetCurrentDir( strFullPath );
|
GetCurrentDir( strFullPath );
|
||||||
util_TrailingSep( strFullPath, false );
|
util_TrailingSep( strFullPath, false );
|
||||||
}
|
}
|
||||||
catch( eFSServices& )
|
catch( eFSServices& )
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // we're relative to a given dir
|
else // we're relative to a given dir
|
||||||
{
|
{
|
||||||
|
@ -850,8 +850,8 @@ int cUnixFSServices::CreateLockedTemporaryFile( const TCHAR* szFilename, int per
|
||||||
O_CREAT | O_EXCL; // only create a new file -- error if it exists already
|
O_CREAT | O_EXCL; // only create a new file -- error if it exists already
|
||||||
|
|
||||||
// create file
|
// create file
|
||||||
int fh = _topen( szFilename, oflags, 0666 );
|
int fh = _topen( szFilename, oflags, 0666 );
|
||||||
if( fh >= 0 )
|
if( fh >= 0 )
|
||||||
{
|
{
|
||||||
// file was created. Now unlink it
|
// file was created. Now unlink it
|
||||||
if( 0 != unlink( szFilename ) )
|
if( 0 != unlink( szFilename ) )
|
||||||
|
@ -873,10 +873,10 @@ void cUnixFSServices::Sleep( int nSeconds ) const
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Function name : IsRoot
|
// Function name : IsRoot
|
||||||
// Description : A root path is all '/'s
|
// Description : A root path is all '/'s
|
||||||
//
|
//
|
||||||
// Return type : bool
|
// Return type : bool
|
||||||
// Argument : const TSTRING& strPath
|
// Argument : const TSTRING& strPath
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
bool cUnixFSServices::IsRoot( const TSTRING& strPath ) const
|
bool cUnixFSServices::IsRoot( const TSTRING& strPath ) const
|
||||||
|
@ -904,12 +904,12 @@ bool cUnixFSServices::IsRoot( const TSTRING& strPath ) const
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// Function name : util_PathFind
|
// Function name : util_PathFind
|
||||||
// Description :
|
// Description :
|
||||||
// takes single-element executible filename and looks in path env var for it
|
// takes single-element executible filename and looks in path env var for it
|
||||||
// assumes path is colon-delimited string of directories.
|
// assumes path is colon-delimited string of directories.
|
||||||
//
|
//
|
||||||
// Return type : bool
|
// Return type : bool
|
||||||
// Argument : TSTRING& strFullPath
|
// Argument : TSTRING& strFullPath
|
||||||
// Argument : const TSTRING& strFilename
|
// Argument : const TSTRING& strFilename
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -989,11 +989,11 @@ bool util_PathFind( TSTRING& strFullPath, const TSTRING& strFilename )
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// Function name : util_FileIsExecutable
|
// Function name : util_FileIsExecutable
|
||||||
// Description : file ( or file a link points to ) must be a regular
|
// Description : file ( or file a link points to ) must be a regular
|
||||||
// file and executable by someone
|
// file and executable by someone
|
||||||
//
|
//
|
||||||
// Return type : bool
|
// Return type : bool
|
||||||
// Argument : const TSTRING& strFile
|
// Argument : const TSTRING& strFile
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
bool util_FileIsExecutable( const TSTRING& strFile )
|
bool util_FileIsExecutable( const TSTRING& strFile )
|
||||||
|
@ -1002,7 +1002,7 @@ bool util_FileIsExecutable( const TSTRING& strFile )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
struct stat s;
|
struct stat s;
|
||||||
if( stat( strFile.c_str(), &s ) < 0 ) // this call handles links
|
if( stat( strFile.c_str(), &s ) < 0 ) // this call handles links
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return( S_ISREG( s.st_mode ) && ( s.st_mode & ( S_IXUSR | S_IXGRP | S_IXOTH ) ) ); // can someone execute it?
|
return( S_ISREG( s.st_mode ) && ( s.st_mode & ( S_IXUSR | S_IXGRP | S_IXOTH ) ) ); // can someone execute it?
|
||||||
|
@ -1010,13 +1010,13 @@ bool util_FileIsExecutable( const TSTRING& strFile )
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Function name : util_RemoveDuplicateSeps
|
// Function name : util_RemoveDuplicateSeps
|
||||||
// Description :
|
// Description :
|
||||||
// takes all adjacent slashes and replaces them with a single slash
|
// takes all adjacent slashes and replaces them with a single slash
|
||||||
// ///root//foo -> /root/foo
|
// ///root//foo -> /root/foo
|
||||||
// rel//foo/// -> rel/foo/
|
// rel//foo/// -> rel/foo/
|
||||||
//
|
//
|
||||||
// Return type : void
|
// Return type : void
|
||||||
// Argument : TSTRING& strPath
|
// Argument : TSTRING& strPath
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
void util_RemoveDuplicateSeps( TSTRING& strPath )
|
void util_RemoveDuplicateSeps( TSTRING& strPath )
|
||||||
|
@ -1051,15 +1051,15 @@ void util_RemoveDuplicateSeps( TSTRING& strPath )
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
// Function name : util_RemoveLastPathElement
|
// Function name : util_RemoveLastPathElement
|
||||||
// Description :
|
// Description :
|
||||||
// effectively pops off a path element from the end, except for the root dir, where it does nothing
|
// effectively pops off a path element from the end, except for the root dir, where it does nothing
|
||||||
// it removes any slashes before and after the element
|
// it removes any slashes before and after the element
|
||||||
// ///root//foo/ -> leaves "///root" ("foo" is strElem)
|
// ///root//foo/ -> leaves "///root" ("foo" is strElem)
|
||||||
// ///root -> leaves "" ("root" is strElem)
|
// ///root -> leaves "" ("root" is strElem)
|
||||||
// // -> leaves "" ("" is strElem)
|
// // -> leaves "" ("" is strElem)
|
||||||
//
|
//
|
||||||
// Return type : void
|
// Return type : void
|
||||||
// Argument : TSTRING& strPath
|
// Argument : TSTRING& strPath
|
||||||
// Argument : TSTRING& strElem
|
// Argument : TSTRING& strElem
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -1091,8 +1091,8 @@ void util_RemoveLastPathElement( TSTRING& strPath, TSTRING& strElem )
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Function name : util_GetNextPathElement
|
// Function name : util_GetNextPathElement
|
||||||
// Description :
|
// Description :
|
||||||
// starting from the left side of the path string, returns the index'th path element
|
// starting from the left side of the path string, returns the index'th path element
|
||||||
// returns true if the element exists, false if there aren't <index + 1> many elements
|
// returns true if the element exists, false if there aren't <index + 1> many elements
|
||||||
//
|
//
|
||||||
|
@ -1101,7 +1101,7 @@ void util_RemoveLastPathElement( TSTRING& strPath, TSTRING& strElem )
|
||||||
// 2rd element of ABC/DEF/GH -> GH
|
// 2rd element of ABC/DEF/GH -> GH
|
||||||
// 1st element of //ABC/DEF/GH -> DEF
|
// 1st element of //ABC/DEF/GH -> DEF
|
||||||
//
|
//
|
||||||
// Return type : bool : got path element? ( i.e. was there index path elements? )
|
// Return type : bool : got path element? ( i.e. was there index path elements? )
|
||||||
// Argument : const TSTRING& strPathC
|
// Argument : const TSTRING& strPathC
|
||||||
// Argument : TSTRING& strElem
|
// Argument : TSTRING& strElem
|
||||||
// Argument : int index
|
// Argument : int index
|
||||||
|
@ -1146,10 +1146,10 @@ bool util_GetNextPathElement( const TSTRING& strPathC, TSTRING& strElem, int ind
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
// Function name : util_TrailingSep
|
// Function name : util_TrailingSep
|
||||||
// Description : ensure that a path ( fLeaveSep ? "has" : "does not have" ) a trailing slash
|
// Description : ensure that a path ( fLeaveSep ? "has" : "does not have" ) a trailing slash
|
||||||
//
|
//
|
||||||
// Return type : bool : was there a trailing slash?
|
// Return type : bool : was there a trailing slash?
|
||||||
// Argument : TSTRING& str
|
// Argument : TSTRING& str
|
||||||
// Argument : bool fLeaveSep
|
// Argument : bool fLeaveSep
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -1179,10 +1179,10 @@ bool util_TrailingSep( TSTRING& str, bool fLeaveSep )
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
// Function name : util_RemoveTrailingSeps
|
// Function name : util_RemoveTrailingSeps
|
||||||
// Description : removes all trailing separators
|
// Description : removes all trailing separators
|
||||||
//
|
//
|
||||||
// Return type : void
|
// Return type : void
|
||||||
// Argument : TSTRING& str
|
// Argument : TSTRING& str
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
void util_RemoveTrailingSeps( TSTRING& str )
|
void util_RemoveTrailingSeps( TSTRING& str )
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
// parameters of dissimilar types. Therefore, *FwdIter need not be
|
// parameters of dissimilar types. Therefore, *FwdIter need not be
|
||||||
// the same type as CmpObjT. Uses a binary search algorithm.
|
// the same type as CmpObjT. Uses a binary search algorithm.
|
||||||
//
|
//
|
||||||
// Return type : FwdIterT : First element in the sequence [first, last)
|
// Return type : FwdIterT : First element in the sequence [first, last)
|
||||||
// that is equal to or greater than 'obj' or
|
// that is equal to or greater than 'obj' or
|
||||||
// 'last' if there is no such element.
|
// 'last' if there is no such element.
|
||||||
//
|
//
|
||||||
|
@ -60,12 +60,12 @@ template< class FwdIterT, class CmpObjT, class CmpFuncT > FwdIterT UpperBound( F
|
||||||
int nElemsInSet = 0;
|
int nElemsInSet = 0;
|
||||||
FwdIterT iCur = first;
|
FwdIterT iCur = first;
|
||||||
for (; iCur != last; ++iCur )
|
for (; iCur != last; ++iCur )
|
||||||
++nElemsInSet;
|
++nElemsInSet;
|
||||||
|
|
||||||
iCur = first;
|
iCur = first;
|
||||||
|
|
||||||
while( 0 < nElemsInSet )
|
while( 0 < nElemsInSet )
|
||||||
{
|
{
|
||||||
// go to halfway point
|
// go to halfway point
|
||||||
int iHalfWay = nElemsInSet/2;
|
int iHalfWay = nElemsInSet/2;
|
||||||
FwdIterT iTemp = iCur;
|
FwdIterT iTemp = iCur;
|
||||||
|
@ -75,15 +75,15 @@ template< class FwdIterT, class CmpObjT, class CmpFuncT > FwdIterT UpperBound( F
|
||||||
if( less( *iTemp, obj ) )
|
if( less( *iTemp, obj ) )
|
||||||
{
|
{
|
||||||
// start next search set at next elem with half of the last search set's elements
|
// start next search set at next elem with half of the last search set's elements
|
||||||
iCur = ++iTemp;
|
iCur = ++iTemp;
|
||||||
nElemsInSet -= iHalfWay + 1; // already searched ( iHalfway + 1 ) elems
|
nElemsInSet -= iHalfWay + 1; // already searched ( iHalfway + 1 ) elems
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// start next search set beginning with half of the last search set's elements
|
// start next search set beginning with half of the last search set's elements
|
||||||
nElemsInSet = iHalfWay;
|
nElemsInSet = iHalfWay;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return iCur;
|
return iCur;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
iUserNotify* iUserNotify::mpInstance = 0;
|
iUserNotify* iUserNotify::mpInstance = 0;
|
||||||
|
|
||||||
iUserNotify::iUserNotify(int verboseLevel) :
|
iUserNotify::iUserNotify(int verboseLevel) :
|
||||||
mVerboseLevel(verboseLevel)
|
mVerboseLevel(verboseLevel)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,12 +59,12 @@ iUserNotify::~iUserNotify()
|
||||||
|
|
||||||
void iUserNotify::SetVerboseLevel(int level)
|
void iUserNotify::SetVerboseLevel(int level)
|
||||||
{
|
{
|
||||||
mVerboseLevel = level;
|
mVerboseLevel = level;
|
||||||
}
|
}
|
||||||
|
|
||||||
int iUserNotify::GetVerboseLevel() const
|
int iUserNotify::GetVerboseLevel() const
|
||||||
{
|
{
|
||||||
return mVerboseLevel;
|
return mVerboseLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -74,8 +74,8 @@ void iUserNotify::NotifySilent( const TCHAR* format, ... )
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
HandleNotify( V_SILENT, format, args );
|
HandleNotify( V_SILENT, format, args );
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -85,8 +85,8 @@ void iUserNotify::NotifyNormal( const TCHAR* format, ... )
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
HandleNotify( V_NORMAL, format, args );
|
HandleNotify( V_NORMAL, format, args );
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -96,8 +96,8 @@ void iUserNotify::NotifyVerbose( const TCHAR* format, ... )
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
HandleNotify( V_VERBOSE, format, args );
|
HandleNotify( V_VERBOSE, format, args );
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -107,8 +107,8 @@ void iUserNotify::Notify(int verboseLevel, const TCHAR* format, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
HandleNotify( verboseLevel, format, args );
|
HandleNotify( verboseLevel, format, args );
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -46,48 +46,48 @@
|
||||||
class iUserNotify
|
class iUserNotify
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// singleton interface; caller is responsible for deleting pointer;
|
// singleton interface; caller is responsible for deleting pointer;
|
||||||
static iUserNotify* GetInstance();
|
static iUserNotify* GetInstance();
|
||||||
static void SetInstance(iUserNotify* pInst);
|
static void SetInstance(iUserNotify* pInst);
|
||||||
|
|
||||||
virtual void Notify(int verboseLevel, const TCHAR* format, ...) ;
|
virtual void Notify(int verboseLevel, const TCHAR* format, ...) ;
|
||||||
// notify the user that an event has occured. The outcome of this operation is
|
// notify the user that an event has occured. The outcome of this operation is
|
||||||
// dependant on the type of object that is implementing this interface (for example,
|
// dependant on the type of object that is implementing this interface (for example,
|
||||||
// a console application would want an iUserNotify that prints things to stdout)
|
// a console application would want an iUserNotify that prints things to stdout)
|
||||||
// If the current verbosity level is less than verboseLevel, nothing will happen.
|
// If the current verbosity level is less than verboseLevel, nothing will happen.
|
||||||
// All output should be sent through the cDisplayEncoder beforehand
|
// All output should be sent through the cDisplayEncoder beforehand
|
||||||
// TODO:BAM -- enforce this somehow?
|
// TODO:BAM -- enforce this somehow?
|
||||||
|
|
||||||
virtual void SetVerboseLevel(int level);
|
virtual void SetVerboseLevel(int level);
|
||||||
virtual int GetVerboseLevel() const;
|
virtual int GetVerboseLevel() const;
|
||||||
// get/set the current verbosity level. Notify()s that occur whose verbosity level
|
// get/set the current verbosity level. Notify()s that occur whose verbosity level
|
||||||
// is greater than the current level will not be processed.
|
// is greater than the current level will not be processed.
|
||||||
|
|
||||||
// a convenience enumeration; no one is bound by law to use these
|
// a convenience enumeration; no one is bound by law to use these
|
||||||
enum VerboseLevel
|
enum VerboseLevel
|
||||||
{
|
{
|
||||||
V_SILENT = 0,
|
V_SILENT = 0,
|
||||||
V_NORMAL = 1,
|
V_NORMAL = 1,
|
||||||
V_VERBOSE = 2
|
V_VERBOSE = 2
|
||||||
};
|
};
|
||||||
//
|
//
|
||||||
// convenience methods for notifying at these three levels...
|
// convenience methods for notifying at these three levels...
|
||||||
//
|
//
|
||||||
void NotifySilent ( const TCHAR* format, ... );
|
void NotifySilent ( const TCHAR* format, ... );
|
||||||
void NotifyNormal ( const TCHAR* format, ... );
|
void NotifyNormal ( const TCHAR* format, ... );
|
||||||
void NotifyVerbose ( const TCHAR* format, ... );
|
void NotifyVerbose ( const TCHAR* format, ... );
|
||||||
|
|
||||||
|
|
||||||
iUserNotify(int verboseLevel = 0);
|
iUserNotify(int verboseLevel = 0);
|
||||||
virtual ~iUserNotify();
|
virtual ~iUserNotify();
|
||||||
protected:
|
protected:
|
||||||
virtual void HandleNotify( int level, const TCHAR* format, va_list& args ) = 0;
|
virtual void HandleNotify( int level, const TCHAR* format, va_list& args ) = 0;
|
||||||
// this is implemented in derived classes to implement the specific type of
|
// this is implemented in derived classes to implement the specific type of
|
||||||
// notification desired
|
// notification desired
|
||||||
|
|
||||||
int mVerboseLevel;
|
int mVerboseLevel;
|
||||||
private:
|
private:
|
||||||
static iUserNotify* mpInstance;
|
static iUserNotify* mpInstance;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -102,29 +102,29 @@ private:
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#define TW_NOTIFY_SILENT\
|
#define TW_NOTIFY_SILENT\
|
||||||
if( iUserNotify::GetInstance()->GetVerboseLevel() >= iUserNotify::V_SILENT )\
|
if( iUserNotify::GetInstance()->GetVerboseLevel() >= iUserNotify::V_SILENT )\
|
||||||
iUserNotify::GetInstance()->NotifySilent
|
iUserNotify::GetInstance()->NotifySilent
|
||||||
|
|
||||||
#define TW_NOTIFY_NORMAL\
|
#define TW_NOTIFY_NORMAL\
|
||||||
if( iUserNotify::GetInstance()->GetVerboseLevel() >= iUserNotify::V_NORMAL )\
|
if( iUserNotify::GetInstance()->GetVerboseLevel() >= iUserNotify::V_NORMAL )\
|
||||||
iUserNotify::GetInstance()->NotifyNormal
|
iUserNotify::GetInstance()->NotifyNormal
|
||||||
|
|
||||||
#define TW_NOTIFY_VERBOSE\
|
#define TW_NOTIFY_VERBOSE\
|
||||||
if( iUserNotify::GetInstance()->GetVerboseLevel() >= iUserNotify::V_VERBOSE )\
|
if( iUserNotify::GetInstance()->GetVerboseLevel() >= iUserNotify::V_VERBOSE )\
|
||||||
iUserNotify::GetInstance()->NotifyVerbose
|
iUserNotify::GetInstance()->NotifyVerbose
|
||||||
|
|
||||||
//#############################################################################
|
//#############################################################################
|
||||||
// inline implementation
|
// inline implementation
|
||||||
//#############################################################################
|
//#############################################################################
|
||||||
inline iUserNotify* iUserNotify::GetInstance()
|
inline iUserNotify* iUserNotify::GetInstance()
|
||||||
{
|
{
|
||||||
ASSERT(mpInstance != 0);
|
ASSERT(mpInstance != 0);
|
||||||
return mpInstance;
|
return mpInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void iUserNotify::SetInstance(iUserNotify* pInst)
|
inline void iUserNotify::SetInstance(iUserNotify* pInst)
|
||||||
{
|
{
|
||||||
mpInstance = pInst;
|
mpInstance = pInst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -38,19 +38,19 @@
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
void cUserNotifyStdout::HandleNotify( int level, const TCHAR* format, va_list& args )
|
void cUserNotifyStdout::HandleNotify( int level, const TCHAR* format, va_list& args )
|
||||||
{
|
{
|
||||||
if(GetVerboseLevel() < level)
|
if(GetVerboseLevel() < level)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// all verbose output now goes to stderr
|
// all verbose output now goes to stderr
|
||||||
if(level < iUserNotify::V_VERBOSE)
|
if(level < iUserNotify::V_VERBOSE)
|
||||||
{
|
{
|
||||||
_vtprintf(format, args);
|
_vtprintf(format, args);
|
||||||
fflush( stdout );
|
fflush( stdout );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_vftprintf(stderr, format, args);
|
_vftprintf(stderr, format, args);
|
||||||
fflush( stderr );
|
fflush( stderr );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,10 +43,10 @@
|
||||||
class cUserNotifyStdout : public iUserNotify
|
class cUserNotifyStdout : public iUserNotify
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void HandleNotify( int level, const TCHAR* format, va_list& args ) ;
|
virtual void HandleNotify( int level, const TCHAR* format, va_list& args ) ;
|
||||||
// formats the string and sends it to stdout
|
// formats the string and sends it to stdout
|
||||||
// NOTE -- a little tripwire specific hack has been applied that makes all output
|
// NOTE -- a little tripwire specific hack has been applied that makes all output
|
||||||
// at or above iUserNotify::V_VERBOSE go to stderr instead of stdout
|
// at or above iUserNotify::V_VERBOSE go to stderr instead of stdout
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __USERNOTIFYSTDOUT_H */
|
#endif /* __USERNOTIFYSTDOUT_H */
|
||||||
|
|
|
@ -61,7 +61,7 @@ public:
|
||||||
TCHAR* string;
|
TCHAR* string;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Select between the different localized string sets
|
// Select between the different localized string sets
|
||||||
// for this product. Returns false if string not defined.
|
// for this product. Returns false if string not defined.
|
||||||
virtual bool SelectStringSet(int setID) = 0;
|
virtual bool SelectStringSet(int setID) = 0;
|
||||||
|
|
||||||
|
@ -83,11 +83,11 @@ public:
|
||||||
// Add a single string. The above rules apply.
|
// Add a single string. The above rules apply.
|
||||||
virtual void AddString(int setID, int stringID, TCHAR* string) = 0;
|
virtual void AddString(int setID, int stringID, TCHAR* string) = 0;
|
||||||
|
|
||||||
// singleton manipulation
|
// singleton manipulation
|
||||||
static iUserString* GetInstance();
|
static iUserString* GetInstance();
|
||||||
static void SetInstance(iUserString* pInst);
|
static void SetInstance(iUserString* pInst);
|
||||||
private:
|
private:
|
||||||
static iUserString* mpInstance;
|
static iUserString* mpInstance;
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -116,14 +116,14 @@ Example Use:
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
inline iUserString* iUserString::GetInstance()
|
inline iUserString* iUserString::GetInstance()
|
||||||
{
|
{
|
||||||
ASSERT(mpInstance);
|
ASSERT(mpInstance);
|
||||||
|
|
||||||
return mpInstance;
|
return mpInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void iUserString::SetInstance(iUserString* pInst)
|
inline void iUserString::SetInstance(iUserString* pInst)
|
||||||
{
|
{
|
||||||
mpInstance = pInst;
|
mpInstance = pInst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ const TCHAR* cUserStringMemBased::GetString(int stringID) const
|
||||||
{
|
{
|
||||||
// mCurrentStringSet is invallid
|
// mCurrentStringSet is invallid
|
||||||
ASSERT(false);
|
ASSERT(false);
|
||||||
return _T("<Bad String Set>");
|
return _T("<Bad String Set>");
|
||||||
}
|
}
|
||||||
|
|
||||||
StringSet::const_iterator stringItr;
|
StringSet::const_iterator stringItr;
|
||||||
|
@ -84,7 +84,7 @@ const TCHAR* cUserStringMemBased::GetString(int stringID) const
|
||||||
{
|
{
|
||||||
// string not found
|
// string not found
|
||||||
ASSERT(false);
|
ASSERT(false);
|
||||||
return _T("<Missing String>");
|
return _T("<Missing String>");
|
||||||
}
|
}
|
||||||
|
|
||||||
return stringItr->second;
|
return stringItr->second;
|
||||||
|
|
|
@ -69,11 +69,11 @@ public:
|
||||||
~cUserStringMemBased();
|
~cUserStringMemBased();
|
||||||
|
|
||||||
// the abstract interface
|
// the abstract interface
|
||||||
virtual bool SelectStringSet (int setID);
|
virtual bool SelectStringSet (int setID);
|
||||||
virtual const TCHAR* GetString (int stringID) const;
|
virtual const TCHAR* GetString (int stringID) const;
|
||||||
virtual void ClearStringSet (int id);
|
virtual void ClearStringSet (int id);
|
||||||
virtual void AddStringSet (int setID, const iUserString::tStringPair* pPairArray);
|
virtual void AddStringSet (int setID, const iUserString::tStringPair* pPairArray);
|
||||||
virtual void AddString (int setID, int stringID, TCHAR* string);
|
virtual void AddString (int setID, int stringID, TCHAR* string);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::map<int, TCHAR*> StringSet;
|
typedef std::map<int, TCHAR*> StringSet;
|
||||||
|
|
|
@ -97,7 +97,7 @@ wchar_t* cUTF8::allocate( const char* in ) THROW( std::bad_alloc )
|
||||||
|
|
||||||
//--Convert
|
//--Convert
|
||||||
|
|
||||||
out[0] = 0x00; // NOTE: Just in case we fail
|
out[0] = 0x00; // NOTE: Just in case we fail
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
//size_t nWritten =
|
//size_t nWritten =
|
||||||
#endif
|
#endif
|
||||||
|
@ -107,8 +107,8 @@ wchar_t* cUTF8::allocate( const char* in ) THROW( std::bad_alloc )
|
||||||
#ifdef _INTEG2 // Verify Output
|
#ifdef _INTEG2 // Verify Output
|
||||||
if ( nWritten == 0 )
|
if ( nWritten == 0 )
|
||||||
{
|
{
|
||||||
cDebug d( "cUTF8::allocate" );
|
cDebug d( "cUTF8::allocate" );
|
||||||
d.TraceError( "MultiByteToWideChar failed with %x\n", ::GetLastError() );
|
d.TraceError( "MultiByteToWideChar failed with %x\n", ::GetLastError() );
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT( out && TSS_IsValidString( out, nWritten ) );
|
ASSERT( out && TSS_IsValidString( out, nWritten ) );
|
||||||
|
@ -119,7 +119,7 @@ wchar_t* cUTF8::allocate( const char* in ) THROW( std::bad_alloc )
|
||||||
|
|
||||||
char* cUTF8::allocate( const wchar_t* in ) THROW( std::bad_alloc )
|
char* cUTF8::allocate( const wchar_t* in ) THROW( std::bad_alloc )
|
||||||
{
|
{
|
||||||
ASSERT( in /*&& TSS_IsValidString( in ) */); // Verify Input
|
ASSERT( in /*&& TSS_IsValidString( in ) */); // Verify Input
|
||||||
|
|
||||||
// Allocate required size
|
// Allocate required size
|
||||||
size_t N = ::WideCharToMultiByte( CP_UTF8, 0, in, -1,0,0,0,0 );
|
size_t N = ::WideCharToMultiByte( CP_UTF8, 0, in, -1,0,0,0,0 );
|
||||||
|
@ -128,7 +128,7 @@ char* cUTF8::allocate( const wchar_t* in ) THROW( std::bad_alloc )
|
||||||
|
|
||||||
//--Convert
|
//--Convert
|
||||||
|
|
||||||
out[0] = 0x00; // NOTE: Just in case we fail
|
out[0] = 0x00; // NOTE: Just in case we fail
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
//size_t nWritten =
|
//size_t nWritten =
|
||||||
#endif
|
#endif
|
||||||
|
@ -138,8 +138,8 @@ char* cUTF8::allocate( const wchar_t* in ) THROW( std::bad_alloc )
|
||||||
#ifdef _INTEG2 // Verify Output
|
#ifdef _INTEG2 // Verify Output
|
||||||
if ( nWritten == 0 )
|
if ( nWritten == 0 )
|
||||||
{
|
{
|
||||||
cDebug d( "cUTF8::allocate" );
|
cDebug d( "cUTF8::allocate" );
|
||||||
d.TraceError( "WideCharToMultiByte failed with %x\n", ::GetLastError() );
|
d.TraceError( "WideCharToMultiByte failed with %x\n", ::GetLastError() );
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT( out /*&& TSS_IsValidString( out, nWritten ) */);
|
ASSERT( out /*&& TSS_IsValidString( out, nWritten ) */);
|
||||||
|
@ -148,5 +148,5 @@ char* cUTF8::allocate( const wchar_t* in ) THROW( std::bad_alloc )
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //_UNICODE
|
#endif //_UNICODE
|
||||||
|
|
||||||
|
|
|
@ -61,12 +61,12 @@
|
||||||
// function to safely convert the string to something printable
|
// function to safely convert the string to something printable
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
#ifdef _UNICODE
|
#ifdef _UNICODE
|
||||||
# define TSS_UTF8( x ) cUTF8( x ).wstr()
|
# define TSS_UTF8( x ) cUTF8( x ).wstr()
|
||||||
#else
|
#else
|
||||||
# define TSS_UTF8( x ) x
|
# define TSS_UTF8( x ) x
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _UNICODE // this class is only needed in unicode builds...
|
#ifdef _UNICODE // this class is only needed in unicode builds...
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Entities Declared in this Module
|
// Entities Declared in this Module
|
||||||
|
|
|
@ -80,7 +80,7 @@ public:
|
||||||
|
|
||||||
~wc16_string_impl(); // call Release() to delete
|
~wc16_string_impl(); // call Release() to delete
|
||||||
private:
|
private:
|
||||||
void operator = (const wc16_string_impl& rhs) { return; } // don't call
|
void operator = (const wc16_string_impl& rhs) { return; } // don't call
|
||||||
};
|
};
|
||||||
|
|
||||||
static WCHAR16 NULL_WCHAR16 = 0;
|
static WCHAR16 NULL_WCHAR16 = 0;
|
||||||
|
@ -119,8 +119,8 @@ void wc16_string::operator = (const wc16_string& rhs)
|
||||||
|
|
||||||
mpData = rhs.mpData;
|
mpData = rhs.mpData;
|
||||||
|
|
||||||
if( mpData )
|
if( mpData )
|
||||||
mpData->AddRef();
|
mpData->AddRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,39 +6,39 @@ class Integer;
|
||||||
template <class T> class AbstractGroup
|
template <class T> class AbstractGroup
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef T Element;
|
typedef T Element;
|
||||||
|
|
||||||
virtual ~AbstractGroup() {}
|
virtual ~AbstractGroup() {}
|
||||||
|
|
||||||
virtual bool Equal(const Element &a, const Element &b) const =0;
|
virtual bool Equal(const Element &a, const Element &b) const =0;
|
||||||
virtual Element Zero() const =0;
|
virtual Element Zero() const =0;
|
||||||
virtual Element Add(const Element &a, const Element &b) const =0;
|
virtual Element Add(const Element &a, const Element &b) const =0;
|
||||||
virtual Element Inverse(const Element &a) const =0;
|
virtual Element Inverse(const Element &a) const =0;
|
||||||
|
|
||||||
virtual Element Double(const Element &a) const;
|
virtual Element Double(const Element &a) const;
|
||||||
virtual Element Subtract(const Element &a, const Element &b) const;
|
virtual Element Subtract(const Element &a, const Element &b) const;
|
||||||
virtual Element& Accumulate(Element &a, const Element &b) const;
|
virtual Element& Accumulate(Element &a, const Element &b) const;
|
||||||
virtual Element& Reduce(Element &a, const Element &b) const;
|
virtual Element& Reduce(Element &a, const Element &b) const;
|
||||||
|
|
||||||
virtual Element IntMultiply(const Element &a, const Integer &e) const;
|
virtual Element IntMultiply(const Element &a, const Integer &e) const;
|
||||||
virtual Element CascadeIntMultiply(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const;
|
virtual Element CascadeIntMultiply(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T> class AbstractRing : public AbstractGroup<T>
|
template <class T> class AbstractRing : public AbstractGroup<T>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef T Element;
|
typedef T Element;
|
||||||
|
|
||||||
virtual bool IsUnit(const Element &a) const =0;
|
virtual bool IsUnit(const Element &a) const =0;
|
||||||
virtual Element One() const =0;
|
virtual Element One() const =0;
|
||||||
virtual Element Multiply(const Element &a, const Element &b) const =0;
|
virtual Element Multiply(const Element &a, const Element &b) const =0;
|
||||||
virtual Element MultiplicativeInverse(const Element &a) const =0;
|
virtual Element MultiplicativeInverse(const Element &a) const =0;
|
||||||
|
|
||||||
virtual Element Square(const Element &a) const;
|
virtual Element Square(const Element &a) const;
|
||||||
virtual Element Divide(const Element &a, const Element &b) const;
|
virtual Element Divide(const Element &a, const Element &b) const;
|
||||||
|
|
||||||
virtual Element Exponentiate(const Element &a, const Integer &e) const;
|
virtual Element Exponentiate(const Element &a, const Integer &e) const;
|
||||||
virtual Element CascadeExponentiate(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const;
|
virtual Element CascadeExponentiate(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ********************************************************
|
// ********************************************************
|
||||||
|
@ -54,19 +54,19 @@ template <class Element, class Iterator> Element GeneralCascadeExponentiation(co
|
||||||
template <class T> class AbstractField : public AbstractRing<T>
|
template <class T> class AbstractField : public AbstractRing<T>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool IsUnit(const typename T::Element &a) const
|
bool IsUnit(const typename T::Element &a) const
|
||||||
{return !this->Equal(a, this->Zero());}
|
{return !this->Equal(a, this->Zero());}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T> class AbstractEuclideanDomain : public AbstractRing<T>
|
template <class T> class AbstractEuclideanDomain : public AbstractRing<T>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef T Element;
|
typedef T Element;
|
||||||
|
|
||||||
virtual void DivisionAlgorithm(Element &r, Element &q, const Element &a, const Element &d) const =0;
|
virtual void DivisionAlgorithm(Element &r, Element &q, const Element &a, const Element &d) const =0;
|
||||||
|
|
||||||
virtual Element Mod(const Element &a, const Element &b) const;
|
virtual Element Mod(const Element &a, const Element &b) const;
|
||||||
virtual Element Gcd(const Element &a, const Element &b) const;
|
virtual Element Gcd(const Element &a, const Element &b) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ********************************************************
|
// ********************************************************
|
||||||
|
@ -74,153 +74,153 @@ public:
|
||||||
template <class T> class MultiplicativeGroup : public AbstractGroup<typename T::Element>
|
template <class T> class MultiplicativeGroup : public AbstractGroup<typename T::Element>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef T Ring;
|
typedef T Ring;
|
||||||
|
|
||||||
MultiplicativeGroup(const Ring &m_ring)
|
MultiplicativeGroup(const Ring &m_ring)
|
||||||
: m_ring(m_ring) {}
|
: m_ring(m_ring) {}
|
||||||
|
|
||||||
const Ring & GetRing() const
|
const Ring & GetRing() const
|
||||||
{return m_ring;}
|
{return m_ring;}
|
||||||
|
|
||||||
bool Equal(const typename T::Element &a, const typename T::Element &b) const
|
bool Equal(const typename T::Element &a, const typename T::Element &b) const
|
||||||
{return m_ring.Equal(a, b);}
|
{return m_ring.Equal(a, b);}
|
||||||
|
|
||||||
typename T::Element Zero() const
|
typename T::Element Zero() const
|
||||||
{return m_ring.One();}
|
{return m_ring.One();}
|
||||||
|
|
||||||
typename T::Element Add(const typename T::Element &a, const typename T::Element &b) const
|
typename T::Element Add(const typename T::Element &a, const typename T::Element &b) const
|
||||||
{return m_ring.Multiply(a, b);}
|
{return m_ring.Multiply(a, b);}
|
||||||
|
|
||||||
typename T::Element& Accumulate(typename T::Element &a, const typename T::Element &b) const
|
typename T::Element& Accumulate(typename T::Element &a, const typename T::Element &b) const
|
||||||
{return a = m_ring.Multiply(a, b);}
|
{return a = m_ring.Multiply(a, b);}
|
||||||
|
|
||||||
typename T::Element Inverse(const typename T::Element &a) const
|
typename T::Element Inverse(const typename T::Element &a) const
|
||||||
{return m_ring.MultiplicativeInverse(a);}
|
{return m_ring.MultiplicativeInverse(a);}
|
||||||
|
|
||||||
typename T::Element Subtract(const typename T::Element &a, const typename T::Element &b) const
|
typename T::Element Subtract(const typename T::Element &a, const typename T::Element &b) const
|
||||||
{return m_ring.Divide(a, b);}
|
{return m_ring.Divide(a, b);}
|
||||||
|
|
||||||
typename T::Element& Reduce(typename T::Element &a, const typename T::Element &b) const
|
typename T::Element& Reduce(typename T::Element &a, const typename T::Element &b) const
|
||||||
{return a = m_ring.Divide(a, b);}
|
{return a = m_ring.Divide(a, b);}
|
||||||
|
|
||||||
typename T::Element Double(const typename T::Element &a) const
|
typename T::Element Double(const typename T::Element &a) const
|
||||||
{return m_ring.Square(a);}
|
{return m_ring.Square(a);}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const Ring &m_ring;
|
const Ring &m_ring;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T> class EuclideanDomainOf : public AbstractEuclideanDomain<T>
|
template <class T> class EuclideanDomainOf : public AbstractEuclideanDomain<T>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef T Element;
|
typedef T Element;
|
||||||
|
|
||||||
EuclideanDomainOf() {}
|
EuclideanDomainOf() {}
|
||||||
|
|
||||||
bool Equal(const Element &a, const Element &b) const
|
bool Equal(const Element &a, const Element &b) const
|
||||||
{return a==b;}
|
{return a==b;}
|
||||||
|
|
||||||
Element Zero() const
|
Element Zero() const
|
||||||
{return Element::Zero();}
|
{return Element::Zero();}
|
||||||
|
|
||||||
Element Add(const Element &a, const Element &b) const
|
Element Add(const Element &a, const Element &b) const
|
||||||
{return a+b;}
|
{return a+b;}
|
||||||
|
|
||||||
Element& Accumulate(Element &a, const Element &b) const
|
Element& Accumulate(Element &a, const Element &b) const
|
||||||
{return a+=b;}
|
{return a+=b;}
|
||||||
|
|
||||||
Element Inverse(const Element &a) const
|
Element Inverse(const Element &a) const
|
||||||
{return -a;}
|
{return -a;}
|
||||||
|
|
||||||
Element Subtract(const Element &a, const Element &b) const
|
Element Subtract(const Element &a, const Element &b) const
|
||||||
{return a-b;}
|
{return a-b;}
|
||||||
|
|
||||||
Element& Reduce(Element &a, const Element &b) const
|
Element& Reduce(Element &a, const Element &b) const
|
||||||
{return a-=b;}
|
{return a-=b;}
|
||||||
|
|
||||||
Element Double(const Element &a) const
|
Element Double(const Element &a) const
|
||||||
{return a.Doubled();}
|
{return a.Doubled();}
|
||||||
|
|
||||||
Element One() const
|
Element One() const
|
||||||
{return Element::One();}
|
{return Element::One();}
|
||||||
|
|
||||||
Element Multiply(const Element &a, const Element &b) const
|
Element Multiply(const Element &a, const Element &b) const
|
||||||
{return a*b;}
|
{return a*b;}
|
||||||
|
|
||||||
Element Square(const Element &a) const
|
Element Square(const Element &a) const
|
||||||
{return a.Squared();}
|
{return a.Squared();}
|
||||||
|
|
||||||
bool IsUnit(const Element &a) const
|
bool IsUnit(const Element &a) const
|
||||||
{return a.IsUnit();}
|
{return a.IsUnit();}
|
||||||
|
|
||||||
Element MultiplicativeInverse(const Element &a) const
|
Element MultiplicativeInverse(const Element &a) const
|
||||||
{return a.MultiplicativeInverse();}
|
{return a.MultiplicativeInverse();}
|
||||||
|
|
||||||
Element Divide(const Element &a, const Element &b) const
|
Element Divide(const Element &a, const Element &b) const
|
||||||
{return a/b;}
|
{return a/b;}
|
||||||
|
|
||||||
Element Mod(const Element &a, const Element &b) const
|
Element Mod(const Element &a, const Element &b) const
|
||||||
{return a%b;}
|
{return a%b;}
|
||||||
|
|
||||||
void DivisionAlgorithm(Element &r, Element &q, const Element &a, const Element &d) const
|
void DivisionAlgorithm(Element &r, Element &q, const Element &a, const Element &d) const
|
||||||
{Element::Divide(r, q, a, d);}
|
{Element::Divide(r, q, a, d);}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T> class QuotientRing : public AbstractRing<typename T::Element>
|
template <class T> class QuotientRing : public AbstractRing<typename T::Element>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef T EuclideanDomain;
|
typedef T EuclideanDomain;
|
||||||
|
|
||||||
QuotientRing(const EuclideanDomain &domain, const typename T::Element &modulus)
|
QuotientRing(const EuclideanDomain &domain, const typename T::Element &modulus)
|
||||||
: m_domain(domain), m_modulus(modulus) {}
|
: m_domain(domain), m_modulus(modulus) {}
|
||||||
|
|
||||||
const EuclideanDomain & GetDomain() const
|
const EuclideanDomain & GetDomain() const
|
||||||
{return m_domain;}
|
{return m_domain;}
|
||||||
|
|
||||||
const typename T::Element & GetModulus() const
|
const typename T::Element & GetModulus() const
|
||||||
{return m_modulus;}
|
{return m_modulus;}
|
||||||
|
|
||||||
bool Equal(const typename T::Element &a, const typename T::Element &b) const
|
bool Equal(const typename T::Element &a, const typename T::Element &b) const
|
||||||
{return m_domain.Equal(m_domain.Mod(m_domain.Subtract(a, b), m_modulus), m_domain.Zero());}
|
{return m_domain.Equal(m_domain.Mod(m_domain.Subtract(a, b), m_modulus), m_domain.Zero());}
|
||||||
|
|
||||||
typename T::Element Zero() const
|
typename T::Element Zero() const
|
||||||
{return m_domain.Zero();}
|
{return m_domain.Zero();}
|
||||||
|
|
||||||
typename T::Element Add(const typename T::Element &a, const typename T::Element &b) const
|
typename T::Element Add(const typename T::Element &a, const typename T::Element &b) const
|
||||||
{return m_domain.Add(a, b);}
|
{return m_domain.Add(a, b);}
|
||||||
|
|
||||||
typename T::Element& Accumulate(typename T::Element &a, const typename T::Element &b) const
|
typename T::Element& Accumulate(typename T::Element &a, const typename T::Element &b) const
|
||||||
{return m_domain.Accumulate(a, b);}
|
{return m_domain.Accumulate(a, b);}
|
||||||
|
|
||||||
typename T::Element Inverse(const typename T::Element &a) const
|
typename T::Element Inverse(const typename T::Element &a) const
|
||||||
{return m_domain.Inverse(a);}
|
{return m_domain.Inverse(a);}
|
||||||
|
|
||||||
typename T::Element Subtract(const typename T::Element &a, const typename T::Element &b) const
|
typename T::Element Subtract(const typename T::Element &a, const typename T::Element &b) const
|
||||||
{return m_domain.Subtract(a, b);}
|
{return m_domain.Subtract(a, b);}
|
||||||
|
|
||||||
typename T::Element& Reduce(typename T::Element &a, const typename T::Element &b) const
|
typename T::Element& Reduce(typename T::Element &a, const typename T::Element &b) const
|
||||||
{return m_domain.Reduce(a, b);}
|
{return m_domain.Reduce(a, b);}
|
||||||
|
|
||||||
typename T::Element Double(const typename T::Element &a) const
|
typename T::Element Double(const typename T::Element &a) const
|
||||||
{return m_domain.Double(a);}
|
{return m_domain.Double(a);}
|
||||||
|
|
||||||
bool IsUnit(const typename T::Element &a) const
|
bool IsUnit(const typename T::Element &a) const
|
||||||
{return m_domain.IsUnit(m_domain.Gcd(a, m_modulus));}
|
{return m_domain.IsUnit(m_domain.Gcd(a, m_modulus));}
|
||||||
|
|
||||||
typename T::Element One() const
|
typename T::Element One() const
|
||||||
{return m_domain.One();}
|
{return m_domain.One();}
|
||||||
|
|
||||||
typename T::Element Multiply(const typename T::Element &a, const typename T::Element &b) const
|
typename T::Element Multiply(const typename T::Element &a, const typename T::Element &b) const
|
||||||
{return m_domain.Mod(m_domain.Multiply(a, b), m_modulus);}
|
{return m_domain.Mod(m_domain.Multiply(a, b), m_modulus);}
|
||||||
|
|
||||||
typename T::Element Square(const typename T::Element &a) const
|
typename T::Element Square(const typename T::Element &a) const
|
||||||
{return m_domain.Mod(m_domain.Square(a), m_modulus);}
|
{return m_domain.Mod(m_domain.Square(a), m_modulus);}
|
||||||
|
|
||||||
typename QuotientRing<T>::Element MultiplicativeInverse(const typename T::Element &a) const;
|
typename QuotientRing<T>::Element MultiplicativeInverse(const typename T::Element &a) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const EuclideanDomain &m_domain;
|
const EuclideanDomain &m_domain;
|
||||||
typename T::Element m_modulus;
|
typename T::Element m_modulus;
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -233,256 +233,256 @@ protected:
|
||||||
|
|
||||||
template <class T> T AbstractGroup<T>::Double(const Element &a) const
|
template <class T> T AbstractGroup<T>::Double(const Element &a) const
|
||||||
{
|
{
|
||||||
return Add(a, a);
|
return Add(a, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> T AbstractGroup<T>::Subtract(const Element &a, const Element &b) const
|
template <class T> T AbstractGroup<T>::Subtract(const Element &a, const Element &b) const
|
||||||
{
|
{
|
||||||
return Add(a, Inverse(b));
|
return Add(a, Inverse(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> T& AbstractGroup<T>::Accumulate(Element &a, const Element &b) const
|
template <class T> T& AbstractGroup<T>::Accumulate(Element &a, const Element &b) const
|
||||||
{
|
{
|
||||||
return a = Add(a, b);
|
return a = Add(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> T& AbstractGroup<T>::Reduce(Element &a, const Element &b) const
|
template <class T> T& AbstractGroup<T>::Reduce(Element &a, const Element &b) const
|
||||||
{
|
{
|
||||||
return a = Subtract(a, b);
|
return a = Subtract(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> T AbstractRing<T>::Square(const Element &a) const
|
template <class T> T AbstractRing<T>::Square(const Element &a) const
|
||||||
{
|
{
|
||||||
return Multiply(a, a);
|
return Multiply(a, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> T AbstractRing<T>::Divide(const Element &a, const Element &b) const
|
template <class T> T AbstractRing<T>::Divide(const Element &a, const Element &b) const
|
||||||
{
|
{
|
||||||
return Multiply(a, MultiplicativeInverse(b));
|
return Multiply(a, MultiplicativeInverse(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> T AbstractEuclideanDomain<T>::Mod(const Element &a, const Element &b) const
|
template <class T> T AbstractEuclideanDomain<T>::Mod(const Element &a, const Element &b) const
|
||||||
{
|
{
|
||||||
Element r, q;
|
Element r, q;
|
||||||
DivisionAlgorithm(r, q, a, b);
|
DivisionAlgorithm(r, q, a, b);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> T AbstractEuclideanDomain<T>::Gcd(const Element &a, const Element &b) const
|
template <class T> T AbstractEuclideanDomain<T>::Gcd(const Element &a, const Element &b) const
|
||||||
{
|
{
|
||||||
Element g[3]={b, a};
|
Element g[3]={b, a};
|
||||||
unsigned int i0=0, i1=1, i2=2;
|
unsigned int i0=0, i1=1, i2=2;
|
||||||
|
|
||||||
while (!this->Equal(g[i1], this->Zero()))
|
while (!this->Equal(g[i1], this->Zero()))
|
||||||
{
|
{
|
||||||
g[i2] = Mod(g[i0], g[i1]);
|
g[i2] = Mod(g[i0], g[i1]);
|
||||||
unsigned int t = i0; i0 = i1; i1 = i2; i2 = t;
|
unsigned int t = i0; i0 = i1; i1 = i2; i2 = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
return g[i0];
|
return g[i0];
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> typename QuotientRing<T>::Element QuotientRing<T>::MultiplicativeInverse(const typename T::Element &a) const
|
template <class T> typename QuotientRing<T>::Element QuotientRing<T>::MultiplicativeInverse(const typename T::Element &a) const
|
||||||
{
|
{
|
||||||
typename T::Element g[3]={m_modulus, a};
|
typename T::Element g[3]={m_modulus, a};
|
||||||
typename T::Element v[3]={m_domain.Zero(), m_domain.One()};
|
typename T::Element v[3]={m_domain.Zero(), m_domain.One()};
|
||||||
typename T::Element y;
|
typename T::Element y;
|
||||||
unsigned int i0=0, i1=1, i2=2;
|
unsigned int i0=0, i1=1, i2=2;
|
||||||
|
|
||||||
while (!this->Equal(g[i1], Zero()))
|
while (!this->Equal(g[i1], Zero()))
|
||||||
{
|
{
|
||||||
// y = g[i0] / g[i1];
|
// y = g[i0] / g[i1];
|
||||||
// g[i2] = g[i0] % g[i1];
|
// g[i2] = g[i0] % g[i1];
|
||||||
m_domain.DivisionAlgorithm(g[i2], y, g[i0], g[i1]);
|
m_domain.DivisionAlgorithm(g[i2], y, g[i0], g[i1]);
|
||||||
// v[i2] = v[i0] - (v[i1] * y);
|
// v[i2] = v[i0] - (v[i1] * y);
|
||||||
v[i2] = m_domain.Subtract(v[i0], m_domain.Multiply(v[i1], y));
|
v[i2] = m_domain.Subtract(v[i0], m_domain.Multiply(v[i1], y));
|
||||||
unsigned int t = i0; i0 = i1; i1 = i2; i2 = t;
|
unsigned int t = i0; i0 = i1; i1 = i2; i2 = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_domain.IsUnit(g[i0]) ? m_domain.Divide(v[i0], g[i0]) : m_domain.Zero();
|
return m_domain.IsUnit(g[i0]) ? m_domain.Divide(v[i0], g[i0]) : m_domain.Zero();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> T AbstractGroup<T>::IntMultiply(const Element &base, const Integer &exponent) const
|
template <class T> T AbstractGroup<T>::IntMultiply(const Element &base, const Integer &exponent) const
|
||||||
{
|
{
|
||||||
unsigned int expLen = exponent.BitCount();
|
unsigned int expLen = exponent.BitCount();
|
||||||
if (expLen==0)
|
if (expLen==0)
|
||||||
return Zero();
|
return Zero();
|
||||||
|
|
||||||
unsigned powerTableSize = (expLen <= 17 ? 1 : (expLen <= 24 ? 2 : (expLen <= 70 ? 4 : (expLen <= 197 ? 8 : (expLen <= 539 ? 16 : (expLen <= 1434 ? 32 : 64))))));
|
unsigned powerTableSize = (expLen <= 17 ? 1 : (expLen <= 24 ? 2 : (expLen <= 70 ? 4 : (expLen <= 197 ? 8 : (expLen <= 539 ? 16 : (expLen <= 1434 ? 32 : 64))))));
|
||||||
std::vector<Element> powerTable(powerTableSize);
|
std::vector<Element> powerTable(powerTableSize);
|
||||||
|
|
||||||
powerTable[0] = base;
|
powerTable[0] = base;
|
||||||
if (powerTableSize > 1)
|
if (powerTableSize > 1)
|
||||||
{
|
{
|
||||||
Element temp = Double(base);
|
Element temp = Double(base);
|
||||||
for (unsigned i=1; i<powerTableSize; i++)
|
for (unsigned i=1; i<powerTableSize; i++)
|
||||||
powerTable[i] = Add(temp, powerTable[i-1]);
|
powerTable[i] = Add(temp, powerTable[i-1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Element result;
|
Element result;
|
||||||
unsigned power = 0, prevPosition = expLen-1;
|
unsigned power = 0, prevPosition = expLen-1;
|
||||||
bool firstTime = true;
|
bool firstTime = true;
|
||||||
|
|
||||||
for (int i = expLen-1; i>=0; i--)
|
for (int i = expLen-1; i>=0; i--)
|
||||||
{
|
{
|
||||||
power = 2*power + exponent.GetBit(i);
|
power = 2*power + exponent.GetBit(i);
|
||||||
|
|
||||||
if (i==0 || power >= powerTableSize)
|
if (i==0 || power >= powerTableSize)
|
||||||
{
|
{
|
||||||
unsigned squaresBefore = prevPosition-i;
|
unsigned squaresBefore = prevPosition-i;
|
||||||
unsigned squaresAfter = 0;
|
unsigned squaresAfter = 0;
|
||||||
prevPosition = i;
|
prevPosition = i;
|
||||||
while (power && power%2 == 0)
|
while (power && power%2 == 0)
|
||||||
{
|
{
|
||||||
power /= 2;
|
power /= 2;
|
||||||
squaresBefore--;
|
squaresBefore--;
|
||||||
squaresAfter++;
|
squaresAfter++;
|
||||||
}
|
}
|
||||||
if (firstTime)
|
if (firstTime)
|
||||||
{
|
{
|
||||||
result = powerTable[(power-1)/2];
|
result = powerTable[(power-1)/2];
|
||||||
firstTime = false;
|
firstTime = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
while (squaresBefore--)
|
while (squaresBefore--)
|
||||||
result = Double(result);
|
result = Double(result);
|
||||||
if (power)
|
if (power)
|
||||||
result = Add(powerTable[(power-1)/2], result);
|
result = Add(powerTable[(power-1)/2], result);
|
||||||
}
|
}
|
||||||
while (squaresAfter--)
|
while (squaresAfter--)
|
||||||
result = Double(result);
|
result = Double(result);
|
||||||
power = 0;
|
power = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> T AbstractGroup<T>::CascadeIntMultiply(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const
|
template <class T> T AbstractGroup<T>::CascadeIntMultiply(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const
|
||||||
{
|
{
|
||||||
const unsigned expLen = STDMAX(e1.BitCount(), e2.BitCount());
|
const unsigned expLen = STDMAX(e1.BitCount(), e2.BitCount());
|
||||||
if (expLen==0)
|
if (expLen==0)
|
||||||
return Zero();
|
return Zero();
|
||||||
|
|
||||||
const unsigned w = (expLen <= 46 ? 1 : (expLen <= 260 ? 2 : 3));
|
const unsigned w = (expLen <= 46 ? 1 : (expLen <= 260 ? 2 : 3));
|
||||||
const unsigned tableSize = 1<<w;
|
const unsigned tableSize = 1<<w;
|
||||||
std::vector<Element> powerTable(tableSize << w);
|
std::vector<Element> powerTable(tableSize << w);
|
||||||
|
|
||||||
powerTable[1] = x;
|
powerTable[1] = x;
|
||||||
powerTable[tableSize] = y;
|
powerTable[tableSize] = y;
|
||||||
if (w==1)
|
if (w==1)
|
||||||
powerTable[3] = Add(x,y);
|
powerTable[3] = Add(x,y);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
powerTable[2] = Double(x);
|
powerTable[2] = Double(x);
|
||||||
powerTable[2*tableSize] = Double(y);
|
powerTable[2*tableSize] = Double(y);
|
||||||
|
|
||||||
unsigned i, j;
|
unsigned i, j;
|
||||||
|
|
||||||
for (i=3; i<tableSize; i+=2)
|
for (i=3; i<tableSize; i+=2)
|
||||||
powerTable[i] = Add(powerTable[i-2], powerTable[2]);
|
powerTable[i] = Add(powerTable[i-2], powerTable[2]);
|
||||||
for (i=1; i<tableSize; i+=2)
|
for (i=1; i<tableSize; i+=2)
|
||||||
for (j=i+tableSize; j<(tableSize<<w); j+=tableSize)
|
for (j=i+tableSize; j<(tableSize<<w); j+=tableSize)
|
||||||
powerTable[j] = Add(powerTable[j-tableSize], y);
|
powerTable[j] = Add(powerTable[j-tableSize], y);
|
||||||
|
|
||||||
for (i=3*tableSize; i<(tableSize<<w); i+=2*tableSize)
|
for (i=3*tableSize; i<(tableSize<<w); i+=2*tableSize)
|
||||||
powerTable[i] = Add(powerTable[i-2*tableSize], powerTable[2*tableSize]);
|
powerTable[i] = Add(powerTable[i-2*tableSize], powerTable[2*tableSize]);
|
||||||
for (i=tableSize; i<(tableSize<<w); i+=2*tableSize)
|
for (i=tableSize; i<(tableSize<<w); i+=2*tableSize)
|
||||||
for (j=i+2; j<i+tableSize; j+=2)
|
for (j=i+2; j<i+tableSize; j+=2)
|
||||||
powerTable[j] = Add(powerTable[j-1], x);
|
powerTable[j] = Add(powerTable[j-1], x);
|
||||||
}
|
}
|
||||||
|
|
||||||
Element result;
|
Element result;
|
||||||
unsigned power1 = 0, power2 = 0, prevPosition = expLen-1;
|
unsigned power1 = 0, power2 = 0, prevPosition = expLen-1;
|
||||||
bool firstTime = true;
|
bool firstTime = true;
|
||||||
|
|
||||||
for (int i = expLen-1; i>=0; i--)
|
for (int i = expLen-1; i>=0; i--)
|
||||||
{
|
{
|
||||||
power1 = 2*power1 + e1.GetBit(i);
|
power1 = 2*power1 + e1.GetBit(i);
|
||||||
power2 = 2*power2 + e2.GetBit(i);
|
power2 = 2*power2 + e2.GetBit(i);
|
||||||
|
|
||||||
if (i==0 || 2*power1 >= tableSize || 2*power2 >= tableSize)
|
if (i==0 || 2*power1 >= tableSize || 2*power2 >= tableSize)
|
||||||
{
|
{
|
||||||
unsigned squaresBefore = prevPosition-i;
|
unsigned squaresBefore = prevPosition-i;
|
||||||
unsigned squaresAfter = 0;
|
unsigned squaresAfter = 0;
|
||||||
prevPosition = i;
|
prevPosition = i;
|
||||||
while ((power1 || power2) && power1%2 == 0 && power2%2==0)
|
while ((power1 || power2) && power1%2 == 0 && power2%2==0)
|
||||||
{
|
{
|
||||||
power1 /= 2;
|
power1 /= 2;
|
||||||
power2 /= 2;
|
power2 /= 2;
|
||||||
squaresBefore--;
|
squaresBefore--;
|
||||||
squaresAfter++;
|
squaresAfter++;
|
||||||
}
|
}
|
||||||
if (firstTime)
|
if (firstTime)
|
||||||
{
|
{
|
||||||
result = powerTable[(power2<<w) + power1];
|
result = powerTable[(power2<<w) + power1];
|
||||||
firstTime = false;
|
firstTime = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
while (squaresBefore--)
|
while (squaresBefore--)
|
||||||
result = Double(result);
|
result = Double(result);
|
||||||
if (power1 || power2)
|
if (power1 || power2)
|
||||||
result = Add(powerTable[(power2<<w) + power1], result);
|
result = Add(powerTable[(power2<<w) + power1], result);
|
||||||
}
|
}
|
||||||
while (squaresAfter--)
|
while (squaresAfter--)
|
||||||
result = Double(result);
|
result = Double(result);
|
||||||
power1 = power2 = 0;
|
power1 = power2 = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Element, class Iterator> Element GeneralCascadeMultiplication(const AbstractGroup<Element> &group, Iterator begin, Iterator end)
|
template <class Element, class Iterator> Element GeneralCascadeMultiplication(const AbstractGroup<Element> &group, Iterator begin, Iterator end)
|
||||||
{
|
{
|
||||||
if (end-begin == 1)
|
if (end-begin == 1)
|
||||||
return group.IntMultiply((*begin).second, (*begin).first);
|
return group.IntMultiply((*begin).second, (*begin).first);
|
||||||
else if (end-begin == 2)
|
else if (end-begin == 2)
|
||||||
return group.CascadeIntMultiply((*begin).second, (*begin).first, (*(begin+1)).second, (*(begin+1)).first);
|
return group.CascadeIntMultiply((*begin).second, (*begin).first, (*(begin+1)).second, (*(begin+1)).first);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Integer q, r;
|
Integer q, r;
|
||||||
Iterator last = end;
|
Iterator last = end;
|
||||||
--last;
|
--last;
|
||||||
|
|
||||||
make_heap(begin, end);
|
make_heap(begin, end);
|
||||||
pop_heap(begin, end);
|
pop_heap(begin, end);
|
||||||
|
|
||||||
while (!!(*begin).first)
|
while (!!(*begin).first)
|
||||||
{
|
{
|
||||||
// (*last).first is largest exponent, (*begin).first is next largest
|
// (*last).first is largest exponent, (*begin).first is next largest
|
||||||
Integer::Divide(r, q, (*last).first, (*begin).first);
|
Integer::Divide(r, q, (*last).first, (*begin).first);
|
||||||
|
|
||||||
if (q == Integer::One())
|
if (q == Integer::One())
|
||||||
group.Accumulate((*begin).second, (*last).second); // avoid overhead of GeneralizedMultiplication()
|
group.Accumulate((*begin).second, (*last).second); // avoid overhead of GeneralizedMultiplication()
|
||||||
else
|
else
|
||||||
group.Accumulate((*begin).second, group.IntMultiply((*last).second, q));
|
group.Accumulate((*begin).second, group.IntMultiply((*last).second, q));
|
||||||
|
|
||||||
(*last).first = r;
|
(*last).first = r;
|
||||||
|
|
||||||
push_heap(begin, end);
|
push_heap(begin, end);
|
||||||
pop_heap(begin, end);
|
pop_heap(begin, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
return group.IntMultiply((*last).second, (*last).first);
|
return group.IntMultiply((*last).second, (*last).first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> T AbstractRing<T>::Exponentiate(const Element &base, const Integer &exponent) const
|
template <class T> T AbstractRing<T>::Exponentiate(const Element &base, const Integer &exponent) const
|
||||||
{
|
{
|
||||||
return MultiplicativeGroup<AbstractRing<T> >(*this).IntMultiply(base, exponent);
|
return MultiplicativeGroup<AbstractRing<T> >(*this).IntMultiply(base, exponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> T AbstractRing<T>::CascadeExponentiate(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const
|
template <class T> T AbstractRing<T>::CascadeExponentiate(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const
|
||||||
{
|
{
|
||||||
return MultiplicativeGroup<AbstractRing<T> >(*this).CascadeIntMultiply(x, e1, y, e2);
|
return MultiplicativeGroup<AbstractRing<T> >(*this).CascadeIntMultiply(x, e1, y, e2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(BREAK_GCC34)
|
#if defined(BREAK_GCC34)
|
||||||
template <class Element, class Iterator> Element GeneralCascadeExponentiation(const AbstractRing<Element> &ring, Iterator begin, Iterator end)
|
template <class Element, class Iterator> Element GeneralCascadeExponentiation(const AbstractRing<Element> &ring, Iterator begin, Iterator end)
|
||||||
{
|
{
|
||||||
MultiplicativeGroup<AbstractRing<Element> > mg(field);
|
MultiplicativeGroup<AbstractRing<Element> > mg(field);
|
||||||
return GeneralCascadeMultiplication<Element>(mg, begin, end);
|
return GeneralCascadeMultiplication<Element>(mg, begin, end);
|
||||||
}
|
}
|
||||||
#endif /* BREAK_GCC34 */
|
#endif /* BREAK_GCC34 */
|
||||||
|
|
||||||
|
|
|
@ -6,100 +6,100 @@
|
||||||
|
|
||||||
unsigned int DERLengthEncode(unsigned int length, byte *output)
|
unsigned int DERLengthEncode(unsigned int length, byte *output)
|
||||||
{
|
{
|
||||||
unsigned int i=0;
|
unsigned int i=0;
|
||||||
if (length <= 0x7f)
|
if (length <= 0x7f)
|
||||||
{
|
{
|
||||||
output[i++] = byte(length);
|
output[i++] = byte(length);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
output[i++] = byte(BytePrecision(length) | 0x80);
|
output[i++] = byte(BytePrecision(length) | 0x80);
|
||||||
for (int j=BytePrecision(length); j; --j)
|
for (int j=BytePrecision(length); j; --j)
|
||||||
{
|
{
|
||||||
output[i++] = byte (length >> (j-1)*8);
|
output[i++] = byte (length >> (j-1)*8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int DERLengthEncode(unsigned int length, BufferedTransformation &bt)
|
unsigned int DERLengthEncode(unsigned int length, BufferedTransformation &bt)
|
||||||
{
|
{
|
||||||
byte buf[10]; // should be more than enough
|
byte buf[10]; // should be more than enough
|
||||||
unsigned int i = DERLengthEncode(length, buf);
|
unsigned int i = DERLengthEncode(length, buf);
|
||||||
assert(i <= 10);
|
assert(i <= 10);
|
||||||
bt.Put(buf, i);
|
bt.Put(buf, i);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BERLengthDecode(BufferedTransformation &bt, unsigned int &length)
|
bool BERLengthDecode(BufferedTransformation &bt, unsigned int &length)
|
||||||
{
|
{
|
||||||
byte b;
|
byte b;
|
||||||
|
|
||||||
if (!bt.Get(b))
|
if (!bt.Get(b))
|
||||||
BERDecodeError();
|
BERDecodeError();
|
||||||
|
|
||||||
if (!(b & 0x80))
|
if (!(b & 0x80))
|
||||||
length = b;
|
length = b;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned int lengthBytes = b & 0x7f;
|
unsigned int lengthBytes = b & 0x7f;
|
||||||
if (bt.MaxRetrieveable() < lengthBytes)
|
if (bt.MaxRetrieveable() < lengthBytes)
|
||||||
BERDecodeError();
|
BERDecodeError();
|
||||||
|
|
||||||
bt.Get(b);
|
bt.Get(b);
|
||||||
while (!b && lengthBytes>1)
|
while (!b && lengthBytes>1)
|
||||||
{
|
{
|
||||||
bt.Get(b);
|
bt.Get(b);
|
||||||
lengthBytes--;
|
lengthBytes--;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (lengthBytes)
|
switch (lengthBytes)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
return false; // indefinite length
|
return false; // indefinite length
|
||||||
case 1:
|
case 1:
|
||||||
length = b;
|
length = b;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
length = b << 8;
|
length = b << 8;
|
||||||
length |= (bt.Get(b), b);
|
length |= (bt.Get(b), b);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
BERDecodeError();
|
BERDecodeError();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
BERSequenceDecoder::BERSequenceDecoder(BufferedTransformation &inQueue)
|
BERSequenceDecoder::BERSequenceDecoder(BufferedTransformation &inQueue)
|
||||||
: inQueue(inQueue)
|
: inQueue(inQueue)
|
||||||
{
|
{
|
||||||
byte b;
|
byte b;
|
||||||
if (!inQueue.Get(b) || b != (SEQUENCE | CONSTRUCTED))
|
if (!inQueue.Get(b) || b != (SEQUENCE | CONSTRUCTED))
|
||||||
BERDecodeError();
|
BERDecodeError();
|
||||||
|
|
||||||
definiteLength = BERLengthDecode(inQueue, length);
|
definiteLength = BERLengthDecode(inQueue, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
BERSequenceDecoder::~BERSequenceDecoder()
|
BERSequenceDecoder::~BERSequenceDecoder()
|
||||||
{
|
{
|
||||||
if (!definiteLength)
|
if (!definiteLength)
|
||||||
{ // remove end-of-content octects
|
{ // remove end-of-content octects
|
||||||
word16 i;
|
word16 i;
|
||||||
if (!inQueue.GetShort(i) || (i!=0))
|
if (!inQueue.GetShort(i) || (i!=0))
|
||||||
BERDecodeError();
|
BERDecodeError();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DERSequenceEncoder::DERSequenceEncoder(BufferedTransformation &outQueue)
|
DERSequenceEncoder::DERSequenceEncoder(BufferedTransformation &outQueue)
|
||||||
: outQueue(outQueue)
|
: outQueue(outQueue)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
DERSequenceEncoder::~DERSequenceEncoder()
|
DERSequenceEncoder::~DERSequenceEncoder()
|
||||||
{
|
{
|
||||||
unsigned int length = (unsigned int)CurrentSize();
|
unsigned int length = (unsigned int)CurrentSize();
|
||||||
outQueue.Put(SEQUENCE | CONSTRUCTED);
|
outQueue.Put(SEQUENCE | CONSTRUCTED);
|
||||||
DERLengthEncode(length, outQueue);
|
DERLengthEncode(length, outQueue);
|
||||||
TransferTo(outQueue);
|
TransferTo(outQueue);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,34 +24,34 @@ bool BERLengthDecode(BufferedTransformation &, unsigned int &);
|
||||||
class BERSequenceDecoder : public BufferedTransformation
|
class BERSequenceDecoder : public BufferedTransformation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BERSequenceDecoder(BufferedTransformation &inQueue);
|
BERSequenceDecoder(BufferedTransformation &inQueue);
|
||||||
~BERSequenceDecoder();
|
~BERSequenceDecoder();
|
||||||
|
|
||||||
void Put(byte) {}
|
void Put(byte) {}
|
||||||
void Put(const byte *, unsigned int) {}
|
void Put(const byte *, unsigned int) {}
|
||||||
|
|
||||||
unsigned long MaxRetrieveable()
|
unsigned long MaxRetrieveable()
|
||||||
{return inQueue.MaxRetrieveable();}
|
{return inQueue.MaxRetrieveable();}
|
||||||
unsigned int Get(byte &outByte)
|
unsigned int Get(byte &outByte)
|
||||||
{return inQueue.Get(outByte);}
|
{return inQueue.Get(outByte);}
|
||||||
unsigned int Get(byte *outString, unsigned int getMax)
|
unsigned int Get(byte *outString, unsigned int getMax)
|
||||||
{return inQueue.Get(outString, getMax);}
|
{return inQueue.Get(outString, getMax);}
|
||||||
unsigned int Peek(byte &outByte) const
|
unsigned int Peek(byte &outByte) const
|
||||||
{return inQueue.Peek(outByte);}
|
{return inQueue.Peek(outByte);}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BufferedTransformation &inQueue;
|
BufferedTransformation &inQueue;
|
||||||
bool definiteLength;
|
bool definiteLength;
|
||||||
unsigned int length;
|
unsigned int length;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DERSequenceEncoder : public ByteQueue
|
class DERSequenceEncoder : public ByteQueue
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DERSequenceEncoder(BufferedTransformation &outQueue);
|
DERSequenceEncoder(BufferedTransformation &outQueue);
|
||||||
~DERSequenceEncoder();
|
~DERSequenceEncoder();
|
||||||
private:
|
private:
|
||||||
BufferedTransformation &outQueue;
|
BufferedTransformation &outQueue;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -105,31 +105,31 @@ typedef unsigned __int64 word64;
|
||||||
|
|
||||||
#elif defined(_KCC)
|
#elif defined(_KCC)
|
||||||
|
|
||||||
#if defined(_ALPHA)
|
#if defined(_ALPHA)
|
||||||
|
|
||||||
typedef unsigned int word;
|
typedef unsigned int word;
|
||||||
typedef unsigned long dword;
|
typedef unsigned long dword;
|
||||||
#define WORD64_AVAILABLE
|
#define WORD64_AVAILABLE
|
||||||
typedef unsigned long word64;
|
typedef unsigned long word64;
|
||||||
#define W64LIT(x) x##LL
|
#define W64LIT(x) x##LL
|
||||||
|
|
||||||
#elif defined(_IRIX)
|
#elif defined(_IRIX)
|
||||||
|
|
||||||
typedef unsigned long word;
|
typedef unsigned long word;
|
||||||
typedef unsigned long long dword;
|
typedef unsigned long long dword;
|
||||||
#define WORD64_AVAILABLE
|
#define WORD64_AVAILABLE
|
||||||
typedef unsigned long long word64;
|
typedef unsigned long long word64;
|
||||||
#define W64LIT(x) x##LL
|
#define W64LIT(x) x##LL
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
typedef unsigned long word;
|
typedef unsigned long word;
|
||||||
typedef unsigned long long dword;
|
typedef unsigned long long dword;
|
||||||
#define WORD64_AVAILABLE
|
#define WORD64_AVAILABLE
|
||||||
typedef unsigned long long word64;
|
typedef unsigned long long word64;
|
||||||
#define W64LIT(x) x##LL
|
#define W64LIT(x) x##LL
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#elif defined(_SUNPRO)
|
#elif defined(_SUNPRO)
|
||||||
|
|
||||||
|
|
|
@ -6,39 +6,39 @@
|
||||||
|
|
||||||
unsigned int RandomNumberGenerator::GetBit()
|
unsigned int RandomNumberGenerator::GetBit()
|
||||||
{
|
{
|
||||||
return Parity(GetByte());
|
return Parity(GetByte());
|
||||||
}
|
}
|
||||||
|
|
||||||
void RandomNumberGenerator::GetBlock(byte *output, unsigned int size)
|
void RandomNumberGenerator::GetBlock(byte *output, unsigned int size)
|
||||||
{
|
{
|
||||||
while (size--)
|
while (size--)
|
||||||
*output++ = GetByte();
|
*output++ = GetByte();
|
||||||
}
|
}
|
||||||
|
|
||||||
word32 RandomNumberGenerator::GetLong(word32 min, word32 max)
|
word32 RandomNumberGenerator::GetLong(word32 min, word32 max)
|
||||||
{
|
{
|
||||||
word32 range = max-min;
|
word32 range = max-min;
|
||||||
const int maxBytes = BytePrecision(range);
|
const int maxBytes = BytePrecision(range);
|
||||||
const int maxBits = BitPrecision(range);
|
const int maxBits = BitPrecision(range);
|
||||||
|
|
||||||
word32 value;
|
word32 value;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
value = 0;
|
value = 0;
|
||||||
for (int i=0; i<maxBytes; i++)
|
for (int i=0; i<maxBytes; i++)
|
||||||
value = (value << 8) | GetByte();
|
value = (value << 8) | GetByte();
|
||||||
|
|
||||||
value = Crop(value, maxBits);
|
value = Crop(value, maxBits);
|
||||||
} while (value > range);
|
} while (value > range);
|
||||||
|
|
||||||
return value+min;
|
return value+min;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StreamCipher::ProcessString(byte *outString, const byte *inString, unsigned int length)
|
void StreamCipher::ProcessString(byte *outString, const byte *inString, unsigned int length)
|
||||||
{
|
{
|
||||||
while(length--)
|
while(length--)
|
||||||
*outString++ = ProcessByte(*inString++);
|
*outString++ = ProcessByte(*inString++);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StreamCipher::ProcessString(byte *inoutString, unsigned int length)
|
void StreamCipher::ProcessString(byte *inoutString, unsigned int length)
|
||||||
|
@ -49,131 +49,131 @@ void StreamCipher::ProcessString(byte *inoutString, unsigned int length)
|
||||||
|
|
||||||
bool MessageAuthenticationCode::Verify(const byte *macIn)
|
bool MessageAuthenticationCode::Verify(const byte *macIn)
|
||||||
{
|
{
|
||||||
SecByteBlock mac(DigestSize());
|
SecByteBlock mac(DigestSize());
|
||||||
Final(mac);
|
Final(mac);
|
||||||
return memcmp(mac, macIn, DigestSize()) == 0;
|
return memcmp(mac, macIn, DigestSize()) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BufferedTransformation::TransferTo(BufferedTransformation &target)
|
void BufferedTransformation::TransferTo(BufferedTransformation &target)
|
||||||
{
|
{
|
||||||
SecByteBlock buf(256);
|
SecByteBlock buf(256);
|
||||||
unsigned int l;
|
unsigned int l;
|
||||||
|
|
||||||
while ((l=Get(buf, 256)) != 0)
|
while ((l=Get(buf, 256)) != 0)
|
||||||
target.Put(buf, l);
|
target.Put(buf, l);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int BufferedTransformation::TransferTo(BufferedTransformation &target, unsigned int size)
|
unsigned int BufferedTransformation::TransferTo(BufferedTransformation &target, unsigned int size)
|
||||||
{
|
{
|
||||||
SecByteBlock buf(256);
|
SecByteBlock buf(256);
|
||||||
unsigned int l, total = 0;
|
unsigned int l, total = 0;
|
||||||
|
|
||||||
while (size && (l=Get(buf, STDMIN(size, 256U))))
|
while (size && (l=Get(buf, STDMIN(size, 256U))))
|
||||||
{
|
{
|
||||||
target.Put(buf, l);
|
target.Put(buf, l);
|
||||||
size -= l;
|
size -= l;
|
||||||
total += l;
|
total += l;
|
||||||
}
|
}
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BufferedTransformation::PutShort(word16 value, bool highFirst)
|
void BufferedTransformation::PutShort(word16 value, bool highFirst)
|
||||||
{
|
{
|
||||||
if (highFirst)
|
if (highFirst)
|
||||||
{
|
{
|
||||||
Put(value>>8);
|
Put(value>>8);
|
||||||
Put(byte(value));
|
Put(byte(value));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Put(byte(value));
|
Put(byte(value));
|
||||||
Put(value>>8);
|
Put(value>>8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BufferedTransformation::PutLong(word32 value, bool highFirst)
|
void BufferedTransformation::PutLong(word32 value, bool highFirst)
|
||||||
{
|
{
|
||||||
if (highFirst)
|
if (highFirst)
|
||||||
{
|
{
|
||||||
for (int i=0; i<4; i++)
|
for (int i=0; i<4; i++)
|
||||||
Put(byte(value>>((3-i)*8)));
|
Put(byte(value>>((3-i)*8)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int i=0; i<4; i++)
|
for (int i=0; i<4; i++)
|
||||||
Put(byte(value>>(i*8)));
|
Put(byte(value>>(i*8)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int BufferedTransformation::GetShort(word16 &value, bool highFirst)
|
int BufferedTransformation::GetShort(word16 &value, bool highFirst)
|
||||||
{
|
{
|
||||||
if (MaxRetrieveable()<2)
|
if (MaxRetrieveable()<2)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
byte buf[2];
|
byte buf[2];
|
||||||
Get(buf, 2);
|
Get(buf, 2);
|
||||||
|
|
||||||
if (highFirst)
|
if (highFirst)
|
||||||
value = (buf[0] << 8) | buf[1];
|
value = (buf[0] << 8) | buf[1];
|
||||||
else
|
else
|
||||||
value = (buf[1] << 8) | buf[0];
|
value = (buf[1] << 8) | buf[0];
|
||||||
|
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BufferedTransformation::GetLong(word32 &value, bool highFirst)
|
int BufferedTransformation::GetLong(word32 &value, bool highFirst)
|
||||||
{
|
{
|
||||||
if (MaxRetrieveable()<4)
|
if (MaxRetrieveable()<4)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
byte buf[4];
|
byte buf[4];
|
||||||
Get(buf, 4);
|
Get(buf, 4);
|
||||||
|
|
||||||
if (highFirst)
|
if (highFirst)
|
||||||
value = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf [3];
|
value = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf [3];
|
||||||
else
|
else
|
||||||
value = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf [0];
|
value = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf [0];
|
||||||
|
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int BufferedTransformation::Skip(unsigned int skipMax)
|
unsigned int BufferedTransformation::Skip(unsigned int skipMax)
|
||||||
{
|
{
|
||||||
byte b;
|
byte b;
|
||||||
unsigned int skipActual=0;
|
unsigned int skipActual=0;
|
||||||
|
|
||||||
while (skipMax-- && Get(b))
|
while (skipMax-- && Get(b))
|
||||||
skipActual++;
|
skipActual++;
|
||||||
return skipActual;
|
return skipActual;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int PK_FixedLengthCryptoSystem::MaxPlainTextLength(unsigned int cipherTextLength) const
|
unsigned int PK_FixedLengthCryptoSystem::MaxPlainTextLength(unsigned int cipherTextLength) const
|
||||||
{
|
{
|
||||||
if (cipherTextLength == CipherTextLength())
|
if (cipherTextLength == CipherTextLength())
|
||||||
return MaxPlainTextLength();
|
return MaxPlainTextLength();
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int PK_FixedLengthCryptoSystem::CipherTextLength(unsigned int plainTextLength) const
|
unsigned int PK_FixedLengthCryptoSystem::CipherTextLength(unsigned int plainTextLength) const
|
||||||
{
|
{
|
||||||
if (plainTextLength <= MaxPlainTextLength())
|
if (plainTextLength <= MaxPlainTextLength())
|
||||||
return CipherTextLength();
|
return CipherTextLength();
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int PK_FixedLengthDecryptor::Decrypt(const byte *cipherText, unsigned int cipherTextLength, byte *plainText)
|
unsigned int PK_FixedLengthDecryptor::Decrypt(const byte *cipherText, unsigned int cipherTextLength, byte *plainText)
|
||||||
{
|
{
|
||||||
if (cipherTextLength != CipherTextLength())
|
if (cipherTextLength != CipherTextLength())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return Decrypt(cipherText, plainText);
|
return Decrypt(cipherText, plainText);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PK_VerifierWithRecovery::Verify(const byte *message, unsigned int messageLength, const byte *signature)
|
bool PK_VerifierWithRecovery::Verify(const byte *message, unsigned int messageLength, const byte *signature)
|
||||||
{
|
{
|
||||||
SecByteBlock recovered(MaxMessageLength());
|
SecByteBlock recovered(MaxMessageLength());
|
||||||
unsigned int rLen = Recover(signature, recovered);
|
unsigned int rLen = Recover(signature, recovered);
|
||||||
return (rLen==messageLength && memcmp(recovered, message, rLen)==0);
|
return (rLen==messageLength && memcmp(recovered, message, rLen)==0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,53 +14,53 @@
|
||||||
class CryptlibException : public std::exception
|
class CryptlibException : public std::exception
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit CryptlibException(const std::string& s) : m_what(s) {}
|
explicit CryptlibException(const std::string& s) : m_what(s) {}
|
||||||
virtual ~CryptlibException() throw() {}
|
virtual ~CryptlibException() throw() {}
|
||||||
const char *what() const throw() {return (m_what.c_str());}
|
const char *what() const throw() {return (m_what.c_str());}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_what;
|
std::string m_what;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// used to specify a direction for a cipher to operate in (encrypt or decrypt)
|
/// used to specify a direction for a cipher to operate in (encrypt or decrypt)
|
||||||
enum CipherDir {
|
enum CipherDir {
|
||||||
///
|
///
|
||||||
ENCRYPTION,
|
ENCRYPTION,
|
||||||
///
|
///
|
||||||
DECRYPTION};
|
DECRYPTION};
|
||||||
|
|
||||||
|
|
||||||
/// abstract base class for block ciphers
|
/// abstract base class for block ciphers
|
||||||
|
|
||||||
/** A particular derived class may change state as blocks are processed,
|
/** A particular derived class may change state as blocks are processed,
|
||||||
so the ProcessBlock() functions are not specified to be const.
|
so the ProcessBlock() functions are not specified to be const.
|
||||||
|
|
||||||
However, most classes derived from BlockTransformation are block ciphers
|
However, most classes derived from BlockTransformation are block ciphers
|
||||||
in ECB mode (for example the DESEncryption class), which are stateless.
|
in ECB mode (for example the DESEncryption class), which are stateless.
|
||||||
These classes should not be used directly, but only in combination with
|
These classes should not be used directly, but only in combination with
|
||||||
a mode class (see \Ref{Mode}). However, if you know what you are doing, and
|
a mode class (see \Ref{Mode}). However, if you know what you are doing, and
|
||||||
need to call ProcessBlock() on a const ECB cipher object, you can safely
|
need to call ProcessBlock() on a const ECB cipher object, you can safely
|
||||||
cast away its constness.
|
cast away its constness.
|
||||||
|
|
||||||
Note: BlockTransformation objects may assume that pointers to input and
|
Note: BlockTransformation objects may assume that pointers to input and
|
||||||
output blocks are aligned on 32-bit word boundaries.
|
output blocks are aligned on 32-bit word boundaries.
|
||||||
*/
|
*/
|
||||||
class BlockTransformation
|
class BlockTransformation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
///
|
///
|
||||||
virtual ~BlockTransformation() {}
|
virtual ~BlockTransformation() {}
|
||||||
|
|
||||||
/// encrypt or decrypt one block in place
|
/// encrypt or decrypt one block in place
|
||||||
//* Precondition: size of inoutBlock == BlockSize().
|
//* Precondition: size of inoutBlock == BlockSize().
|
||||||
virtual void ProcessBlock(byte *inoutBlock) =0;
|
virtual void ProcessBlock(byte *inoutBlock) =0;
|
||||||
|
|
||||||
/// encrypt or decrypt one block, may assume inBlock != outBlock
|
/// encrypt or decrypt one block, may assume inBlock != outBlock
|
||||||
//* Precondition: size of inBlock and outBlock == BlockSize().
|
//* Precondition: size of inBlock and outBlock == BlockSize().
|
||||||
virtual void ProcessBlock(const byte *inBlock, byte *outBlock) =0;
|
virtual void ProcessBlock(const byte *inBlock, byte *outBlock) =0;
|
||||||
|
|
||||||
/// block size of the cipher in bytes
|
/// block size of the cipher in bytes
|
||||||
virtual unsigned int BlockSize() const =0;
|
virtual unsigned int BlockSize() const =0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -69,275 +69,275 @@ public:
|
||||||
class StreamCipher
|
class StreamCipher
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
///
|
///
|
||||||
virtual ~StreamCipher() {}
|
virtual ~StreamCipher() {}
|
||||||
|
|
||||||
/// encrypt or decrypt one byte
|
/// encrypt or decrypt one byte
|
||||||
virtual byte ProcessByte(byte input) =0;
|
virtual byte ProcessByte(byte input) =0;
|
||||||
|
|
||||||
/// encrypt or decrypt an array of bytes of specified length in place
|
/// encrypt or decrypt an array of bytes of specified length in place
|
||||||
virtual void ProcessString(byte *inoutString, unsigned int length);
|
virtual void ProcessString(byte *inoutString, unsigned int length);
|
||||||
/// encrypt or decrypt an array of bytes of specified length, may assume inString != outString
|
/// encrypt or decrypt an array of bytes of specified length, may assume inString != outString
|
||||||
virtual void ProcessString(byte *outString, const byte *inString, unsigned int length);
|
virtual void ProcessString(byte *outString, const byte *inString, unsigned int length);
|
||||||
};
|
};
|
||||||
|
|
||||||
/// abstract base class for random access stream ciphers
|
/// abstract base class for random access stream ciphers
|
||||||
|
|
||||||
class RandomAccessStreamCipher : public virtual StreamCipher
|
class RandomAccessStreamCipher : public virtual StreamCipher
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
///
|
///
|
||||||
virtual ~RandomAccessStreamCipher() {}
|
virtual ~RandomAccessStreamCipher() {}
|
||||||
/*/ specify that the next byte to be processed is at absolute position n
|
/*/ specify that the next byte to be processed is at absolute position n
|
||||||
in the plaintext/ciphertext stream */
|
in the plaintext/ciphertext stream */
|
||||||
virtual void Seek(unsigned long n) =0;
|
virtual void Seek(unsigned long n) =0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// abstract base class for random number generators
|
/// abstract base class for random number generators
|
||||||
/** All return values are uniformly distributed over the range specified.
|
/** All return values are uniformly distributed over the range specified.
|
||||||
*/
|
*/
|
||||||
class RandomNumberGenerator
|
class RandomNumberGenerator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
///
|
///
|
||||||
virtual ~RandomNumberGenerator() {}
|
virtual ~RandomNumberGenerator() {}
|
||||||
|
|
||||||
/// generate new random byte and return it
|
/// generate new random byte and return it
|
||||||
virtual byte GetByte() =0;
|
virtual byte GetByte() =0;
|
||||||
|
|
||||||
/// generate new random bit and return it
|
/// generate new random bit and return it
|
||||||
/** Default implementation is to call GetByte() and return its parity. */
|
/** Default implementation is to call GetByte() and return its parity. */
|
||||||
virtual unsigned int GetBit();
|
virtual unsigned int GetBit();
|
||||||
|
|
||||||
/// generate a random 32 bit word in the range min to max, inclusive
|
/// generate a random 32 bit word in the range min to max, inclusive
|
||||||
virtual word32 GetLong(word32 a=0, word32 b=0xffffffffL);
|
virtual word32 GetLong(word32 a=0, word32 b=0xffffffffL);
|
||||||
/// generate a random 16 bit word in the range min to max, inclusive
|
/// generate a random 16 bit word in the range min to max, inclusive
|
||||||
virtual word16 GetShort(word16 a=0, word16 b=0xffff)
|
virtual word16 GetShort(word16 a=0, word16 b=0xffff)
|
||||||
{return (word16)GetLong(a, b);}
|
{return (word16)GetLong(a, b);}
|
||||||
|
|
||||||
/// generate random array of bytes
|
/// generate random array of bytes
|
||||||
//* Default implementation is to call GetByte size times.
|
//* Default implementation is to call GetByte size times.
|
||||||
virtual void GetBlock(byte *output, unsigned int size);
|
virtual void GetBlock(byte *output, unsigned int size);
|
||||||
};
|
};
|
||||||
|
|
||||||
/// randomly shuffle the specified array, resulting permutation is uniformly distributed
|
/// randomly shuffle the specified array, resulting permutation is uniformly distributed
|
||||||
template <class T> void Shuffle(RandomNumberGenerator &rng, T *array, unsigned int size)
|
template <class T> void Shuffle(RandomNumberGenerator &rng, T *array, unsigned int size)
|
||||||
{
|
{
|
||||||
while (--size)
|
while (--size)
|
||||||
swap(array[size], array[(unsigned int)rng.GetLong(0, size)]);
|
swap(array[size], array[(unsigned int)rng.GetLong(0, size)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// abstract base class for hash functions
|
/// abstract base class for hash functions
|
||||||
/** HashModule objects are stateful. They are created in an initial state,
|
/** HashModule objects are stateful. They are created in an initial state,
|
||||||
change state as Update() is called, and return to the initial
|
change state as Update() is called, and return to the initial
|
||||||
state when Final() is called. This interface allows a large message to
|
state when Final() is called. This interface allows a large message to
|
||||||
be hashed in pieces by calling Update() on each piece followed by
|
be hashed in pieces by calling Update() on each piece followed by
|
||||||
calling Final().
|
calling Final().
|
||||||
*/
|
*/
|
||||||
class HashModule
|
class HashModule
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
///
|
///
|
||||||
virtual ~HashModule() {}
|
virtual ~HashModule() {}
|
||||||
|
|
||||||
/// process more input
|
/// process more input
|
||||||
virtual void Update(const byte *input, unsigned int length) =0;
|
virtual void Update(const byte *input, unsigned int length) =0;
|
||||||
|
|
||||||
/*/ calculate hash for the current message (the concatenation of all
|
/*/ calculate hash for the current message (the concatenation of all
|
||||||
inputs passed in via Update()), then reinitialize the object */
|
inputs passed in via Update()), then reinitialize the object */
|
||||||
//* Precondition: size of digest == DigestSize().
|
//* Precondition: size of digest == DigestSize().
|
||||||
virtual void Final(byte *digest) =0;
|
virtual void Final(byte *digest) =0;
|
||||||
|
|
||||||
/// size of the hash returned by Final()
|
/// size of the hash returned by Final()
|
||||||
virtual unsigned int DigestSize() const =0;
|
virtual unsigned int DigestSize() const =0;
|
||||||
|
|
||||||
/// use this if your input is short and you don't want to call Update() and Final() seperately
|
/// use this if your input is short and you don't want to call Update() and Final() seperately
|
||||||
virtual void CalculateDigest(byte *digest, const byte *input, int length)
|
virtual void CalculateDigest(byte *digest, const byte *input, int length)
|
||||||
{Update(input, length); Final(digest);}
|
{Update(input, length); Final(digest);}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// abstract base class for message authentication codes
|
/// abstract base class for message authentication codes
|
||||||
|
|
||||||
/** The main differences between a MAC and an hash function (in terms of
|
/** The main differences between a MAC and an hash function (in terms of
|
||||||
programmatic interface) is that a MAC is keyed, and that calculating
|
programmatic interface) is that a MAC is keyed, and that calculating
|
||||||
a MAC for the same message twice may produce two different results so
|
a MAC for the same message twice may produce two different results so
|
||||||
verifying a MAC may not be simply recalculating it and doing a bitwise
|
verifying a MAC may not be simply recalculating it and doing a bitwise
|
||||||
comparison.
|
comparison.
|
||||||
*/
|
*/
|
||||||
class MessageAuthenticationCode : public virtual HashModule
|
class MessageAuthenticationCode : public virtual HashModule
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
///
|
///
|
||||||
virtual ~MessageAuthenticationCode() {}
|
virtual ~MessageAuthenticationCode() {}
|
||||||
|
|
||||||
/// verify that mac is a valid MAC for the current message, then reinitialize the object
|
/// verify that mac is a valid MAC for the current message, then reinitialize the object
|
||||||
/** Default implementation is to call Final() and do a bitwise comparison
|
/** Default implementation is to call Final() and do a bitwise comparison
|
||||||
between its output and mac. */
|
between its output and mac. */
|
||||||
virtual bool Verify(const byte *mac);
|
virtual bool Verify(const byte *mac);
|
||||||
|
|
||||||
/// use this if your input is short and you don't want to call Update() and Verify() seperately
|
/// use this if your input is short and you don't want to call Update() and Verify() seperately
|
||||||
virtual bool VerifyMAC(const byte *mac, const byte *input, int length)
|
virtual bool VerifyMAC(const byte *mac, const byte *input, int length)
|
||||||
{Update(input, length); return Verify(mac);}
|
{Update(input, length); return Verify(mac);}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// abstract base class for buffered transformations
|
/// abstract base class for buffered transformations
|
||||||
|
|
||||||
/** BufferedTransformation is a generalization of \Ref{BlockTransformation},
|
/** BufferedTransformation is a generalization of \Ref{BlockTransformation},
|
||||||
\Ref{StreamCipher}, and \Ref{HashModule}.
|
\Ref{StreamCipher}, and \Ref{HashModule}.
|
||||||
|
|
||||||
A buffered transformation is an object that takes a stream of bytes
|
A buffered transformation is an object that takes a stream of bytes
|
||||||
as input (this may be done in stages), does some computation on them, and
|
as input (this may be done in stages), does some computation on them, and
|
||||||
then places the result into an internal buffer for later retrieval. Any
|
then places the result into an internal buffer for later retrieval. Any
|
||||||
partial result already in the output buffer is not modified by further
|
partial result already in the output buffer is not modified by further
|
||||||
input.
|
input.
|
||||||
|
|
||||||
Computation is generally done as soon as possible, but some buffering
|
Computation is generally done as soon as possible, but some buffering
|
||||||
on the input may be done for performance reasons.
|
on the input may be done for performance reasons.
|
||||||
*/
|
*/
|
||||||
class BufferedTransformation
|
class BufferedTransformation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
///
|
///
|
||||||
virtual ~BufferedTransformation() {}
|
virtual ~BufferedTransformation() {}
|
||||||
|
|
||||||
//@Man: INPUT
|
//@Man: INPUT
|
||||||
//@{
|
//@{
|
||||||
/// input a byte for processing
|
/// input a byte for processing
|
||||||
virtual void Put(byte inByte) =0;
|
virtual void Put(byte inByte) =0;
|
||||||
/// input multiple bytes
|
/// input multiple bytes
|
||||||
virtual void Put(const byte *inString, unsigned int length) =0;
|
virtual void Put(const byte *inString, unsigned int length) =0;
|
||||||
/// signal that no more input is available
|
/// signal that no more input is available
|
||||||
virtual void InputFinished() {}
|
virtual void InputFinished() {}
|
||||||
|
|
||||||
/// input a 16-bit word, big-endian or little-endian depending on highFirst
|
/// input a 16-bit word, big-endian or little-endian depending on highFirst
|
||||||
void PutShort(word16 value, bool highFirst=true);
|
void PutShort(word16 value, bool highFirst=true);
|
||||||
/// input a 32-bit word
|
/// input a 32-bit word
|
||||||
void PutLong(word32 value, bool highFirst=true);
|
void PutLong(word32 value, bool highFirst=true);
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
//@Man: RETRIEVAL
|
//@Man: RETRIEVAL
|
||||||
//@{
|
//@{
|
||||||
/// returns number of bytes that is currently ready for retrieval
|
/// returns number of bytes that is currently ready for retrieval
|
||||||
/** All retrieval functions return the actual number of bytes
|
/** All retrieval functions return the actual number of bytes
|
||||||
retrieved, which is the lesser of the request number and
|
retrieved, which is the lesser of the request number and
|
||||||
MaxRetrieveable(). */
|
MaxRetrieveable(). */
|
||||||
virtual unsigned long MaxRetrieveable() =0;
|
virtual unsigned long MaxRetrieveable() =0;
|
||||||
|
|
||||||
/// try to retrieve a single byte
|
/// try to retrieve a single byte
|
||||||
virtual unsigned int Get(byte &outByte) =0;
|
virtual unsigned int Get(byte &outByte) =0;
|
||||||
/// try to retrieve multiple bytes
|
/// try to retrieve multiple bytes
|
||||||
virtual unsigned int Get(byte *outString, unsigned int getMax) =0;
|
virtual unsigned int Get(byte *outString, unsigned int getMax) =0;
|
||||||
|
|
||||||
/// try to retrieve a 16-bit word, big-endian or little-endian depending on highFirst
|
/// try to retrieve a 16-bit word, big-endian or little-endian depending on highFirst
|
||||||
int GetShort(word16 &value, bool highFirst=true);
|
int GetShort(word16 &value, bool highFirst=true);
|
||||||
/// try to retrieve a 32-bit word
|
/// try to retrieve a 32-bit word
|
||||||
int GetLong(word32 &value, bool highFirst=true);
|
int GetLong(word32 &value, bool highFirst=true);
|
||||||
|
|
||||||
/// move all of the buffered output to target as input
|
/// move all of the buffered output to target as input
|
||||||
virtual void TransferTo(BufferedTransformation &target);
|
virtual void TransferTo(BufferedTransformation &target);
|
||||||
/// same as above but only transfer up to transferMax bytes
|
/// same as above but only transfer up to transferMax bytes
|
||||||
virtual unsigned int TransferTo(BufferedTransformation &target, unsigned int transferMax);
|
virtual unsigned int TransferTo(BufferedTransformation &target, unsigned int transferMax);
|
||||||
|
|
||||||
/// peek at the next byte without removing it from the output buffer
|
/// peek at the next byte without removing it from the output buffer
|
||||||
virtual unsigned int Peek(byte &outByte) const =0;
|
virtual unsigned int Peek(byte &outByte) const =0;
|
||||||
|
|
||||||
/// discard some bytes from the output buffer
|
/// discard some bytes from the output buffer
|
||||||
unsigned int Skip(unsigned int skipMax);
|
unsigned int Skip(unsigned int skipMax);
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
//@Man: ATTACHMENT
|
//@Man: ATTACHMENT
|
||||||
//@{
|
//@{
|
||||||
/** Some BufferedTransformation objects (e.g. \Ref{Filter} objects)
|
/** Some BufferedTransformation objects (e.g. \Ref{Filter} objects)
|
||||||
allow other BufferedTransformation objects to be attached. When
|
allow other BufferedTransformation objects to be attached. When
|
||||||
this is done, the first object instead of buffering its output,
|
this is done, the first object instead of buffering its output,
|
||||||
sents that output to the attached object as input. See the
|
sents that output to the attached object as input. See the
|
||||||
documentation for the \Ref{Filter} class for the details.
|
documentation for the \Ref{Filter} class for the details.
|
||||||
*/
|
*/
|
||||||
///
|
///
|
||||||
virtual bool Attachable() {return false;}
|
virtual bool Attachable() {return false;}
|
||||||
///
|
///
|
||||||
virtual void Detach(BufferedTransformation *p = 0) {} // NULL is undefined at this point
|
virtual void Detach(BufferedTransformation *p = 0) {} // NULL is undefined at this point
|
||||||
///
|
///
|
||||||
virtual void Attach(BufferedTransformation *) {}
|
virtual void Attach(BufferedTransformation *) {}
|
||||||
/// call InputFinished() for all attached objects
|
/// call InputFinished() for all attached objects
|
||||||
virtual void Close() {InputFinished();}
|
virtual void Close() {InputFinished();}
|
||||||
//@}
|
//@}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// abstract base class for public-key encryptors and decryptors
|
/// abstract base class for public-key encryptors and decryptors
|
||||||
|
|
||||||
/** This class provides an interface common to encryptors and decryptors
|
/** This class provides an interface common to encryptors and decryptors
|
||||||
for querying their plaintext and ciphertext lengths.
|
for querying their plaintext and ciphertext lengths.
|
||||||
*/
|
*/
|
||||||
class PK_CryptoSystem
|
class PK_CryptoSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
///
|
///
|
||||||
virtual ~PK_CryptoSystem() {}
|
virtual ~PK_CryptoSystem() {}
|
||||||
|
|
||||||
/// maximum length of plaintext for a given ciphertext length
|
/// maximum length of plaintext for a given ciphertext length
|
||||||
//* This function returns 0 if cipherTextLength is not valid (too long or too short).
|
//* This function returns 0 if cipherTextLength is not valid (too long or too short).
|
||||||
virtual unsigned int MaxPlainTextLength(unsigned int cipherTextLength) const =0;
|
virtual unsigned int MaxPlainTextLength(unsigned int cipherTextLength) const =0;
|
||||||
|
|
||||||
/// calculate length of ciphertext given length of plaintext
|
/// calculate length of ciphertext given length of plaintext
|
||||||
//* This function returns 0 if plainTextLength is not valid (too long).
|
//* This function returns 0 if plainTextLength is not valid (too long).
|
||||||
virtual unsigned int CipherTextLength(unsigned int plainTextLength) const =0;
|
virtual unsigned int CipherTextLength(unsigned int plainTextLength) const =0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// abstract base class for public-key encryptors
|
/// abstract base class for public-key encryptors
|
||||||
|
|
||||||
/** An encryptor is also a public encryption key. It contains both the
|
/** An encryptor is also a public encryption key. It contains both the
|
||||||
key and the algorithm to perform the encryption.
|
key and the algorithm to perform the encryption.
|
||||||
*/
|
*/
|
||||||
class PK_Encryptor : public virtual PK_CryptoSystem
|
class PK_Encryptor : public virtual PK_CryptoSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// encrypt a byte string
|
/// encrypt a byte string
|
||||||
/** Preconditions:
|
/** Preconditions:
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item CipherTextLength(plainTextLength) != 0 (i.e., plainText isn't too long)
|
\item CipherTextLength(plainTextLength) != 0 (i.e., plainText isn't too long)
|
||||||
\item size of cipherText == CipherTextLength(plainTextLength)
|
\item size of cipherText == CipherTextLength(plainTextLength)
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
*/
|
*/
|
||||||
virtual void Encrypt(RandomNumberGenerator &rng, const byte *plainText, unsigned int plainTextLength, byte *cipherText) =0;
|
virtual void Encrypt(RandomNumberGenerator &rng, const byte *plainText, unsigned int plainTextLength, byte *cipherText) =0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// abstract base class for public-key decryptors
|
/// abstract base class for public-key decryptors
|
||||||
|
|
||||||
/** An decryptor is also a private decryption key. It contains both the
|
/** An decryptor is also a private decryption key. It contains both the
|
||||||
key and the algorithm to perform the decryption.
|
key and the algorithm to perform the decryption.
|
||||||
*/
|
*/
|
||||||
class PK_Decryptor : public virtual PK_CryptoSystem
|
class PK_Decryptor : public virtual PK_CryptoSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// decrypt a byte string, and return the length of plaintext
|
/// decrypt a byte string, and return the length of plaintext
|
||||||
/** Precondition: size of plainText == MaxPlainTextLength(cipherTextLength)
|
/** Precondition: size of plainText == MaxPlainTextLength(cipherTextLength)
|
||||||
bytes.
|
bytes.
|
||||||
|
|
||||||
The function returns the actual length of the plaintext, or 0
|
The function returns the actual length of the plaintext, or 0
|
||||||
if decryption fails.
|
if decryption fails.
|
||||||
*/
|
*/
|
||||||
virtual unsigned int Decrypt(const byte *cipherText, unsigned int cipherTextLength, byte *plainText) =0;
|
virtual unsigned int Decrypt(const byte *cipherText, unsigned int cipherTextLength, byte *plainText) =0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// abstract base class for encryptors and decryptors with fixed length ciphertext
|
/// abstract base class for encryptors and decryptors with fixed length ciphertext
|
||||||
|
|
||||||
/** A simplified interface (as embodied in this
|
/** A simplified interface (as embodied in this
|
||||||
class and its subclasses) is provided for crypto systems (such
|
class and its subclasses) is provided for crypto systems (such
|
||||||
as RSA) whose ciphertext depend only on the key, not on the length
|
as RSA) whose ciphertext depend only on the key, not on the length
|
||||||
of the plaintext. The maximum plaintext length also depend only on
|
of the plaintext. The maximum plaintext length also depend only on
|
||||||
the key.
|
the key.
|
||||||
*/
|
*/
|
||||||
class PK_FixedLengthCryptoSystem : public virtual PK_CryptoSystem
|
class PK_FixedLengthCryptoSystem : public virtual PK_CryptoSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
///
|
///
|
||||||
virtual unsigned int MaxPlainTextLength() const =0;
|
virtual unsigned int MaxPlainTextLength() const =0;
|
||||||
///
|
///
|
||||||
virtual unsigned int CipherTextLength() const =0;
|
virtual unsigned int CipherTextLength() const =0;
|
||||||
|
|
||||||
unsigned int MaxPlainTextLength(unsigned int cipherTextLength) const;
|
unsigned int MaxPlainTextLength(unsigned int cipherTextLength) const;
|
||||||
unsigned int CipherTextLength(unsigned int plainTextLength) const;
|
unsigned int CipherTextLength(unsigned int plainTextLength) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// abstract base class for encryptors with fixed length ciphertext
|
/// abstract base class for encryptors with fixed length ciphertext
|
||||||
|
@ -351,160 +351,160 @@ class PK_FixedLengthEncryptor : public virtual PK_Encryptor, public virtual PK_F
|
||||||
class PK_FixedLengthDecryptor : public virtual PK_Decryptor, public virtual PK_FixedLengthCryptoSystem
|
class PK_FixedLengthDecryptor : public virtual PK_Decryptor, public virtual PK_FixedLengthCryptoSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// decrypt a byte string, and return the length of plaintext
|
/// decrypt a byte string, and return the length of plaintext
|
||||||
/** Preconditions:
|
/** Preconditions:
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item length of cipherText == CipherTextLength()
|
\item length of cipherText == CipherTextLength()
|
||||||
\item size of plainText == MaxPlainTextLength()
|
\item size of plainText == MaxPlainTextLength()
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
The function returns the actual length of the plaintext, or 0
|
The function returns the actual length of the plaintext, or 0
|
||||||
if decryption fails.
|
if decryption fails.
|
||||||
*/
|
*/
|
||||||
virtual unsigned int Decrypt(const byte *cipherText, byte *plainText) =0;
|
virtual unsigned int Decrypt(const byte *cipherText, byte *plainText) =0;
|
||||||
|
|
||||||
unsigned int Decrypt(const byte *cipherText, unsigned int cipherTextLength, byte *plainText);
|
unsigned int Decrypt(const byte *cipherText, unsigned int cipherTextLength, byte *plainText);
|
||||||
};
|
};
|
||||||
|
|
||||||
/// abstract base class for public-key signers and verifiers
|
/// abstract base class for public-key signers and verifiers
|
||||||
|
|
||||||
/** This class provides an interface common to signers and verifiers
|
/** This class provides an interface common to signers and verifiers
|
||||||
for querying their signature lengths and maximum message lengths.
|
for querying their signature lengths and maximum message lengths.
|
||||||
|
|
||||||
The maximum message length is typically very low (less than 1000)
|
The maximum message length is typically very low (less than 1000)
|
||||||
because it is intended that only message digests (see \Ref{HashModule})
|
because it is intended that only message digests (see \Ref{HashModule})
|
||||||
should be signed.
|
should be signed.
|
||||||
*/
|
*/
|
||||||
class PK_SignatureSystem
|
class PK_SignatureSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
///
|
///
|
||||||
virtual ~PK_SignatureSystem() {};
|
virtual ~PK_SignatureSystem() {};
|
||||||
|
|
||||||
/// maximum length of a message that can be signed or verified
|
/// maximum length of a message that can be signed or verified
|
||||||
virtual unsigned int MaxMessageLength() const =0;
|
virtual unsigned int MaxMessageLength() const =0;
|
||||||
/// signature length support by this object (as either input or output)
|
/// signature length support by this object (as either input or output)
|
||||||
virtual unsigned int SignatureLength() const =0;
|
virtual unsigned int SignatureLength() const =0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// abstract base class for public-key signers
|
/// abstract base class for public-key signers
|
||||||
|
|
||||||
/** A signer is also a private signature key. It contains both the
|
/** A signer is also a private signature key. It contains both the
|
||||||
key and the algorithm to perform the signature.
|
key and the algorithm to perform the signature.
|
||||||
*/
|
*/
|
||||||
class PK_Signer : public virtual PK_SignatureSystem
|
class PK_Signer : public virtual PK_SignatureSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// sign a message
|
/// sign a message
|
||||||
/** Preconditions:
|
/** Preconditions:
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item messageLen <= MaxMessageLength()
|
\item messageLen <= MaxMessageLength()
|
||||||
\item size of signature == SignatureLength()
|
\item size of signature == SignatureLength()
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
*/
|
*/
|
||||||
virtual void Sign(RandomNumberGenerator &rng, const byte *message, unsigned int messageLen, byte *signature) =0;
|
virtual void Sign(RandomNumberGenerator &rng, const byte *message, unsigned int messageLen, byte *signature) =0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// abstract base class for public-key verifiers
|
/// abstract base class for public-key verifiers
|
||||||
|
|
||||||
/** A verifier is also a public verification key. It contains both the
|
/** A verifier is also a public verification key. It contains both the
|
||||||
key and the algorithm to perform the verification.
|
key and the algorithm to perform the verification.
|
||||||
*/
|
*/
|
||||||
class PK_Verifier : public virtual PK_SignatureSystem
|
class PK_Verifier : public virtual PK_SignatureSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// check whether sig is a valid signature for message
|
/// check whether sig is a valid signature for message
|
||||||
/** Preconditions:
|
/** Preconditions:
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item messageLen <= MaxMessageLength()
|
\item messageLen <= MaxMessageLength()
|
||||||
\item length of signature == SignatureLength()
|
\item length of signature == SignatureLength()
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
*/
|
*/
|
||||||
virtual bool Verify(const byte *message, unsigned int messageLen, const byte *sig) =0;
|
virtual bool Verify(const byte *message, unsigned int messageLen, const byte *sig) =0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// abstract base class for public-key verifiers with recovery
|
/// abstract base class for public-key verifiers with recovery
|
||||||
|
|
||||||
/** In a signature scheme with recovery, a verifier is able to extract
|
/** In a signature scheme with recovery, a verifier is able to extract
|
||||||
a message from its valid signature. This saves space since
|
a message from its valid signature. This saves space since
|
||||||
you don't need to store the message seperately.
|
you don't need to store the message seperately.
|
||||||
*/
|
*/
|
||||||
class PK_VerifierWithRecovery : public PK_Verifier
|
class PK_VerifierWithRecovery : public PK_Verifier
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// recover a message from its signature, return length of message, or 0 if signature is invalid
|
/// recover a message from its signature, return length of message, or 0 if signature is invalid
|
||||||
/** Preconditions:
|
/** Preconditions:
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item length of signature == SignatureLength()
|
\item length of signature == SignatureLength()
|
||||||
\item size of recoveredMessage == MaxMessageLength()
|
\item size of recoveredMessage == MaxMessageLength()
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
*/
|
*/
|
||||||
virtual unsigned int Recover(const byte *signature, byte *recoveredMessage) =0;
|
virtual unsigned int Recover(const byte *signature, byte *recoveredMessage) =0;
|
||||||
|
|
||||||
bool Verify(const byte *message, unsigned int messageLen, const byte *signature);
|
bool Verify(const byte *message, unsigned int messageLen, const byte *signature);
|
||||||
};
|
};
|
||||||
|
|
||||||
/// abstract base class for key agreement protocols
|
/// abstract base class for key agreement protocols
|
||||||
|
|
||||||
/** This class defines the interface for symmetric 2-pass key agreement
|
/** This class defines the interface for symmetric 2-pass key agreement
|
||||||
protocols. It isn't very general and only basic Diffie-Hellman
|
protocols. It isn't very general and only basic Diffie-Hellman
|
||||||
protocols fit the abstraction, so possibly a more general interface
|
protocols fit the abstraction, so possibly a more general interface
|
||||||
is needed.
|
is needed.
|
||||||
|
|
||||||
To use a KeyAgreementProtocol class, the two parties create matching
|
To use a KeyAgreementProtocol class, the two parties create matching
|
||||||
KeyAgreementProtocol objects, call Setup() on these objects,
|
KeyAgreementProtocol objects, call Setup() on these objects,
|
||||||
and send each other the public values produced. The objects are
|
and send each other the public values produced. The objects are
|
||||||
responsible for remembering the corresponding secret values, and
|
responsible for remembering the corresponding secret values, and
|
||||||
will produce a shared secret value when Agree() is called with the
|
will produce a shared secret value when Agree() is called with the
|
||||||
other party's public value.
|
other party's public value.
|
||||||
*/
|
*/
|
||||||
class KeyAgreementProtocol
|
class KeyAgreementProtocol
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
///
|
///
|
||||||
virtual ~KeyAgreementProtocol() {}
|
virtual ~KeyAgreementProtocol() {}
|
||||||
|
|
||||||
///
|
///
|
||||||
virtual unsigned int PublicValueLength() const =0;
|
virtual unsigned int PublicValueLength() const =0;
|
||||||
///
|
///
|
||||||
virtual unsigned int AgreedKeyLength() const =0;
|
virtual unsigned int AgreedKeyLength() const =0;
|
||||||
|
|
||||||
/// produce public value
|
/// produce public value
|
||||||
//* Precondition: size of publicValue == PublicValueLength()
|
//* Precondition: size of publicValue == PublicValueLength()
|
||||||
virtual void Setup(RandomNumberGenerator &rng, byte *publicValue) =0;
|
virtual void Setup(RandomNumberGenerator &rng, byte *publicValue) =0;
|
||||||
|
|
||||||
/// calculate agreed key given other party's public value
|
/// calculate agreed key given other party's public value
|
||||||
/** Precondition:
|
/** Precondition:
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item Setup() was called previously on this object
|
\item Setup() was called previously on this object
|
||||||
\item size of agreedKey == AgreedKeyLength()
|
\item size of agreedKey == AgreedKeyLength()
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
*/
|
*/
|
||||||
virtual void Agree(const byte *otherPublicValue, byte *agreedKey) const =0;
|
virtual void Agree(const byte *otherPublicValue, byte *agreedKey) const =0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// abstract base class for all objects that support precomputation
|
/// abstract base class for all objects that support precomputation
|
||||||
|
|
||||||
/** The class defines a common interface for doing precomputation,
|
/** The class defines a common interface for doing precomputation,
|
||||||
and loading and saving precomputation.
|
and loading and saving precomputation.
|
||||||
*/
|
*/
|
||||||
class PK_Precomputation
|
class PK_Precomputation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
///
|
///
|
||||||
virtual ~PK_Precomputation() {}
|
virtual ~PK_Precomputation() {}
|
||||||
|
|
||||||
///
|
///
|
||||||
/** The exact semantics of Precompute() is varies, but
|
/** The exact semantics of Precompute() is varies, but
|
||||||
typically it means calculate a table of n objects
|
typically it means calculate a table of n objects
|
||||||
that can be used later to speed up computation.
|
that can be used later to speed up computation.
|
||||||
*/
|
*/
|
||||||
virtual void Precompute(unsigned int n) =0;
|
virtual void Precompute(unsigned int n) =0;
|
||||||
|
|
||||||
/// retrieve previously saved precomputation
|
/// retrieve previously saved precomputation
|
||||||
virtual void LoadPrecomputation(BufferedTransformation &storedPrecomputation) =0;
|
virtual void LoadPrecomputation(BufferedTransformation &storedPrecomputation) =0;
|
||||||
/// save precomputation for later use
|
/// save precomputation for later use
|
||||||
virtual void SavePrecomputation(BufferedTransformation &storedPrecomputation) const =0;
|
virtual void SavePrecomputation(BufferedTransformation &storedPrecomputation) const =0;
|
||||||
};
|
};
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
|
@ -29,187 +29,187 @@
|
||||||
#ifdef notdef
|
#ifdef notdef
|
||||||
/* initial permutation IP */
|
/* initial permutation IP */
|
||||||
static byte ip[] = {
|
static byte ip[] = {
|
||||||
58, 50, 42, 34, 26, 18, 10, 2,
|
58, 50, 42, 34, 26, 18, 10, 2,
|
||||||
60, 52, 44, 36, 28, 20, 12, 4,
|
60, 52, 44, 36, 28, 20, 12, 4,
|
||||||
62, 54, 46, 38, 30, 22, 14, 6,
|
62, 54, 46, 38, 30, 22, 14, 6,
|
||||||
64, 56, 48, 40, 32, 24, 16, 8,
|
64, 56, 48, 40, 32, 24, 16, 8,
|
||||||
57, 49, 41, 33, 25, 17, 9, 1,
|
57, 49, 41, 33, 25, 17, 9, 1,
|
||||||
59, 51, 43, 35, 27, 19, 11, 3,
|
59, 51, 43, 35, 27, 19, 11, 3,
|
||||||
61, 53, 45, 37, 29, 21, 13, 5,
|
61, 53, 45, 37, 29, 21, 13, 5,
|
||||||
63, 55, 47, 39, 31, 23, 15, 7
|
63, 55, 47, 39, 31, 23, 15, 7
|
||||||
};
|
};
|
||||||
|
|
||||||
/* final permutation IP^-1 */
|
/* final permutation IP^-1 */
|
||||||
static byte fp[] = {
|
static byte fp[] = {
|
||||||
40, 8, 48, 16, 56, 24, 64, 32,
|
40, 8, 48, 16, 56, 24, 64, 32,
|
||||||
39, 7, 47, 15, 55, 23, 63, 31,
|
39, 7, 47, 15, 55, 23, 63, 31,
|
||||||
38, 6, 46, 14, 54, 22, 62, 30,
|
38, 6, 46, 14, 54, 22, 62, 30,
|
||||||
37, 5, 45, 13, 53, 21, 61, 29,
|
37, 5, 45, 13, 53, 21, 61, 29,
|
||||||
36, 4, 44, 12, 52, 20, 60, 28,
|
36, 4, 44, 12, 52, 20, 60, 28,
|
||||||
35, 3, 43, 11, 51, 19, 59, 27,
|
35, 3, 43, 11, 51, 19, 59, 27,
|
||||||
34, 2, 42, 10, 50, 18, 58, 26,
|
34, 2, 42, 10, 50, 18, 58, 26,
|
||||||
33, 1, 41, 9, 49, 17, 57, 25
|
33, 1, 41, 9, 49, 17, 57, 25
|
||||||
};
|
};
|
||||||
/* expansion operation matrix */
|
/* expansion operation matrix */
|
||||||
static byte ei[] = {
|
static byte ei[] = {
|
||||||
32, 1, 2, 3, 4, 5,
|
32, 1, 2, 3, 4, 5,
|
||||||
4, 5, 6, 7, 8, 9,
|
4, 5, 6, 7, 8, 9,
|
||||||
8, 9, 10, 11, 12, 13,
|
8, 9, 10, 11, 12, 13,
|
||||||
12, 13, 14, 15, 16, 17,
|
12, 13, 14, 15, 16, 17,
|
||||||
16, 17, 18, 19, 20, 21,
|
16, 17, 18, 19, 20, 21,
|
||||||
20, 21, 22, 23, 24, 25,
|
20, 21, 22, 23, 24, 25,
|
||||||
24, 25, 26, 27, 28, 29,
|
24, 25, 26, 27, 28, 29,
|
||||||
28, 29, 30, 31, 32, 1
|
28, 29, 30, 31, 32, 1
|
||||||
};
|
};
|
||||||
/* The (in)famous S-boxes */
|
/* The (in)famous S-boxes */
|
||||||
static byte sbox[8][64] = {
|
static byte sbox[8][64] = {
|
||||||
/* S1 */
|
/* S1 */
|
||||||
14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
|
14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
|
||||||
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
|
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
|
||||||
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
|
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
|
||||||
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
|
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
|
||||||
|
|
||||||
/* S2 */
|
/* S2 */
|
||||||
15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
|
15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
|
||||||
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
|
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
|
||||||
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
|
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
|
||||||
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
|
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
|
||||||
|
|
||||||
/* S3 */
|
/* S3 */
|
||||||
10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
|
10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
|
||||||
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
|
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
|
||||||
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
|
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
|
||||||
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
|
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
|
||||||
|
|
||||||
/* S4 */
|
/* S4 */
|
||||||
7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
|
7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
|
||||||
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
|
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
|
||||||
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
|
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
|
||||||
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
|
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
|
||||||
|
|
||||||
/* S5 */
|
/* S5 */
|
||||||
2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
|
2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
|
||||||
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
|
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
|
||||||
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
|
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
|
||||||
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
|
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
|
||||||
|
|
||||||
/* S6 */
|
/* S6 */
|
||||||
12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
|
12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
|
||||||
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
|
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
|
||||||
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
|
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
|
||||||
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
|
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
|
||||||
|
|
||||||
/* S7 */
|
/* S7 */
|
||||||
4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
|
4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
|
||||||
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
|
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
|
||||||
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
|
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
|
||||||
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
|
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
|
||||||
|
|
||||||
/* S8 */
|
/* S8 */
|
||||||
13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
|
13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
|
||||||
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
|
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
|
||||||
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
|
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
|
||||||
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
|
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
|
||||||
};
|
};
|
||||||
|
|
||||||
/* 32-bit permutation function P used on the output of the S-boxes */
|
/* 32-bit permutation function P used on the output of the S-boxes */
|
||||||
static byte p32i[] = {
|
static byte p32i[] = {
|
||||||
16, 7, 20, 21,
|
16, 7, 20, 21,
|
||||||
29, 12, 28, 17,
|
29, 12, 28, 17,
|
||||||
1, 15, 23, 26,
|
1, 15, 23, 26,
|
||||||
5, 18, 31, 10,
|
5, 18, 31, 10,
|
||||||
2, 8, 24, 14,
|
2, 8, 24, 14,
|
||||||
32, 27, 3, 9,
|
32, 27, 3, 9,
|
||||||
19, 13, 30, 6,
|
19, 13, 30, 6,
|
||||||
22, 11, 4, 25
|
22, 11, 4, 25
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* permuted choice table (key) */
|
/* permuted choice table (key) */
|
||||||
static const byte pc1[] = {
|
static const byte pc1[] = {
|
||||||
57, 49, 41, 33, 25, 17, 9,
|
57, 49, 41, 33, 25, 17, 9,
|
||||||
1, 58, 50, 42, 34, 26, 18,
|
1, 58, 50, 42, 34, 26, 18,
|
||||||
10, 2, 59, 51, 43, 35, 27,
|
10, 2, 59, 51, 43, 35, 27,
|
||||||
19, 11, 3, 60, 52, 44, 36,
|
19, 11, 3, 60, 52, 44, 36,
|
||||||
|
|
||||||
63, 55, 47, 39, 31, 23, 15,
|
63, 55, 47, 39, 31, 23, 15,
|
||||||
7, 62, 54, 46, 38, 30, 22,
|
7, 62, 54, 46, 38, 30, 22,
|
||||||
14, 6, 61, 53, 45, 37, 29,
|
14, 6, 61, 53, 45, 37, 29,
|
||||||
21, 13, 5, 28, 20, 12, 4
|
21, 13, 5, 28, 20, 12, 4
|
||||||
};
|
};
|
||||||
|
|
||||||
/* number left rotations of pc1 */
|
/* number left rotations of pc1 */
|
||||||
static const byte totrot[] = {
|
static const byte totrot[] = {
|
||||||
1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28
|
1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28
|
||||||
};
|
};
|
||||||
|
|
||||||
/* permuted choice key (table) */
|
/* permuted choice key (table) */
|
||||||
static const byte pc2[] = {
|
static const byte pc2[] = {
|
||||||
14, 17, 11, 24, 1, 5,
|
14, 17, 11, 24, 1, 5,
|
||||||
3, 28, 15, 6, 21, 10,
|
3, 28, 15, 6, 21, 10,
|
||||||
23, 19, 12, 4, 26, 8,
|
23, 19, 12, 4, 26, 8,
|
||||||
16, 7, 27, 20, 13, 2,
|
16, 7, 27, 20, 13, 2,
|
||||||
41, 52, 31, 37, 47, 55,
|
41, 52, 31, 37, 47, 55,
|
||||||
30, 40, 51, 45, 33, 48,
|
30, 40, 51, 45, 33, 48,
|
||||||
44, 49, 39, 56, 34, 53,
|
44, 49, 39, 56, 34, 53,
|
||||||
46, 42, 50, 36, 29, 32
|
46, 42, 50, 36, 29, 32
|
||||||
};
|
};
|
||||||
|
|
||||||
/* End of DES-defined tables */
|
/* End of DES-defined tables */
|
||||||
|
|
||||||
/* bit 0 is left-most in byte */
|
/* bit 0 is left-most in byte */
|
||||||
static const int bytebit[] = {
|
static const int bytebit[] = {
|
||||||
0200,0100,040,020,010,04,02,01
|
0200,0100,040,020,010,04,02,01
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Set key (initialize key schedule array) */
|
/* Set key (initialize key schedule array) */
|
||||||
DES::DES(const byte *key, CipherDir dir)
|
DES::DES(const byte *key, CipherDir dir)
|
||||||
: k(32)
|
: k(32)
|
||||||
{
|
{
|
||||||
SecByteBlock buffer(56+56+8);
|
SecByteBlock buffer(56+56+8);
|
||||||
byte *const pc1m=buffer; /* place to modify pc1 into */
|
byte *const pc1m=buffer; /* place to modify pc1 into */
|
||||||
byte *const pcr=pc1m+56; /* place to rotate pc1 into */
|
byte *const pcr=pc1m+56; /* place to rotate pc1 into */
|
||||||
byte *const ks=pcr+56;
|
byte *const ks=pcr+56;
|
||||||
register unsigned int i,j,l;
|
register unsigned int i,j,l;
|
||||||
int m;
|
int m;
|
||||||
|
|
||||||
for (j=0; j<56; j++) { /* convert pc1 to bits of key */
|
for (j=0; j<56; j++) { /* convert pc1 to bits of key */
|
||||||
l=pc1[j]-1; /* integer bit location */
|
l=pc1[j]-1; /* integer bit location */
|
||||||
m = l & 07; /* find bit */
|
m = l & 07; /* find bit */
|
||||||
pc1m[j]=(key[l>>3] & /* find which key byte l is in */
|
pc1m[j]=(key[l>>3] & /* find which key byte l is in */
|
||||||
bytebit[m]) /* and which bit of that byte */
|
bytebit[m]) /* and which bit of that byte */
|
||||||
? 1 : 0; /* and store 1-bit result */
|
? 1 : 0; /* and store 1-bit result */
|
||||||
}
|
}
|
||||||
for (i=0; i<16; i++) { /* key chunk for each iteration */
|
for (i=0; i<16; i++) { /* key chunk for each iteration */
|
||||||
memset(ks,0,8); /* Clear key schedule */
|
memset(ks,0,8); /* Clear key schedule */
|
||||||
for (j=0; j<56; j++) /* rotate pc1 the right amount */
|
for (j=0; j<56; j++) /* rotate pc1 the right amount */
|
||||||
pcr[j] = pc1m[(l=j+totrot[i])<(j<28? 28 : 56) ? l: l-28];
|
pcr[j] = pc1m[(l=j+totrot[i])<(j<28? 28 : 56) ? l: l-28];
|
||||||
/* rotate left and right halves independently */
|
/* rotate left and right halves independently */
|
||||||
for (j=0; j<48; j++){ /* select bits individually */
|
for (j=0; j<48; j++){ /* select bits individually */
|
||||||
/* check bit that goes to ks[j] */
|
/* check bit that goes to ks[j] */
|
||||||
if (pcr[pc2[j]-1]){
|
if (pcr[pc2[j]-1]){
|
||||||
/* mask it in if it's there */
|
/* mask it in if it's there */
|
||||||
l= j % 6;
|
l= j % 6;
|
||||||
ks[j/6] |= bytebit[l] >> 2;
|
ks[j/6] |= bytebit[l] >> 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Now convert to odd/even interleaved form for use in F */
|
/* Now convert to odd/even interleaved form for use in F */
|
||||||
k[2*i] = ((word32)ks[0] << 24)
|
k[2*i] = ((word32)ks[0] << 24)
|
||||||
| ((word32)ks[2] << 16)
|
| ((word32)ks[2] << 16)
|
||||||
| ((word32)ks[4] << 8)
|
| ((word32)ks[4] << 8)
|
||||||
| ((word32)ks[6]);
|
| ((word32)ks[6]);
|
||||||
k[2*i+1] = ((word32)ks[1] << 24)
|
k[2*i+1] = ((word32)ks[1] << 24)
|
||||||
| ((word32)ks[3] << 16)
|
| ((word32)ks[3] << 16)
|
||||||
| ((word32)ks[5] << 8)
|
| ((word32)ks[5] << 8)
|
||||||
| ((word32)ks[7]);
|
| ((word32)ks[7]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dir==DECRYPTION) // reverse key schedule order
|
if (dir==DECRYPTION) // reverse key schedule order
|
||||||
for (i=0; i<16; i+=2)
|
for (i=0; i<16; i+=2)
|
||||||
{
|
{
|
||||||
std::swap(k[i], k[32-2-i]);
|
std::swap(k[i], k[32-2-i]);
|
||||||
std::swap(k[i+1], k[32-1-i]);
|
std::swap(k[i+1], k[32-1-i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* End of C code common to both versions */
|
/* End of C code common to both versions */
|
||||||
|
|
||||||
|
@ -219,47 +219,47 @@ DES::DES(const byte *key, CipherDir dir)
|
||||||
/*
|
/*
|
||||||
inline void IPERM(word32 &left, word32 &right)
|
inline void IPERM(word32 &left, word32 &right)
|
||||||
{
|
{
|
||||||
word32 work;
|
word32 work;
|
||||||
|
|
||||||
work = ((left >> 4) ^ right) & 0x0f0f0f0f;
|
work = ((left >> 4) ^ right) & 0x0f0f0f0f;
|
||||||
right ^= work;
|
right ^= work;
|
||||||
left ^= work << 4;
|
left ^= work << 4;
|
||||||
work = ((left >> 16) ^ right) & 0xffff;
|
work = ((left >> 16) ^ right) & 0xffff;
|
||||||
right ^= work;
|
right ^= work;
|
||||||
left ^= work << 16;
|
left ^= work << 16;
|
||||||
work = ((right >> 2) ^ left) & 0x33333333;
|
work = ((right >> 2) ^ left) & 0x33333333;
|
||||||
left ^= work;
|
left ^= work;
|
||||||
right ^= (work << 2);
|
right ^= (work << 2);
|
||||||
work = ((right >> 8) ^ left) & 0xff00ff;
|
work = ((right >> 8) ^ left) & 0xff00ff;
|
||||||
left ^= work;
|
left ^= work;
|
||||||
right ^= (work << 8);
|
right ^= (work << 8);
|
||||||
right = rotl(right, 1);
|
right = rotl(right, 1);
|
||||||
work = (left ^ right) & 0xaaaaaaaa;
|
work = (left ^ right) & 0xaaaaaaaa;
|
||||||
left ^= work;
|
left ^= work;
|
||||||
right ^= work;
|
right ^= work;
|
||||||
left = rotl(left, 1);
|
left = rotl(left, 1);
|
||||||
}
|
}
|
||||||
inline void FPERM(word32 &left, word32 &right)
|
inline void FPERM(word32 &left, word32 &right)
|
||||||
{
|
{
|
||||||
word32 work;
|
word32 work;
|
||||||
|
|
||||||
right = rotr(right, 1);
|
right = rotr(right, 1);
|
||||||
work = (left ^ right) & 0xaaaaaaaa;
|
work = (left ^ right) & 0xaaaaaaaa;
|
||||||
left ^= work;
|
left ^= work;
|
||||||
right ^= work;
|
right ^= work;
|
||||||
left = rotr(left, 1);
|
left = rotr(left, 1);
|
||||||
work = ((left >> 8) ^ right) & 0xff00ff;
|
work = ((left >> 8) ^ right) & 0xff00ff;
|
||||||
right ^= work;
|
right ^= work;
|
||||||
left ^= work << 8;
|
left ^= work << 8;
|
||||||
work = ((left >> 2) ^ right) & 0x33333333;
|
work = ((left >> 2) ^ right) & 0x33333333;
|
||||||
right ^= work;
|
right ^= work;
|
||||||
left ^= work << 2;
|
left ^= work << 2;
|
||||||
work = ((right >> 16) ^ left) & 0xffff;
|
work = ((right >> 16) ^ left) & 0xffff;
|
||||||
left ^= work;
|
left ^= work;
|
||||||
right ^= work << 16;
|
right ^= work << 16;
|
||||||
work = ((right >> 4) ^ left) & 0x0f0f0f0f;
|
work = ((right >> 4) ^ left) & 0x0f0f0f0f;
|
||||||
left ^= work;
|
left ^= work;
|
||||||
right ^= work << 4;
|
right ^= work << 4;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -268,153 +268,153 @@ inline void FPERM(word32 &left, word32 &right)
|
||||||
// (like in MSVC)
|
// (like in MSVC)
|
||||||
inline void IPERM(word32 &left, word32 &right)
|
inline void IPERM(word32 &left, word32 &right)
|
||||||
{
|
{
|
||||||
word32 work;
|
word32 work;
|
||||||
|
|
||||||
right = rotl(right, 4U);
|
right = rotl(right, 4U);
|
||||||
work = (left ^ right) & 0xf0f0f0f0;
|
work = (left ^ right) & 0xf0f0f0f0;
|
||||||
left ^= work;
|
left ^= work;
|
||||||
right = rotr(right^work, 20U);
|
right = rotr(right^work, 20U);
|
||||||
work = (left ^ right) & 0xffff0000;
|
work = (left ^ right) & 0xffff0000;
|
||||||
left ^= work;
|
left ^= work;
|
||||||
right = rotr(right^work, 18U);
|
right = rotr(right^work, 18U);
|
||||||
work = (left ^ right) & 0x33333333;
|
work = (left ^ right) & 0x33333333;
|
||||||
left ^= work;
|
left ^= work;
|
||||||
right = rotr(right^work, 6U);
|
right = rotr(right^work, 6U);
|
||||||
work = (left ^ right) & 0x00ff00ff;
|
work = (left ^ right) & 0x00ff00ff;
|
||||||
left ^= work;
|
left ^= work;
|
||||||
right = rotl(right^work, 9U);
|
right = rotl(right^work, 9U);
|
||||||
work = (left ^ right) & 0xaaaaaaaa;
|
work = (left ^ right) & 0xaaaaaaaa;
|
||||||
left = rotl(left^work, 1U);
|
left = rotl(left^work, 1U);
|
||||||
right ^= work;
|
right ^= work;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void FPERM(word32 &left, word32 &right)
|
inline void FPERM(word32 &left, word32 &right)
|
||||||
{
|
{
|
||||||
word32 work;
|
word32 work;
|
||||||
|
|
||||||
right = rotr(right, 1U);
|
right = rotr(right, 1U);
|
||||||
work = (left ^ right) & 0xaaaaaaaa;
|
work = (left ^ right) & 0xaaaaaaaa;
|
||||||
right ^= work;
|
right ^= work;
|
||||||
left = rotr(left^work, 9U);
|
left = rotr(left^work, 9U);
|
||||||
work = (left ^ right) & 0x00ff00ff;
|
work = (left ^ right) & 0x00ff00ff;
|
||||||
right ^= work;
|
right ^= work;
|
||||||
left = rotl(left^work, 6U);
|
left = rotl(left^work, 6U);
|
||||||
work = (left ^ right) & 0x33333333;
|
work = (left ^ right) & 0x33333333;
|
||||||
right ^= work;
|
right ^= work;
|
||||||
left = rotl(left^work, 18U);
|
left = rotl(left^work, 18U);
|
||||||
work = (left ^ right) & 0xffff0000;
|
work = (left ^ right) & 0xffff0000;
|
||||||
right ^= work;
|
right ^= work;
|
||||||
left = rotl(left^work, 20U);
|
left = rotl(left^work, 20U);
|
||||||
work = (left ^ right) & 0xf0f0f0f0;
|
work = (left ^ right) & 0xf0f0f0f0;
|
||||||
right ^= work;
|
right ^= work;
|
||||||
left = rotr(left^work, 4U);
|
left = rotr(left^work, 4U);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encrypt or decrypt a block of data in ECB mode
|
// Encrypt or decrypt a block of data in ECB mode
|
||||||
void DES::ProcessBlock(const byte *inBlock, byte * outBlock)
|
void DES::ProcessBlock(const byte *inBlock, byte * outBlock)
|
||||||
{
|
{
|
||||||
word32 l,r,work;
|
word32 l,r,work;
|
||||||
|
|
||||||
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
||||||
l = *(word32 *)inBlock;
|
l = *(word32 *)inBlock;
|
||||||
r = *(word32 *)(inBlock+4);
|
r = *(word32 *)(inBlock+4);
|
||||||
#else
|
#else
|
||||||
l = byteReverse(*(word32 *)inBlock);
|
l = byteReverse(*(word32 *)inBlock);
|
||||||
r = byteReverse(*(word32 *)(inBlock+4));
|
r = byteReverse(*(word32 *)(inBlock+4));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
IPERM(l,r);
|
IPERM(l,r);
|
||||||
|
|
||||||
const word32 *kptr=k;
|
const word32 *kptr=k;
|
||||||
|
|
||||||
for (unsigned i=0; i<8; i++)
|
for (unsigned i=0; i<8; i++)
|
||||||
{
|
{
|
||||||
work = rotr(r, 4U) ^ kptr[4*i+0];
|
work = rotr(r, 4U) ^ kptr[4*i+0];
|
||||||
l ^= Spbox[6][(work) & 0x3f]
|
l ^= Spbox[6][(work) & 0x3f]
|
||||||
^ Spbox[4][(work >> 8) & 0x3f]
|
^ Spbox[4][(work >> 8) & 0x3f]
|
||||||
^ Spbox[2][(work >> 16) & 0x3f]
|
^ Spbox[2][(work >> 16) & 0x3f]
|
||||||
^ Spbox[0][(work >> 24) & 0x3f];
|
^ Spbox[0][(work >> 24) & 0x3f];
|
||||||
work = r ^ kptr[4*i+1];
|
work = r ^ kptr[4*i+1];
|
||||||
l ^= Spbox[7][(work) & 0x3f]
|
l ^= Spbox[7][(work) & 0x3f]
|
||||||
^ Spbox[5][(work >> 8) & 0x3f]
|
^ Spbox[5][(work >> 8) & 0x3f]
|
||||||
^ Spbox[3][(work >> 16) & 0x3f]
|
^ Spbox[3][(work >> 16) & 0x3f]
|
||||||
^ Spbox[1][(work >> 24) & 0x3f];
|
^ Spbox[1][(work >> 24) & 0x3f];
|
||||||
|
|
||||||
work = rotr(l, 4U) ^ kptr[4*i+2];
|
work = rotr(l, 4U) ^ kptr[4*i+2];
|
||||||
r ^= Spbox[6][(work) & 0x3f]
|
r ^= Spbox[6][(work) & 0x3f]
|
||||||
^ Spbox[4][(work >> 8) & 0x3f]
|
^ Spbox[4][(work >> 8) & 0x3f]
|
||||||
^ Spbox[2][(work >> 16) & 0x3f]
|
^ Spbox[2][(work >> 16) & 0x3f]
|
||||||
^ Spbox[0][(work >> 24) & 0x3f];
|
^ Spbox[0][(work >> 24) & 0x3f];
|
||||||
work = l ^ kptr[4*i+3];
|
work = l ^ kptr[4*i+3];
|
||||||
r ^= Spbox[7][(work) & 0x3f]
|
r ^= Spbox[7][(work) & 0x3f]
|
||||||
^ Spbox[5][(work >> 8) & 0x3f]
|
^ Spbox[5][(work >> 8) & 0x3f]
|
||||||
^ Spbox[3][(work >> 16) & 0x3f]
|
^ Spbox[3][(work >> 16) & 0x3f]
|
||||||
^ Spbox[1][(work >> 24) & 0x3f];
|
^ Spbox[1][(work >> 24) & 0x3f];
|
||||||
}
|
}
|
||||||
|
|
||||||
FPERM(l,r);
|
FPERM(l,r);
|
||||||
|
|
||||||
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
||||||
*(word32 *)outBlock = r;
|
*(word32 *)outBlock = r;
|
||||||
*(word32 *)(outBlock+4) = l;
|
*(word32 *)(outBlock+4) = l;
|
||||||
#else
|
#else
|
||||||
*(word32 *)outBlock = byteReverse(r);
|
*(word32 *)outBlock = byteReverse(r);
|
||||||
*(word32 *)(outBlock+4) = byteReverse(l);
|
*(word32 *)(outBlock+4) = byteReverse(l);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void DES_EDE_Encryption::ProcessBlock(byte *inoutBlock)
|
void DES_EDE_Encryption::ProcessBlock(byte *inoutBlock)
|
||||||
{
|
{
|
||||||
e.ProcessBlock(inoutBlock);
|
e.ProcessBlock(inoutBlock);
|
||||||
d.ProcessBlock(inoutBlock);
|
d.ProcessBlock(inoutBlock);
|
||||||
e.ProcessBlock(inoutBlock);
|
e.ProcessBlock(inoutBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DES_EDE_Encryption::ProcessBlock(const byte *inBlock, byte *outBlock)
|
void DES_EDE_Encryption::ProcessBlock(const byte *inBlock, byte *outBlock)
|
||||||
{
|
{
|
||||||
e.ProcessBlock(inBlock, outBlock);
|
e.ProcessBlock(inBlock, outBlock);
|
||||||
d.ProcessBlock(outBlock);
|
d.ProcessBlock(outBlock);
|
||||||
e.ProcessBlock(outBlock);
|
e.ProcessBlock(outBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DES_EDE_Decryption::ProcessBlock(byte *inoutBlock)
|
void DES_EDE_Decryption::ProcessBlock(byte *inoutBlock)
|
||||||
{
|
{
|
||||||
d.ProcessBlock(inoutBlock);
|
d.ProcessBlock(inoutBlock);
|
||||||
e.ProcessBlock(inoutBlock);
|
e.ProcessBlock(inoutBlock);
|
||||||
d.ProcessBlock(inoutBlock);
|
d.ProcessBlock(inoutBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DES_EDE_Decryption::ProcessBlock(const byte *inBlock, byte *outBlock)
|
void DES_EDE_Decryption::ProcessBlock(const byte *inBlock, byte *outBlock)
|
||||||
{
|
{
|
||||||
d.ProcessBlock(inBlock, outBlock);
|
d.ProcessBlock(inBlock, outBlock);
|
||||||
e.ProcessBlock(outBlock);
|
e.ProcessBlock(outBlock);
|
||||||
d.ProcessBlock(outBlock);
|
d.ProcessBlock(outBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TripleDES_Encryption::ProcessBlock(byte *inoutBlock)
|
void TripleDES_Encryption::ProcessBlock(byte *inoutBlock)
|
||||||
{
|
{
|
||||||
e1.ProcessBlock(inoutBlock);
|
e1.ProcessBlock(inoutBlock);
|
||||||
d.ProcessBlock(inoutBlock);
|
d.ProcessBlock(inoutBlock);
|
||||||
e2.ProcessBlock(inoutBlock);
|
e2.ProcessBlock(inoutBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TripleDES_Encryption::ProcessBlock(const byte *inBlock, byte *outBlock)
|
void TripleDES_Encryption::ProcessBlock(const byte *inBlock, byte *outBlock)
|
||||||
{
|
{
|
||||||
e1.ProcessBlock(inBlock, outBlock);
|
e1.ProcessBlock(inBlock, outBlock);
|
||||||
d.ProcessBlock(outBlock);
|
d.ProcessBlock(outBlock);
|
||||||
e2.ProcessBlock(outBlock);
|
e2.ProcessBlock(outBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TripleDES_Decryption::ProcessBlock(byte *inoutBlock)
|
void TripleDES_Decryption::ProcessBlock(byte *inoutBlock)
|
||||||
{
|
{
|
||||||
d1.ProcessBlock(inoutBlock);
|
d1.ProcessBlock(inoutBlock);
|
||||||
e.ProcessBlock(inoutBlock);
|
e.ProcessBlock(inoutBlock);
|
||||||
d2.ProcessBlock(inoutBlock);
|
d2.ProcessBlock(inoutBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TripleDES_Decryption::ProcessBlock(const byte *inBlock, byte *outBlock)
|
void TripleDES_Decryption::ProcessBlock(const byte *inBlock, byte *outBlock)
|
||||||
{
|
{
|
||||||
d1.ProcessBlock(inBlock, outBlock);
|
d1.ProcessBlock(inBlock, outBlock);
|
||||||
e.ProcessBlock(outBlock);
|
e.ProcessBlock(outBlock);
|
||||||
d2.ProcessBlock(outBlock);
|
d2.ProcessBlock(outBlock);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,99 +7,99 @@
|
||||||
class DES : public BlockTransformation
|
class DES : public BlockTransformation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DES(const byte *userKey, CipherDir);
|
DES(const byte *userKey, CipherDir);
|
||||||
|
|
||||||
void ProcessBlock(const byte *inBlock, byte * outBlock);
|
void ProcessBlock(const byte *inBlock, byte * outBlock);
|
||||||
void ProcessBlock(byte * inoutBlock)
|
void ProcessBlock(byte * inoutBlock)
|
||||||
{DES::ProcessBlock(inoutBlock, inoutBlock);}
|
{DES::ProcessBlock(inoutBlock, inoutBlock);}
|
||||||
|
|
||||||
enum {KEYLENGTH=8, BLOCKSIZE=8};
|
enum {KEYLENGTH=8, BLOCKSIZE=8};
|
||||||
unsigned int BlockSize() const {return BLOCKSIZE;}
|
unsigned int BlockSize() const {return BLOCKSIZE;}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static const word32 Spbox[8][64];
|
static const word32 Spbox[8][64];
|
||||||
|
|
||||||
SecBlock<word32> k;
|
SecBlock<word32> k;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DESEncryption : public DES
|
class DESEncryption : public DES
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DESEncryption(const byte * userKey)
|
DESEncryption(const byte * userKey)
|
||||||
: DES (userKey, ENCRYPTION) {}
|
: DES (userKey, ENCRYPTION) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class DESDecryption : public DES
|
class DESDecryption : public DES
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DESDecryption(const byte * userKey)
|
DESDecryption(const byte * userKey)
|
||||||
: DES (userKey, DECRYPTION) {}
|
: DES (userKey, DECRYPTION) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class DES_EDE_Encryption : public BlockTransformation
|
class DES_EDE_Encryption : public BlockTransformation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DES_EDE_Encryption(const byte * userKey)
|
DES_EDE_Encryption(const byte * userKey)
|
||||||
: e(userKey, ENCRYPTION), d(userKey + DES::KEYLENGTH, DECRYPTION) {}
|
: e(userKey, ENCRYPTION), d(userKey + DES::KEYLENGTH, DECRYPTION) {}
|
||||||
|
|
||||||
void ProcessBlock(const byte *inBlock, byte * outBlock);
|
void ProcessBlock(const byte *inBlock, byte * outBlock);
|
||||||
void ProcessBlock(byte * inoutBlock);
|
void ProcessBlock(byte * inoutBlock);
|
||||||
|
|
||||||
enum {KEYLENGTH=16, BLOCKSIZE=8};
|
enum {KEYLENGTH=16, BLOCKSIZE=8};
|
||||||
unsigned int BlockSize() const {return BLOCKSIZE;}
|
unsigned int BlockSize() const {return BLOCKSIZE;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DES e, d;
|
DES e, d;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DES_EDE_Decryption : public BlockTransformation
|
class DES_EDE_Decryption : public BlockTransformation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DES_EDE_Decryption(const byte * userKey)
|
DES_EDE_Decryption(const byte * userKey)
|
||||||
: d(userKey, DECRYPTION), e(userKey + DES::KEYLENGTH, ENCRYPTION) {}
|
: d(userKey, DECRYPTION), e(userKey + DES::KEYLENGTH, ENCRYPTION) {}
|
||||||
|
|
||||||
void ProcessBlock(const byte *inBlock, byte * outBlock);
|
void ProcessBlock(const byte *inBlock, byte * outBlock);
|
||||||
void ProcessBlock(byte * inoutBlock);
|
void ProcessBlock(byte * inoutBlock);
|
||||||
|
|
||||||
enum {KEYLENGTH=16, BLOCKSIZE=8};
|
enum {KEYLENGTH=16, BLOCKSIZE=8};
|
||||||
unsigned int BlockSize() const {return BLOCKSIZE;}
|
unsigned int BlockSize() const {return BLOCKSIZE;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DES d, e;
|
DES d, e;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TripleDES_Encryption : public BlockTransformation
|
class TripleDES_Encryption : public BlockTransformation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TripleDES_Encryption(const byte * userKey)
|
TripleDES_Encryption(const byte * userKey)
|
||||||
: e1(userKey, ENCRYPTION), d(userKey + DES::KEYLENGTH, DECRYPTION),
|
: e1(userKey, ENCRYPTION), d(userKey + DES::KEYLENGTH, DECRYPTION),
|
||||||
e2(userKey + 2*DES::KEYLENGTH, ENCRYPTION) {}
|
e2(userKey + 2*DES::KEYLENGTH, ENCRYPTION) {}
|
||||||
|
|
||||||
void ProcessBlock(const byte *inBlock, byte * outBlock);
|
void ProcessBlock(const byte *inBlock, byte * outBlock);
|
||||||
void ProcessBlock(byte * inoutBlock);
|
void ProcessBlock(byte * inoutBlock);
|
||||||
|
|
||||||
enum {KEYLENGTH=24, BLOCKSIZE=8};
|
enum {KEYLENGTH=24, BLOCKSIZE=8};
|
||||||
unsigned int BlockSize() const {return BLOCKSIZE;}
|
unsigned int BlockSize() const {return BLOCKSIZE;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DES e1, d, e2;
|
DES e1, d, e2;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TripleDES_Decryption : public BlockTransformation
|
class TripleDES_Decryption : public BlockTransformation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TripleDES_Decryption(const byte * userKey)
|
TripleDES_Decryption(const byte * userKey)
|
||||||
: d1(userKey + 2*DES::KEYLENGTH, DECRYPTION), e(userKey + DES::KEYLENGTH, ENCRYPTION),
|
: d1(userKey + 2*DES::KEYLENGTH, DECRYPTION), e(userKey + DES::KEYLENGTH, ENCRYPTION),
|
||||||
d2(userKey, DECRYPTION) {}
|
d2(userKey, DECRYPTION) {}
|
||||||
|
|
||||||
void ProcessBlock(const byte *inBlock, byte * outBlock);
|
void ProcessBlock(const byte *inBlock, byte * outBlock);
|
||||||
void ProcessBlock(byte * inoutBlock);
|
void ProcessBlock(byte * inoutBlock);
|
||||||
|
|
||||||
enum {KEYLENGTH=24, BLOCKSIZE=8};
|
enum {KEYLENGTH=24, BLOCKSIZE=8};
|
||||||
unsigned int BlockSize() const {return BLOCKSIZE;}
|
unsigned int BlockSize() const {return BLOCKSIZE;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DES d1, e, d2;
|
DES d1, e, d2;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
#include "asn.h"
|
#include "asn.h"
|
||||||
|
|
||||||
ElGamalCryptoPublicKey::ElGamalCryptoPublicKey(const Integer &p, const Integer &g, const Integer &y)
|
ElGamalCryptoPublicKey::ElGamalCryptoPublicKey(const Integer &p, const Integer &g, const Integer &y)
|
||||||
: p(p), g(g), y(y), modulusLen(p.ByteCount()),
|
: p(p), g(g), y(y), modulusLen(p.ByteCount()),
|
||||||
gpc(p, g, ExponentBitLength(), 1), ypc(p, y, ExponentBitLength(), 1)
|
gpc(p, g, ExponentBitLength(), 1), ypc(p, y, ExponentBitLength(), 1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,99 +18,99 @@ ElGamalCryptoPublicKey::~ElGamalCryptoPublicKey()
|
||||||
|
|
||||||
ElGamalCryptoPublicKey::ElGamalCryptoPublicKey(BufferedTransformation &bt)
|
ElGamalCryptoPublicKey::ElGamalCryptoPublicKey(BufferedTransformation &bt)
|
||||||
{
|
{
|
||||||
BERSequenceDecoder seq(bt);
|
BERSequenceDecoder seq(bt);
|
||||||
p.BERDecode(seq);
|
p.BERDecode(seq);
|
||||||
modulusLen=p.ByteCount();
|
modulusLen=p.ByteCount();
|
||||||
g.BERDecode(seq);
|
g.BERDecode(seq);
|
||||||
y.BERDecode(seq);
|
y.BERDecode(seq);
|
||||||
gpc.Precompute(p, g, ExponentBitLength(), 1);
|
gpc.Precompute(p, g, ExponentBitLength(), 1);
|
||||||
ypc.Precompute(p, y, ExponentBitLength(), 1);
|
ypc.Precompute(p, y, ExponentBitLength(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElGamalCryptoPublicKey::DEREncode(BufferedTransformation &bt) const
|
void ElGamalCryptoPublicKey::DEREncode(BufferedTransformation &bt) const
|
||||||
{
|
{
|
||||||
DERSequenceEncoder seq(bt);
|
DERSequenceEncoder seq(bt);
|
||||||
p.DEREncode(seq);
|
p.DEREncode(seq);
|
||||||
g.DEREncode(seq);
|
g.DEREncode(seq);
|
||||||
y.DEREncode(seq);
|
y.DEREncode(seq);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElGamalCryptoPublicKey::Precompute(unsigned int precomputationStorage)
|
void ElGamalCryptoPublicKey::Precompute(unsigned int precomputationStorage)
|
||||||
{
|
{
|
||||||
gpc.Precompute(p, g, ExponentBitLength(), precomputationStorage);
|
gpc.Precompute(p, g, ExponentBitLength(), precomputationStorage);
|
||||||
ypc.Precompute(p, y, ExponentBitLength(), precomputationStorage);
|
ypc.Precompute(p, y, ExponentBitLength(), precomputationStorage);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElGamalCryptoPublicKey::LoadPrecomputation(BufferedTransformation &bt)
|
void ElGamalCryptoPublicKey::LoadPrecomputation(BufferedTransformation &bt)
|
||||||
{
|
{
|
||||||
gpc.Load(p, bt);
|
gpc.Load(p, bt);
|
||||||
ypc.Load(p, bt);
|
ypc.Load(p, bt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElGamalCryptoPublicKey::SavePrecomputation(BufferedTransformation &bt) const
|
void ElGamalCryptoPublicKey::SavePrecomputation(BufferedTransformation &bt) const
|
||||||
{
|
{
|
||||||
gpc.Save(bt);
|
gpc.Save(bt);
|
||||||
ypc.Save(bt);
|
ypc.Save(bt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElGamalCryptoPublicKey::Encrypt(RandomNumberGenerator &rng, const byte *plainText, unsigned int plainTextLength, byte *cipherText)
|
void ElGamalCryptoPublicKey::Encrypt(RandomNumberGenerator &rng, const byte *plainText, unsigned int plainTextLength, byte *cipherText)
|
||||||
{
|
{
|
||||||
assert(plainTextLength <= MaxPlainTextLength());
|
assert(plainTextLength <= MaxPlainTextLength());
|
||||||
|
|
||||||
SecByteBlock block(modulusLen-1);
|
SecByteBlock block(modulusLen-1);
|
||||||
rng.GetBlock(block, modulusLen-2-plainTextLength);
|
rng.GetBlock(block, modulusLen-2-plainTextLength);
|
||||||
memcpy(block+modulusLen-2-plainTextLength, plainText, plainTextLength);
|
memcpy(block+modulusLen-2-plainTextLength, plainText, plainTextLength);
|
||||||
block[modulusLen-2] = plainTextLength;
|
block[modulusLen-2] = plainTextLength;
|
||||||
|
|
||||||
Integer m(block, modulusLen-1);
|
Integer m(block, modulusLen-1);
|
||||||
Integer a,b;
|
Integer a,b;
|
||||||
RawEncrypt(Integer(rng, ExponentBitLength()), m, a, b);
|
RawEncrypt(Integer(rng, ExponentBitLength()), m, a, b);
|
||||||
|
|
||||||
a.Encode(cipherText, modulusLen);
|
a.Encode(cipherText, modulusLen);
|
||||||
b.Encode(cipherText+modulusLen, modulusLen);
|
b.Encode(cipherText+modulusLen, modulusLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElGamalCryptoPublicKey::RawEncrypt(const Integer &k, const Integer &m, Integer &a, Integer &b) const
|
void ElGamalCryptoPublicKey::RawEncrypt(const Integer &k, const Integer &m, Integer &a, Integer &b) const
|
||||||
{
|
{
|
||||||
// a = a_exp_b_mod_c(g, k, p);
|
// a = a_exp_b_mod_c(g, k, p);
|
||||||
// b = m * a_exp_b_mod_c(y, k, p) % p;
|
// b = m * a_exp_b_mod_c(y, k, p) % p;
|
||||||
a = gpc.Exponentiate(k);
|
a = gpc.Exponentiate(k);
|
||||||
b = m * ypc.Exponentiate(k) % p;
|
b = m * ypc.Exponentiate(k) % p;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int ElGamalCryptoPublicKey::ExponentBitLength() const
|
unsigned int ElGamalCryptoPublicKey::ExponentBitLength() const
|
||||||
{
|
{
|
||||||
return 2*DiscreteLogWorkFactor(p.BitCount());
|
return 2*DiscreteLogWorkFactor(p.BitCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
// *************************************************************
|
// *************************************************************
|
||||||
|
|
||||||
ElGamalCryptoPrivateKey::ElGamalCryptoPrivateKey(const Integer &p, const Integer &g, const Integer &y, const Integer &x)
|
ElGamalCryptoPrivateKey::ElGamalCryptoPrivateKey(const Integer &p, const Integer &g, const Integer &y, const Integer &x)
|
||||||
: ElGamalCryptoPublicKey(p, g, y), x(x)
|
: ElGamalCryptoPublicKey(p, g, y), x(x)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ElGamalCryptoPrivateKey::ElGamalCryptoPrivateKey(RandomNumberGenerator &rng, unsigned int pbits)
|
ElGamalCryptoPrivateKey::ElGamalCryptoPrivateKey(RandomNumberGenerator &rng, unsigned int pbits)
|
||||||
{
|
{
|
||||||
PrimeAndGenerator pg(1, rng, pbits);
|
PrimeAndGenerator pg(1, rng, pbits);
|
||||||
p = pg.Prime();
|
p = pg.Prime();
|
||||||
modulusLen=p.ByteCount();
|
modulusLen=p.ByteCount();
|
||||||
g = pg.Generator();
|
g = pg.Generator();
|
||||||
x.Randomize(rng, ExponentBitLength());
|
x.Randomize(rng, ExponentBitLength());
|
||||||
gpc.Precompute(p, g, ExponentBitLength(), 1);
|
gpc.Precompute(p, g, ExponentBitLength(), 1);
|
||||||
y = gpc.Exponentiate(x);
|
y = gpc.Exponentiate(x);
|
||||||
ypc.Precompute(p, y, ExponentBitLength(), 1);
|
ypc.Precompute(p, y, ExponentBitLength(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ElGamalCryptoPrivateKey::ElGamalCryptoPrivateKey(RandomNumberGenerator &rng, const Integer &pIn, const Integer &gIn)
|
ElGamalCryptoPrivateKey::ElGamalCryptoPrivateKey(RandomNumberGenerator &rng, const Integer &pIn, const Integer &gIn)
|
||||||
{
|
{
|
||||||
p = pIn;
|
p = pIn;
|
||||||
modulusLen=p.ByteCount();
|
modulusLen=p.ByteCount();
|
||||||
g = gIn;
|
g = gIn;
|
||||||
x.Randomize(rng, ExponentBitLength());
|
x.Randomize(rng, ExponentBitLength());
|
||||||
gpc.Precompute(p, g, ExponentBitLength(), 1);
|
gpc.Precompute(p, g, ExponentBitLength(), 1);
|
||||||
y = gpc.Exponentiate(x);
|
y = gpc.Exponentiate(x);
|
||||||
ypc.Precompute(p, y, ExponentBitLength(), 1);
|
ypc.Precompute(p, y, ExponentBitLength(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ElGamalCryptoPrivateKey::~ElGamalCryptoPrivateKey()
|
ElGamalCryptoPrivateKey::~ElGamalCryptoPrivateKey()
|
||||||
|
@ -121,191 +121,191 @@ ElGamalCryptoPrivateKey::~ElGamalCryptoPrivateKey()
|
||||||
|
|
||||||
ElGamalCryptoPrivateKey::ElGamalCryptoPrivateKey(BufferedTransformation &bt)
|
ElGamalCryptoPrivateKey::ElGamalCryptoPrivateKey(BufferedTransformation &bt)
|
||||||
{
|
{
|
||||||
BERSequenceDecoder seq(bt);
|
BERSequenceDecoder seq(bt);
|
||||||
p.BERDecode(seq);
|
p.BERDecode(seq);
|
||||||
modulusLen=p.ByteCount();
|
modulusLen=p.ByteCount();
|
||||||
g.BERDecode(seq);
|
g.BERDecode(seq);
|
||||||
y.BERDecode(seq);
|
y.BERDecode(seq);
|
||||||
x.BERDecode(seq);
|
x.BERDecode(seq);
|
||||||
gpc.Precompute(p, g, ExponentBitLength(), 1);
|
gpc.Precompute(p, g, ExponentBitLength(), 1);
|
||||||
ypc.Precompute(p, y, ExponentBitLength(), 1);
|
ypc.Precompute(p, y, ExponentBitLength(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElGamalCryptoPrivateKey::DEREncode(BufferedTransformation &bt) const
|
void ElGamalCryptoPrivateKey::DEREncode(BufferedTransformation &bt) const
|
||||||
{
|
{
|
||||||
DERSequenceEncoder seq(bt);
|
DERSequenceEncoder seq(bt);
|
||||||
p.DEREncode(seq);
|
p.DEREncode(seq);
|
||||||
g.DEREncode(seq);
|
g.DEREncode(seq);
|
||||||
y.DEREncode(seq);
|
y.DEREncode(seq);
|
||||||
x.DEREncode(seq);
|
x.DEREncode(seq);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int ElGamalCryptoPrivateKey::Decrypt(const byte *cipherText, byte *plainText)
|
unsigned int ElGamalCryptoPrivateKey::Decrypt(const byte *cipherText, byte *plainText)
|
||||||
{
|
{
|
||||||
Integer a(cipherText, modulusLen);
|
Integer a(cipherText, modulusLen);
|
||||||
Integer b(cipherText+modulusLen, modulusLen);
|
Integer b(cipherText+modulusLen, modulusLen);
|
||||||
Integer m;
|
Integer m;
|
||||||
|
|
||||||
RawDecrypt(a, b, m);
|
RawDecrypt(a, b, m);
|
||||||
m.Encode(plainText, 1);
|
m.Encode(plainText, 1);
|
||||||
unsigned int plainTextLength = plainText[0];
|
unsigned int plainTextLength = plainText[0];
|
||||||
if (plainTextLength > MaxPlainTextLength())
|
if (plainTextLength > MaxPlainTextLength())
|
||||||
return 0;
|
return 0;
|
||||||
m >>= 8;
|
m >>= 8;
|
||||||
m.Encode(plainText, plainTextLength);
|
m.Encode(plainText, plainTextLength);
|
||||||
return plainTextLength;
|
return plainTextLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElGamalCryptoPrivateKey::RawDecrypt(const Integer &a, const Integer &b, Integer &m) const
|
void ElGamalCryptoPrivateKey::RawDecrypt(const Integer &a, const Integer &b, Integer &m) const
|
||||||
{
|
{
|
||||||
if (x.BitCount()+20 < p.BitCount()) // if x is short
|
if (x.BitCount()+20 < p.BitCount()) // if x is short
|
||||||
m = b * EuclideanMultiplicativeInverse(a_exp_b_mod_c(a, x, p), p) % p;
|
m = b * EuclideanMultiplicativeInverse(a_exp_b_mod_c(a, x, p), p) % p;
|
||||||
else // save a multiplicative inverse calculation
|
else // save a multiplicative inverse calculation
|
||||||
m = b * a_exp_b_mod_c(a, p-1-x, p) % p;
|
m = b * a_exp_b_mod_c(a, p-1-x, p) % p;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
|
|
||||||
ElGamalSigPublicKey::ElGamalSigPublicKey(const Integer &p, const Integer &q, const Integer &g, const Integer &y)
|
ElGamalSigPublicKey::ElGamalSigPublicKey(const Integer &p, const Integer &q, const Integer &g, const Integer &y)
|
||||||
: p(p), q(q), g(g), y(y), qLen(q.ByteCount()),
|
: p(p), q(q), g(g), y(y), qLen(q.ByteCount()),
|
||||||
gpc(p, g, ExponentBitLength(), 1), ypc(p, y, ExponentBitLength(), 1)
|
gpc(p, g, ExponentBitLength(), 1), ypc(p, y, ExponentBitLength(), 1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ElGamalSigPublicKey::ElGamalSigPublicKey(BufferedTransformation &bt)
|
ElGamalSigPublicKey::ElGamalSigPublicKey(BufferedTransformation &bt)
|
||||||
{
|
{
|
||||||
BERSequenceDecoder seq(bt);
|
BERSequenceDecoder seq(bt);
|
||||||
p.BERDecode(seq);
|
p.BERDecode(seq);
|
||||||
q.BERDecode(seq);
|
q.BERDecode(seq);
|
||||||
g.BERDecode(seq);
|
g.BERDecode(seq);
|
||||||
y.BERDecode(seq);
|
y.BERDecode(seq);
|
||||||
qLen = q.ByteCount();
|
qLen = q.ByteCount();
|
||||||
gpc.Precompute(p, g, ExponentBitLength(), 1);
|
gpc.Precompute(p, g, ExponentBitLength(), 1);
|
||||||
ypc.Precompute(p, y, ExponentBitLength(), 1);
|
ypc.Precompute(p, y, ExponentBitLength(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElGamalSigPublicKey::DEREncode(BufferedTransformation &bt) const
|
void ElGamalSigPublicKey::DEREncode(BufferedTransformation &bt) const
|
||||||
{
|
{
|
||||||
DERSequenceEncoder seq(bt);
|
DERSequenceEncoder seq(bt);
|
||||||
p.DEREncode(seq);
|
p.DEREncode(seq);
|
||||||
q.DEREncode(seq);
|
q.DEREncode(seq);
|
||||||
g.DEREncode(seq);
|
g.DEREncode(seq);
|
||||||
y.DEREncode(seq);
|
y.DEREncode(seq);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElGamalSigPublicKey::Precompute(unsigned int precomputationStorage)
|
void ElGamalSigPublicKey::Precompute(unsigned int precomputationStorage)
|
||||||
{
|
{
|
||||||
gpc.Precompute(p, g, ExponentBitLength(), precomputationStorage);
|
gpc.Precompute(p, g, ExponentBitLength(), precomputationStorage);
|
||||||
ypc.Precompute(p, y, ExponentBitLength(), precomputationStorage);
|
ypc.Precompute(p, y, ExponentBitLength(), precomputationStorage);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElGamalSigPublicKey::LoadPrecomputation(BufferedTransformation &bt)
|
void ElGamalSigPublicKey::LoadPrecomputation(BufferedTransformation &bt)
|
||||||
{
|
{
|
||||||
gpc.Load(p, bt);
|
gpc.Load(p, bt);
|
||||||
ypc.Load(p, bt);
|
ypc.Load(p, bt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElGamalSigPublicKey::SavePrecomputation(BufferedTransformation &bt) const
|
void ElGamalSigPublicKey::SavePrecomputation(BufferedTransformation &bt) const
|
||||||
{
|
{
|
||||||
gpc.Save(bt);
|
gpc.Save(bt);
|
||||||
ypc.Save(bt);
|
ypc.Save(bt);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ElGamalSigPublicKey::Verify(const byte *message, unsigned int messageLen, const byte *signature)
|
bool ElGamalSigPublicKey::Verify(const byte *message, unsigned int messageLen, const byte *signature)
|
||||||
{
|
{
|
||||||
assert(messageLen <= MaxMessageLength());
|
assert(messageLen <= MaxMessageLength());
|
||||||
|
|
||||||
Integer m(message, messageLen);
|
Integer m(message, messageLen);
|
||||||
Integer r(signature, qLen);
|
Integer r(signature, qLen);
|
||||||
Integer s(signature+qLen, qLen);
|
Integer s(signature+qLen, qLen);
|
||||||
return RawVerify(m, r, s);
|
return RawVerify(m, r, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ElGamalSigPublicKey::RawVerify(const Integer &m, const Integer &r, const Integer &s) const
|
bool ElGamalSigPublicKey::RawVerify(const Integer &m, const Integer &r, const Integer &s) const
|
||||||
{
|
{
|
||||||
// check r != 0 && r == (g^s * y^r + m) mod q
|
// check r != 0 && r == (g^s * y^r + m) mod q
|
||||||
return !!r && r == (gpc.CascadeExponentiate(s, ypc, r) + m) % q;
|
return !!r && r == (gpc.CascadeExponentiate(s, ypc, r) + m) % q;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int ElGamalSigPublicKey::ExponentBitLength() const
|
unsigned int ElGamalSigPublicKey::ExponentBitLength() const
|
||||||
{
|
{
|
||||||
return q.BitCount();
|
return q.BitCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
// *************************************************************
|
// *************************************************************
|
||||||
|
|
||||||
ElGamalSigPrivateKey::ElGamalSigPrivateKey(const Integer &p, const Integer &q, const Integer &g, const Integer &y, const Integer &x)
|
ElGamalSigPrivateKey::ElGamalSigPrivateKey(const Integer &p, const Integer &q, const Integer &g, const Integer &y, const Integer &x)
|
||||||
: ElGamalSigPublicKey(p, q, g, y), x(x)
|
: ElGamalSigPublicKey(p, q, g, y), x(x)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ElGamalSigPrivateKey::ElGamalSigPrivateKey(RandomNumberGenerator &rng, unsigned int pbits)
|
ElGamalSigPrivateKey::ElGamalSigPrivateKey(RandomNumberGenerator &rng, unsigned int pbits)
|
||||||
{
|
{
|
||||||
PrimeAndGenerator pg(1, rng, pbits, 2*DiscreteLogWorkFactor(pbits));
|
PrimeAndGenerator pg(1, rng, pbits, 2*DiscreteLogWorkFactor(pbits));
|
||||||
p = pg.Prime();
|
p = pg.Prime();
|
||||||
q = pg.SubPrime();
|
q = pg.SubPrime();
|
||||||
g = pg.Generator();
|
g = pg.Generator();
|
||||||
x.Randomize(rng, 2, q-2, Integer::ANY);
|
x.Randomize(rng, 2, q-2, Integer::ANY);
|
||||||
gpc.Precompute(p, g, ExponentBitLength(), 1);
|
gpc.Precompute(p, g, ExponentBitLength(), 1);
|
||||||
y = gpc.Exponentiate(x);
|
y = gpc.Exponentiate(x);
|
||||||
ypc.Precompute(p, y, ExponentBitLength(), 1);
|
ypc.Precompute(p, y, ExponentBitLength(), 1);
|
||||||
qLen = q.ByteCount();
|
qLen = q.ByteCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
ElGamalSigPrivateKey::ElGamalSigPrivateKey(RandomNumberGenerator &rng, const Integer &pIn, const Integer &qIn, const Integer &gIn)
|
ElGamalSigPrivateKey::ElGamalSigPrivateKey(RandomNumberGenerator &rng, const Integer &pIn, const Integer &qIn, const Integer &gIn)
|
||||||
{
|
{
|
||||||
p = pIn;
|
p = pIn;
|
||||||
q = qIn;
|
q = qIn;
|
||||||
g = gIn;
|
g = gIn;
|
||||||
x.Randomize(rng, 2, q-2, Integer::ANY);
|
x.Randomize(rng, 2, q-2, Integer::ANY);
|
||||||
gpc.Precompute(p, g, ExponentBitLength(), 1);
|
gpc.Precompute(p, g, ExponentBitLength(), 1);
|
||||||
y = gpc.Exponentiate(x);
|
y = gpc.Exponentiate(x);
|
||||||
ypc.Precompute(p, y, ExponentBitLength(), 1);
|
ypc.Precompute(p, y, ExponentBitLength(), 1);
|
||||||
qLen = q.ByteCount();
|
qLen = q.ByteCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
ElGamalSigPrivateKey::ElGamalSigPrivateKey(BufferedTransformation &bt)
|
ElGamalSigPrivateKey::ElGamalSigPrivateKey(BufferedTransformation &bt)
|
||||||
{
|
{
|
||||||
BERSequenceDecoder seq(bt);
|
BERSequenceDecoder seq(bt);
|
||||||
p.BERDecode(seq);
|
p.BERDecode(seq);
|
||||||
q.BERDecode(seq);
|
q.BERDecode(seq);
|
||||||
g.BERDecode(seq);
|
g.BERDecode(seq);
|
||||||
y.BERDecode(seq);
|
y.BERDecode(seq);
|
||||||
x.BERDecode(seq);
|
x.BERDecode(seq);
|
||||||
gpc.Precompute(p, g, ExponentBitLength(), 1);
|
gpc.Precompute(p, g, ExponentBitLength(), 1);
|
||||||
ypc.Precompute(p, y, ExponentBitLength(), 1);
|
ypc.Precompute(p, y, ExponentBitLength(), 1);
|
||||||
qLen = q.ByteCount();
|
qLen = q.ByteCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElGamalSigPrivateKey::DEREncode(BufferedTransformation &bt) const
|
void ElGamalSigPrivateKey::DEREncode(BufferedTransformation &bt) const
|
||||||
{
|
{
|
||||||
DERSequenceEncoder seq(bt);
|
DERSequenceEncoder seq(bt);
|
||||||
p.DEREncode(seq);
|
p.DEREncode(seq);
|
||||||
q.DEREncode(seq);
|
q.DEREncode(seq);
|
||||||
g.DEREncode(seq);
|
g.DEREncode(seq);
|
||||||
y.DEREncode(seq);
|
y.DEREncode(seq);
|
||||||
x.DEREncode(seq);
|
x.DEREncode(seq);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElGamalSigPrivateKey::Sign(RandomNumberGenerator &rng, const byte *message, unsigned int messageLen, byte *signature)
|
void ElGamalSigPrivateKey::Sign(RandomNumberGenerator &rng, const byte *message, unsigned int messageLen, byte *signature)
|
||||||
{
|
{
|
||||||
assert(messageLen <= MaxMessageLength());
|
assert(messageLen <= MaxMessageLength());
|
||||||
|
|
||||||
Integer m(message, messageLen);
|
Integer m(message, messageLen);
|
||||||
Integer r;
|
Integer r;
|
||||||
Integer s;
|
Integer s;
|
||||||
|
|
||||||
RawSign(rng, m, r, s);
|
RawSign(rng, m, r, s);
|
||||||
r.Encode(signature, qLen);
|
r.Encode(signature, qLen);
|
||||||
s.Encode(signature+qLen, qLen);
|
s.Encode(signature+qLen, qLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElGamalSigPrivateKey::RawSign(RandomNumberGenerator &rng, const Integer &m, Integer &r, Integer &s) const
|
void ElGamalSigPrivateKey::RawSign(RandomNumberGenerator &rng, const Integer &m, Integer &r, Integer &s) const
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
Integer k(rng, 2, q-2, Integer::ANY);
|
Integer k(rng, 2, q-2, Integer::ANY);
|
||||||
r = (gpc.Exponentiate(k) + m) % q;
|
r = (gpc.Exponentiate(k) + m) % q;
|
||||||
s = (k - x*r) % q;
|
s = (k - x*r) % q;
|
||||||
} while (!r); // make sure r != 0
|
} while (!r); // make sure r != 0
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,70 +6,70 @@
|
||||||
class ElGamalCryptoPublicKey : public PK_WithPrecomputation<PK_FixedLengthEncryptor>
|
class ElGamalCryptoPublicKey : public PK_WithPrecomputation<PK_FixedLengthEncryptor>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ElGamalCryptoPublicKey(const Integer &p, const Integer &g, const Integer &y);
|
ElGamalCryptoPublicKey(const Integer &p, const Integer &g, const Integer &y);
|
||||||
ElGamalCryptoPublicKey(BufferedTransformation &bt);
|
ElGamalCryptoPublicKey(BufferedTransformation &bt);
|
||||||
|
|
||||||
~ElGamalCryptoPublicKey();
|
~ElGamalCryptoPublicKey();
|
||||||
|
|
||||||
void DEREncode(BufferedTransformation &bt) const;
|
void DEREncode(BufferedTransformation &bt) const;
|
||||||
|
|
||||||
void Precompute(unsigned int precomputationStorage=16);
|
void Precompute(unsigned int precomputationStorage=16);
|
||||||
void LoadPrecomputation(BufferedTransformation &storedPrecomputation);
|
void LoadPrecomputation(BufferedTransformation &storedPrecomputation);
|
||||||
void SavePrecomputation(BufferedTransformation &storedPrecomputation) const;
|
void SavePrecomputation(BufferedTransformation &storedPrecomputation) const;
|
||||||
|
|
||||||
void Encrypt(RandomNumberGenerator &rng, const byte *plainText, unsigned int plainTextLength, byte *cipherText);
|
void Encrypt(RandomNumberGenerator &rng, const byte *plainText, unsigned int plainTextLength, byte *cipherText);
|
||||||
|
|
||||||
unsigned int MaxPlainTextLength() const {return STDMIN(255U, modulusLen-3);}
|
unsigned int MaxPlainTextLength() const {return STDMIN(255U, modulusLen-3);}
|
||||||
unsigned int CipherTextLength() const {return 2*modulusLen;}
|
unsigned int CipherTextLength() const {return 2*modulusLen;}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ElGamalCryptoPublicKey() {}
|
ElGamalCryptoPublicKey() {}
|
||||||
void RawEncrypt(const Integer &k, const Integer &m, Integer &a, Integer &b) const;
|
void RawEncrypt(const Integer &k, const Integer &m, Integer &a, Integer &b) const;
|
||||||
unsigned int ExponentBitLength() const;
|
unsigned int ExponentBitLength() const;
|
||||||
|
|
||||||
Integer p, g, y;
|
Integer p, g, y;
|
||||||
unsigned int modulusLen;
|
unsigned int modulusLen;
|
||||||
ModExpPrecomputation gpc, ypc;
|
ModExpPrecomputation gpc, ypc;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ElGamalCryptoPrivateKey : public ElGamalCryptoPublicKey, public PK_FixedLengthDecryptor
|
class ElGamalCryptoPrivateKey : public ElGamalCryptoPublicKey, public PK_FixedLengthDecryptor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ElGamalCryptoPrivateKey(const Integer &p, const Integer &g, const Integer &y, const Integer &x);
|
ElGamalCryptoPrivateKey(const Integer &p, const Integer &g, const Integer &y, const Integer &x);
|
||||||
ElGamalCryptoPrivateKey(RandomNumberGenerator &rng, unsigned int pbits);
|
ElGamalCryptoPrivateKey(RandomNumberGenerator &rng, unsigned int pbits);
|
||||||
// generate a random private key, given p and g
|
// generate a random private key, given p and g
|
||||||
ElGamalCryptoPrivateKey(RandomNumberGenerator &rng, const Integer &p, const Integer &g);
|
ElGamalCryptoPrivateKey(RandomNumberGenerator &rng, const Integer &p, const Integer &g);
|
||||||
|
|
||||||
~ElGamalCryptoPrivateKey();
|
~ElGamalCryptoPrivateKey();
|
||||||
|
|
||||||
ElGamalCryptoPrivateKey(BufferedTransformation &bt);
|
ElGamalCryptoPrivateKey(BufferedTransformation &bt);
|
||||||
void DEREncode(BufferedTransformation &bt) const;
|
void DEREncode(BufferedTransformation &bt) const;
|
||||||
|
|
||||||
unsigned int Decrypt(const byte *cipherText, byte *plainText);
|
unsigned int Decrypt(const byte *cipherText, byte *plainText);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void RawDecrypt(const Integer &a, const Integer &b, Integer &m) const;
|
void RawDecrypt(const Integer &a, const Integer &b, Integer &m) const;
|
||||||
|
|
||||||
Integer x;
|
Integer x;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ElGamalSigPublicKey : public PK_WithPrecomputation<PK_Verifier>
|
class ElGamalSigPublicKey : public PK_WithPrecomputation<PK_Verifier>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ElGamalSigPublicKey(const Integer &p, const Integer &q, const Integer &g, const Integer &y);
|
ElGamalSigPublicKey(const Integer &p, const Integer &q, const Integer &g, const Integer &y);
|
||||||
ElGamalSigPublicKey(BufferedTransformation &bt);
|
ElGamalSigPublicKey(BufferedTransformation &bt);
|
||||||
|
|
||||||
void DEREncode(BufferedTransformation &bt) const;
|
void DEREncode(BufferedTransformation &bt) const;
|
||||||
|
|
||||||
void Precompute(unsigned int precomputationStorage=16);
|
void Precompute(unsigned int precomputationStorage=16);
|
||||||
void LoadPrecomputation(BufferedTransformation &storedPrecomputation);
|
void LoadPrecomputation(BufferedTransformation &storedPrecomputation);
|
||||||
void SavePrecomputation(BufferedTransformation &storedPrecomputation) const;
|
void SavePrecomputation(BufferedTransformation &storedPrecomputation) const;
|
||||||
|
|
||||||
bool Verify(const byte *message, unsigned int messageLen, const byte *signature);
|
bool Verify(const byte *message, unsigned int messageLen, const byte *signature);
|
||||||
|
|
||||||
// message length for signature is unlimited, but only message digests should be signed
|
// message length for signature is unlimited, but only message digests should be signed
|
||||||
unsigned int MaxMessageLength() const {return 0xffff;}
|
unsigned int MaxMessageLength() const {return 0xffff;}
|
||||||
unsigned int SignatureLength() const {return 2*qLen;}
|
unsigned int SignatureLength() const {return 2*qLen;}
|
||||||
|
|
||||||
const Integer& GetPrime() { return p; }
|
const Integer& GetPrime() { return p; }
|
||||||
const Integer& GetParameterQ() { return q; }
|
const Integer& GetParameterQ() { return q; }
|
||||||
|
@ -77,34 +77,34 @@ public:
|
||||||
const Integer& GetParameterY() { return y; }
|
const Integer& GetParameterY() { return y; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ElGamalSigPublicKey() {}
|
ElGamalSigPublicKey() {}
|
||||||
bool RawVerify(const Integer &m, const Integer &a, const Integer &b) const;
|
bool RawVerify(const Integer &m, const Integer &a, const Integer &b) const;
|
||||||
unsigned int ExponentBitLength() const;
|
unsigned int ExponentBitLength() const;
|
||||||
|
|
||||||
Integer p, q, g, y;
|
Integer p, q, g, y;
|
||||||
unsigned int qLen;
|
unsigned int qLen;
|
||||||
ModExpPrecomputation gpc, ypc;
|
ModExpPrecomputation gpc, ypc;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ElGamalSigPrivateKey : public ElGamalSigPublicKey, public PK_WithPrecomputation<PK_Signer>
|
class ElGamalSigPrivateKey : public ElGamalSigPublicKey, public PK_WithPrecomputation<PK_Signer>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ElGamalSigPrivateKey(const Integer &p, const Integer &q, const Integer &g, const Integer &y, const Integer &x);
|
ElGamalSigPrivateKey(const Integer &p, const Integer &q, const Integer &g, const Integer &y, const Integer &x);
|
||||||
ElGamalSigPrivateKey(RandomNumberGenerator &rng, unsigned int pbits);
|
ElGamalSigPrivateKey(RandomNumberGenerator &rng, unsigned int pbits);
|
||||||
// generate a random private key, given p and g
|
// generate a random private key, given p and g
|
||||||
ElGamalSigPrivateKey(RandomNumberGenerator &rng, const Integer &p, const Integer &q, const Integer &g);
|
ElGamalSigPrivateKey(RandomNumberGenerator &rng, const Integer &p, const Integer &q, const Integer &g);
|
||||||
|
|
||||||
ElGamalSigPrivateKey(BufferedTransformation &bt);
|
ElGamalSigPrivateKey(BufferedTransformation &bt);
|
||||||
void DEREncode(BufferedTransformation &bt) const;
|
void DEREncode(BufferedTransformation &bt) const;
|
||||||
|
|
||||||
void Sign(RandomNumberGenerator &rng, const byte *message, unsigned int messageLen, byte *signature);
|
void Sign(RandomNumberGenerator &rng, const byte *message, unsigned int messageLen, byte *signature);
|
||||||
|
|
||||||
const Integer& GetParameterX() { return x; }
|
const Integer& GetParameterX() { return x; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void RawSign(RandomNumberGenerator &rng, const Integer &m, Integer &a, Integer &b) const;
|
void RawSign(RandomNumberGenerator &rng, const Integer &m, Integer &a, Integer &b) const;
|
||||||
|
|
||||||
Integer x;
|
Integer x;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -7,58 +7,58 @@ USING_NAMESPACE(std)
|
||||||
|
|
||||||
template <class T> void ExponentiationPrecomputation<T>::Precompute(const Element &base, unsigned int maxExpBits)
|
template <class T> void ExponentiationPrecomputation<T>::Precompute(const Element &base, unsigned int maxExpBits)
|
||||||
{
|
{
|
||||||
assert(storage <= maxExpBits);
|
assert(storage <= maxExpBits);
|
||||||
exponentBase = Integer::Power2((maxExpBits+storage-1)/storage);
|
exponentBase = Integer::Power2((maxExpBits+storage-1)/storage);
|
||||||
|
|
||||||
g[0] = base;
|
g[0] = base;
|
||||||
for (unsigned i=1; i<storage; i++)
|
for (unsigned i=1; i<storage; i++)
|
||||||
g[i] = group.IntMultiply(g[i-1], exponentBase);
|
g[i] = group.IntMultiply(g[i-1], exponentBase);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> typename ExponentiationPrecomputation<T>::Element ExponentiationPrecomputation<T>::Exponentiate(const Integer &exponent) const
|
template <class T> typename ExponentiationPrecomputation<T>::Element ExponentiationPrecomputation<T>::Exponentiate(const Integer &exponent) const
|
||||||
{
|
{
|
||||||
vector<pair<Integer, Element> > eb(storage); // array of segments of the exponent and precalculated bases
|
vector<pair<Integer, Element> > eb(storage); // array of segments of the exponent and precalculated bases
|
||||||
Integer temp, e = exponent;
|
Integer temp, e = exponent;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
for (i=0; i+1<storage; i++)
|
for (i=0; i+1<storage; i++)
|
||||||
{
|
{
|
||||||
Integer::Divide(eb[i].first, temp, e, exponentBase);
|
Integer::Divide(eb[i].first, temp, e, exponentBase);
|
||||||
swap(temp, e);
|
swap(temp, e);
|
||||||
eb[i].second = g[i];
|
eb[i].second = g[i];
|
||||||
}
|
}
|
||||||
eb[i].first = e;
|
eb[i].first = e;
|
||||||
eb[i].second = g[i];
|
eb[i].second = g[i];
|
||||||
|
|
||||||
return GeneralCascadeMultiplication<Element>(group, eb.begin(), eb.end());
|
return GeneralCascadeMultiplication<Element>(group, eb.begin(), eb.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> typename ExponentiationPrecomputation<T>::Element
|
template <class T> typename ExponentiationPrecomputation<T>::Element
|
||||||
ExponentiationPrecomputation<T>::CascadeExponentiate(const Integer &exponent,
|
ExponentiationPrecomputation<T>::CascadeExponentiate(const Integer &exponent,
|
||||||
const ExponentiationPrecomputation<T> &pc2, const Integer &exponent2) const
|
const ExponentiationPrecomputation<T> &pc2, const Integer &exponent2) const
|
||||||
{
|
{
|
||||||
vector<pair<Integer, Element> > eb(storage+pc2.storage); // array of segments of the exponent and precalculated bases
|
vector<pair<Integer, Element> > eb(storage+pc2.storage); // array of segments of the exponent and precalculated bases
|
||||||
Integer temp, e = exponent;
|
Integer temp, e = exponent;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
for (i=0; i+1<storage; i++)
|
for (i=0; i+1<storage; i++)
|
||||||
{
|
{
|
||||||
Integer::Divide(eb[i].first, temp, e, exponentBase);
|
Integer::Divide(eb[i].first, temp, e, exponentBase);
|
||||||
swap(temp, e);
|
swap(temp, e);
|
||||||
eb[i].second = g[i];
|
eb[i].second = g[i];
|
||||||
}
|
}
|
||||||
eb[i].first = e;
|
eb[i].first = e;
|
||||||
eb[i].second = g[i];
|
eb[i].second = g[i];
|
||||||
|
|
||||||
e = exponent2;
|
e = exponent2;
|
||||||
for (i=storage; i+1<storage+pc2.storage; i++)
|
for (i=storage; i+1<storage+pc2.storage; i++)
|
||||||
{
|
{
|
||||||
Integer::Divide(eb[i].first, temp, e, exponentBase);
|
Integer::Divide(eb[i].first, temp, e, exponentBase);
|
||||||
swap(temp, e);
|
swap(temp, e);
|
||||||
eb[i].second = pc2.g[i-storage];
|
eb[i].second = pc2.g[i-storage];
|
||||||
}
|
}
|
||||||
eb[i].first = e;
|
eb[i].first = e;
|
||||||
eb[i].second = pc2.g[i-storage];
|
eb[i].second = pc2.g[i-storage];
|
||||||
|
|
||||||
return GeneralCascadeMultiplication<Element>(group, eb.begin(), eb.end());
|
return GeneralCascadeMultiplication<Element>(group, eb.begin(), eb.end());
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,25 +15,25 @@
|
||||||
template <class T> class ExponentiationPrecomputation
|
template <class T> class ExponentiationPrecomputation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef T Group;
|
typedef T Group;
|
||||||
typedef typename Group::Element Element;
|
typedef typename Group::Element Element;
|
||||||
|
|
||||||
ExponentiationPrecomputation(const Group &group) : group(group) {}
|
ExponentiationPrecomputation(const Group &group) : group(group) {}
|
||||||
|
|
||||||
ExponentiationPrecomputation(const Group &group, const Element &base, unsigned int maxExpBits, unsigned int storage)
|
ExponentiationPrecomputation(const Group &group, const Element &base, unsigned int maxExpBits, unsigned int storage)
|
||||||
: group(group), storage(storage), g(storage) {Precompute(base, maxExpBits);}
|
: group(group), storage(storage), g(storage) {Precompute(base, maxExpBits);}
|
||||||
|
|
||||||
ExponentiationPrecomputation(const Group &group, const ExponentiationPrecomputation &pc)
|
ExponentiationPrecomputation(const Group &group, const ExponentiationPrecomputation &pc)
|
||||||
: group(group), storage(pc.storage), exponentBase(pc.exponentBase), g(pc.g) {}
|
: group(group), storage(pc.storage), exponentBase(pc.exponentBase), g(pc.g) {}
|
||||||
|
|
||||||
void Precompute(const Element &base, unsigned int maxExpBits);
|
void Precompute(const Element &base, unsigned int maxExpBits);
|
||||||
Element Exponentiate(const Integer &exponent) const;
|
Element Exponentiate(const Integer &exponent) const;
|
||||||
Element CascadeExponentiate(const Integer &exponent, const ExponentiationPrecomputation<Group> &pc2, const Integer &exponent2) const;
|
Element CascadeExponentiate(const Integer &exponent, const ExponentiationPrecomputation<Group> &pc2, const Integer &exponent2) const;
|
||||||
|
|
||||||
const Group &group;
|
const Group &group;
|
||||||
unsigned int storage; // number of precalculated bases
|
unsigned int storage; // number of precalculated bases
|
||||||
Integer exponentBase; // what base to represent the exponent in
|
Integer exponentBase; // what base to represent the exponent in
|
||||||
std::vector<Element> g; // precalculated bases
|
std::vector<Element> g; // precalculated bases
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -6,92 +6,92 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
Filter::Filter(BufferedTransformation *outQ)
|
Filter::Filter(BufferedTransformation *outQ)
|
||||||
: outQueue(outQ ? outQ : new ByteQueue)
|
: outQueue(outQ ? outQ : new ByteQueue)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Filter::Filter(const Filter &source)
|
Filter::Filter(const Filter &source)
|
||||||
: outQueue(new ByteQueue)
|
: outQueue(new ByteQueue)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Filter::Detach(BufferedTransformation *newOut)
|
void Filter::Detach(BufferedTransformation *newOut)
|
||||||
{
|
{
|
||||||
std::auto_ptr<BufferedTransformation> out(newOut ? newOut : new ByteQueue);
|
std::auto_ptr<BufferedTransformation> out(newOut ? newOut : new ByteQueue);
|
||||||
outQueue->Close();
|
outQueue->Close();
|
||||||
outQueue->TransferTo(*out);
|
outQueue->TransferTo(*out);
|
||||||
outQueue.reset(out.release());
|
outQueue.reset(out.release());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Filter::Attach(BufferedTransformation *newOut)
|
void Filter::Attach(BufferedTransformation *newOut)
|
||||||
{
|
{
|
||||||
if (outQueue->Attachable())
|
if (outQueue->Attachable())
|
||||||
outQueue->Attach(newOut);
|
outQueue->Attach(newOut);
|
||||||
else
|
else
|
||||||
Detach(newOut);
|
Detach(newOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockFilterBase::BlockFilterBase(BlockTransformation &c,
|
BlockFilterBase::BlockFilterBase(BlockTransformation &c,
|
||||||
BufferedTransformation *outQ)
|
BufferedTransformation *outQ)
|
||||||
: Filter(outQ), cipher(c), S(cipher.BlockSize()), inBuf(S)
|
: Filter(outQ), cipher(c), S(cipher.BlockSize()), inBuf(S)
|
||||||
{
|
{
|
||||||
inBufSize=0;
|
inBufSize=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlockFilterBase::ProcessBuf()
|
void BlockFilterBase::ProcessBuf()
|
||||||
{
|
{
|
||||||
cipher.ProcessBlock(inBuf);
|
cipher.ProcessBlock(inBuf);
|
||||||
outQueue->Put(inBuf, S);
|
outQueue->Put(inBuf, S);
|
||||||
inBufSize=0;
|
inBufSize=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlockFilterBase::Put(const byte *inString, unsigned int length)
|
void BlockFilterBase::Put(const byte *inString, unsigned int length)
|
||||||
{
|
{
|
||||||
while (length--)
|
while (length--)
|
||||||
BlockFilterBase::Put(*inString++);
|
BlockFilterBase::Put(*inString++);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlockEncryptionFilter::InputFinished()
|
void BlockEncryptionFilter::InputFinished()
|
||||||
{
|
{
|
||||||
if (inBufSize == S)
|
if (inBufSize == S)
|
||||||
ProcessBuf();
|
ProcessBuf();
|
||||||
// pad last block
|
// pad last block
|
||||||
memset(inBuf+inBufSize, S-inBufSize, S-inBufSize);
|
memset(inBuf+inBufSize, S-inBufSize, S-inBufSize);
|
||||||
ProcessBuf();
|
ProcessBuf();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlockDecryptionFilter::InputFinished()
|
void BlockDecryptionFilter::InputFinished()
|
||||||
{
|
{
|
||||||
cipher.ProcessBlock(inBuf);
|
cipher.ProcessBlock(inBuf);
|
||||||
if (inBuf[S-1] > S)
|
if (inBuf[S-1] > S)
|
||||||
inBuf[S-1] = 0; // something's wrong with the padding
|
inBuf[S-1] = 0; // something's wrong with the padding
|
||||||
outQueue->Put(inBuf, S-inBuf[S-1]);
|
outQueue->Put(inBuf, S-inBuf[S-1]);
|
||||||
inBufSize=0;
|
inBufSize=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StreamCipherFilter::Put(const byte *inString, unsigned int length)
|
void StreamCipherFilter::Put(const byte *inString, unsigned int length)
|
||||||
{
|
{
|
||||||
SecByteBlock temp(length);
|
SecByteBlock temp(length);
|
||||||
cipher.ProcessString(temp, inString, length);
|
cipher.ProcessString(temp, inString, length);
|
||||||
outQueue->Put(temp, length);
|
outQueue->Put(temp, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HashFilter::InputFinished()
|
void HashFilter::InputFinished()
|
||||||
{
|
{
|
||||||
SecByteBlock buf(hash.DigestSize());
|
SecByteBlock buf(hash.DigestSize());
|
||||||
hash.Final(buf);
|
hash.Final(buf);
|
||||||
outQueue->Put(buf, hash.DigestSize());
|
outQueue->Put(buf, hash.DigestSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferedTransformation *Insert(const byte *in, unsigned int length, BufferedTransformation *outQueue)
|
BufferedTransformation *Insert(const byte *in, unsigned int length, BufferedTransformation *outQueue)
|
||||||
{
|
{
|
||||||
outQueue->Put(in, length);
|
outQueue->Put(in, length);
|
||||||
return outQueue;
|
return outQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Extract(Source *source, byte *out, unsigned int length)
|
unsigned int Extract(Source *source, byte *out, unsigned int length)
|
||||||
{
|
{
|
||||||
while (source->MaxRetrieveable() < length && source->Pump(1));
|
while (source->MaxRetrieveable() < length && source->Pump(1));
|
||||||
return source->Get(out, length);
|
return source->Get(out, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,149 +8,149 @@
|
||||||
class Filter : public BufferedTransformation
|
class Filter : public BufferedTransformation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Filter(BufferedTransformation *outQ = NULL);
|
Filter(BufferedTransformation *outQ = NULL);
|
||||||
Filter(const Filter &source);
|
Filter(const Filter &source);
|
||||||
|
|
||||||
bool Attachable() {return true;}
|
bool Attachable() {return true;}
|
||||||
void Detach(BufferedTransformation *newOut = NULL);
|
void Detach(BufferedTransformation *newOut = NULL);
|
||||||
void Attach(BufferedTransformation *newOut);
|
void Attach(BufferedTransformation *newOut);
|
||||||
void Close()
|
void Close()
|
||||||
{InputFinished(); outQueue->Close();}
|
{InputFinished(); outQueue->Close();}
|
||||||
|
|
||||||
unsigned long MaxRetrieveable()
|
unsigned long MaxRetrieveable()
|
||||||
{return outQueue->MaxRetrieveable();}
|
{return outQueue->MaxRetrieveable();}
|
||||||
|
|
||||||
unsigned int Get(byte &outByte)
|
unsigned int Get(byte &outByte)
|
||||||
{return outQueue->Get(outByte);}
|
{return outQueue->Get(outByte);}
|
||||||
unsigned int Get(byte *outString, unsigned int getMax)
|
unsigned int Get(byte *outString, unsigned int getMax)
|
||||||
{return outQueue->Get(outString, getMax);}
|
{return outQueue->Get(outString, getMax);}
|
||||||
|
|
||||||
unsigned int Peek(byte &outByte) const
|
unsigned int Peek(byte &outByte) const
|
||||||
{return outQueue->Peek(outByte);}
|
{return outQueue->Peek(outByte);}
|
||||||
|
|
||||||
BufferedTransformation *OutQueue() {return outQueue.get();}
|
BufferedTransformation *OutQueue() {return outQueue.get();}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
member_ptr<BufferedTransformation> outQueue;
|
member_ptr<BufferedTransformation> outQueue;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void operator=(const Filter &); // assignment not allowed
|
void operator=(const Filter &); // assignment not allowed
|
||||||
};
|
};
|
||||||
|
|
||||||
class BlockFilterBase : public Filter
|
class BlockFilterBase : public Filter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BlockFilterBase(BlockTransformation &cipher,
|
BlockFilterBase(BlockTransformation &cipher,
|
||||||
BufferedTransformation *outQueue);
|
BufferedTransformation *outQueue);
|
||||||
virtual ~BlockFilterBase() {}
|
virtual ~BlockFilterBase() {}
|
||||||
|
|
||||||
void Put(byte inByte)
|
void Put(byte inByte)
|
||||||
{
|
{
|
||||||
if (inBufSize == S)
|
if (inBufSize == S)
|
||||||
ProcessBuf();
|
ProcessBuf();
|
||||||
inBuf[inBufSize++]=inByte;
|
inBuf[inBufSize++]=inByte;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Put(const byte *inString, unsigned int length);
|
void Put(const byte *inString, unsigned int length);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void ProcessBuf();
|
void ProcessBuf();
|
||||||
|
|
||||||
BlockTransformation &cipher;
|
BlockTransformation &cipher;
|
||||||
const unsigned int S;
|
const unsigned int S;
|
||||||
SecByteBlock inBuf;
|
SecByteBlock inBuf;
|
||||||
unsigned int inBufSize;
|
unsigned int inBufSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
class BlockEncryptionFilter : public BlockFilterBase
|
class BlockEncryptionFilter : public BlockFilterBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BlockEncryptionFilter(BlockTransformation &cipher, BufferedTransformation *outQueue = NULL)
|
BlockEncryptionFilter(BlockTransformation &cipher, BufferedTransformation *outQueue = NULL)
|
||||||
: BlockFilterBase(cipher, outQueue) {}
|
: BlockFilterBase(cipher, outQueue) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void InputFinished();
|
void InputFinished();
|
||||||
};
|
};
|
||||||
|
|
||||||
class BlockDecryptionFilter : public BlockFilterBase
|
class BlockDecryptionFilter : public BlockFilterBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BlockDecryptionFilter(BlockTransformation &cipher, BufferedTransformation *outQueue = NULL)
|
BlockDecryptionFilter(BlockTransformation &cipher, BufferedTransformation *outQueue = NULL)
|
||||||
: BlockFilterBase(cipher, outQueue) {}
|
: BlockFilterBase(cipher, outQueue) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void InputFinished();
|
void InputFinished();
|
||||||
};
|
};
|
||||||
|
|
||||||
class StreamCipherFilter : public Filter
|
class StreamCipherFilter : public Filter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
StreamCipherFilter(StreamCipher &c,
|
StreamCipherFilter(StreamCipher &c,
|
||||||
BufferedTransformation *outQueue = NULL)
|
BufferedTransformation *outQueue = NULL)
|
||||||
: Filter(outQueue), cipher(c) {}
|
: Filter(outQueue), cipher(c) {}
|
||||||
|
|
||||||
void Put(byte inByte)
|
void Put(byte inByte)
|
||||||
{outQueue->Put(cipher.ProcessByte(inByte));}
|
{outQueue->Put(cipher.ProcessByte(inByte));}
|
||||||
|
|
||||||
void Put(const byte *inString, unsigned int length);
|
void Put(const byte *inString, unsigned int length);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StreamCipher &cipher;
|
StreamCipher &cipher;
|
||||||
};
|
};
|
||||||
|
|
||||||
class HashFilter : public Filter
|
class HashFilter : public Filter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HashFilter(HashModule &hm, BufferedTransformation *outQueue = NULL)
|
HashFilter(HashModule &hm, BufferedTransformation *outQueue = NULL)
|
||||||
: Filter(outQueue), hash(hm) {}
|
: Filter(outQueue), hash(hm) {}
|
||||||
|
|
||||||
void InputFinished();
|
void InputFinished();
|
||||||
|
|
||||||
void Put(byte inByte)
|
void Put(byte inByte)
|
||||||
{hash.Update(&inByte, 1);}
|
{hash.Update(&inByte, 1);}
|
||||||
|
|
||||||
void Put(const byte *inString, unsigned int length)
|
void Put(const byte *inString, unsigned int length)
|
||||||
{hash.Update(inString, length);}
|
{hash.Update(inString, length);}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HashModule &hash;
|
HashModule &hash;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Source : public Filter
|
class Source : public Filter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Source(BufferedTransformation *outQ = NULL)
|
Source(BufferedTransformation *outQ = NULL)
|
||||||
: Filter(outQ) {}
|
: Filter(outQ) {}
|
||||||
|
|
||||||
void Put(byte)
|
void Put(byte)
|
||||||
{Pump(1);}
|
{Pump(1);}
|
||||||
void Put(const byte *, unsigned int length)
|
void Put(const byte *, unsigned int length)
|
||||||
{Pump(length);}
|
{Pump(length);}
|
||||||
void InputFinished()
|
void InputFinished()
|
||||||
{PumpAll();}
|
{PumpAll();}
|
||||||
|
|
||||||
virtual unsigned int Pump(unsigned int size) =0;
|
virtual unsigned int Pump(unsigned int size) =0;
|
||||||
virtual unsigned long PumpAll() =0;
|
virtual unsigned long PumpAll() =0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Sink : public BufferedTransformation
|
class Sink : public BufferedTransformation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
unsigned long MaxRetrieveable()
|
unsigned long MaxRetrieveable()
|
||||||
{return 0;}
|
{return 0;}
|
||||||
unsigned int Get(byte &)
|
unsigned int Get(byte &)
|
||||||
{return 0;}
|
{return 0;}
|
||||||
unsigned int Get(byte *, unsigned int)
|
unsigned int Get(byte *, unsigned int)
|
||||||
{return 0;}
|
{return 0;}
|
||||||
unsigned int Peek(byte &) const
|
unsigned int Peek(byte &) const
|
||||||
{return 0;}
|
{return 0;}
|
||||||
};
|
};
|
||||||
|
|
||||||
class BitBucket : public Sink
|
class BitBucket : public Sink
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void Put(byte) {}
|
void Put(byte) {}
|
||||||
void Put(const byte *, unsigned int) {}
|
void Put(const byte *, unsigned int) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
BufferedTransformation *Insert(const byte *in, unsigned int length, BufferedTransformation *outQueue);
|
BufferedTransformation *Insert(const byte *in, unsigned int length, BufferedTransformation *outQueue);
|
||||||
|
|
|
@ -6,132 +6,132 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
Fork::Fork(int n, BufferedTransformation *const *givenOutPorts)
|
Fork::Fork(int n, BufferedTransformation *const *givenOutPorts)
|
||||||
: numberOfPorts(n), outPorts(n)
|
: numberOfPorts(n), outPorts(n)
|
||||||
{
|
{
|
||||||
currentPort = 0;
|
currentPort = 0;
|
||||||
|
|
||||||
for (unsigned int i=0; i<numberOfPorts; i++)
|
for (unsigned int i=0; i<numberOfPorts; i++)
|
||||||
outPorts[i].reset(givenOutPorts ? givenOutPorts[i] : new ByteQueue);
|
outPorts[i].reset(givenOutPorts ? givenOutPorts[i] : new ByteQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fork::SelectOutPort(int portNumber)
|
void Fork::SelectOutPort(int portNumber)
|
||||||
{
|
{
|
||||||
currentPort = portNumber;
|
currentPort = portNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fork::Detach(BufferedTransformation *newOut)
|
void Fork::Detach(BufferedTransformation *newOut)
|
||||||
{
|
{
|
||||||
std::auto_ptr<BufferedTransformation> out(newOut ? newOut : new ByteQueue);
|
std::auto_ptr<BufferedTransformation> out(newOut ? newOut : new ByteQueue);
|
||||||
outPorts[currentPort]->Close();
|
outPorts[currentPort]->Close();
|
||||||
outPorts[currentPort]->TransferTo(*out);
|
outPorts[currentPort]->TransferTo(*out);
|
||||||
outPorts[currentPort].reset(out.release());
|
outPorts[currentPort].reset(out.release());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fork::Attach(BufferedTransformation *newOut)
|
void Fork::Attach(BufferedTransformation *newOut)
|
||||||
{
|
{
|
||||||
if (outPorts[currentPort]->Attachable())
|
if (outPorts[currentPort]->Attachable())
|
||||||
outPorts[currentPort]->Attach(newOut);
|
outPorts[currentPort]->Attach(newOut);
|
||||||
else
|
else
|
||||||
Detach(newOut);
|
Detach(newOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fork::Close()
|
void Fork::Close()
|
||||||
{
|
{
|
||||||
InputFinished();
|
InputFinished();
|
||||||
|
|
||||||
for (unsigned int i=0; i<numberOfPorts; i++)
|
for (unsigned int i=0; i<numberOfPorts; i++)
|
||||||
outPorts[i]->Close();
|
outPorts[i]->Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fork::Put(byte inByte)
|
void Fork::Put(byte inByte)
|
||||||
{
|
{
|
||||||
for (unsigned int i=0; i<numberOfPorts; i++)
|
for (unsigned int i=0; i<numberOfPorts; i++)
|
||||||
outPorts[i]->Put(inByte);
|
outPorts[i]->Put(inByte);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fork::Put(const byte *inString, unsigned int length)
|
void Fork::Put(const byte *inString, unsigned int length)
|
||||||
{
|
{
|
||||||
for (unsigned int i=0; i<numberOfPorts; i++)
|
for (unsigned int i=0; i<numberOfPorts; i++)
|
||||||
outPorts[i]->Put(inString, length);
|
outPorts[i]->Put(inString, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ********************************************************
|
// ********************************************************
|
||||||
|
|
||||||
Join::Join(unsigned int n, BufferedTransformation *outQ)
|
Join::Join(unsigned int n, BufferedTransformation *outQ)
|
||||||
: Filter(outQ),
|
: Filter(outQ),
|
||||||
numberOfPorts(n),
|
numberOfPorts(n),
|
||||||
inPorts(n),
|
inPorts(n),
|
||||||
interfacesOpen(n),
|
interfacesOpen(n),
|
||||||
interfaces(n)
|
interfaces(n)
|
||||||
{
|
{
|
||||||
for (unsigned int i=0; i<numberOfPorts; i++)
|
for (unsigned int i=0; i<numberOfPorts; i++)
|
||||||
{
|
{
|
||||||
inPorts[i].reset(new ByteQueue);
|
inPorts[i].reset(new ByteQueue);
|
||||||
interfaces[i].reset(new Interface(*this, *inPorts[i], i));
|
interfaces[i].reset(new Interface(*this, *inPorts[i], i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Interface * Join::ReleaseInterface(unsigned int i)
|
Interface * Join::ReleaseInterface(unsigned int i)
|
||||||
{
|
{
|
||||||
return interfaces[i].release();
|
return interfaces[i].release();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Join::NotifyInput(unsigned int i, unsigned int /* length */)
|
void Join::NotifyInput(unsigned int i, unsigned int /* length */)
|
||||||
{
|
{
|
||||||
AccessPort(i).TransferTo(*outQueue);
|
AccessPort(i).TransferTo(*outQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Join::NotifyClose(unsigned int /* id */)
|
void Join::NotifyClose(unsigned int /* id */)
|
||||||
{
|
{
|
||||||
if ((--interfacesOpen) == 0)
|
if ((--interfacesOpen) == 0)
|
||||||
outQueue->Close();
|
outQueue->Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ********************************************************
|
// ********************************************************
|
||||||
|
|
||||||
void Interface::Put(byte inByte)
|
void Interface::Put(byte inByte)
|
||||||
{
|
{
|
||||||
bq.Put(inByte);
|
bq.Put(inByte);
|
||||||
parent.NotifyInput(id, 1);
|
parent.NotifyInput(id, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interface::Put(const byte *inString, unsigned int length)
|
void Interface::Put(const byte *inString, unsigned int length)
|
||||||
{
|
{
|
||||||
bq.Put(inString, length);
|
bq.Put(inString, length);
|
||||||
parent.NotifyInput(id, length);
|
parent.NotifyInput(id, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long Interface::MaxRetrieveable()
|
unsigned long Interface::MaxRetrieveable()
|
||||||
{
|
{
|
||||||
return parent.MaxRetrieveable();
|
return parent.MaxRetrieveable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interface::Close()
|
void Interface::Close()
|
||||||
{
|
{
|
||||||
parent.NotifyClose(id);
|
parent.NotifyClose(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interface::Detach(BufferedTransformation *bt)
|
void Interface::Detach(BufferedTransformation *bt)
|
||||||
{
|
{
|
||||||
parent.Detach(bt);
|
parent.Detach(bt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interface::Attach(BufferedTransformation *bt)
|
void Interface::Attach(BufferedTransformation *bt)
|
||||||
{
|
{
|
||||||
parent.Attach(bt);
|
parent.Attach(bt);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Interface::Get(byte &outByte)
|
unsigned int Interface::Get(byte &outByte)
|
||||||
{
|
{
|
||||||
return parent.Get(outByte);
|
return parent.Get(outByte);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Interface::Get(byte *outString, unsigned int getMax)
|
unsigned int Interface::Get(byte *outString, unsigned int getMax)
|
||||||
{
|
{
|
||||||
return parent.Get(outString, getMax);
|
return parent.Get(outString, getMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Interface::Peek(byte &outByte) const
|
unsigned int Interface::Peek(byte &outByte) const
|
||||||
{
|
{
|
||||||
return parent.Peek(outByte);
|
return parent.Peek(outByte);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,39 +8,39 @@
|
||||||
class Fork : public BufferedTransformation
|
class Fork : public BufferedTransformation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Fork(int number_of_outports, BufferedTransformation *const *outports = NULL);
|
Fork(int number_of_outports, BufferedTransformation *const *outports = NULL);
|
||||||
|
|
||||||
void SelectOutPort(int portNumber);
|
void SelectOutPort(int portNumber);
|
||||||
|
|
||||||
bool Attachable() {return true;}
|
bool Attachable() {return true;}
|
||||||
void Detach(BufferedTransformation *newOut = NULL);
|
void Detach(BufferedTransformation *newOut = NULL);
|
||||||
void Attach(BufferedTransformation *newOut);
|
void Attach(BufferedTransformation *newOut);
|
||||||
virtual void Close();
|
virtual void Close();
|
||||||
|
|
||||||
unsigned long MaxRetrieveable()
|
unsigned long MaxRetrieveable()
|
||||||
{return outPorts[currentPort]->MaxRetrieveable();}
|
{return outPorts[currentPort]->MaxRetrieveable();}
|
||||||
// virtual void InputFinished()
|
// virtual void InputFinished()
|
||||||
// {outPorts[currentPort]->InputFinished();}
|
// {outPorts[currentPort]->InputFinished();}
|
||||||
|
|
||||||
unsigned int Get(byte &outByte)
|
unsigned int Get(byte &outByte)
|
||||||
{return outPorts[currentPort]->Get(outByte);}
|
{return outPorts[currentPort]->Get(outByte);}
|
||||||
unsigned int Get(byte *outString, unsigned int getMax)
|
unsigned int Get(byte *outString, unsigned int getMax)
|
||||||
{return outPorts[currentPort]->Get(outString, getMax);}
|
{return outPorts[currentPort]->Get(outString, getMax);}
|
||||||
unsigned int Peek(byte &outByte) const
|
unsigned int Peek(byte &outByte) const
|
||||||
{return outPorts[currentPort]->Peek(outByte);}
|
{return outPorts[currentPort]->Peek(outByte);}
|
||||||
|
|
||||||
virtual void Put(byte inByte);
|
virtual void Put(byte inByte);
|
||||||
virtual void Put(const byte *inString, unsigned int length);
|
virtual void Put(const byte *inString, unsigned int length);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
unsigned int NumberOfPorts() const {return numberOfPorts;}
|
unsigned int NumberOfPorts() const {return numberOfPorts;}
|
||||||
BufferedTransformation& AccessPort(unsigned int i) {return *outPorts[i];}
|
BufferedTransformation& AccessPort(unsigned int i) {return *outPorts[i];}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Fork(const Fork &); // no copying allowed
|
Fork(const Fork &); // no copying allowed
|
||||||
|
|
||||||
unsigned int numberOfPorts, currentPort;
|
unsigned int numberOfPorts, currentPort;
|
||||||
vector_member_ptrs<BufferedTransformation> outPorts;
|
vector_member_ptrs<BufferedTransformation> outPorts;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Join;
|
class Join;
|
||||||
|
@ -48,57 +48,57 @@ class Join;
|
||||||
class Interface : public BufferedTransformation
|
class Interface : public BufferedTransformation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Interface(Join &p, ByteQueue &b, int i)
|
Interface(Join &p, ByteQueue &b, int i)
|
||||||
: parent(p), bq(b), id(i) {}
|
: parent(p), bq(b), id(i) {}
|
||||||
|
|
||||||
unsigned long MaxRetrieveable();
|
unsigned long MaxRetrieveable();
|
||||||
void Close();
|
void Close();
|
||||||
bool Attachable() {return true;}
|
bool Attachable() {return true;}
|
||||||
void Detach(BufferedTransformation *bt);
|
void Detach(BufferedTransformation *bt);
|
||||||
void Attach(BufferedTransformation *bt);
|
void Attach(BufferedTransformation *bt);
|
||||||
|
|
||||||
void Put(byte inByte);
|
void Put(byte inByte);
|
||||||
void Put(const byte *inString, unsigned int length);
|
void Put(const byte *inString, unsigned int length);
|
||||||
unsigned int Get(byte &outByte);
|
unsigned int Get(byte &outByte);
|
||||||
unsigned int Get(byte *outString, unsigned int getMax);
|
unsigned int Get(byte *outString, unsigned int getMax);
|
||||||
unsigned int Peek(byte &outByte) const;
|
unsigned int Peek(byte &outByte) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Join &parent;
|
Join &parent;
|
||||||
ByteQueue &bq;
|
ByteQueue &bq;
|
||||||
const int id;
|
const int id;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Join : public Filter
|
class Join : public Filter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Join(unsigned int number_of_inports, BufferedTransformation *outQ = NULL);
|
Join(unsigned int number_of_inports, BufferedTransformation *outQ = NULL);
|
||||||
|
|
||||||
// Note that ReleaseInterface is similar but not completely compatible
|
// Note that ReleaseInterface is similar but not completely compatible
|
||||||
// with SelectInterface of version 2.0. ReleaseInterface can be called
|
// with SelectInterface of version 2.0. ReleaseInterface can be called
|
||||||
// only once for each interface, and if an interface is released,
|
// only once for each interface, and if an interface is released,
|
||||||
// the caller will be responsible for deleting it.
|
// the caller will be responsible for deleting it.
|
||||||
Interface *ReleaseInterface(unsigned int i);
|
Interface *ReleaseInterface(unsigned int i);
|
||||||
|
|
||||||
virtual void NotifyInput(unsigned int interfaceId, unsigned int length);
|
virtual void NotifyInput(unsigned int interfaceId, unsigned int length);
|
||||||
virtual void NotifyClose(unsigned int interfaceId);
|
virtual void NotifyClose(unsigned int interfaceId);
|
||||||
|
|
||||||
void Put(byte inByte) {outQueue->Put(inByte);}
|
void Put(byte inByte) {outQueue->Put(inByte);}
|
||||||
void Put(const byte *inString, unsigned int length)
|
void Put(const byte *inString, unsigned int length)
|
||||||
{outQueue->Put(inString, length);}
|
{outQueue->Put(inString, length);}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
unsigned int NumberOfPorts() const {return numberOfPorts;}
|
unsigned int NumberOfPorts() const {return numberOfPorts;}
|
||||||
ByteQueue& AccessPort(unsigned int i) {return *inPorts[i];}
|
ByteQueue& AccessPort(unsigned int i) {return *inPorts[i];}
|
||||||
unsigned int InterfacesOpen() const {return interfacesOpen;}
|
unsigned int InterfacesOpen() const {return interfacesOpen;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Join(const Join &); // no copying allowed
|
Join(const Join &); // no copying allowed
|
||||||
|
|
||||||
unsigned int numberOfPorts;
|
unsigned int numberOfPorts;
|
||||||
vector_member_ptrs<ByteQueue> inPorts;
|
vector_member_ptrs<ByteQueue> inPorts;
|
||||||
unsigned int interfacesOpen;
|
unsigned int interfacesOpen;
|
||||||
vector_member_ptrs<Interface> interfaces;
|
vector_member_ptrs<Interface> interfaces;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -11,309 +11,309 @@ Integer operator+(const Integer &a, const Integer &b);
|
||||||
|
|
||||||
/// multiple precision integer and basic arithmetics
|
/// multiple precision integer and basic arithmetics
|
||||||
/** This class can represent positive and negative integers
|
/** This class can represent positive and negative integers
|
||||||
with absolute value less than 2**(8 * sizeof(word) * 2**sizeof(int)).
|
with absolute value less than 2**(8 * sizeof(word) * 2**sizeof(int)).
|
||||||
*/
|
*/
|
||||||
class Integer
|
class Integer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//@Man: ENUMS, EXCEPTIONS, and TYPEDEFS
|
//@Man: ENUMS, EXCEPTIONS, and TYPEDEFS
|
||||||
//@{
|
//@{
|
||||||
/// division by zero exception
|
/// division by zero exception
|
||||||
class DivideByZero : public CryptlibException
|
class DivideByZero : public CryptlibException
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DivideByZero() : CryptlibException("Integer: division by zero") {}
|
DivideByZero() : CryptlibException("Integer: division by zero") {}
|
||||||
};
|
};
|
||||||
|
|
||||||
///
|
///
|
||||||
enum Signedness {
|
enum Signedness {
|
||||||
///
|
///
|
||||||
UNSIGNED,
|
UNSIGNED,
|
||||||
///
|
///
|
||||||
SIGNED};
|
SIGNED};
|
||||||
|
|
||||||
///
|
///
|
||||||
enum RandomNumberType {
|
enum RandomNumberType {
|
||||||
///
|
///
|
||||||
ANY,
|
ANY,
|
||||||
///
|
///
|
||||||
ODD,
|
ODD,
|
||||||
///
|
///
|
||||||
PRIME,
|
PRIME,
|
||||||
/// not actually a Blum integer, but rather a prime that is 3 mod 4
|
/// not actually a Blum integer, but rather a prime that is 3 mod 4
|
||||||
BLUMINT};
|
BLUMINT};
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
//@Man: CREATORS
|
//@Man: CREATORS
|
||||||
//@{
|
//@{
|
||||||
/// creates the zero integer
|
/// creates the zero integer
|
||||||
Integer();
|
Integer();
|
||||||
|
|
||||||
/// copy constructor
|
/// copy constructor
|
||||||
Integer(const Integer& t);
|
Integer(const Integer& t);
|
||||||
|
|
||||||
/// convert from long
|
/// convert from long
|
||||||
Integer(long value);
|
Integer(long value);
|
||||||
|
|
||||||
/// convert from string
|
/// convert from string
|
||||||
/** str can be in base 2, 8, 10, or 16. Base is determined by a
|
/** str can be in base 2, 8, 10, or 16. Base is determined by a
|
||||||
case insensitive suffix of 'h', 'o', or 'b'. No suffix means base 10.
|
case insensitive suffix of 'h', 'o', or 'b'. No suffix means base 10.
|
||||||
*/
|
*/
|
||||||
Integer(const char *str);
|
Integer(const char *str);
|
||||||
|
|
||||||
/// convert from big-endian byte array
|
/// convert from big-endian byte array
|
||||||
Integer(const byte *encodedInteger, unsigned int byteCount, Signedness s=UNSIGNED);
|
Integer(const byte *encodedInteger, unsigned int byteCount, Signedness s=UNSIGNED);
|
||||||
|
|
||||||
/// convert from Basic Encoding Rules encoded byte array
|
/// convert from Basic Encoding Rules encoded byte array
|
||||||
Integer(const byte *BEREncodedInteger);
|
Integer(const byte *BEREncodedInteger);
|
||||||
|
|
||||||
/// convert from BER encoded byte array stored in a BufferedTransformation object
|
/// convert from BER encoded byte array stored in a BufferedTransformation object
|
||||||
Integer(BufferedTransformation &bt);
|
Integer(BufferedTransformation &bt);
|
||||||
|
|
||||||
/// create a random integer
|
/// create a random integer
|
||||||
/** The random integer created is uniformly distributed over [0, 2**bitcount). */
|
/** The random integer created is uniformly distributed over [0, 2**bitcount). */
|
||||||
Integer(RandomNumberGenerator &rng, unsigned int bitcount);
|
Integer(RandomNumberGenerator &rng, unsigned int bitcount);
|
||||||
|
|
||||||
/// create a random integer of special type
|
/// create a random integer of special type
|
||||||
/** Ideally, the random integer created should be uniformly distributed
|
/** Ideally, the random integer created should be uniformly distributed
|
||||||
over {x | min <= x <= max and x is of rnType}. However the actual
|
over {x | min <= x <= max and x is of rnType}. However the actual
|
||||||
distribution may not uniform because sequential search is used to
|
distribution may not uniform because sequential search is used to
|
||||||
find an appropriate number from a random starting point.
|
find an appropriate number from a random starting point.
|
||||||
*/
|
*/
|
||||||
Integer(RandomNumberGenerator &rng, const Integer &min, const Integer &max, RandomNumberType rnType=ANY);
|
Integer(RandomNumberGenerator &rng, const Integer &min, const Integer &max, RandomNumberType rnType=ANY);
|
||||||
|
|
||||||
/// create the integer 2**e
|
/// create the integer 2**e
|
||||||
static Integer Power2(unsigned int e);
|
static Integer Power2(unsigned int e);
|
||||||
|
|
||||||
/// avoid calling constructors for these frequently used integers
|
/// avoid calling constructors for these frequently used integers
|
||||||
static const Integer &Zero();
|
static const Integer &Zero();
|
||||||
///
|
///
|
||||||
static const Integer &One();
|
static const Integer &One();
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
//@Man: ACCESSORS
|
//@Man: ACCESSORS
|
||||||
//@{
|
//@{
|
||||||
/// return equivalent signed long if possible, otherwise undefined
|
/// return equivalent signed long if possible, otherwise undefined
|
||||||
long ConvertToLong() const;
|
long ConvertToLong() const;
|
||||||
|
|
||||||
/// minimum number of bytes to encode this integer
|
/// minimum number of bytes to encode this integer
|
||||||
/** MinEncodedSize of 0 is 1 */
|
/** MinEncodedSize of 0 is 1 */
|
||||||
unsigned int MinEncodedSize(Signedness=UNSIGNED) const;
|
unsigned int MinEncodedSize(Signedness=UNSIGNED) const;
|
||||||
/// encode in big-endian format
|
/// encode in big-endian format
|
||||||
/** unsigned means ignore sign, signed means use two's complement.
|
/** unsigned means ignore sign, signed means use two's complement.
|
||||||
if outputLen < MinEncodedSize, the most significant bytes will be dropped
|
if outputLen < MinEncodedSize, the most significant bytes will be dropped
|
||||||
if outputLen > MinEncodedSize, the most significant bytes will be padded
|
if outputLen > MinEncodedSize, the most significant bytes will be padded
|
||||||
*/
|
*/
|
||||||
unsigned int Encode(byte *output, unsigned int outputLen, Signedness=UNSIGNED) const;
|
unsigned int Encode(byte *output, unsigned int outputLen, Signedness=UNSIGNED) const;
|
||||||
|
|
||||||
/// encode integer using Distinguished Encoding Rules, returns size of output
|
/// encode integer using Distinguished Encoding Rules, returns size of output
|
||||||
unsigned int DEREncode(byte *output) const;
|
unsigned int DEREncode(byte *output) const;
|
||||||
/// encode using DER, put result into a BufferedTransformation object
|
/// encode using DER, put result into a BufferedTransformation object
|
||||||
unsigned int DEREncode(BufferedTransformation &bt) const;
|
unsigned int DEREncode(BufferedTransformation &bt) const;
|
||||||
|
|
||||||
/// number of significant bits = floor(log2(abs(*this))) - 1
|
/// number of significant bits = floor(log2(abs(*this))) - 1
|
||||||
unsigned int BitCount() const;
|
unsigned int BitCount() const;
|
||||||
/// number of significant bytes = ceiling(BitCount()/8)
|
/// number of significant bytes = ceiling(BitCount()/8)
|
||||||
unsigned int ByteCount() const;
|
unsigned int ByteCount() const;
|
||||||
/// number of significant words = ceiling(ByteCount()/sizeof(word))
|
/// number of significant words = ceiling(ByteCount()/sizeof(word))
|
||||||
unsigned int WordCount() const;
|
unsigned int WordCount() const;
|
||||||
|
|
||||||
/// return the n-th bit, n=0 being the least significant bit
|
/// return the n-th bit, n=0 being the least significant bit
|
||||||
bool GetBit(unsigned int n) const;
|
bool GetBit(unsigned int n) const;
|
||||||
/// return the n-th byte
|
/// return the n-th byte
|
||||||
byte GetByte(unsigned int n) const;
|
byte GetByte(unsigned int n) const;
|
||||||
|
|
||||||
///
|
///
|
||||||
bool IsNegative() const {return sign == NEGATIVE;}
|
bool IsNegative() const {return sign == NEGATIVE;}
|
||||||
///
|
///
|
||||||
bool NotNegative() const {return sign == POSITIVE;}
|
bool NotNegative() const {return sign == POSITIVE;}
|
||||||
///
|
///
|
||||||
bool IsPositive() const {return sign == POSITIVE && !!*this;}
|
bool IsPositive() const {return sign == POSITIVE && !!*this;}
|
||||||
///
|
///
|
||||||
bool IsEven() const {return GetBit(0) == 0;}
|
bool IsEven() const {return GetBit(0) == 0;}
|
||||||
///
|
///
|
||||||
bool IsOdd() const {return GetBit(0) == 1;}
|
bool IsOdd() const {return GetBit(0) == 1;}
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
//@Man: MANIPULATORS
|
//@Man: MANIPULATORS
|
||||||
//@{
|
//@{
|
||||||
///
|
///
|
||||||
Integer& operator=(const Integer& t);
|
Integer& operator=(const Integer& t);
|
||||||
|
|
||||||
///
|
///
|
||||||
Integer& operator+=(const Integer& t);
|
Integer& operator+=(const Integer& t);
|
||||||
///
|
///
|
||||||
Integer& operator-=(const Integer& t);
|
Integer& operator-=(const Integer& t);
|
||||||
///
|
///
|
||||||
Integer& operator*=(const Integer& t) {return *this = *this*t;}
|
Integer& operator*=(const Integer& t) {return *this = *this*t;}
|
||||||
///
|
///
|
||||||
Integer& operator/=(const Integer& t) {return *this = *this/t;}
|
Integer& operator/=(const Integer& t) {return *this = *this/t;}
|
||||||
///
|
///
|
||||||
Integer& operator%=(const Integer& t) {return *this = *this%t;}
|
Integer& operator%=(const Integer& t) {return *this = *this%t;}
|
||||||
///
|
///
|
||||||
Integer& operator/=(word t) {return *this = *this/t;}
|
Integer& operator/=(word t) {return *this = *this/t;}
|
||||||
///
|
///
|
||||||
Integer& operator%=(word t) {return *this = *this%t;}
|
Integer& operator%=(word t) {return *this = *this%t;}
|
||||||
|
|
||||||
///
|
///
|
||||||
Integer& operator<<=(unsigned int);
|
Integer& operator<<=(unsigned int);
|
||||||
///
|
///
|
||||||
Integer& operator>>=(unsigned int);
|
Integer& operator>>=(unsigned int);
|
||||||
|
|
||||||
///
|
///
|
||||||
void Decode(const byte *input, unsigned int inputLen, Signedness=UNSIGNED);
|
void Decode(const byte *input, unsigned int inputLen, Signedness=UNSIGNED);
|
||||||
|
|
||||||
///
|
///
|
||||||
void BERDecode(const byte *input);
|
void BERDecode(const byte *input);
|
||||||
///
|
///
|
||||||
void BERDecode(BufferedTransformation &bt);
|
void BERDecode(BufferedTransformation &bt);
|
||||||
|
|
||||||
///
|
///
|
||||||
void Randomize(RandomNumberGenerator &rng, unsigned int bitcount);
|
void Randomize(RandomNumberGenerator &rng, unsigned int bitcount);
|
||||||
///
|
///
|
||||||
void Randomize(RandomNumberGenerator &rng, const Integer &min, const Integer &max);
|
void Randomize(RandomNumberGenerator &rng, const Integer &min, const Integer &max);
|
||||||
///
|
///
|
||||||
void Randomize(RandomNumberGenerator &rng, const Integer &min, const Integer &max, RandomNumberType rnType);
|
void Randomize(RandomNumberGenerator &rng, const Integer &min, const Integer &max, RandomNumberType rnType);
|
||||||
|
|
||||||
/// set the n-th bit to value
|
/// set the n-th bit to value
|
||||||
void SetBit(unsigned int n, bool value=1);
|
void SetBit(unsigned int n, bool value=1);
|
||||||
/// set the n-th byte to value
|
/// set the n-th byte to value
|
||||||
void SetByte(unsigned int n, byte value);
|
void SetByte(unsigned int n, byte value);
|
||||||
|
|
||||||
///
|
///
|
||||||
void Negate();
|
void Negate();
|
||||||
///
|
///
|
||||||
void SetPositive() {sign = POSITIVE;}
|
void SetPositive() {sign = POSITIVE;}
|
||||||
///
|
///
|
||||||
void SetNegative() {if (!!(*this)) sign = NEGATIVE;}
|
void SetNegative() {if (!!(*this)) sign = NEGATIVE;}
|
||||||
|
|
||||||
///
|
///
|
||||||
friend void swap(Integer &a, Integer &b);
|
friend void swap(Integer &a, Integer &b);
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
//@Man: UNARY OPERATORS
|
//@Man: UNARY OPERATORS
|
||||||
//@{
|
//@{
|
||||||
///
|
///
|
||||||
bool operator!() const;
|
bool operator!() const;
|
||||||
///
|
///
|
||||||
Integer operator+() const {return *this;}
|
Integer operator+() const {return *this;}
|
||||||
///
|
///
|
||||||
Integer operator-() const;
|
Integer operator-() const;
|
||||||
///
|
///
|
||||||
Integer& operator++();
|
Integer& operator++();
|
||||||
///
|
///
|
||||||
Integer& operator--();
|
Integer& operator--();
|
||||||
///
|
///
|
||||||
Integer operator++(int) {Integer temp = *this; ++*this; return temp;}
|
Integer operator++(int) {Integer temp = *this; ++*this; return temp;}
|
||||||
///
|
///
|
||||||
Integer operator--(int) {Integer temp = *this; --*this; return temp;}
|
Integer operator--(int) {Integer temp = *this; --*this; return temp;}
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
//@Man: BINARY OPERATORS
|
//@Man: BINARY OPERATORS
|
||||||
//@{
|
//@{
|
||||||
///
|
///
|
||||||
friend Integer operator+(const Integer &a, const Integer &b);
|
friend Integer operator+(const Integer &a, const Integer &b);
|
||||||
///
|
///
|
||||||
friend Integer operator-(const Integer &a, const Integer &b);
|
friend Integer operator-(const Integer &a, const Integer &b);
|
||||||
///
|
///
|
||||||
friend Integer operator*(const Integer &a, const Integer &b);
|
friend Integer operator*(const Integer &a, const Integer &b);
|
||||||
///
|
///
|
||||||
friend Integer operator/(const Integer &a, const Integer &b);
|
friend Integer operator/(const Integer &a, const Integer &b);
|
||||||
///
|
///
|
||||||
friend Integer operator%(const Integer &a, const Integer &b);
|
friend Integer operator%(const Integer &a, const Integer &b);
|
||||||
///
|
///
|
||||||
friend Integer operator/(const Integer &a, word b);
|
friend Integer operator/(const Integer &a, word b);
|
||||||
///
|
///
|
||||||
friend word operator%(const Integer &a, word b);
|
friend word operator%(const Integer &a, word b);
|
||||||
|
|
||||||
///
|
///
|
||||||
Integer operator>>(unsigned int n) const {return Integer(*this)>>=n;}
|
Integer operator>>(unsigned int n) const {return Integer(*this)>>=n;}
|
||||||
///
|
///
|
||||||
Integer operator<<(unsigned int n) const {return Integer(*this)<<=n;}
|
Integer operator<<(unsigned int n) const {return Integer(*this)<<=n;}
|
||||||
|
|
||||||
///
|
///
|
||||||
friend bool operator==(const Integer& a, const Integer& b) {return (a.Compare(b)==0);}
|
friend bool operator==(const Integer& a, const Integer& b) {return (a.Compare(b)==0);}
|
||||||
///
|
///
|
||||||
friend bool operator!=(const Integer& a, const Integer& b) {return (a.Compare(b)!=0);}
|
friend bool operator!=(const Integer& a, const Integer& b) {return (a.Compare(b)!=0);}
|
||||||
///
|
///
|
||||||
friend bool operator> (const Integer& a, const Integer& b) {return (a.Compare(b)> 0);}
|
friend bool operator> (const Integer& a, const Integer& b) {return (a.Compare(b)> 0);}
|
||||||
///
|
///
|
||||||
friend bool operator>=(const Integer& a, const Integer& b) {return (a.Compare(b)>=0);}
|
friend bool operator>=(const Integer& a, const Integer& b) {return (a.Compare(b)>=0);}
|
||||||
///
|
///
|
||||||
friend bool operator< (const Integer& a, const Integer& b) {return (a.Compare(b)< 0);}
|
friend bool operator< (const Integer& a, const Integer& b) {return (a.Compare(b)< 0);}
|
||||||
///
|
///
|
||||||
friend bool operator<=(const Integer& a, const Integer& b) {return (a.Compare(b)<=0);}
|
friend bool operator<=(const Integer& a, const Integer& b) {return (a.Compare(b)<=0);}
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
//@Man: OTHER ARITHMETIC FUNCTIONS
|
//@Man: OTHER ARITHMETIC FUNCTIONS
|
||||||
//@{
|
//@{
|
||||||
/// signed comparison
|
/// signed comparison
|
||||||
/** returns:
|
/** returns:
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item -1 if *this < a
|
\item -1 if *this < a
|
||||||
\item 0 if *this = a
|
\item 0 if *this = a
|
||||||
\item 1 if *this > a
|
\item 1 if *this > a
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
*/
|
*/
|
||||||
int Compare(const Integer& a) const;
|
int Compare(const Integer& a) const;
|
||||||
|
|
||||||
///
|
///
|
||||||
Integer AbsoluteValue() const;
|
Integer AbsoluteValue() const;
|
||||||
///
|
///
|
||||||
Integer Doubled() const {return *this + *this;}
|
Integer Doubled() const {return *this + *this;}
|
||||||
///
|
///
|
||||||
Integer Squared() const {return *this * (*this);}
|
Integer Squared() const {return *this * (*this);}
|
||||||
/// extract square root, return floor of square root if not perfect square
|
/// extract square root, return floor of square root if not perfect square
|
||||||
Integer SquareRoot() const;
|
Integer SquareRoot() const;
|
||||||
/// return whether this integer is a perfect square
|
/// return whether this integer is a perfect square
|
||||||
bool IsSquare() const;
|
bool IsSquare() const;
|
||||||
|
|
||||||
/// is 1 or -1
|
/// is 1 or -1
|
||||||
bool IsUnit() const;
|
bool IsUnit() const;
|
||||||
/// return inverse if 1 or -1, otherwise return 0
|
/// return inverse if 1 or -1, otherwise return 0
|
||||||
Integer MultiplicativeInverse() const;
|
Integer MultiplicativeInverse() const;
|
||||||
|
|
||||||
/// modular multiplication
|
/// modular multiplication
|
||||||
friend Integer a_times_b_mod_c(const Integer &x, const Integer& y, const Integer& m);
|
friend Integer a_times_b_mod_c(const Integer &x, const Integer& y, const Integer& m);
|
||||||
/// modular exponentiation
|
/// modular exponentiation
|
||||||
friend Integer a_exp_b_mod_c(const Integer &x, const Integer& e, const Integer& m);
|
friend Integer a_exp_b_mod_c(const Integer &x, const Integer& e, const Integer& m);
|
||||||
|
|
||||||
/// calculate r and q such that (a == d*q + r) && (0 <= r < abs(d))
|
/// calculate r and q such that (a == d*q + r) && (0 <= r < abs(d))
|
||||||
static void Divide(Integer &r, Integer &q, const Integer &a, const Integer &d);
|
static void Divide(Integer &r, Integer &q, const Integer &a, const Integer &d);
|
||||||
/// use a faster division algorithm when divisor is short
|
/// use a faster division algorithm when divisor is short
|
||||||
static word ShortDivide(Integer &q, const Integer &a, word d);
|
static word ShortDivide(Integer &q, const Integer &a, word d);
|
||||||
|
|
||||||
/// greatest common divisor
|
/// greatest common divisor
|
||||||
static Integer Gcd(const Integer &a, const Integer &n);
|
static Integer Gcd(const Integer &a, const Integer &n);
|
||||||
/// calculate multiplicative inverse of *this mod n
|
/// calculate multiplicative inverse of *this mod n
|
||||||
Integer InverseMod(const Integer &n) const;
|
Integer InverseMod(const Integer &n) const;
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
//@Man: INPUT/OUTPUT
|
//@Man: INPUT/OUTPUT
|
||||||
//@{
|
//@{
|
||||||
///
|
///
|
||||||
friend std::istream& operator>>(std::istream& in, Integer &a);
|
friend std::istream& operator>>(std::istream& in, Integer &a);
|
||||||
///
|
///
|
||||||
friend std::ostream& operator<<(std::ostream& out, const Integer &a);
|
friend std::ostream& operator<<(std::ostream& out, const Integer &a);
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class ModularArithmetic;
|
friend class ModularArithmetic;
|
||||||
friend class MontgomeryRepresentation;
|
friend class MontgomeryRepresentation;
|
||||||
friend class HalfMontgomeryRepresentation;
|
friend class HalfMontgomeryRepresentation;
|
||||||
|
|
||||||
Integer(word value, unsigned int length);
|
Integer(word value, unsigned int length);
|
||||||
|
|
||||||
int PositiveCompare(const Integer &t) const;
|
int PositiveCompare(const Integer &t) const;
|
||||||
friend void PositiveAdd(Integer &sum, const Integer &a, const Integer &b);
|
friend void PositiveAdd(Integer &sum, const Integer &a, const Integer &b);
|
||||||
friend void PositiveSubtract(Integer &diff, const Integer &a, const Integer &b);
|
friend void PositiveSubtract(Integer &diff, const Integer &a, const Integer &b);
|
||||||
friend void PositiveMultiply(Integer &product, const Integer &a, const Integer &b);
|
friend void PositiveMultiply(Integer &product, const Integer &a, const Integer &b);
|
||||||
friend void PositiveDivide(Integer &remainder, Integer "ient, const Integer ÷nd, const Integer &divisor);
|
friend void PositiveDivide(Integer &remainder, Integer "ient, const Integer ÷nd, const Integer &divisor);
|
||||||
|
|
||||||
enum Sign {POSITIVE=0, NEGATIVE=1};
|
enum Sign {POSITIVE=0, NEGATIVE=1};
|
||||||
|
|
||||||
SecWordBlock reg;
|
SecWordBlock reg;
|
||||||
Sign sign;
|
Sign sign;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -6,32 +6,32 @@
|
||||||
|
|
||||||
/* The following classes are explicitly instantiated in iterhash.cpp
|
/* The following classes are explicitly instantiated in iterhash.cpp
|
||||||
|
|
||||||
IteratedHash<word32>
|
IteratedHash<word32>
|
||||||
IteratedHash<word64> // #ifdef WORD64_AVAILABLE
|
IteratedHash<word64> // #ifdef WORD64_AVAILABLE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template <class T> class IteratedHash : public virtual HashModule
|
template <class T> class IteratedHash : public virtual HashModule
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IteratedHash(unsigned int blockSize, unsigned int digestSize);
|
IteratedHash(unsigned int blockSize, unsigned int digestSize);
|
||||||
~IteratedHash();
|
~IteratedHash();
|
||||||
void Update(const byte *input, unsigned int length);
|
void Update(const byte *input, unsigned int length);
|
||||||
|
|
||||||
typedef T HashWordType;
|
typedef T HashWordType;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void PadLastBlock(unsigned int lastBlockSize, byte padFirst=0x80);
|
void PadLastBlock(unsigned int lastBlockSize, byte padFirst=0x80);
|
||||||
virtual void Init() =0;
|
virtual void Init() =0;
|
||||||
virtual void HashBlock(const T *input) =0;
|
virtual void HashBlock(const T *input) =0;
|
||||||
|
|
||||||
unsigned int blockSize;
|
unsigned int blockSize;
|
||||||
word32 countLo, countHi; // 64-bit bit count
|
word32 countLo, countHi; // 64-bit bit count
|
||||||
SecBlock<T> data; // Data buffer
|
SecBlock<T> data; // Data buffer
|
||||||
SecBlock<T> digest; // Message digest
|
SecBlock<T> digest; // Message digest
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T> IteratedHash<T>::IteratedHash(unsigned int blockSize, unsigned int digestSize)
|
template <class T> IteratedHash<T>::IteratedHash(unsigned int blockSize, unsigned int digestSize)
|
||||||
: blockSize(blockSize), data(blockSize/sizeof(T)), digest(digestSize/sizeof(T))
|
: blockSize(blockSize), data(blockSize/sizeof(T)), digest(digestSize/sizeof(T))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,69 +41,69 @@ template <class T> IteratedHash<T>::~IteratedHash()
|
||||||
|
|
||||||
template <class T> void IteratedHash<T>::Update(const byte *input, unsigned int len)
|
template <class T> void IteratedHash<T>::Update(const byte *input, unsigned int len)
|
||||||
{
|
{
|
||||||
word32 tmp = countLo;
|
word32 tmp = countLo;
|
||||||
if ((countLo = tmp + ((word32)len << 3)) < tmp)
|
if ((countLo = tmp + ((word32)len << 3)) < tmp)
|
||||||
countHi++; // Carry from low to high
|
countHi++; // Carry from low to high
|
||||||
countHi += len >> 29;
|
countHi += len >> 29;
|
||||||
|
|
||||||
assert((blockSize & (blockSize-1)) == 0); // blockSize is a power of 2
|
assert((blockSize & (blockSize-1)) == 0); // blockSize is a power of 2
|
||||||
unsigned int num = (unsigned int)(tmp >> 3) & (blockSize-1);
|
unsigned int num = (unsigned int)(tmp >> 3) & (blockSize-1);
|
||||||
|
|
||||||
if (num != 0)
|
if (num != 0)
|
||||||
{
|
{
|
||||||
if ((num+len) >= blockSize)
|
if ((num+len) >= blockSize)
|
||||||
{
|
{
|
||||||
memcpy((byte *)data.ptr+num, input, blockSize-num);
|
memcpy((byte *)data.ptr+num, input, blockSize-num);
|
||||||
HashBlock(data);
|
HashBlock(data);
|
||||||
input += (blockSize-num);
|
input += (blockSize-num);
|
||||||
len-=(blockSize - num);
|
len-=(blockSize - num);
|
||||||
num=0;
|
num=0;
|
||||||
// drop through and do the rest
|
// drop through and do the rest
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memcpy((byte *)data.ptr+num, input, len);
|
memcpy((byte *)data.ptr+num, input, len);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// we now can process the input data in blocks of blockSize
|
// we now can process the input data in blocks of blockSize
|
||||||
// chars and save the leftovers to this->data.
|
// chars and save the leftovers to this->data.
|
||||||
if (len >= blockSize)
|
if (len >= blockSize)
|
||||||
{
|
{
|
||||||
if ((ptr_size_type)input % sizeof(T)) // test for alignment
|
if ((ptr_size_type)input % sizeof(T)) // test for alignment
|
||||||
do
|
do
|
||||||
{ // copy input first if it's not aligned correctly
|
{ // copy input first if it's not aligned correctly
|
||||||
memcpy(data, input, blockSize);
|
memcpy(data, input, blockSize);
|
||||||
HashBlock(data);
|
HashBlock(data);
|
||||||
input+=blockSize;
|
input+=blockSize;
|
||||||
len-=blockSize;
|
len-=blockSize;
|
||||||
} while (len >= blockSize);
|
} while (len >= blockSize);
|
||||||
else
|
else
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
HashBlock((T *)input);
|
HashBlock((T *)input);
|
||||||
input+=blockSize;
|
input+=blockSize;
|
||||||
len-=blockSize;
|
len-=blockSize;
|
||||||
} while (len >= blockSize);
|
} while (len >= blockSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(data, input, len);
|
memcpy(data, input, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> void IteratedHash<T>::PadLastBlock(unsigned int lastBlockSize, byte padFirst)
|
template <class T> void IteratedHash<T>::PadLastBlock(unsigned int lastBlockSize, byte padFirst)
|
||||||
{
|
{
|
||||||
unsigned int num = (unsigned int)(countLo >> 3) & (blockSize-1);
|
unsigned int num = (unsigned int)(countLo >> 3) & (blockSize-1);
|
||||||
assert(num < blockSize);
|
assert(num < blockSize);
|
||||||
((byte *)data.ptr)[num++]=padFirst;
|
((byte *)data.ptr)[num++]=padFirst;
|
||||||
if (num <= lastBlockSize)
|
if (num <= lastBlockSize)
|
||||||
memset((byte *)data.ptr+num, 0, lastBlockSize-num);
|
memset((byte *)data.ptr+num, 0, lastBlockSize-num);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memset((byte *)data.ptr+num, 0, blockSize-num);
|
memset((byte *)data.ptr+num, 0, blockSize-num);
|
||||||
HashBlock(data);
|
HashBlock(data);
|
||||||
memset(data, 0, lastBlockSize);
|
memset(data, 0, lastBlockSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// provide empty definitions to avoid instantiation warnings
|
// provide empty definitions to avoid instantiation warnings
|
||||||
|
|
|
@ -6,67 +6,67 @@
|
||||||
|
|
||||||
void xorbuf(byte *buf, const byte *mask, unsigned int count)
|
void xorbuf(byte *buf, const byte *mask, unsigned int count)
|
||||||
{
|
{
|
||||||
if (((ptr_size_type)buf | (ptr_size_type)mask | count) % WORD_SIZE == 0)
|
if (((ptr_size_type)buf | (ptr_size_type)mask | count) % WORD_SIZE == 0)
|
||||||
XorWords((word *)buf, (const word *)mask, count/WORD_SIZE);
|
XorWords((word *)buf, (const word *)mask, count/WORD_SIZE);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (unsigned int i=0; i<count; i++)
|
for (unsigned int i=0; i<count; i++)
|
||||||
buf[i] ^= mask[i];
|
buf[i] ^= mask[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void xorbuf(byte *output, const byte *input, const byte *mask, unsigned int count)
|
void xorbuf(byte *output, const byte *input, const byte *mask, unsigned int count)
|
||||||
{
|
{
|
||||||
if (((ptr_size_type)output | (ptr_size_type)input | (ptr_size_type)mask | count) % WORD_SIZE == 0)
|
if (((ptr_size_type)output | (ptr_size_type)input | (ptr_size_type)mask | count) % WORD_SIZE == 0)
|
||||||
XorWords((word *)output, (const word *)input, (const word *)mask, count/WORD_SIZE);
|
XorWords((word *)output, (const word *)input, (const word *)mask, count/WORD_SIZE);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (unsigned int i=0; i<count; i++)
|
for (unsigned int i=0; i<count; i++)
|
||||||
output[i] = input[i] ^ mask[i];
|
output[i] = input[i] ^ mask[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Parity(unsigned long value)
|
unsigned int Parity(unsigned long value)
|
||||||
{
|
{
|
||||||
for (unsigned int i=8*sizeof(value)/2; i>0; i/=2)
|
for (unsigned int i=8*sizeof(value)/2; i>0; i/=2)
|
||||||
value ^= value >> i;
|
value ^= value >> i;
|
||||||
return (unsigned int)value&1;
|
return (unsigned int)value&1;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int BytePrecision(unsigned long value)
|
unsigned int BytePrecision(unsigned long value)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
for (i=sizeof(value); i; --i)
|
for (i=sizeof(value); i; --i)
|
||||||
if (value >> (i-1)*8)
|
if (value >> (i-1)*8)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int BitPrecision(unsigned long value)
|
unsigned int BitPrecision(unsigned long value)
|
||||||
{
|
{
|
||||||
if (!value)
|
if (!value)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
unsigned int l=0, h=8*sizeof(value);
|
unsigned int l=0, h=8*sizeof(value);
|
||||||
|
|
||||||
while (h-l > 1)
|
while (h-l > 1)
|
||||||
{
|
{
|
||||||
unsigned int t = (l+h)/2;
|
unsigned int t = (l+h)/2;
|
||||||
if (value >> t)
|
if (value >> t)
|
||||||
l = t;
|
l = t;
|
||||||
else
|
else
|
||||||
h = t;
|
h = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long Crop(unsigned long value, int size)
|
unsigned long Crop(unsigned long value, int size)
|
||||||
{
|
{
|
||||||
if (size < 8*(int)sizeof(value))
|
if (size < 8*(int)sizeof(value))
|
||||||
return (value & ((1L << size) - 1));
|
return (value & ((1L << size) - 1));
|
||||||
else
|
else
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue