git-svn-id: https://svn.code.sf.net/p/flaim/code/trunk@7 0109f412-320b-0410-ab79-c3e0c5ffbbe6
916 lines
19 KiB
C++
916 lines
19 KiB
C++
//-------------------------------------------------------------------------
|
|
// 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);
|
|
}
|