Renamed version4 to flaim and version5 to xflaim

git-svn-id: https://svn.code.sf.net/p/flaim/code/trunk@7 0109f412-320b-0410-ab79-c3e0c5ffbbe6
This commit is contained in:
dsandersoremutah
2006-01-27 21:06:39 +00:00
parent 4072ed64c8
commit c55dab446f
612 changed files with 0 additions and 0 deletions

915
flaim/src/f64bitfh.cpp Normal file
View File

@@ -0,0 +1,915 @@
//-------------------------------------------------------------------------
// Desc: Abstraction class for 64 bit files.
// Tabs: 3
//
// Copyright (c) 2001,2003,2005-2006 Novell, Inc. All Rights Reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of version 2 of the GNU General Public
// License as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, contact Novell, Inc.
//
// To contact Novell about this file by physical or electronic mail,
// you may find current contact information at www.novell.com
//
// $Id: f64bitfh.cpp 12329 2006-01-20 17:49:30 -0700 (Fri, 20 Jan 2006) ahodgkinson $
//-------------------------------------------------------------------------
#include "flaimsys.h"
/****************************************************************************
Desc:
****************************************************************************/
F_64BitFileHandle::F_64BitFileHandle(
FLMUINT uiMaxFileSize)
{
m_bOpen = FALSE;
m_ucPath[ 0] = 0;
m_ui64EOF = 0;
m_pLockFileHdl = NULL;
f_memset( m_pFileHdlList, 0, sizeof( FH_INFO) * F_64BIT_FHDL_LIST_SIZE);
m_uiMaxFileSize = uiMaxFileSize;
if( !m_uiMaxFileSize)
{
m_uiMaxFileSize = F_64BIT_FHDL_DEFAULT_MAX_FILE_SIZE;
}
}
/****************************************************************************
Desc:
****************************************************************************/
F_64BitFileHandle::~F_64BitFileHandle()
{
if( m_bOpen)
{
Close();
}
flmAssert( !m_pLockFileHdl);
}
/****************************************************************************
Desc:
****************************************************************************/
void F_64BitFileHandle::ReleaseLockFile(
const char * pszBasePath,
FLMBOOL bDelete)
{
#ifndef FLM_UNIX
F_UNREFERENCED_PARM( bDelete);
F_UNREFERENCED_PARM( pszBasePath);
#endif
if( m_pLockFileHdl)
{
/*
Release the lock file
*/
(void)m_pLockFileHdl->Close();
m_pLockFileHdl->Release();
m_pLockFileHdl = NULL;
#ifdef FLM_UNIX
if( bDelete)
{
char szTmpPath[ F_PATH_MAX_SIZE];
/*
Delete the lock file
*/
f_strcpy( szTmpPath, pszBasePath);
f_pathAppend( szTmpPath, "64.LCK");
gv_FlmSysData.pFileSystem->Delete( szTmpPath);
}
#endif
}
}
/****************************************************************************
Desc: Closes all data files associated with the object
****************************************************************************/
void F_64BitFileHandle::Close(
FLMBOOL bDelete)
{
RCODE rc = FERR_OK;
FLMUINT uiLoop;
F_DirHdl * pDir = NULL;
char szTmpPath[ F_PATH_MAX_SIZE];
if( !m_bOpen)
{
return;
}
for( uiLoop = 0; uiLoop < F_64BIT_FHDL_LIST_SIZE; uiLoop++)
{
if( m_pFileHdlList[ uiLoop].pFileHdl)
{
if( m_pFileHdlList[ uiLoop].bDirty)
{
(void)m_pFileHdlList[ uiLoop].pFileHdl->Flush();
}
m_pFileHdlList[ uiLoop].pFileHdl->Close();
m_pFileHdlList[ uiLoop].pFileHdl->Release();
f_memset( &m_pFileHdlList[ uiLoop], 0, sizeof( FH_INFO));
}
}
m_ui64EOF = 0;
m_bOpen = FALSE;
if( bDelete)
{
if( RC_OK( gv_FlmSysData.pFileSystem->OpenDir(
m_ucPath, "*.64", &pDir)))
{
/*
Remove all data files
*/
for( rc = pDir->Next(); !RC_BAD( rc) ; rc = pDir->Next() )
{
pDir->CurrentItemPath( szTmpPath);
flmAssert( f_strstr( szTmpPath, ".64") != 0);
(void)gv_FlmSysData.pFileSystem->Delete( szTmpPath);
}
pDir->Release();
pDir = NULL;
}
/*
Release and delete the lock file
*/
(void)ReleaseLockFile( m_ucPath, TRUE);
/*
Remove the directory
*/
(void)gv_FlmSysData.pFileSystem->RemoveDir( m_ucPath);
}
else
{
(void)ReleaseLockFile( m_ucPath, FALSE);
}
}
/****************************************************************************
Desc: Removes a 64-bit file
****************************************************************************/
RCODE F_64BitFileHandle::Delete(
const char * pszPath)
{
RCODE rc = FERR_OK;
F_DirHdl * pDir = NULL;
char szTmpPath[ F_PATH_MAX_SIZE];
// Can't use this handle to delete something if we already
// have a file open.
if( m_bOpen)
{
// Can't jump to exit, because it calls ReleaseLockFile
return( RC_SET( FERR_FAILURE));
}
if( RC_BAD( rc = gv_FlmSysData.pFileSystem->Exists( pszPath)))
{
goto Exit;
}
if( !gv_FlmSysData.pFileSystem->IsDir( pszPath))
{
/*
If the path specifies a single file rather than a
64-bit directory, just go ahead and delete the file.
*/
rc = gv_FlmSysData.pFileSystem->Delete( pszPath);
goto Exit;
}
if( RC_BAD( rc = CreateLockFile( pszPath)))
{
goto Exit;
}
if( RC_OK( gv_FlmSysData.pFileSystem->OpenDir(
pszPath, "*.64", &pDir)))
{
/*
Remove all data files
*/
for( rc = pDir->Next(); !RC_BAD( rc) ; rc = pDir->Next())
{
pDir->CurrentItemPath( szTmpPath);
flmAssert( f_strstr( szTmpPath, ".64") != 0);
(void)gv_FlmSysData.pFileSystem->Delete( szTmpPath);
}
pDir->Release();
pDir = NULL;
rc = FERR_OK;
}
/*
Release and delete the lock file
*/
(void)ReleaseLockFile( pszPath, TRUE);
/*
Remove the directory
*/
(void)gv_FlmSysData.pFileSystem->RemoveDir( pszPath);
Exit:
(void)ReleaseLockFile( pszPath, FALSE);
return( rc);
}
/****************************************************************************
Desc: Creates a new 64-bit "file"
****************************************************************************/
RCODE F_64BitFileHandle::Create(
const char * pszPath)
{
RCODE rc = FERR_OK;
FLMBOOL bCreatedDir = FALSE;
if( m_bOpen)
{
rc = RC_SET( FERR_FAILURE);
goto Exit;
}
if( RC_BAD( rc = gv_FlmSysData.pFileSystem->CreateDir( pszPath)))
{
goto Exit;
}
f_strcpy( m_ucPath, pszPath);
bCreatedDir = TRUE;
/*
Create the lock file
*/
if( RC_BAD( rc = CreateLockFile( m_ucPath)))
{
goto Exit;
}
/*
Initialize the EOF to 0 and set the state to open
*/
m_ui64EOF = 0;
m_bOpen = TRUE;
Exit:
/*
Release the lock file
*/
if( RC_BAD( rc))
{
(void)ReleaseLockFile( m_ucPath, TRUE);
if( bCreatedDir)
{
(void)gv_FlmSysData.pFileSystem->RemoveDir( m_ucPath);
}
}
return( rc);
}
/****************************************************************************
Desc: Creates a new 64-bit file with a unique, generated name
****************************************************************************/
RCODE F_64BitFileHandle::CreateUnique(
char * pszPath,
const char * pszFileExtension)
{
RCODE rc = FERR_OK;
FLMUINT uiCount;
FLMBOOL bModext = TRUE;
FLMBOOL bCreatedDir = FALSE;
FLMUINT uiBaseTime = 0;
char ucHighByte = 0;
char szDirName[ F_FILENAME_SIZE];
char szTmpPath[ F_PATH_MAX_SIZE];
char szBasePath[ F_PATH_MAX_SIZE];
if( m_bOpen)
{
rc = RC_SET( FERR_FAILURE);
goto Exit;
}
if( !pszPath || pszPath[ 0] == '\0')
{
#if defined( FLM_UNIX)
f_strcpy( szBasePath, "./");
#elif defined( FLM_NLM)
f_strcpy( szBasePath, "SYS:_NETWARE");
#else
szBasePath[ 0] = '\0';
#endif
}
else
{
f_strcpy( szBasePath, pszPath);
}
if ((pszFileExtension) && (f_strlen( pszFileExtension) >= 3))
{
bModext = FALSE;
}
uiCount = 0;
szDirName[ 0] = '\0';
do
{
f_pathCreateUniqueName( &uiBaseTime, szDirName, pszFileExtension,
&ucHighByte, bModext);
f_strcpy( szTmpPath, szBasePath);
f_pathAppend( szTmpPath, szDirName);
rc = gv_FlmSysData.pFileSystem->CreateDir( szTmpPath);
} while ((rc != FERR_OK) && (uiCount++ < 20));
if( RC_BAD( rc))
{
goto Exit;
}
f_strcpy( m_ucPath, szTmpPath);
bCreatedDir = TRUE;
/*
Create the lock file
*/
if( RC_BAD( rc = CreateLockFile( m_ucPath)))
{
goto Exit;
}
/*
Initialize the EOF to 0 and set the state to open
*/
m_ui64EOF = 0;
m_bOpen = TRUE;
Exit:
/*
Release the lock file
*/
if( RC_BAD( rc))
{
ReleaseLockFile( m_ucPath, TRUE);
if( bCreatedDir)
{
(void)gv_FlmSysData.pFileSystem->RemoveDir( m_ucPath);
}
}
return( rc);
}
/****************************************************************************
Desc: Opens an existing 64-bit file
****************************************************************************/
RCODE F_64BitFileHandle::Open(
const char * pszPath)
{
RCODE rc = FERR_OK;
F_DirHdl * pDir = NULL;
FLMUINT uiTmp;
FLMUINT uiHighFileNum = 0;
FLMUINT uiHighOffset = 0;
if( m_bOpen)
{
rc = RC_SET( FERR_FAILURE);
goto Exit;
}
if( RC_BAD( gv_FlmSysData.pFileSystem->Exists( pszPath)) ||
!gv_FlmSysData.pFileSystem->IsDir( pszPath))
{
rc = RC_SET( FERR_IO_PATH_NOT_FOUND);
goto Exit;
}
f_strcpy( m_ucPath, pszPath);
/*
Create the lock file
*/
if( RC_BAD( rc = CreateLockFile( m_ucPath)))
{
goto Exit;
}
/*
Need to determine the current EOF
*/
if( RC_BAD( rc = gv_FlmSysData.pFileSystem->OpenDir(
m_ucPath, "*.64", &pDir)))
{
goto Exit;
}
/*
Find all data files to determine the EOF
*/
for( rc = pDir->Next(); !RC_BAD( rc) ; rc = pDir->Next() )
{
if( RC_OK( GetFileNum( pDir->CurrentItemName(), &uiTmp)))
{
if( uiTmp >= uiHighFileNum)
{
uiHighFileNum = uiTmp;
uiHighOffset = pDir->CurrentItemSize();
}
}
}
rc = FERR_OK;
m_ui64EOF = (((FLMUINT64)uiHighFileNum) * (FLMUINT64)m_uiMaxFileSize) +
(FLMUINT64)uiHighOffset;
m_bOpen = TRUE;
Exit:
if( pDir)
{
pDir->Release();
}
/*
Release the lock file
*/
if( RC_BAD( rc))
{
ReleaseLockFile( m_ucPath, FALSE);
}
return( rc);
}
/****************************************************************************
Desc: Flushes cached data to the data file(s)
****************************************************************************/
RCODE F_64BitFileHandle::Flush( void)
{
RCODE rc = FERR_OK;
FLMUINT uiLoop;
if( !m_bOpen)
{
rc = RC_SET( FERR_FAILURE);
goto Exit;
}
for( uiLoop = 0; uiLoop < F_64BIT_FHDL_LIST_SIZE; uiLoop++)
{
if( m_pFileHdlList[ uiLoop].bDirty)
{
if( RC_BAD( rc = m_pFileHdlList[ uiLoop].pFileHdl->Flush()))
{
goto Exit;
}
m_pFileHdlList[ uiLoop].bDirty = FALSE;
}
}
Exit:
return( rc);
}
/****************************************************************************
Desc: Reads data from the file
****************************************************************************/
RCODE F_64BitFileHandle::Read(
FLMUINT64 ui64Offset, // Offset to begin reading
FLMUINT uiLength, // Number of bytes to read
void * pvBuffer, // Buffer
FLMUINT * puiBytesRead) // [out] Number of bytes read
{
RCODE rc = FERR_OK;
FLMUINT uiFileNum = GetFileNum( ui64Offset);
FLMUINT uiFileOffset = GetFileOffset( ui64Offset);
FLMUINT uiTmp;
FLMUINT uiTotalBytesRead = 0;
FLMUINT uiBytesToRead;
FLMUINT uiMaxReadLen;
F_FileHdl * pFileHdl;
/*
Handle the case of a 0-byte read
*/
if( !uiLength)
{
if( ui64Offset >= m_ui64EOF)
{
rc = RC_SET( FERR_IO_END_OF_FILE);
}
goto Exit;
}
/*
Read the data file(s), moving to new files as needed.
*/
for( ;;)
{
if( ui64Offset >= m_ui64EOF)
{
rc = RC_SET( FERR_IO_END_OF_FILE);
goto Exit;
}
uiMaxReadLen = m_uiMaxFileSize - uiFileOffset;
flmAssert( uiMaxReadLen != 0);
uiTmp = (uiLength >= uiMaxReadLen ? uiMaxReadLen : uiLength);
uiBytesToRead = (((FLMUINT64)uiTmp > (FLMUINT64)(m_ui64EOF - ui64Offset))
? (FLMUINT)(m_ui64EOF - ui64Offset)
: uiTmp);
if( RC_BAD( rc = GetFileHdl( uiFileNum, FALSE, &pFileHdl)))
{
if( rc == FERR_IO_PATH_NOT_FOUND)
{
/*
Handle the case of a sparse file by filling the unread
portion of the buffer with zeros.
*/
f_memset( pvBuffer, 0, uiBytesToRead);
uiTmp = uiBytesToRead;
rc = FERR_OK;
}
else
{
goto Exit;
}
}
else
{
if( RC_BAD( rc = pFileHdl->Read( uiFileOffset, uiBytesToRead,
pvBuffer, &uiTmp)))
{
if( rc == FERR_IO_END_OF_FILE)
{
/*
Handle the case of a sparse file by filling the unread
portion of the buffer with zeros.
*/
f_memset( &(((FLMBYTE *)(pvBuffer))[ uiTmp]),
0, (FLMUINT)(uiBytesToRead - uiTmp));
uiTmp = uiBytesToRead;
rc = FERR_OK;
}
else
{
goto Exit;
}
}
}
uiTotalBytesRead += uiTmp;
uiLength -= uiTmp;
if( !uiLength)
{
break;
}
/*
Set up for next read
*/
pvBuffer = ((FLMBYTE *)pvBuffer) + uiTmp;
ui64Offset += uiTmp;
uiFileNum = GetFileNum( ui64Offset);
uiFileOffset = GetFileOffset( ui64Offset);
}
Exit:
*puiBytesRead = uiTotalBytesRead;
return( rc);
}
/****************************************************************************
Desc: Writes data to the file
****************************************************************************/
RCODE F_64BitFileHandle::Write(
FLMUINT64 ui64Offset, // Offset
FLMUINT uiLength, // Number of bytes to write.
void * pvBuffer, // Buffer that contains bytes to be written
FLMUINT * puiBytesWritten) // Number of bytes written.
{
RCODE rc = FERR_OK;
FLMUINT uiFileNum = GetFileNum( ui64Offset);
FLMUINT uiFileOffset = GetFileOffset( ui64Offset);
FLMUINT uiTmp;
FLMUINT uiTotalBytesWritten = 0;
FLMUINT uiBytesToWrite;
FLMUINT uiMaxWriteLen;
F_FileHdl * pFileHdl;
/*
Don't allow zero-length writes
*/
flmAssert( uiLength);
/*
Write to the data file(s), moving to new files as needed.
*/
for( ;;)
{
if( RC_BAD( rc = GetFileHdl( uiFileNum, TRUE, &pFileHdl)))
{
goto Exit;
}
uiMaxWriteLen = m_uiMaxFileSize - uiFileOffset;
flmAssert( uiMaxWriteLen != 0);
uiBytesToWrite = uiLength >= uiMaxWriteLen ? uiMaxWriteLen : uiLength;
uiTmp = 0;
rc = pFileHdl->Write( uiFileOffset, uiBytesToWrite, pvBuffer, &uiTmp);
uiTotalBytesWritten += uiTmp;
uiLength -= uiTmp;
ui64Offset += uiTmp;
if( RC_BAD( rc))
{
goto Exit;
}
if( !uiLength)
{
break;
}
/*
Set up for next write
*/
pvBuffer = ((FLMBYTE *)pvBuffer) + uiTmp;
uiFileNum = GetFileNum( ui64Offset);
uiFileOffset = GetFileOffset( ui64Offset);
}
Exit:
if( ui64Offset > m_ui64EOF)
{
m_ui64EOF = ui64Offset;
}
*puiBytesWritten = uiTotalBytesWritten;
return( rc);
}
/****************************************************************************
Desc: Returns the requested file handle
****************************************************************************/
RCODE F_64BitFileHandle::GetFileHdl(
FLMUINT uiFileNum,
FLMBOOL bGetForWrite,
F_FileHdl ** ppFileHdl)
{
RCODE rc = FERR_OK;
FLMUINT uiSlot;
F_FileHdl * pTmpHdl;
char ucPath[ F_PATH_MAX_SIZE];
flmAssert( m_bOpen);
*ppFileHdl = NULL;
uiSlot = uiFileNum % F_64BIT_FHDL_LIST_SIZE;
pTmpHdl = m_pFileHdlList[ uiSlot].pFileHdl;
if( pTmpHdl && m_pFileHdlList[ uiSlot].uiFileNum != uiFileNum)
{
if( RC_BAD( rc = pTmpHdl->Flush()))
{
goto Exit;
}
pTmpHdl->Close();
pTmpHdl->Release();
pTmpHdl = NULL;
f_memset( &m_pFileHdlList[ uiSlot], 0, sizeof( FH_INFO));
}
if( !pTmpHdl)
{
DataFilePath( uiFileNum, ucPath);
if( RC_BAD( rc = gv_FlmSysData.pFileSystem->Open( ucPath, F_IO_RDWR,
&pTmpHdl)))
{
if( rc == FERR_IO_PATH_NOT_FOUND && bGetForWrite)
{
if( RC_BAD( rc = gv_FlmSysData.pFileSystem->Create( ucPath,
F_IO_RDWR | F_IO_EXCL, &pTmpHdl)))
{
goto Exit;
}
}
else
{
goto Exit;
}
}
m_pFileHdlList[ uiSlot].pFileHdl = pTmpHdl;
m_pFileHdlList[ uiSlot].uiFileNum = uiFileNum;
flmAssert( !m_pFileHdlList[ uiSlot].bDirty);
}
*ppFileHdl = m_pFileHdlList[ uiSlot].pFileHdl;
if( bGetForWrite)
{
m_pFileHdlList[ uiSlot].bDirty = TRUE;
}
Exit:
return( rc);
}
/****************************************************************************
Desc: Given a data file name, returns the file's number
****************************************************************************/
RCODE F_64BitFileHandle::GetFileNum(
const char * pucFileName,
FLMUINT * puiFileNum)
{
RCODE rc = FERR_OK;
FLMUINT uiCnt = 0;
FLMUINT uiDigit;
FLMUINT uiFileNum = 0;
if( f_strlen( pucFileName) != 11) // XXXXXXXX.64
{
rc = RC_SET( FERR_IO_INVALID_PATH);
goto Exit;
}
if( f_strcmp( &pucFileName[ 8], ".64") != 0)
{
rc = RC_SET( FERR_IO_INVALID_PATH);
goto Exit;
}
while( uiCnt < 8)
{
uiDigit = pucFileName[ uiCnt];
if( uiDigit >= NATIVE_LOWER_A && uiDigit <= NATIVE_LOWER_F)
{
uiDigit = (FLMUINT)(uiDigit - NATIVE_LOWER_A) + 10;
}
else if( uiDigit >= NATIVE_UPPER_A && uiDigit <= NATIVE_UPPER_F)
{
uiDigit = (FLMUINT)(uiDigit - NATIVE_UPPER_A) + 10;
}
else if( uiDigit >= NATIVE_ZERO && uiDigit <= NATIVE_NINE)
{
uiDigit -= NATIVE_ZERO;
}
else
{
/*
Invalid character found in the file name
*/
rc = RC_SET( FERR_IO_INVALID_PATH);
goto Exit;
}
uiFileNum <<= 4;
uiFileNum += uiDigit;
uiCnt++;
}
*puiFileNum = uiFileNum;
Exit:
return( rc);
}
/****************************************************************************
Desc: This routine obtains exclusive access to a 64-bit file by creating
a .lck file. The object holds the .lck file open as long as the
64-bit file is open.
****************************************************************************/
RCODE F_64BitFileHandle::CreateLockFile(
const char * pszBasePath)
{
RCODE rc = FERR_OK;
char szLockPath [F_PATH_MAX_SIZE];
F_FileHdlImp * pLockFileHdl = NULL;
f_strcpy( szLockPath, pszBasePath);
f_pathAppend( szLockPath, "64.LCK");
/*
Attempt to create the lock file. If it fails, the lock file
may have been left because of a crash. Hence, we first try
to delete the file. If that succeeds, we then attempt to
create the file again. If it, or the 2nd create fail, we simply
return an access denied error.
*/
#ifndef FLM_UNIX
if( RC_BAD( gv_FlmSysData.pFileSystem->Create( szLockPath,
F_IO_RDWR | F_IO_EXCL | F_IO_SH_DENYRW | F_IO_DELETE_ON_CLOSE,
(F_FileHdl **)&pLockFileHdl)))
{
if( RC_BAD( gv_FlmSysData.pFileSystem->Delete( szLockPath)))
{
rc = RC_SET( FERR_IO_ACCESS_DENIED);
goto Exit;
}
else if (RC_BAD( gv_FlmSysData.pFileSystem->Create( szLockPath,
F_IO_RDWR | F_IO_EXCL | F_IO_SH_DENYRW | F_IO_DELETE_ON_CLOSE,
(F_FileHdl **)&pLockFileHdl)))
{
rc = RC_SET( FERR_IO_ACCESS_DENIED);
goto Exit;
}
}
#else
if( RC_BAD( gv_FlmSysData.pFileSystem->Create( szLockPath,
F_IO_RDWR | F_IO_EXCL | F_IO_SH_DENYRW,
(F_FileHdl **)&pLockFileHdl)))
{
if( RC_BAD( gv_FlmSysData.pFileSystem->Open( szLockPath,
F_IO_RDWR | F_IO_SH_DENYRW,
(F_FileHdl **)&pLockFileHdl)))
{
rc = RC_SET( FERR_IO_ACCESS_DENIED);
goto Exit;
}
}
if( RC_BAD( pLockFileHdl->Lock()))
{
rc = RC_SET( FERR_IO_ACCESS_DENIED);
goto Exit;
}
#endif
m_pLockFileHdl = pLockFileHdl;
pLockFileHdl = NULL;
Exit:
if (pLockFileHdl)
{
(void)pLockFileHdl->Close();
pLockFileHdl->Release();
pLockFileHdl = NULL;
}
return( rc);
}