mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@1871 3b4a5df2-a311-0410-b5c6-a8a6f20db521
1039 lines
25 KiB
C++
1039 lines
25 KiB
C++
//**************************************************************************
|
|
//
|
|
// Filename : DbMan.c
|
|
//
|
|
// Purpose : function definitions for the database manager
|
|
//
|
|
// Modification history :
|
|
//
|
|
// 24sep96:HJH ->creation
|
|
//
|
|
//**************************************************************************
|
|
|
|
//**************************************************************************
|
|
//
|
|
// Includes
|
|
//
|
|
//**************************************************************************
|
|
|
|
#ifdef JA2_PRECOMPILED_HEADERS
|
|
#include "JA2 SGP ALL.H"
|
|
#elif defined( WIZ8_PRECOMPILED_HEADERS )
|
|
#include "WIZ8 SGP ALL.H"
|
|
#else
|
|
#include "types.h"
|
|
#include <stdlib.h>
|
|
#include <malloc.h>
|
|
#include <stdio.h>
|
|
#include "windows.h"
|
|
#include "FileMan.h"
|
|
#include "MemMan.h"
|
|
#include "DbMan.h"
|
|
#include "Debug.h"
|
|
#endif
|
|
|
|
//**************************************************************************
|
|
//
|
|
// Defines
|
|
//
|
|
//**************************************************************************
|
|
|
|
#define FILENAME_LENGTH 600
|
|
#define IM_FILENAME_LENGTH 100
|
|
#define BUCKET_FILENAME_LENGTH 100
|
|
#define INITIAL_NUM_HANDLES 20
|
|
#define NUM_FILES_TO_ADD_AT_A_TIME 20
|
|
|
|
#define CHECKF(exp) if (!(exp)) { return(FALSE); }
|
|
#define CHECKV(exp) if (!(exp)) { return; }
|
|
#define CHECKN(exp) if (!(exp)) { return(NULL); }
|
|
#define CHECKBI(exp) if (!(exp)) { return(-1); }
|
|
#define CHECK0(exp) if (!(exp)) { return(0); }
|
|
|
|
#define PRINT_DEBUG_INFO FileDebugPrint();
|
|
|
|
#define ExtractFileIndex( exp ) ( (HFILEINDEX)((exp)>>16) )
|
|
#define ExtractDbIndex( exp ) ( (HDBINDEX)((exp)&0x0000FFFF) )
|
|
|
|
//**************************************************************************
|
|
//
|
|
// Typedefs
|
|
//
|
|
//**************************************************************************
|
|
|
|
|
|
// NOTE: the file format of the index file will be as follows:
|
|
//
|
|
// UINT32 # - number of entries to follow for filenames starting with '0'
|
|
// entry 1 filename
|
|
// entry 1 databasename
|
|
// entry 2 filename
|
|
// entry 2 databasename
|
|
// ...
|
|
// entry # filename
|
|
// entry # databasename
|
|
//
|
|
// UINT32 # - number of entries to follow for filenames starting with '1'
|
|
// entry 1 filename
|
|
// entry 1 databasename
|
|
// entry 2 filename
|
|
// entry 2 databasename
|
|
// ...
|
|
// entry # filename
|
|
// entry # databasename
|
|
//
|
|
// ...
|
|
//
|
|
// UINT32 # - number of entries to follow for filenames starting with 'z'
|
|
// entry 1 filename
|
|
// entry 1 databasename
|
|
// entry 2 filename
|
|
// entry 2 databasename
|
|
// ...
|
|
// entry # filename
|
|
// entry # databasename
|
|
//
|
|
// UINT32 #### - offset in file to entries for the letter '0'
|
|
// ...
|
|
// UINT32 #### - offset in file to entries for the letter '9'
|
|
// UINT32 #### - offset in file to entries for the letter 'a'
|
|
// ...
|
|
// UINT32 #### - offset in file to entries for the letter 'z'
|
|
//
|
|
// - each set of entries for a letter will comprise a bucket
|
|
|
|
typedef struct DbBucketTag
|
|
{
|
|
CHAR cFirstLetter;
|
|
|
|
CHAR *pstrFilenames;
|
|
CHAR *pstrDatabasenames;
|
|
UINT32 uiNumNames;
|
|
} DbBucket;
|
|
|
|
typedef struct DbFileTag
|
|
{
|
|
CHAR strFilename[FILENAME_LENGTH];
|
|
INT32 iFileSize; // if 0, this structure is not in use
|
|
INT32 iOffsetIntoFile;
|
|
INT32 iCurrentPosition;
|
|
} DbFile;
|
|
|
|
typedef struct DbInfoTag
|
|
{
|
|
CHAR strFilename[FILENAME_LENGTH];
|
|
HWFILE hFile; // if 0, this structure is not in use
|
|
|
|
DbFile *pOpenFiles;
|
|
UINT32 uiNumFiles;
|
|
} DbInfo;
|
|
|
|
typedef struct DbSystemTag
|
|
{
|
|
DbBucket bucket;
|
|
CHAR strIndexFilename[FILENAME_LENGTH];
|
|
|
|
DbInfo *pDBFiles;
|
|
UINT32 uiNumDBFiles;
|
|
|
|
BOOLEAN fDebug;
|
|
} DbSystem;
|
|
|
|
// this is for reading the database file
|
|
typedef struct DbHeaderTag
|
|
{
|
|
CHAR strSignature[20];
|
|
INT32 iNumFiles;
|
|
INT32 iOffsetToIndex;
|
|
} DbHeader;
|
|
|
|
// this is for reading the database file
|
|
typedef struct IndexMemberTag
|
|
{
|
|
CHAR strFilename[IM_FILENAME_LENGTH];
|
|
INT32 iFileSize;
|
|
INT32 iOffsetIntoFile;
|
|
INT32 time;
|
|
} IndexMember;
|
|
|
|
//**************************************************************************
|
|
//
|
|
// Variables
|
|
//
|
|
//**************************************************************************
|
|
|
|
DbSystem gdb;
|
|
|
|
//**************************************************************************
|
|
//
|
|
// Function Prototypes
|
|
//
|
|
//**************************************************************************
|
|
|
|
void DbDebugPrint( void );
|
|
HDBFILE CreateDBFileHandle( HFILEINDEX, HDBINDEX );
|
|
BOOLEAN InitDB( DbInfo *pDBInfo, STR strFilename );
|
|
HDBINDEX OpenDatabaseContainingFile( STR strFilename );
|
|
BOOLEAN InitFile( HWFILE hDBFile, DbFile *pFileInfo, STR strFilename );
|
|
BOOLEAN LoadBucket( CHAR cFirstLetter );
|
|
BOOLEAN GetShortFilename( STR strFilename, STR strPathname );
|
|
|
|
//**************************************************************************
|
|
//
|
|
// Functions
|
|
//
|
|
//**************************************************************************
|
|
|
|
//**************************************************************************
|
|
//
|
|
// CreateDBFileHandle
|
|
//
|
|
// Creates a file handle from two indices.
|
|
//
|
|
// Parameter List :
|
|
// Return Value :
|
|
// Modification history :
|
|
//
|
|
// 24sep96:HJH ->creation
|
|
//
|
|
//**************************************************************************
|
|
|
|
HDBFILE CreateDBFileHandle( HFILEINDEX high, HDBINDEX low )
|
|
{
|
|
return( (((LONG)high)<<16)|low );
|
|
}
|
|
|
|
//**************************************************************************
|
|
//
|
|
// DbSystemInit
|
|
//
|
|
// Starts up the database system.
|
|
//
|
|
// Parameter List :
|
|
// Return Value :
|
|
// Modification history :
|
|
//
|
|
// 24sep96:HJH ->creation
|
|
//
|
|
//**************************************************************************
|
|
|
|
BOOLEAN InitializeDatabaseManager( STR strIndexFilename )
|
|
{
|
|
INT32 i;
|
|
UINT32 uiSize;
|
|
|
|
if ( !FileExistsNoDB( strIndexFilename ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
uiSize = INITIAL_NUM_HANDLES * sizeof(DbInfo);
|
|
gdb.fDebug = FALSE;
|
|
gdb.pDBFiles = (DbInfo *) MemAlloc( uiSize );
|
|
CHECKF( gdb.pDBFiles );
|
|
|
|
gdb.uiNumDBFiles = INITIAL_NUM_HANDLES;
|
|
|
|
for ( i=0 ; i<INITIAL_NUM_HANDLES ; i++ )
|
|
{
|
|
gdb.pDBFiles[i].hFile = 0;
|
|
}
|
|
|
|
strcpy( gdb.strIndexFilename, strIndexFilename );
|
|
|
|
RegisterDebugTopic( TOPIC_DATABASE_MANAGER, "Database Manager");
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
//**************************************************************************
|
|
//
|
|
// DbSystemShutdown
|
|
//
|
|
// Shuts down the database system.
|
|
//
|
|
// Parameter List :
|
|
// Return Value :
|
|
// Modification history :
|
|
//
|
|
// 24sep96:HJH ->creation
|
|
//
|
|
//**************************************************************************
|
|
|
|
void ShutdownDatabaseManager( void )
|
|
{
|
|
UINT32 i;
|
|
|
|
MemFree( gdb.bucket.pstrFilenames );
|
|
MemFree( gdb.bucket.pstrDatabasenames );
|
|
|
|
// close any unclosed files
|
|
for ( i=1 ; i<gdb.uiNumDBFiles ; i++ )
|
|
{
|
|
DbClose((HDBINDEX)i);
|
|
//if ( gdb.pDBFiles[i].hFile )
|
|
//{
|
|
// FileClose(gdb.pDBFiles[i].hFile);
|
|
// gdb.pDBFiles[i].hFile = 0;
|
|
//}
|
|
}
|
|
|
|
// release memory used
|
|
MemFree( gdb.pDBFiles );
|
|
|
|
UnRegisterDebugTopic( TOPIC_DATABASE_MANAGER, "Database Manager" );
|
|
}
|
|
|
|
//**************************************************************************
|
|
//
|
|
// DbDebug
|
|
//
|
|
// To set whether or not we should print debug info.
|
|
//
|
|
// Parameter List :
|
|
// Return Value :
|
|
// Modification history :
|
|
//
|
|
// 24sep96:HJH ->creation
|
|
//
|
|
//**************************************************************************
|
|
|
|
void DbDebug( BOOLEAN fFlag )
|
|
{
|
|
gdb.fDebug = fFlag;
|
|
}
|
|
|
|
//**************************************************************************
|
|
//
|
|
// DbExists
|
|
//
|
|
// Checks if a database file exists.
|
|
//
|
|
// Parameter List :
|
|
//
|
|
// STR ->name of file to check existence of
|
|
//
|
|
// Return Value :
|
|
//
|
|
// BOOLEAN ->TRUE if it exists
|
|
// ->FALSE if not
|
|
//
|
|
// Modification history :
|
|
//
|
|
// 24sep96:HJH ->creation
|
|
//
|
|
//**************************************************************************
|
|
|
|
BOOLEAN DbExists( STR strFilename )
|
|
{
|
|
return( FileExists( strFilename ) );
|
|
}
|
|
|
|
//**************************************************************************
|
|
//
|
|
// DbOpen
|
|
//
|
|
// Opens a database.
|
|
//
|
|
// Parameter List :
|
|
//
|
|
// STR ->filename
|
|
//
|
|
// Return Value :
|
|
//
|
|
// HDBINDEX ->handle of opened file
|
|
// ->0 if unsuccessful
|
|
//
|
|
// Modification history :
|
|
//
|
|
// 24sep96:HJH ->creation
|
|
//
|
|
//**************************************************************************
|
|
|
|
HDBINDEX DbOpen( STR strFilename )
|
|
{
|
|
HDBINDEX hDBIndex;
|
|
UINT16 i;
|
|
CHAR cShortFilename[FILENAME_LENGTH];
|
|
CHAR cShortDBName[FILENAME_LENGTH];
|
|
BOOLEAN fFound;
|
|
|
|
fFound = FALSE;
|
|
hDBIndex = 0;
|
|
|
|
// first, find any already open databases, and make sure that if we're trying to
|
|
// open one that's already open, then we just return an index to it
|
|
for ( i=1 ; i<gdb.uiNumDBFiles ; i++ )
|
|
{
|
|
if ( gdb.pDBFiles[i].hFile != 0 )
|
|
{
|
|
GetShortFilename( cShortFilename, strFilename );
|
|
GetShortFilename( cShortDBName, gdb.pDBFiles[i].strFilename );
|
|
if ( strcmp( cShortFilename, cShortDBName ) == 0 )
|
|
{
|
|
fFound = TRUE;
|
|
hDBIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// if we didn't find the database already open, then open it
|
|
if ( !fFound )
|
|
{
|
|
for ( i=1 ; i<gdb.uiNumDBFiles ; i++ )
|
|
{
|
|
if ( gdb.pDBFiles[i].hFile == 0 )
|
|
{
|
|
if ( InitDB( &gdb.pDBFiles[i], strFilename ) )
|
|
hDBIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// if we didn't have enough space to open the file, allocate more and open it
|
|
if ( i == gdb.uiNumDBFiles )
|
|
{
|
|
DbInfo *pNew;
|
|
|
|
pNew = (DbInfo *) MemRealloc( gdb.pDBFiles, gdb.uiNumDBFiles + NUM_FILES_TO_ADD_AT_A_TIME );
|
|
|
|
if ( !pNew )
|
|
{
|
|
return(0);
|
|
}
|
|
gdb.pDBFiles = (DbInfo *)pNew;
|
|
|
|
if ( InitDB( &gdb.pDBFiles[i], strFilename ) )
|
|
hDBIndex = i;
|
|
}
|
|
|
|
//ASSERT(hDBIndex);
|
|
DbgMessage( TOPIC_DATABASE_MANAGER, DBG_LEVEL_2, "Opening Database File" );
|
|
DbgMessage( TOPIC_DATABASE_MANAGER, DBG_LEVEL_2, strFilename );
|
|
|
|
return(hDBIndex);
|
|
}
|
|
|
|
//**************************************************************************
|
|
//
|
|
// DbClose
|
|
//
|
|
//
|
|
// Parameter List :
|
|
//
|
|
// HWFILE hFile ->handle to database file to close
|
|
//
|
|
// Return Value :
|
|
// Modification history :
|
|
//
|
|
// 24sep96:HJH ->creation
|
|
//
|
|
//**************************************************************************
|
|
|
|
void DbClose( HDBINDEX hFile )
|
|
{
|
|
if ( hFile && gdb.pDBFiles[hFile].hFile )
|
|
{
|
|
MemFree( gdb.pDBFiles[hFile].pOpenFiles );
|
|
FileClose( gdb.pDBFiles[hFile].hFile );
|
|
gdb.pDBFiles[hFile].hFile = 0;
|
|
|
|
DbgMessage( TOPIC_DATABASE_MANAGER, DBG_LEVEL_2, "Closing Database File" );
|
|
}
|
|
}
|
|
|
|
//**************************************************************************
|
|
//
|
|
// DbFileOpen
|
|
//
|
|
// Opens a file in a database.
|
|
//
|
|
// Parameter List :
|
|
//
|
|
// STR ->filename
|
|
// UIN32 ->access - read or write, or both
|
|
// BOOLEAN ->delete on close
|
|
//
|
|
// Return Value :
|
|
//
|
|
// HWFILE ->handle of opened file
|
|
//
|
|
// Modification history :
|
|
//
|
|
// 24sep96:HJH ->creation
|
|
//
|
|
//**************************************************************************
|
|
|
|
HDBFILE DbFileOpen( STR strFilename )
|
|
{
|
|
HDBFILE hFile;
|
|
HFILEINDEX hFileIndex = 0xffff;
|
|
HDBINDEX hDBIndex;
|
|
UINT16 i;
|
|
|
|
hDBIndex = OpenDatabaseContainingFile( strFilename );
|
|
if ( !hDBIndex )
|
|
return(0);
|
|
|
|
for ( i=1 ; i<gdb.pDBFiles[hDBIndex].uiNumFiles ; i++ )
|
|
{
|
|
if ( gdb.pDBFiles[hDBIndex].pOpenFiles[i].iFileSize == 0 )
|
|
{
|
|
if ( InitFile( gdb.pDBFiles[hDBIndex].hFile, &gdb.pDBFiles[hDBIndex].pOpenFiles[i], strFilename ) )
|
|
hFileIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
if ( i == gdb.pDBFiles[hDBIndex].uiNumFiles )
|
|
{
|
|
DbFile *pNew;
|
|
|
|
pNew = (DbFile *) MemRealloc( gdb.pDBFiles[hDBIndex].pOpenFiles,
|
|
gdb.pDBFiles[hDBIndex].uiNumFiles + NUM_FILES_TO_ADD_AT_A_TIME );
|
|
|
|
if ( !pNew )
|
|
{
|
|
return(0);
|
|
}
|
|
gdb.pDBFiles[hDBIndex].pOpenFiles = (DbFile *)pNew;
|
|
|
|
if ( InitFile( gdb.pDBFiles[hDBIndex].hFile, &gdb.pDBFiles[hDBIndex].pOpenFiles[i], strFilename ) )
|
|
hFileIndex = i;
|
|
else
|
|
return(0);
|
|
}
|
|
|
|
//ASSERT(hDBIndex);
|
|
//ASSERT(hFileIndex);
|
|
|
|
hFile = CreateDBFileHandle( hFileIndex, hDBIndex );
|
|
return(hFile);
|
|
}
|
|
|
|
//**************************************************************************
|
|
//
|
|
// DbFileClose
|
|
//
|
|
//
|
|
// Parameter List :
|
|
//
|
|
// HWFILE hFile ->handle to database file to close
|
|
//
|
|
// Return Value :
|
|
// Modification history :
|
|
//
|
|
// 24sep96:HJH ->creation
|
|
//
|
|
//**************************************************************************
|
|
|
|
void DbFileClose( HDBFILE hDBFile )
|
|
{
|
|
HFILEINDEX hFileIndex;
|
|
HDBINDEX hDBIndex;
|
|
|
|
hFileIndex = ExtractFileIndex( hDBFile );
|
|
hDBIndex = ExtractDbIndex( hDBFile );
|
|
|
|
if ( hDBIndex >= gdb.uiNumDBFiles )
|
|
return;
|
|
|
|
if ( gdb.pDBFiles[hDBIndex].pOpenFiles )
|
|
{
|
|
if ( hFileIndex >= gdb.pDBFiles[hDBIndex].uiNumFiles )
|
|
return;
|
|
|
|
if ( gdb.pDBFiles[hDBIndex].pOpenFiles[hFileIndex].iFileSize )
|
|
{
|
|
gdb.pDBFiles[hDBIndex].pOpenFiles[hFileIndex].iFileSize = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
//**************************************************************************
|
|
//
|
|
// DbFileRead
|
|
//
|
|
// To read a file in a database.
|
|
//
|
|
// Parameter List :
|
|
//
|
|
// HWFILE ->handle to file to read from
|
|
// void * ->source buffer
|
|
// UINT32 ->num bytes to read
|
|
// UINT32 ->num bytes read
|
|
//
|
|
// Return Value :
|
|
//
|
|
// BOOLEAN ->TRUE if successful
|
|
// ->FALSE if not
|
|
//
|
|
// Modification history :
|
|
//
|
|
// 24sep96:HJH ->creation
|
|
//
|
|
//**************************************************************************
|
|
|
|
BOOLEAN DbFileRead(HDBFILE hDBFile, PTR pDest, UINT32 uiBytesToRead, UINT32 *puiBytesRead)
|
|
{
|
|
HFILEINDEX hFileIndex;
|
|
HDBINDEX hDBIndex;
|
|
HWFILE hFile;
|
|
UINT32 uiStartPos, uiCurPos, uiBytesRead;
|
|
|
|
hFileIndex = ExtractFileIndex( hDBFile );
|
|
hDBIndex = ExtractDbIndex( hDBFile );
|
|
|
|
CHECKF( hDBIndex < gdb.uiNumDBFiles );
|
|
CHECKF( gdb.pDBFiles[hDBIndex].pOpenFiles )
|
|
CHECKF( hFileIndex < gdb.pDBFiles[hDBIndex].uiNumFiles );
|
|
CHECKF( gdb.pDBFiles[hDBIndex].pOpenFiles[hFileIndex].iFileSize );
|
|
|
|
hFile = gdb.pDBFiles[hDBIndex].hFile;
|
|
uiStartPos = gdb.pDBFiles[hDBIndex].pOpenFiles[hFileIndex].iOffsetIntoFile;
|
|
uiCurPos = gdb.pDBFiles[hDBIndex].pOpenFiles[hFileIndex].iCurrentPosition;
|
|
|
|
CHECKF( hFile );
|
|
|
|
FileSeek( hFile, uiStartPos + uiCurPos, FILE_SEEK_FROM_START );
|
|
FileRead( hFile, pDest, uiBytesToRead, &uiBytesRead );
|
|
|
|
if ( puiBytesRead )
|
|
*puiBytesRead = uiBytesRead;
|
|
|
|
gdb.pDBFiles[hDBIndex].pOpenFiles[hFileIndex].iCurrentPosition += uiBytesToRead;
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
//**************************************************************************
|
|
//
|
|
// DbFileLoad
|
|
//
|
|
// To open, read, and close a file.
|
|
//
|
|
// Parameter List :
|
|
//
|
|
//
|
|
// Return Value :
|
|
//
|
|
// BOOLEAN ->TRUE if successful
|
|
// ->FALSE if not
|
|
//
|
|
// Modification history :
|
|
//
|
|
// 24sep96:HJH ->creation
|
|
//
|
|
//**************************************************************************
|
|
|
|
BOOLEAN DbFileLoad(STR filename, PTR pDest, UINT32 uiBytesToRead, UINT32 *puiBytesRead)
|
|
{
|
|
HDBFILE hDBFile;
|
|
UINT32 uiBytesRead;
|
|
|
|
hDBFile = DbFileOpen( filename );
|
|
CHECKF( hDBFile );
|
|
|
|
DbFileRead( hDBFile, pDest, uiBytesToRead, &uiBytesRead );
|
|
DbFileClose( hDBFile );
|
|
|
|
if ( puiBytesRead )
|
|
*puiBytesRead = uiBytesRead;
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
//**************************************************************************
|
|
//
|
|
// DbFileSeek
|
|
//
|
|
// To seek to a position in a file in a database.
|
|
//
|
|
// Parameter List :
|
|
//
|
|
// HWFILE ->handle to file to seek in
|
|
// UINT32 ->distance to seek
|
|
// UINT8 ->how to seek
|
|
//
|
|
// Return Value :
|
|
//
|
|
// BOOLEAN ->TRUE if successful
|
|
// ->FALSE if not
|
|
//
|
|
// Modification history :
|
|
//
|
|
// 24sep96:HJH ->creation
|
|
//
|
|
//**************************************************************************
|
|
|
|
BOOLEAN DbFileSeek( HDBFILE hDBFile, UINT32 uiDistance, UINT8 uiHow )
|
|
{
|
|
HFILEINDEX hFileIndex;
|
|
HDBINDEX hDBIndex;
|
|
UINT32 uiStartPos, uiCurPos, uiSize;
|
|
|
|
hFileIndex = ExtractFileIndex( hDBFile );
|
|
hDBIndex = ExtractDbIndex( hDBFile );
|
|
|
|
CHECKF( hDBIndex < gdb.uiNumDBFiles );
|
|
CHECKF( gdb.pDBFiles[hDBIndex].pOpenFiles )
|
|
CHECKF( hFileIndex < gdb.pDBFiles[hDBIndex].uiNumFiles );
|
|
CHECKF( gdb.pDBFiles[hDBIndex].pOpenFiles[hFileIndex].iFileSize );
|
|
|
|
uiStartPos = gdb.pDBFiles[hDBIndex].pOpenFiles[hFileIndex].iOffsetIntoFile;
|
|
uiCurPos = gdb.pDBFiles[hDBIndex].pOpenFiles[hFileIndex].iCurrentPosition;
|
|
uiSize = gdb.pDBFiles[hDBIndex].pOpenFiles[hFileIndex].iFileSize;
|
|
|
|
if ( uiHow == FILE_SEEK_FROM_START )
|
|
uiCurPos = uiDistance;
|
|
else if ( uiHow == FILE_SEEK_FROM_END )
|
|
uiCurPos = uiSize - uiDistance;
|
|
else if ( uiHow == FILE_SEEK_FROM_CURRENT )
|
|
uiCurPos += uiDistance;
|
|
else
|
|
return(FALSE);
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
//**************************************************************************
|
|
//
|
|
// DbFileGetSize
|
|
//
|
|
// To get the current position in a file.
|
|
//
|
|
// Parameter List :
|
|
//
|
|
// HWFILE ->handle to file
|
|
//
|
|
// Return Value :
|
|
//
|
|
// INT32 ->current offset in file if successful
|
|
// ->-1 if not
|
|
//
|
|
// Modification history :
|
|
//
|
|
// 24sep96:HJH ->creation
|
|
//
|
|
//**************************************************************************
|
|
|
|
UINT32 DbFileGetPos( HDBFILE hDBFile )
|
|
{
|
|
HFILEINDEX hFileIndex;
|
|
HDBINDEX hDBIndex;
|
|
|
|
hFileIndex = ExtractFileIndex( hDBFile );
|
|
hDBIndex = ExtractDbIndex( hDBFile );
|
|
|
|
CHECK0( hDBIndex < gdb.uiNumDBFiles );
|
|
CHECK0( gdb.pDBFiles[hDBIndex].pOpenFiles )
|
|
CHECK0( hFileIndex < gdb.pDBFiles[hDBIndex].uiNumFiles );
|
|
CHECK0( gdb.pDBFiles[hDBIndex].pOpenFiles[hFileIndex].iFileSize );
|
|
|
|
return(gdb.pDBFiles[hDBIndex].pOpenFiles[hFileIndex].iCurrentPosition);
|
|
}
|
|
|
|
//**************************************************************************
|
|
//
|
|
// DbFileGetSize
|
|
//
|
|
// To get the current file size.
|
|
//
|
|
// Parameter List :
|
|
//
|
|
// HWFILE ->handle to file
|
|
//
|
|
// Return Value :
|
|
//
|
|
// INT32 ->file size in file if successful
|
|
// ->0 if not
|
|
//
|
|
// Modification history :
|
|
//
|
|
// 24sep96:HJH ->creation
|
|
//
|
|
//**************************************************************************
|
|
|
|
UINT32 DbFileGetSize( HDBFILE hDBFile )
|
|
{
|
|
HFILEINDEX hFileIndex;
|
|
HDBINDEX hDBIndex;
|
|
|
|
hFileIndex = ExtractFileIndex( hDBFile );
|
|
hDBIndex = ExtractDbIndex( hDBFile );
|
|
|
|
CHECK0( hDBIndex < gdb.uiNumDBFiles );
|
|
CHECK0( gdb.pDBFiles[hDBIndex].pOpenFiles )
|
|
CHECK0( hFileIndex < gdb.pDBFiles[hDBIndex].uiNumFiles );
|
|
CHECK0( gdb.pDBFiles[hDBIndex].pOpenFiles[hFileIndex].iFileSize );
|
|
|
|
return(gdb.pDBFiles[hDBIndex].pOpenFiles[hFileIndex].iFileSize);
|
|
}
|
|
|
|
//**************************************************************************
|
|
//
|
|
// DbDebugPrint
|
|
//
|
|
// To print the debug state to output.
|
|
//
|
|
// Parameter List :
|
|
// Return Value :
|
|
// Modification history :
|
|
//
|
|
// 24sep96:HJH ->creation
|
|
//
|
|
//**************************************************************************
|
|
|
|
void DbDebugPrint( void )
|
|
{
|
|
}
|
|
|
|
//**************************************************************************
|
|
//
|
|
// InitDB
|
|
//
|
|
// To initialize a database info structure.
|
|
//
|
|
// Parameter List :
|
|
// Return Value :
|
|
// Modification history :
|
|
//
|
|
// 15oct96:HJH ->creation
|
|
//
|
|
//**************************************************************************
|
|
|
|
BOOLEAN InitDB( DbInfo *pDBInfo, STR strFilename )
|
|
{
|
|
HWFILE hFile;
|
|
INT32 i;
|
|
|
|
CHECKF(pDBInfo);
|
|
|
|
hFile = FileOpen( strFilename, FILE_ACCESS_READ, FALSE );
|
|
CHECKF( hFile );
|
|
|
|
strcpy( pDBInfo->strFilename, strFilename );
|
|
pDBInfo->hFile = hFile;
|
|
pDBInfo->pOpenFiles = (DbFile *) MemAlloc(INITIAL_NUM_HANDLES * sizeof(DbFile));
|
|
|
|
if ( !pDBInfo->pOpenFiles )
|
|
{
|
|
FileClose( hFile );
|
|
return(FALSE);
|
|
}
|
|
|
|
for ( i=0 ; i<INITIAL_NUM_HANDLES ; i++ )
|
|
{
|
|
pDBInfo->pOpenFiles[i].iFileSize = 0;
|
|
}
|
|
pDBInfo->uiNumFiles = INITIAL_NUM_HANDLES;
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
//**************************************************************************
|
|
//
|
|
// OpenDatabaseContainingFile
|
|
//
|
|
// To open, or find the already opened database, containing the given file.
|
|
//
|
|
// Parameter List :
|
|
// Return Value :
|
|
// Modification history :
|
|
//
|
|
// 15oct96:HJH ->creation
|
|
//
|
|
//**************************************************************************
|
|
|
|
HDBINDEX OpenDatabaseContainingFile( STR strFilename )
|
|
{
|
|
CHAR cFirst, cFilename[FILENAME_LENGTH], cCheckname[FILENAME_LENGTH];
|
|
UINT32 i;
|
|
HDBINDEX hIndex;
|
|
|
|
hIndex = 0;
|
|
GetShortFilename( cFilename, strFilename );
|
|
|
|
cFirst = cFilename[0];
|
|
|
|
if ( cFirst != gdb.bucket.cFirstLetter )
|
|
LoadBucket( cFirst );
|
|
|
|
for ( i=0 ; i<gdb.bucket.uiNumNames ; i++ )
|
|
{
|
|
GetShortFilename( cCheckname, &(gdb.bucket.pstrFilenames[i*BUCKET_FILENAME_LENGTH]) );
|
|
|
|
if ( strcmp( cCheckname, cFilename ) == 0 )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( i < gdb.bucket.uiNumNames )
|
|
{
|
|
hIndex = DbOpen( &gdb.bucket.pstrDatabasenames[i*BUCKET_FILENAME_LENGTH] );
|
|
}
|
|
|
|
return( hIndex );
|
|
}
|
|
|
|
//**************************************************************************
|
|
//
|
|
// InitFile
|
|
//
|
|
// To initialize a file info structure.
|
|
//
|
|
// Parameter List :
|
|
// Return Value :
|
|
// Modification history :
|
|
//
|
|
// 15oct96:HJH ->creation
|
|
//
|
|
//**************************************************************************
|
|
|
|
BOOLEAN InitFile( HWFILE hDBFile, DbFile *pFileInfo, STR strFilename )
|
|
{
|
|
DbHeader header;
|
|
IndexMember im;
|
|
UINT32 uiBytesRead;
|
|
INT32 i;
|
|
CHAR cFilename[FILENAME_LENGTH], cShortFilename[FILENAME_LENGTH];
|
|
|
|
CHECKF( pFileInfo );
|
|
CHECKF( strFilename );
|
|
CHECKF( hDBFile );
|
|
|
|
FileSeek( hDBFile, 0, FILE_SEEK_FROM_START );
|
|
FileRead( hDBFile, &header, sizeof(DbHeader), &uiBytesRead );
|
|
CHECKF( uiBytesRead == sizeof(DbHeader) );
|
|
FileSeek( hDBFile, header.iOffsetToIndex, FILE_SEEK_FROM_START );
|
|
|
|
GetShortFilename( cShortFilename, strFilename );
|
|
for ( i=0 ; i<header.iNumFiles ; i++ )
|
|
{
|
|
FileRead( hDBFile, &im, sizeof(IndexMember), &uiBytesRead );
|
|
CHECKF( uiBytesRead == sizeof(IndexMember) );
|
|
GetShortFilename( cFilename, im.strFilename );
|
|
if ( strcmp( cFilename, cShortFilename ) == 0 )
|
|
{
|
|
strcpy( pFileInfo->strFilename, strFilename );
|
|
pFileInfo->iFileSize = im.iFileSize;
|
|
pFileInfo->iOffsetIntoFile = im.iOffsetIntoFile;
|
|
pFileInfo->iCurrentPosition = 0;
|
|
return(TRUE);
|
|
}
|
|
}
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
//**************************************************************************
|
|
//
|
|
// LoadBucket
|
|
//
|
|
// To load a bucketfull of file-database name pairs.
|
|
//
|
|
// Parameter List :
|
|
// Return Value :
|
|
// Modification history :
|
|
//
|
|
// 15oct96:HJH ->creation
|
|
//
|
|
//**************************************************************************
|
|
|
|
BOOLEAN LoadBucket( CHAR cFirstLetter )
|
|
{
|
|
HWFILE hFile;
|
|
UINT32 i, uiPosition, uiBytesRead, uiNumEntries, uiSize;
|
|
CHAR cFilename[FILENAME_LENGTH], cDatabasename[FILENAME_LENGTH];
|
|
|
|
uiNumEntries = 0;
|
|
|
|
MemFree( gdb.bucket.pstrFilenames );
|
|
MemFree( gdb.bucket.pstrDatabasenames );
|
|
|
|
hFile = FileOpen( gdb.strIndexFilename, FILE_ACCESS_READ, FALSE );
|
|
CHECKF(hFile);
|
|
uiSize = FileGetSize( hFile );
|
|
|
|
if ( cFirstLetter >= 'a' && cFirstLetter <= 'z' )
|
|
uiPosition = 'z' - cFirstLetter + 1;
|
|
else
|
|
uiPosition = 26 + ('9' - cFirstLetter + 1);
|
|
|
|
FileSeek( hFile, sizeof(UINT32)*uiPosition, FILE_SEEK_FROM_END );
|
|
FileRead( hFile, &uiPosition, sizeof(UINT32), &uiBytesRead );
|
|
if ( uiPosition > uiSize )
|
|
{
|
|
// error
|
|
return(FALSE);
|
|
}
|
|
|
|
FileSeek( hFile, uiPosition, FILE_SEEK_FROM_START );
|
|
FileRead( hFile, &uiNumEntries, sizeof(UINT32), &uiBytesRead );
|
|
|
|
CHECKF(uiNumEntries);
|
|
|
|
gdb.bucket.pstrFilenames = (STR8)MemAlloc( uiNumEntries * FILENAME_LENGTH);
|
|
CHECKF(gdb.bucket.pstrFilenames);
|
|
|
|
gdb.bucket.pstrDatabasenames = (STR8)MemAlloc( uiNumEntries * FILENAME_LENGTH);
|
|
if ( !gdb.bucket.pstrDatabasenames )
|
|
{
|
|
MemFree(gdb.bucket.pstrFilenames);
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
for ( i=0 ; i<uiNumEntries ; i++ )
|
|
{
|
|
FileRead( hFile, cFilename, BUCKET_FILENAME_LENGTH, &uiBytesRead );
|
|
FileRead( hFile, cDatabasename, BUCKET_FILENAME_LENGTH, &uiBytesRead );
|
|
|
|
strcpy( &gdb.bucket.pstrFilenames[i*BUCKET_FILENAME_LENGTH], cFilename );
|
|
strcpy( &gdb.bucket.pstrDatabasenames[i*BUCKET_FILENAME_LENGTH], cDatabasename );
|
|
}
|
|
|
|
FileClose( hFile );
|
|
|
|
gdb.bucket.uiNumNames = uiNumEntries;
|
|
gdb.bucket.cFirstLetter = cFirstLetter;
|
|
|
|
DbgMessage( TOPIC_DATABASE_MANAGER, DBG_LEVEL_2, "Loading Different Bucket" );
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
//**************************************************************************
|
|
//
|
|
// GetShortFilename
|
|
//
|
|
// To chop up a path, and return just the short filename.
|
|
//
|
|
// Parameter List :
|
|
// Return Value :
|
|
// Modification history :
|
|
//
|
|
// 15oct96:HJH ->creation
|
|
//
|
|
//**************************************************************************
|
|
|
|
BOOLEAN GetShortFilename( STR strFilename, STR strPathname )
|
|
{
|
|
CHAR *pcLast;
|
|
|
|
pcLast = strrchr( strPathname, '\\' );
|
|
|
|
if ( pcLast )
|
|
{
|
|
pcLast = pcLast + 1;
|
|
strcpy( strFilename, pcLast );
|
|
}
|
|
else
|
|
strcpy( strFilename, strPathname );
|
|
|
|
return(TRUE);
|
|
}
|
|
|