📄 file.cpp
字号:
#include <direct.h>
#include <errno.h>
#include <fcntl.h>
#include <io.h>
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#include "gl.h"
#define UPROUND( a, b ) ((a)+((b)-1))/(b)*(b)
#define DIRITEM_UNIT 64
#define NONE 0
#define ARCHIVE 1
#define DIR_DISK 2
#define DIR_RAM 4
PackFile cfile;
Directory* PackSubdir( DWORD& fp, char *dpath, char *spath );
/////////////////////////////////////////////////////////////////////
Directory::~Directory()
{
delete[] items;
}
// read directory from disk
int Directory::ReadDisk( FILE *fp )
{
if( items )
delete[] items;
fread( &cur, sizeof( long ), 1, fp );
fread( &num, sizeof( long ), 1, fp );
fread( &items, sizeof( DirItem* ), 1, fp );
items = new DirItem[num];
if( items == NULL )
return -1;
for( int i=0; i<num; i++ ){
fread( &items[i].type, sizeof( BYTE ), 1, fp );
fread( items[i].filename, 13, 1, fp );
// puts( items[i].filename );
fread( &items[i].address, sizeof( DWORD ), 1, fp );
fread( &items[i].length, sizeof( DWORD ), 1, fp );
}
if( errno ){
delete[] items;
return -1;
}
return 0;
}
// whether the dname is in this directory
int Directory::SearchDir( char dname[13], int type )
{
if( strcmp( items[cur].filename, dname ) == 0
&& ( items[cur].type & type ))
return cur;
for( int i=2; i<num; i++ ){
if( strcmp( items[i].filename, dname ) == 0
&& ( items[i].type & type ))
return i;
}
return 0;
}
/////////////////////////////////////////////////////////////////////
File::File(){
fp = NULL;
count = 0;
};
File::~File()
{
if( fp != NULL )
fclose( fp );
}
int File::Close( void ){
if( fp ) return fclose( fp );
return -1;
}
char* File::Gets( char* buf, int size )
{
fpos_t pos1, pos2;
char *temp;
fgetpos( fp, &pos1 );
temp = fgets( buf, size, fp );
fgetpos( fp, &pos2 );
count += (DWORD)(pos2 - pos1);
return temp;
}
int File::Getw( void )
{
int w;
if( length - count - 2 < 0 )
return EOF;
count += fread( &w, 1, 2, fp );
return w;
}
int File::Getdw( void )
{
int dw;
if( length - count - 4 < 0 )
return EOF;
count += fread( &dw, 1, 4, fp );
return dw;
}
int File::Read( void* buffer, DWORD size )
{
int rs;
if( length - count - size < 0 )
size = length - count;
rs = fread( buffer, 1, size, fp );
count += rs;
return rs;
}
int File::Seek( DWORD d, int mode )
{
switch( mode ){
case SEEK_SET:
break;
case SEEK_CUR:
default:
d += count;
break;
case SEEK_END:
d += length - 1;
break;
}
if( d > length ){
d = length - count - 1;
count = length - 1;
}
else if( d < 0 ){
d = 0 - count;
count = 0;
}
else{
d = d - count;
count += d;
}
return fseek( fp, d, SEEK_CUR );
fpos_t t;
fgetpos( fp, &t );
printf( "fpos: %u\n", t );
return 0;
}
/////////////////////////////////////////////////////////////////////
// helper functions
int FileCount( char *path )
{
_finddata_t fd;
long hFile;
int i = 0;
if(( hFile = _findfirst( "*.*", &fd )) == -1 )
return 0;
i++;
while( (_findnext( hFile, &fd )) == 0 ){
if( fd.name[0] != '.' )
i++;
}
return i;
}
int GetDirName( char* dname, char* fullname, int level )
{
if( level <= 0 ){
dname[0] = 0;
return false;
}
char *temp = fullname;
while( *fullname ){
if( *fullname == '\\' ){
level --;
if( level == 0 ){
while( *temp != '\\' )
*dname++ = *temp ++;
*dname = 0;
return true;
}
temp = fullname + 1;
}
fullname ++;
}
return false;
}
int GetFileName( char* dname, char *fullname )
{
char *temp = fullname;
while( *fullname ){
if( *fullname == '\\' )
temp = fullname + 1;
fullname ++;
}
while( *temp )
*dname++ = *temp++;
*dname = 0;
return true;
}
int GetPathName( char* dname, char *fullname )
{
char *temp = NULL, *pname = fullname;
while( *pname ){
if( *pname == '\\' )
temp = pname;
pname ++;
}
pname = fullname;
while( pname <= temp )
*dname++ = *pname++;
*dname = 0;
return true;
}
/////////////////////////////////////////////////////////////////////
//将一个目录下的所有文件(包括子目录)打包成一个文件.
/////////////////////////////////////////////////////////////////////
// filename: destination package filename
// mode: CFILE_APPEND, CFILE_DELETE, CFILE_CREATE
static int WriteDirToDisk( FILE *fp, Directory *dir )
{
FILE *file;
int j;
Directory *dirtemp;
fwrite( &(dir->cur), sizeof( long ), 1, fp );
fwrite( &(dir->num), sizeof( long ), 1, fp );
fwrite( &(dir->items), sizeof( DirItem* ), 1, fp );
// write items[0] to disk
fwrite( &(dir->items[0].type), sizeof( BYTE ), 1, fp );
fwrite( dir->items[0].filename, 13, 1, fp );
fwrite( &(dir->items[0].address), sizeof( DWORD ), 1, fp );
fwrite( &(dir->items[0].length), sizeof( DWORD ), 1, fp );
// write items[1] to disk
fwrite( &(dir->items[1].type), sizeof( BYTE ), 1, fp );
fwrite( dir->items[1].filename, 13, 1, fp );
dirtemp = ( Directory* )(dir->items[1].address);
if( dirtemp )
fwrite( &(dirtemp->items[0].address), sizeof( DWORD ), 1, fp );
else
fwrite( &(dir->items[1].address), sizeof( DWORD ), 1, fp );
fwrite( &(dir->items[1].length), sizeof( DWORD ), 1, fp );
for( int i=2; i<dir->num; i++ ){
if( dir->items[i].type == DIR_DISK ){
fwrite( &(dir->items[i].type), sizeof( BYTE ), 1, fp );
fwrite( dir->items[i].filename, 13, 1, fp );
dirtemp = ( Directory* )dir->items[i].address;
fwrite( &(dirtemp->items[0].address), sizeof( DWORD ), 1, fp );
fwrite( &(dir->items[i].length), sizeof( DWORD ), 1, fp );
}
else{
fwrite( &(dir->items[i].type), sizeof( BYTE ), 1, fp );
fwrite( dir->items[i].filename, 13, 1, fp );
fwrite( &(dir->items[i].address), sizeof( DWORD ), 1, fp );
fwrite( &(dir->items[i].length), sizeof( DWORD ), 1, fp );
}
}
char *buf = new char[4096];
if( buf == NULL )
return -1;
for( i=2; i<dir->num; i++ ){
if( dir->items[i].type == ARCHIVE ){
puts( dir->items[i].filename );
fflush( fp );
if( ( file = fopen( dir->items[i].filename, "rb" )) == NULL )
return -1;
fseek( fp, dir->items[i].address, SEEK_SET );
while( (j = fread( buf, 1, 4096, file )) != 0 )
fwrite( buf, 1, j, fp );
fclose( file );
}
}
if( errno )
return -1;
return 0;
}
int CreatePackage( char *filename, char *spath )
{
FILE *fp;
Directory *dirp, *dirtemp, *dirsave;
char *curPath;
DWORD fpos = 0;
if( (fp = fopen( filename, "wb+" )) == NULL )
return -1;
if( (curPath = getcwd( NULL, 0 )) == NULL )
return -1;
if( chdir( spath ) != 0 )
return -1;
dirp = PackSubdir( fpos, "\\", "." );
dirsave = dirp;
dirp->items[0].address = dirp->items[1].address = 0;
dirp->cur = 2;
//create dirctory tree first
while( 1 ){
while( dirp->cur < dirp->num ){
if( dirp->items[dirp->cur].type == DIR_DISK ){
chdir( dirp->items[dirp->cur].filename );
dirtemp = PackSubdir( fpos, dirp->items[dirp->cur].filename, "." );
if( dirtemp == NULL )
return -1;
dirtemp->items[1].address = ( DWORD )dirp;
dirtemp->items[1].length = dirp->items[0].length;
dirp->items[dirp->cur].address = ( DWORD )dirtemp;
dirp->items[dirp->cur].length = dirtemp->items[0].length;
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;
chdir( ".." );
}
// then, we write directory tree and its files to disk
puts( "write to disk." );
dirp = dirsave;
dirp->cur = 2;
chdir( spath );
WriteDirToDisk( fp, dirp );
while( 1 ){
while( dirp->cur < dirp->num ){
if( dirp->items[dirp->cur].type == DIR_DISK ){
chdir( dirp->items[dirp->cur].filename );
dirtemp = ( Directory* )dirp->items[dirp->cur].address;
dirp = dirtemp;
dirp->cur = 2;
WriteDirToDisk( fp, dirtemp );
}
else
dirp->cur ++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -