📄 file.cpp
字号:
}
dirtemp = dirp;
dirp = ( Directory* )dirp->items[1].address;
if( dirp == NULL )
break;
dirp->cur ++;
if( dirp->items[1].address == 0 && dirp->cur >= dirp->num )
break;
chdir( ".." );
}
fclose( fp );
chdir( curPath );
free( curPath );
return 0;
}
// pack the files in the spath into package, exclude subdirectory
// it's used to create directory tree
Directory* PackSubdir( DWORD& fpos, char *dpath, char *spath )
{
printf( "pack subdir %s \n", spath );
// DIR *dirp;
// dirent *direntp;
_finddata_t fd;
long hFile;
int ftemp;
int i;
Directory *dir;
dir = new Directory;
if( dir == NULL )
return NULL;
if( _chdir( spath ) == -1 ){
goto error;
}
// num includes all files and subdirs and '..' '.' )
dir->num = FileCount( spath ) + 2;
printf( "total files:%d\n", dir->num );
dir->items = new DirItem[ dir->num ];
memset( (char*)dir->items, 0, sizeof( DirItem ) * dir->num );
if( dir->items == NULL ){
delete dir;
return NULL;
}
// items[0] is point to this directory
strcpy( dir->items[0].filename, dpath );
dir->items[0].address = fpos;
// sizeof( DirItem ) = 22
dir->items[0].length = sizeof(Directory) + 22*UPROUND( dir->num, DIRITEM_UNIT );
dir->items[0].type = DIR_DISK;
// items[1] is point to the parent directory
strcpy( dir->items[1].filename, ".." );
dir->items[1].type = DIR_DISK;
fpos += dir->items[0].length;
if(( hFile = _findfirst( "*.*", &fd )) == -1 )
return NULL;
for( i=2; i<dir->num; i++ ){
if( fd.name[0] == '.' ){
i--;
continue;
}
if( !( fd.attrib & _A_SUBDIR )){ // file
if( (ftemp = open( fd.name, O_RDONLY )) == -1 ){
#ifdef _DEBUG
puts( fd.name );
#endif
return NULL;
}
puts( fd.name );
strcpy( dir->items[i].filename, fd.name );
dir->items[i].address = fpos;
dir->items[i].type = ARCHIVE;
dir->items[i].length = filelength( ftemp );
fpos += dir->items[i].length;
close( ftemp );
}
else if( fd.attrib & _A_SUBDIR ){ // subdirectory
puts( fd.name );
dir->items[i].type = DIR_DISK;
strcpy( dir->items[i].filename, fd.name );
}
_findnext( hFile, &fd );
}
puts( "pack subdir end." );
return dir;
error:
delete dir;
return NULL;
}
Directory* ReadDirFromDisk( FILE *fp, long fpos, Directory* parent )
{
if( fsetpos( fp, (fpos_t*)&fpos ) != 0 )
return NULL;
Directory *dir = new Directory;
if( dir == NULL )
return NULL;
if( dir->ReadDisk( fp ) != 0 ){
delete dir;
return NULL;
}
dir->items[1].address = ( DWORD )parent;
return dir;
}
/////////////////////////////////////////////////////////////////////
PackFile::PackFile()
{
for( int i=0; i<MAX_CFILE_NUM; i++ ){
file[i].fname[0] = 0;
file[i].root = NULL;
// file[i].fp = NULL;
// count[i] = 0;
}
}
PackFile::~PackFile()
{
for( int i=0; i<MAX_CFILE_NUM; i++ ){
if( file[i].root )
Close( i );
}
}
// example:convert "aaa.bmp" to "aaa bmp"
// not been used !!
void PackFile::FixFname( char *newfname, char *fname )
{
int i = 0;
memset( newfname, ' ', 11 );
newfname[11] = 0;
while( *fname ){
if( *fname != '.' ){
*newfname++ = *fname;
i++;
}
else{
newfname += 7 - i;
}
fname ++;
}
}
int PackFile::Close( char* fname )
{
for( int i=0; i<MAX_CFILE_NUM; i++ ){
if( strcmp( file[i].fname, fname ) == 0 )
return Close( i );
}
return -1;
}
// free the memory occupied by the package file[id]
int PackFile::Close( int id )
{
if( file[id].root == NULL )
return 0;
Directory *dirp = file[id].root, *dirtemp;
dirp->cur = 2;
while( 1 ){
while( dirp->cur < dirp->num ){
if( dirp->items[dirp->cur].type == DIR_RAM ){
dirtemp = ( Directory* )dirp->items[dirp->cur].address;
if( dirtemp == NULL )
return -1;
dirp = dirtemp;
dirp->cur = 2;
}
else
dirp->cur ++;
}
dirtemp = dirp;
dirp = ( Directory* )dirp->items[1].address;
if( dirp == NULL )
break;
dirp->cur ++;
if( dirp->items[1].address == 0 && dirp->cur >= dirp->num )
break;
delete dirtemp;
}
delete file[id].root;
file[id].root = NULL;
file[id].fname[0] = 0;
return 0;
}
// open package file
int PackFile::OpenCfile( int id, char *filename )
{
FILE *fp;
if( (fp = fopen( filename, "rb" )) == NULL )
return -1;
if(( file[id].root = ReadDirFromDisk( fp, 0, NULL )) == NULL ){
fclose( fp );
return -1;
}
strcpy( file[id].fname, filename );
file[id].currentDir = NULL;
file[id].currentPath[0] = 0;
fclose( fp );
return 0;
}
// open subfile in the package file
File* PackFile::OpenSubfile( int id, char* subname )
{
if( file[id].root == NULL )
return NULL;
FILE *fp;
if((fp = fopen( file[id].fname, "rb" )) == NULL )
return NULL;
int i, j;
char dname[13], path[MAX_PATH_LEN];
Directory* dirp, *dirtemp;
GetPathName( path, subname );
if( file[id].currentDir && strcmp( file[id].currentPath, path ) == 0 ){
// currentPath can accelerate the finding speed
dirp = file[id].currentDir;
if(( j = dirp->SearchDir( dname, ARCHIVE )) != 0 )
goto foundsubfile;
}
i = 1;
dirp = file[id].root;
while( GetDirName( dname, subname, i ) ){
// printf( "%s: %d, %s\n", subname, i, dname );
// find the subdirectory in the directory tree
if( (j = dirp->SearchDir( dname, DIR_DISK | DIR_RAM )) != 0 ){
if( dirp->items[j].type == DIR_DISK ){
dirtemp = ReadDirFromDisk( fp, dirp->items[j].address, dirp );
if( dirtemp == NULL )
return NULL;
dirp->items[j].address = ( DWORD )dirtemp;
dirp->items[j].type = DIR_RAM;
dirp = dirtemp;
}
else
dirp = ( Directory* )dirp->items[j].address;
}
else{
puts( "not found " );
return NULL;
}
i ++;
}
GetFileName( dname, subname );
#ifdef _DEBUG
puts( dname );
#endif
if((j = dirp->SearchDir( dname, ARCHIVE )) != 0 ){
// find and open the subfile
file[id].currentDir = dirp;
strcpy( file[id].currentPath, path );
foundsubfile:
File* subf = new File;
subf->fp = fp;
subf->address = dirp->items[j].address;
subf->length = dirp->items[j].length;
fseek( fp, subf->address, SEEK_SET );
return subf;
}
else{
fclose( fp );
return NULL;
}
}
// normal file does not occupy PackFile resource
File* PackFile::OpenNormalFile( char* filename )
{
FILE *fp;
if(( fp = fopen( filename, "rb" )) == NULL ){
#ifdef _DEBUG
printf( "in CFil::OpenNormalFile: open file %s error\n", filename );
#endif
return NULL;
}
File *subfp = new File;
if( subfp == NULL )
goto error;
subfp->fp = fp;
subfp->address = 0;
subfp->length = filelength( fileno( fp ));
return subfp;
error:
delete subfp;
fclose( fp );
return NULL;
}
// fname format: packagefilename#directory/subfilename
File* PackFile::Open( char* fname )
{
char *p;
int i, lessuse;
strupr( fname );
if(( p = strchr( fname, '#' )) == NULL )
// the fname isn't a package file's name
return OpenNormalFile( fname );
// fname include package file name, but with no subfile name
if( *( p+1 ) == 0 )
return NULL;
*p = 0;
#ifdef _DEBUG
puts( fname );
#endif
for( i=0; i<MAX_CFILE_NUM; i++ ){
if( strcmp( file[i].fname, fname ) == 0 ){
// package file has been opened
return OpenSubfile( i, p+1 );
}
}
// package file hasn't been opened
for( i=0, lessuse=-1; i<MAX_CFILE_NUM; i++ ){
if( file[i].root == NULL )
lessuse = i;
}
if( lessuse < 0 ) // no space to open package file
return NULL;
OpenCfile( lessuse, fname );
return OpenSubfile( lessuse, p+1 );
}
/*void main( void )
{
puts( "package" );
PackFile cfile;
if( cfile.Open( "d:\\wcpp\\gamedev\\mytext.pak#dat\\wav\\song.wav" ) )
puts( "OK" );
else
puts( "shit" );
CreatePackage( "d:\\wcpp\\gamedev\\vbe\\text.pak", "d:\\wcpp\\gamedev\\vbe\\pic" );
puts( "create packgae" );
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -