#include "precomp.h"
#include "gtools.h"
#include "stdarg.h"
#ifdef _WIN32
#include "direct.h"
#else
#include "sys/stat.h"
#include "sys/types.h"
#include "unistd.h"
#endif
PList::PList()
{
m_pHead = m_pTail = 0;
m_lCount = 0;
}
PList::~PList()
{
DeleteContents();
}
bool PList::DeleteContents()
{
while( m_pHead )
{
PNode* pNext = m_pHead->m_pNext;
m_pHead->m_pNext = 0;
delete m_pHead;
m_pHead = pNext;
}
m_pHead = m_pTail = 0;
m_lCount = 0;
return true;
}
bool PList::RemoveContents()
{
while( m_pHead )
{
PNode* pNext = m_pHead->m_pNext;
m_pHead->m_pNext = m_pHead->m_pPrevious = 0;
m_pHead = pNext;
}
m_pHead = m_pTail = 0;
m_lCount = 0;
return true;
}
bool PList::Contains( PNode* p )
{
bool bSuccess = false;
if( p != 0 )
{
for( PNode* q = m_pHead; q; q = q->m_pNext )
{
if( q == p )
{
bSuccess = true;
break;
}
}
}
return bSuccess;
}
bool PList::AddHead( PNode* p )
{
p->m_pPrevious = 0;
m_lCount++;
if( !m_pHead )
{
m_pHead = m_pTail = p;
p->m_pNext = 0;
}
else
{
p->m_pNext = m_pHead;
m_pHead->m_pPrevious = p;
m_pHead = p;
}
return true;
}
bool PList::AddTail( PNode* p )
{
if( !m_pTail )
{
m_pHead = m_pTail = p;
p->m_pNext = 0;
m_lCount = 1;
}
else
{
m_lCount++;
p->m_pNext = 0;
p->m_pPrevious = m_pTail;
m_pTail->m_pNext = p;
m_pTail = p;
}
return true;
}
bool PList::InsertBefore( PNode* p, PNode* q )
{
if( !q )
return AddTail( p );
if( !q->m_pPrevious )
return AddHead( p );
++m_lCount;
p->m_pPrevious = q->m_pPrevious;
p->m_pPrevious->m_pNext = p;
q->m_pPrevious = p;
p->m_pNext = q;
return true;
}
bool PList::InsertAfter( PNode* p, PNode* q )
{
if( !q )
return AddHead( p );
if( !q->m_pNext )
return AddTail( p );
return InsertBefore( p, q->m_pNext );
}
void PList::Delete( PNode* p )
{
Remove( p );
delete p;
}
void PList::Remove( PNode* p )
{
m_lCount--;
if( m_pHead == p )
m_pHead = p->m_pNext;
if( m_pTail == p )
m_pTail = p->m_pPrevious;
if( p->m_pNext )
p->m_pNext->m_pPrevious = p->m_pPrevious;
if( p->m_pPrevious )
p->m_pPrevious->m_pNext = p->m_pNext;
p->m_pNext = p->m_pPrevious = 0;
}
bool PList::IsEmpty()
{
return m_pHead ? true : false;
}
PNode* PList::Find( long lZeroBasedIndex )
{
long lIndex = 0;
for( PNode* p = m_pHead; p; p = p->m_pNext )
if( lIndex++ == lZeroBasedIndex )
return p;
return 0;
}
bool PList::Merge( PList& s )
{
while( s.m_pHead )
{
PNode* pNode = s.m_pHead;
s.Remove( s.m_pHead );
AddTail( pNode );
}
return true;
}
// reduce if your crap OS cannot handle tit - it ;(
#define BUFFERSIZE_FOR_SPRINTF 10480
PString::PString()
{
m_iStringLength = 0;
m_lpszData = 0;
}
inline void PString::CopyStringData(const char* lpszFrom)
{
if( lpszFrom )
{
m_iStringLength = strlen( lpszFrom )+1;
if( m_iStringLength < sizeof(m_szFixedBuffer) )
{
m_lpszData = m_szFixedBuffer;
strcpy( m_lpszData, lpszFrom );
}
else if( m_iStringLength > 0 )
{
m_lpszData = new char[ m_iStringLength ];
if( m_lpszData != 0 )
strcpy( m_lpszData, lpszFrom );
else m_iStringLength = 0;
}
else m_lpszData = 0;
}
else
{
m_lpszData = 0;
m_iStringLength = 0;
}
}
inline void PString::DeleteStringData()
{
if( (m_lpszData != m_szFixedBuffer) && m_lpszData )
delete m_lpszData;
m_lpszData = 0;
m_iStringLength = 0;
}
void PString::Append( const char* pString, unsigned long dwSize )
{
// *NOT* optimized
unsigned long dwCombinedLength = m_iStringLength + dwSize;
if( dwCombinedLength && dwSize )
{
char* lpszData = new char[ dwCombinedLength + 2 ];
if( m_lpszData && m_iStringLength )
strcpy( lpszData, m_lpszData );
strncpy( lpszData+m_iStringLength, pString, dwSize );
lpszData[dwCombinedLength] = 0;
DeleteStringData();
CopyStringData(lpszData);
delete lpszData;
}
}
PString::PString( const char* lpszArgument )
{
CopyStringData( lpszArgument );
}
PString::PString( const PString& objectSrc )
{
CopyStringData( objectSrc.m_lpszData );
}
PString::PString( int, const char* szFormat, ... )
{
if( szFormat )
{
char buffer[BUFFERSIZE_FOR_SPRINTF];
va_list argptr;
va_start( argptr, szFormat );
::vsprintf(buffer,szFormat,argptr);
buffer[BUFFERSIZE_FOR_SPRINTF-1]=0;
CopyStringData( buffer );
}
else
{
m_iStringLength = 0;
m_lpszData = 0;
}
}
PString::~PString()
{
DeleteStringData();
}
void PString::sprintf( const char* szFormat, ... )
{
DeleteStringData();
m_lpszData = 0;
m_iStringLength = 0;
if( szFormat )
{
char buffer[BUFFERSIZE_FOR_SPRINTF];
va_list argptr;
va_start( argptr, szFormat );
::vsprintf(buffer,szFormat,argptr);
buffer[BUFFERSIZE_FOR_SPRINTF-1]=0;
CopyStringData( buffer );
}
}
void PString::vsprintf( const char* szFormat, va_list args )
{
DeleteStringData();
m_lpszData = 0;
m_iStringLength = 0;
if( szFormat )
{
char buffer[BUFFERSIZE_FOR_SPRINTF];
::vsprintf(buffer,szFormat,args);
buffer[BUFFERSIZE_FOR_SPRINTF-1]=0;
CopyStringData( buffer );
}
}
PString& PString::operator=( const char* objectSrc )
{
if( objectSrc != m_lpszData )
{
DeleteStringData();
CopyStringData( objectSrc );
}
return *this;
}
PString& PString::operator=( PString& objectSrc )
{
if( this != &objectSrc )
{
DeleteStringData();
CopyStringData( objectSrc.m_lpszData );
}
return *this;
}
#ifdef _WIN32
#include "windows.h"
#else
#include "errno.h"
#endif
PString GetLastErrorString()
{
#ifdef _WIN32
PString strResult;
void* lpMsgBuf = NULL;
if( FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL,
GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ) && lpMsgBuf )
{
strResult = (LPCSTR) lpMsgBuf;
LocalFree( lpMsgBuf );
LPSTR p = strResult;
while( isspace(p[strlen(p)-1]) )
p[strlen(p)-1] = 0;
}
return strResult;
#else
return PString(strerror(errno));
#endif
}
BOOL ChangeDirectory( LPCSTR lpszDirectory )
{
if( !lpszDirectory )
return FALSE;
#ifndef _WIN32
if( chdir( lpszDirectory ) < 0 )
{
return FALSE;
}
else
{
return TRUE;
}
#else
// determine if contains a drive letter
LPCSTR lpszDrive = strchr( lpszDirectory, ':' );
if( lpszDrive )
{
if( _chdrive( toupper(lpszDrive[-1]) - 'A' + 1 ) == -1 )
{
return FALSE;
}
}
return SetCurrentDirectory( lpszDirectory );
#endif
} // ChangeDirectory()
PString GetCurrentDirectory()
{
char szBuffer[1024];
*szBuffer = 0;
#ifdef _WIN32
::GetCurrentDirectory( sizeof(szBuffer), szBuffer );
#elif defined(TARGET_IS_UNIX)
getcwd (szBuffer,sizeof(szBuffer));
#endif
return PString( szBuffer );
} // GetCurrentDirectory()
BOOL MakeSurePathExists( LPCSTR lpszFileName )
{
char szBuffer[1024];
strcpy( szBuffer, lpszFileName );
// if a path is given, change the current drive
PString strCurrentDirectory( GetCurrentDirectory() );
#ifdef _WIN32
LPSTR lpszPathSeparator = strchr( lpszFileName, ':' );
if( lpszPathSeparator )
{
CHAR szDrive[] = "?:\\";
szDrive[0] = lpszPathSeparator[-1];
// fail if unable to change to drive specified
if( !ChangeDirectory( szDrive ) )
{
return FALSE;
}
if( lpszPathSeparator[1] == '\\' )
lpszPathSeparator += 2;
else
lpszPathSeparator += 1;
strcpy( szBuffer, lpszPathSeparator );
}
else
{
// check if networkpath is given
if( lpszFileName[0] == '\\' && lpszFileName[1] == '\\')
{
// skip Rechnername
LPSTR pPath = strchr( lpszFileName+2, '\\');
if( pPath )
{
// skip Freigabename
pPath = strchr( pPath+1, '\\');
if( pPath)
{
// this is the path we should check
strcpy( szBuffer, pPath);
// first change drive
*pPath = 0;
//PTrace( "PMakeSurePathExists sets current network drive %s", lpszFileName );
if( !ChangeDirectory( lpszFileName ) )
{
return FALSE;
}
*pPath = '\\';
}
}
}
}
#endif
LPSTR lpszReadPosition = szBuffer;
while( *lpszReadPosition )
{
CHAR c = *lpszReadPosition;
if( (c == '\\') || (c == '/') )
{
// check if this partial path exists
*lpszReadPosition = 0;
if( *szBuffer )
{
#ifdef TARGET_IS_WIN32
if( !CreateDirectory( szBuffer, 0 )
{
DWORD dwLastError = GetLastError();
if( dwLastError != ERROR_ALREADY_EXISTS )
{
ChangeDirectory( strCurrentDirectory );
SetLastError(dwLastError);
return FALSE;
}
}
#elif defined(TARGET_IS_UNIX)
int result = mkdir( szBuffer, S_IRWXU|S_IRWXG|S_IRWXO );
#endif
}
*lpszReadPosition = SLASH_CHAR;
}
lpszReadPosition++;
}
if( szBuffer[0] )
{
#ifdef _WIN32
if( !CreateDirectory( szBuffer, 0 ) )
{
DWORD dwLastError = GetLastError();
if( dwLastError != ERROR_ALREADY_EXISTS )
{
ChangeDirectory( strCurrentDirectory );
SetLastError(dwLastError);
return FALSE;
}
}
#else
int result = mkdir( szBuffer, S_IRWXU|S_IRWXG|S_IRWXO );
#endif
}
ChangeDirectory( strCurrentDirectory );
#ifdef _WIN32
SetLastError(S_OK);
#endif
return TRUE;
} // PMakeSurePathExists()
syntax highlighted by Code2HTML, v. 0.9.1