From e33e19d0587146859d48a134ec9fd94e7b7ba5cd Mon Sep 17 00:00:00 2001 From: "FWoltermann@gmail.com" Date: Thu, 8 Dec 2011 14:53:40 +0000 Subject: Initial upload --- Datafile/Archive.cpp | 460 ++++++++++++++++++++++++++++++++++++++++++++++++++ Datafile/Archive.h | 83 +++++++++ Datafile/DataFile.dsp | 112 ++++++++++++ Datafile/DataFile.dsw | 29 ++++ Datafile/DataFile.mak | 231 +++++++++++++++++++++++++ Datafile/DataFile.mdp | Bin 0 -> 34816 bytes Datafile/Main.cpp | 453 +++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 1368 insertions(+) create mode 100644 Datafile/Archive.cpp create mode 100644 Datafile/Archive.h create mode 100644 Datafile/DataFile.dsp create mode 100644 Datafile/DataFile.dsw create mode 100644 Datafile/DataFile.mak create mode 100644 Datafile/DataFile.mdp create mode 100644 Datafile/Main.cpp (limited to 'Datafile') diff --git a/Datafile/Archive.cpp b/Datafile/Archive.cpp new file mode 100644 index 0000000..d9f9088 --- /dev/null +++ b/Datafile/Archive.cpp @@ -0,0 +1,460 @@ +/* Project nGen + John DiCamillo Software Consulting + Copyright © 1997. All Rights Reserved. + + SUBSYSTEM: DataFile.exe + FILE: Archive.cpp + AUTHOR: John DiCamillo + +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "zlib.h" +#include +#include "Archive.h" + +int verbose = 1; +int err; + +#define CHECK_ERR(err, msg) { \ + if (err != Z_OK) { \ + fprintf(stderr, "%s error: %d\n", msg, err); \ + exit(1); \ + } \ +} + +// +--------------------------------------------------------------------+ + +DataArchive::DataArchive(const char* name) +{ + ZeroMemory(this, sizeof(DataArchive)); + + if (name) + LoadDatafile(name); +} + +DataArchive::~DataArchive() +{ + delete [] block_map; +} + +// +--------------------------------------------------------------------+ + +void DataArchive::WriteEntry(int index, BYTE* buf) +{ + int f = _open(datafile, _O_RDWR|_O_CREAT|_O_BINARY, _S_IREAD|_S_IWRITE); + + if (f != -1) { + header.dir_size_comp = DirBlocks() * BLOCK_SIZE; + dirbuf = new BYTE[header.dir_size_comp]; + + err = compress(dirbuf, &header.dir_size_comp, + (BYTE*) directory, header.nfiles * sizeof(DataEntry)); + CHECK_ERR(err, "compress"); + + header.dir_blocks = Blocks(header.dir_size_comp) * BLOCK_SIZE; + + _lseek(f, 0, SEEK_SET); + _write(f, &header, sizeof(DataHeader)); + _lseek(f, sizeof(DataHeader) + header.dir_offset, SEEK_SET); + _write(f, dirbuf, header.dir_blocks); + + delete [] dirbuf; + + if (buf && directory[index].size_comp) { + _lseek(f, sizeof(DataHeader) + directory[index].offset, SEEK_SET); + _write(f, buf, directory[index].size_comp); + } + _close(f); + } + else + perror("WriteEntry"); +} + +// +--------------------------------------------------------------------+ + +DWORD DataArchive::Blocks(DWORD raw_size) +{ + int full_blocks = raw_size / BLOCK_SIZE; + int part_blocks = (raw_size % BLOCK_SIZE) > 0; + + return full_blocks + part_blocks; +} + +DWORD DataArchive::DirBlocks() +{ + DWORD result = Blocks(header.nfiles * sizeof(DataEntry)); + if (result == 0) result = 1; + return result; +} + +DWORD DataArchive::FileBlocks(int index) +{ + return Blocks(directory[index].size_comp); +} + +// +--------------------------------------------------------------------+ + +void DataArchive::CreateBlockMap() +{ + delete [] block_map; + block_map = 0; + + if (header.nfiles == 0) return; + + DWORD i,j; + DWORD dir_usage = header.dir_offset + DirBlocks() * BLOCK_SIZE; + DWORD max_usage = dir_usage; + + for (i = 0; i < header.nfiles; i++) { + DWORD last_block = directory[i].offset + FileBlocks(i) * BLOCK_SIZE; + if (last_block > max_usage) + max_usage = last_block; + } + + nblocks = max_usage/BLOCK_SIZE; + block_map = new DWORD[nblocks]; + ZeroMemory(block_map, nblocks*sizeof(DWORD)); + + DWORD first_block = header.dir_offset/BLOCK_SIZE + + (header.dir_offset%BLOCK_SIZE > 0); + + for (j = 0; j < DirBlocks(); j++) + block_map[first_block+j] = 1; + + for (i = 0; i < header.nfiles; i++) { + DWORD first_block = directory[i].offset/BLOCK_SIZE + + (directory[i].offset%BLOCK_SIZE > 0); + + for (j = 0; j < FileBlocks(i); j++) + block_map[first_block+j] = i+2; + } +} + +// +--------------------------------------------------------------------+ + +int DataArchive::FindDataBlocks(int need) +{ + if ((int) (nblocks)-need > 0) { + DWORD start; + int i; + + for (start = 0; start < nblocks-need; start++) { + for (i = 0; block_map[start+i] == 0 && i < need; i++); + + if (i == need) return start*BLOCK_SIZE; + + start += i; + } + } + + return nblocks*BLOCK_SIZE; +} + +// +--------------------------------------------------------------------+ + +void DataArchive::LoadDatafile(const char* name) +{ + strncpy(datafile, name, NAMELEN-1); + header.nfiles = 0; + + FILE* f = fopen(datafile, "rb"); + if (f) { + fread(&header, sizeof(DataHeader), 1, f); + + if (header.version != VERSION) { + printf("ERROR: datafile '%s' invalid version '%d'\n", + datafile, header.version); + fclose(f); + exit(-2); + } + + DWORD len = DirBlocks() * BLOCK_SIZE; + + dirbuf = new BYTE[len]; + fseek(f, sizeof(DataHeader) + header.dir_offset, SEEK_SET); + fread(dirbuf, header.dir_size_comp, 1, f); + + int err = uncompress((BYTE*) directory, &len, + dirbuf, header.dir_size_comp); + if (err != Z_OK) + ZeroMemory(directory, sizeof(directory)); + + delete [] dirbuf; + CreateBlockMap(); + } + else { + printf("Creating Archive '%s'...\n", datafile); + + header.version = VERSION; + header.nfiles = 0; + header.dir_blocks = 0; + header.dir_size_comp = 0; + header.dir_offset = 0; + + nblocks = DirBlocks(); + + delete [] block_map; + block_map = 0; + } +} + +// +--------------------------------------------------------------------+ + +int DataArchive::FindEntry(const char* req_name) +{ + int entry = -1; + + for (DWORD i = 0; i < header.nfiles; i++) + if (!stricmp(directory[i].name, req_name)) + return i; + + return entry; +} + +// +--------------------------------------------------------------------+ + +BYTE* DataArchive::CompressEntry(int i) +{ + char* name = directory[i].name; + + FILE* f = fopen(name, "rb"); + + if (f) { + fseek(f, 0, SEEK_END); + DWORD len = ftell(f); + fseek(f, 0, SEEK_SET); + + BYTE* buf = new BYTE[len]; + + fread(buf, len, 1, f); + fclose(f); + + directory[i].size_orig = len; + + directory[i].size_comp = (int) (len * 1.1); + BYTE* cbuf = new BYTE[directory[i].size_comp]; + + err = compress(cbuf, &directory[i].size_comp, buf, len); + CHECK_ERR(err, "compress"); + + delete [] buf; + return cbuf; + } + + return 0; +} + +// +--------------------------------------------------------------------+ + +int DataArchive::ExpandEntry(int i, BYTE*& buf) +{ + DWORD len = 0; + + FILE* f = fopen(datafile, "rb"); + + if (f) { + DWORD clen = directory[i].size_comp; + BYTE* cbuf = new BYTE[clen]; + + fseek(f, sizeof(DataHeader) + directory[i].offset, SEEK_SET); + fread(cbuf, clen, 1, f); + + len = directory[i].size_orig; + buf = new BYTE[len]; + + int err = uncompress(buf, &len, cbuf, clen); + if (err != Z_OK) { + delete [] buf; + buf = 0; + } + + delete [] cbuf; + fclose(f); + } + + return len; +} + +// +--------------------------------------------------------------------+ + +int DataArchive::InsertEntry(const char* name) +{ + if (!name) return -1; + + DWORD len = strlen(name); + + for (int i = 0; i < MAX_FILES; i++) { + if (directory[i].size_orig == 0) { + strncpy(directory[i].name, name, NAMELEN); + directory[i].name[NAMELEN-1] = '\0'; + directory[i].size_orig = 1; + + return i; + } + } + + return -1; +} + +// +--------------------------------------------------------------------+ + +void DataArchive::RemoveEntry(int index) +{ + ZeroMemory(&directory[index], sizeof(DataEntry)); +} + +// +--------------------------------------------------------------------+ + +void DataArchive::Insert(const char* name) +{ + DWORD old_blocks = 0, old_offset = 0, new_blocks = 0; + DWORD old_dir_blocks = 0, old_dir_offset = 0, new_dir_blocks = 0; + int added = 0; + + int index = FindEntry(name); + + if (index < 0) { + old_dir_blocks = DirBlocks(); + old_dir_offset = header.dir_offset; + + index = InsertEntry(name); + + if (index >= (int) header.nfiles) { + header.nfiles = index+1; + added = 1; + } + + new_dir_blocks = DirBlocks(); + + if (new_dir_blocks > old_dir_blocks) { + header.dir_offset = FindDataBlocks(new_dir_blocks); + CreateBlockMap(); + } + } + else { + old_blocks = FileBlocks(index); + old_offset = directory[index].offset; + } + + if (index >= 0) { + DataEntry& e = directory[index]; + + if (verbose) printf(" Inserting: %-48s ", e.name); + + BYTE* buf = CompressEntry(index); + + if (!buf) { + // this is (almost) unrecoverable, + // so we quit before screwing things up: + printf("ERROR: Could not compress %d:%s\n", index, directory[index].name); + exit(1); + } + + new_blocks = FileBlocks(index); + + // the file is new, or got bigger, + // need to find room for the data: + if (new_blocks > old_blocks) { + directory[index].offset = FindDataBlocks(new_blocks); + CreateBlockMap(); + } + + WriteEntry(index, buf); + delete [] buf; + + if (verbose) { + int ratio = (int) (100.0 * (double) e.size_comp / (double) e.size_orig); + printf("%9d => %9d (%2d%%)\n", e.size_orig, e.size_comp, ratio); + } + } + else if (added) + header.nfiles--; +} + +// +--------------------------------------------------------------------+ + +void DataArchive::Extract(const char* name) +{ + int index = FindEntry(name); + + if (index < 0) { + printf("Could not extract '%s', not found\n", name); + return; + } + + BYTE* buf; + ExpandEntry(index, buf); + + FILE* f = fopen(directory[index].name, "wb"); + if (f) { + fwrite(buf, directory[index].size_orig, 1, f); + fclose(f); + } + else + printf("Could not extract '%s', could not open file for writing\n", name); + + delete [] buf; + + if (verbose) printf(" Extracted: %s\n", name); +} + +// +--------------------------------------------------------------------+ + +void DataArchive::Remove(const char* name) +{ + int index = FindEntry(name); + + if (index < 0) { + printf("Could not remove '%s', not found\n", name); + return; + } + + RemoveEntry(index); + WriteEntry(index, 0); + + if (verbose) printf(" Removed: %s\n", name); +} + +// +--------------------------------------------------------------------+ + +void DataArchive::List() +{ + int total_orig = 0; + int total_comp = 0; + + printf("DATAFILE: %s\n", datafile); + printf("Files: %d\n", header.nfiles); + printf("\n"); + printf("Index Orig Size Comp Size Ratio Name\n"); + printf("----- --------- --------- ----- ----------------\n"); + + for (DWORD i = 0; i < header.nfiles; i++) { + DataEntry& e = directory[i]; + int ratio = (int) (100.0 * (double) e.size_comp / (double) e.size_orig); + + printf("%5d %9d %9d %2d%% %s\n", i+1, e.size_orig, e.size_comp, ratio, e.name); + + total_orig += e.size_orig; + total_comp += e.size_comp; + } + + int total_ratio = (int) (100.0 * (double) total_comp / (double) total_orig); + + printf("----- --------- --------- -----\n"); + printf("TOTAL %9d %9d %2d%%\n\n", total_orig, total_comp, total_ratio); +} + + +// +--------------------------------------------------------------------+ + diff --git a/Datafile/Archive.h b/Datafile/Archive.h new file mode 100644 index 0000000..f3ec099 --- /dev/null +++ b/Datafile/Archive.h @@ -0,0 +1,83 @@ +/* Project nGen + John DiCamillo Software Consulting + Copyright © 1997. All Rights Reserved. + + SUBSYSTEM: DataFile.exe + FILE: Archive.hpp + AUTHOR: John DiCamillo + +*/ + +#ifndef ARCHIVE_HPP +#define ARCHIVE_HPP + +// +------------------------------------------------------------------+ + +#define VERSION 0x0010 +#define BLOCK_SIZE 1024 +#define MAX_FILES 4096 +#define FILE_BLOCK 1024 +#define NAMELEN 64 + +// +------------------------------------------------------------------+ + +struct DataHeader +{ + DWORD version; + DWORD nfiles; + DWORD dir_blocks; + DWORD dir_size_comp; + DWORD dir_offset; +}; + +struct DataEntry +{ + char name[NAMELEN]; + DWORD size_orig; + DWORD size_comp; + DWORD offset; +}; + +class DataArchive +{ +public: + // ctor: + DataArchive(const char* name = 0); + ~DataArchive(); + + // operations: + void LoadDatafile(const char* name); + void Insert(const char* name); + void Extract(const char* name); + void Remove(const char* name); + void List(); + + void WriteEntry(int index, BYTE* buf); + int FindEntry(const char* req_name); + int ExpandEntry(int index, BYTE*& buf); + BYTE* CompressEntry(int index); + int InsertEntry(const char* name); + void RemoveEntry(int index); + DWORD Blocks(DWORD raw_size); + DWORD DirBlocks(); + DWORD FileBlocks(int index); + int FindDataBlocks(int blocks_needed); + void CreateBlockMap(); + + DWORD NumFiles() { return header.nfiles; } + DataEntry* GetFile(int i) { if (i>=0 && i<(int)header.nfiles) return &directory[i]; return 0; } + +private: + // persistent data members: + DataHeader header; + DataEntry directory[MAX_FILES]; + BYTE* dirbuf; + + // transient members: + char datafile[NAMELEN]; + + DWORD* block_map; + DWORD nblocks; +}; + +#endif diff --git a/Datafile/DataFile.dsp b/Datafile/DataFile.dsp new file mode 100644 index 0000000..66afdf9 --- /dev/null +++ b/Datafile/DataFile.dsp @@ -0,0 +1,112 @@ +# Microsoft Developer Studio Project File - Name="DataFile" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=DataFile - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "DataFile.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "DataFile.mak" CFG="DataFile - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "DataFile - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "DataFile - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "DataFile - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir ".\Release" +# PROP BASE Intermediate_Dir ".\Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir ".\Release" +# PROP Intermediate_Dir ".\Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /W3 /GX /O2 /I "..\zlib" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "DataFile - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir ".\Debug" +# PROP BASE Intermediate_Dir ".\Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir ".\Debug" +# PROP Intermediate_Dir ".\Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\zlib" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 + +!ENDIF + +# Begin Target + +# Name "DataFile - Win32 Release" +# Name "DataFile - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90" +# Begin Source File + +SOURCE=.\Archive.cpp +# End Source File +# Begin Source File + +SOURCE=.\main.cpp +# End Source File +# Begin Source File + +SOURCE=\USERS\MILO\GameDev\zlib\Release\zlib.lib +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd" +# Begin Source File + +SOURCE=.\Archive.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/Datafile/DataFile.dsw b/Datafile/DataFile.dsw new file mode 100644 index 0000000..8a0f764 --- /dev/null +++ b/Datafile/DataFile.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "DataFile"=.\DataFile.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/Datafile/DataFile.mak b/Datafile/DataFile.mak new file mode 100644 index 0000000..765d647 --- /dev/null +++ b/Datafile/DataFile.mak @@ -0,0 +1,231 @@ +# Microsoft Developer Studio Generated NMAKE File, Format Version 4.20 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +!IF "$(CFG)" == "" +CFG=DataFile - Win32 Debug +!MESSAGE No configuration specified. Defaulting to DataFile - Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "DataFile - Win32 Release" && "$(CFG)" !=\ + "DataFile - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE on this makefile +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "DataFile.mak" CFG="DataFile - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "DataFile - Win32 Release" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "DataFile - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF +################################################################################ +# Begin Project +# PROP Target_Last_Scanned "DataFile - Win32 Debug" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "DataFile - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +OUTDIR=.\Release +INTDIR=.\Release + +ALL : "$(OUTDIR)\DataFile.exe" + +CLEAN : + -@erase "$(INTDIR)\Archive.obj" + -@erase "$(INTDIR)\main.obj" + -@erase "$(OUTDIR)\DataFile.exe" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /W3 /GX /O2 /I "../zlib" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +CPP_PROJ=/nologo /ML /W3 /GX /O2 /I "../zlib" /D "WIN32" /D "NDEBUG" /D\ + "_CONSOLE" /Fp"$(INTDIR)/DataFile.pch" /YX /Fo"$(INTDIR)/" /c +CPP_OBJS=.\Release/ +CPP_SBRS=.\. +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/DataFile.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ + odbccp32.lib /nologo /subsystem:console /incremental:no\ + /pdb:"$(OUTDIR)/DataFile.pdb" /machine:I386 /out:"$(OUTDIR)/DataFile.exe" +LINK32_OBJS= \ + "$(INTDIR)\Archive.obj" \ + "$(INTDIR)\main.obj" \ + "..\zlib\Release\zlib.lib" + +"$(OUTDIR)\DataFile.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "DataFile - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +OUTDIR=.\Debug +INTDIR=.\Debug + +ALL : "$(OUTDIR)\DataFile.exe" + +CLEAN : + -@erase "$(INTDIR)\Archive.obj" + -@erase "$(INTDIR)\main.obj" + -@erase "$(INTDIR)\vc40.idb" + -@erase "$(INTDIR)\vc40.pdb" + -@erase "$(OUTDIR)\DataFile.exe" + -@erase "$(OUTDIR)\DataFile.ilk" + -@erase "$(OUTDIR)\DataFile.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "../zlib" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_PROJ=/nologo /MLd /W3 /Gm /GX /Zi /Od /I "../zlib" /D "WIN32" /D "_DEBUG"\ + /D "_CONSOLE" /Fp"$(INTDIR)/DataFile.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/"\ + /c +CPP_OBJS=.\Debug/ +CPP_SBRS=.\. +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/DataFile.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ + odbccp32.lib /nologo /subsystem:console /incremental:yes\ + /pdb:"$(OUTDIR)/DataFile.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)/DataFile.exe" +LINK32_OBJS= \ + "$(INTDIR)\Archive.obj" \ + "$(INTDIR)\main.obj" \ + "..\zlib\Release\zlib.lib" + +"$(OUTDIR)\DataFile.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.c{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +################################################################################ +# Begin Target + +# Name "DataFile - Win32 Release" +# Name "DataFile - Win32 Debug" + +!IF "$(CFG)" == "DataFile - Win32 Release" + +!ELSEIF "$(CFG)" == "DataFile - Win32 Debug" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE=.\main.cpp +DEP_CPP_MAIN_=\ + ".\Archive.hpp"\ + + +"$(INTDIR)\main.obj" : $(SOURCE) $(DEP_CPP_MAIN_) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=\USERS\MILO\GameDev\zlib\Release\zlib.lib + +!IF "$(CFG)" == "DataFile - Win32 Release" + +!ELSEIF "$(CFG)" == "DataFile - Win32 Debug" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Archive.cpp +DEP_CPP_ARCHI=\ + "..\zlib\zconf.h"\ + ".\../zlib\zlib.h"\ + ".\Archive.hpp"\ + {$(INCLUDE)}"\sys\stat.h"\ + {$(INCLUDE)}"\sys\types.h"\ + + +"$(INTDIR)\Archive.obj" : $(SOURCE) $(DEP_CPP_ARCHI) "$(INTDIR)" + + +# End Source File +# End Target +# End Project +################################################################################ diff --git a/Datafile/DataFile.mdp b/Datafile/DataFile.mdp new file mode 100644 index 0000000..25c0627 Binary files /dev/null and b/Datafile/DataFile.mdp differ diff --git a/Datafile/Main.cpp b/Datafile/Main.cpp new file mode 100644 index 0000000..dd4370b --- /dev/null +++ b/Datafile/Main.cpp @@ -0,0 +1,453 @@ +/* Project nGen + John DiCamillo Software Consulting + Copyright © 1997. All Rights Reserved. + + SUBSYSTEM: DataFile.exe + FILE: main.cpp + AUTHOR: John DiCamillo + +*/ + +#include +#include +#include +#include +#include +#include +#include "Archive.h" + +//#define MOD_MAKER 1 + +// +------------------------------------------------------------------+ + +void insertFile(DataArchive& a, const char* sPath, WIN32_FIND_DATA* find) +{ + char sFile[256]; + char sFlat[256]; + DWORD find_attrib_forbidden = + FILE_ATTRIBUTE_DIRECTORY | + FILE_ATTRIBUTE_HIDDEN | + FILE_ATTRIBUTE_SYSTEM | + FILE_ATTRIBUTE_OFFLINE; + + if (sPath && *sPath) + sprintf(sFile, "%s/%s", sPath, find->cFileName); + else + strcpy(sFile, find->cFileName); + + if (find->dwFileAttributes & find_attrib_forbidden) { + printf(" Skipping: %-48s \n", sFile); + return; + } + + int n = strlen(sFile); + + if (n >= NAMELEN) { + printf(" Skipping: %-48s (NAME TOO LONG!)\n", sFile); + return; + } + + for (int i = 0; i < n; i++) + sFlat[i] = tolower(sFile[i]); + + if (strstr(sFlat, ".exe")) { + printf(" Skipping: %-48s (executable file)\n", sFile); + } + else if (strstr(sFlat, ".cmd")) { + printf(" Skipping: %-48s (executable file)\n", sFile); + } + else if (strstr(sFlat, ".bat")) { + printf(" Skipping: %-48s (executable file)\n", sFile); + } + else if (strstr(sFlat, ".bin")) { + printf(" Skipping: %-48s (unknown file)\n", sFile); + } + else if (strstr(sFlat, ".db")) { + printf(" Skipping: %-48s (unknown file)\n", sFile); + } + else if (strstr(sFlat, ".dat")) { + printf(" Skipping: %-48s (data file)\n", sFile); + } + else if (strstr(sFlat, ".zip")) { + printf(" Skipping: %-48s (zip file)\n", sFile); + } + else if (strstr(sFlat, ".arc")) { + printf(" Skipping: %-48s (archive file)\n", sFile); + } + else if (strstr(sFlat, ".psd")) { + printf(" Skipping: %-48s (PSD file)\n", sFile); + } + else { + a.Insert(sFile); + } +} + +// +------------------------------------------------------------------+ + +void ins(DataArchive& a, int argc, char* argv[]) +{ + char sPath[256]; + char* pDirSep = 0; + + for (int i = 0; i < argc; i++) { + if (strchr(argv[i], '*')) { + strcpy(sPath, argv[i]); + + if ((pDirSep = strrchr(sPath, '\\')) != 0) + *pDirSep = 0; + + else if ((pDirSep = strrchr(sPath, '/')) != 0) + *pDirSep = 0; + + else + sPath[0] = 0; + + WIN32_FIND_DATA find; + HANDLE h = FindFirstFile(argv[i], &find); + if (h != INVALID_HANDLE_VALUE) { + insertFile(a, sPath, &find); + + while (FindNextFile(h,&find)) { + insertFile(a, sPath, &find); + } + + FindClose(h); + } + } + else { + a.Insert(argv[i]); + } + } +} + +// +--------------------------------------------------------------------+ + +void build(DataArchive& a, const char* sBasePath); + +void buildFile(DataArchive& a, const char* sPath, WIN32_FIND_DATA& find) +{ + if (find.cFileName[0] == '.') { + } + + else if (find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + char subdir[256]; + if (sPath && *sPath) + sprintf(subdir, "%s/%s", sPath, find.cFileName); + else + sprintf(subdir, "%s", find.cFileName); + + build(a, subdir); + } + + else { + insertFile(a, sPath, &find); + } +} + +void build(DataArchive& a, const char* sBasePath) +{ + char sPath[256]; + char sFind[256]; + + if (sBasePath && *sBasePath) { + strcpy(sPath, sBasePath); + sprintf(sFind, "%s\\*.*", sPath); + } + else { + sPath[0] = 0; + strcpy(sFind, "*.*"); + } + + WIN32_FIND_DATA find; + HANDLE h = FindFirstFile(sFind, &find); + if (h != INVALID_HANDLE_VALUE) { + do + buildFile(a, sPath, find); + + while (FindNextFile(h, &find)); + + FindClose(h); + } +} + +void mak(DataArchive& a) +{ + build(a, 0); +} + +// +--------------------------------------------------------------------+ +// for now, pattern must be either "*" or "*.???" + +int match(const char* sFile, const char* sPattern) +{ + int nPatternType = 0; + char* sExt = 0; + + const int PATTERN_NOWILD = 0; + const int PATTERN_STAR = 1; + const int PATTERN_STAR_DOT_STAR = 2; + const int PATTERN_STAR_DOT_EXT = 3; + + // what kind of pattern matching? + if (strchr(sPattern, '*')) { + if (strchr(sPattern, '.')) { + if (strcmp(sPattern, "*.*") == 0) { + nPatternType = PATTERN_STAR_DOT_STAR; + } + else { + nPatternType = PATTERN_STAR_DOT_EXT; + sExt = strchr(sPattern, '.'); + } + } + + else { + nPatternType = PATTERN_STAR; + } + } + + int file_matches_pattern = 0; + + switch (nPatternType) { + case PATTERN_NOWILD: + default: + file_matches_pattern = (stricmp(sFile, sPattern) == 0); + break; + + + case PATTERN_STAR: + case PATTERN_STAR_DOT_STAR: + file_matches_pattern = 1; + break; + + case PATTERN_STAR_DOT_EXT: + file_matches_pattern = (strstr(sFile, sExt) != 0); + break; + } + + return file_matches_pattern; +} + +void ext(DataArchive& a, int argc, char* argv[]) +{ + if (argc) { + char sPath[256]; + char sPatt[256]; + char* pDirSep; + int nPath; + + for (int i = 0; i < argc; i++) { + if (strchr(argv[i], '*')) { + strcpy(sPath, argv[i]); + + if ((pDirSep = strrchr(sPath, '\\')) != 0) { + strcpy(sPatt, pDirSep+1); + *pDirSep = 0; + nPath = strlen(sPath); + } + + else if ((pDirSep = strrchr(sPath, '/')) != 0) { + strcpy(sPatt, pDirSep+1); + *pDirSep = 0; + nPath = strlen(sPath); + } + + else { + strcpy(sPatt, sPath); + sPath[0] = 0; + nPath = 0; + } + + // for each file in the archive: + for (unsigned j = 0; j < a.NumFiles(); j++) { + DataEntry* pde = a.GetFile(j); + + if (pde) { + // if we are extracting from a sub-directory, + if (nPath) { + // and this file is in the sub-directory, + if (strnicmp(pde->name, sPath, nPath) == 0) { + // and this file matches the pattern: + if (match(pde->name+nPath+1, sPatt)) { + char sName[256]; + strcpy(sName, pde->name); + a.Extract(sName); + } + } + } + + // if we are extracting from the main directory, + else { + // and this file is in the main directory, + if (strchr(pde->name, '/') == 0) { + // and this file matches the pattern: + if (match(pde->name, sPatt)) { + char sName[256]; + strcpy(sName, pde->name); + a.Extract(sName); + } + } + } + } + } + } + + else { + // for each file in the archive: + for (unsigned j = 0; j < a.NumFiles(); j++) { + DataEntry* pde = a.GetFile(j); + + if (pde) { + if (stricmp(pde->name, argv[i]) == 0) { + a.Extract(argv[i]); + } + } + } + } + } + } + + // full archive extraction: + else { + for (int i = 0; i < (int)a.NumFiles(); i++) + a.Extract(a.GetFile(i)->name); + } +} + +void del(DataArchive& a, int argc, char* argv[]) +{ + char sPath[256]; + char sPatt[256]; + char* pDirSep; + int nPath; + + for (int i = 0; i < argc; i++) { + if (strchr(argv[i], '*')) { + strcpy(sPath, argv[i]); + + if ((pDirSep = strrchr(sPath, '\\')) != 0) { + strcpy(sPatt, pDirSep+1); + *pDirSep = 0; + nPath = strlen(sPath); + } + + else if ((pDirSep = strrchr(sPath, '/')) != 0) { + strcpy(sPatt, pDirSep+1); + *pDirSep = 0; + nPath = strlen(sPath); + } + + else { + strcpy(sPatt, sPath); + sPath[0] = 0; + nPath = 0; + } + + // for each file in the archive: + for (unsigned j = 0; j < a.NumFiles(); j++) { + DataEntry* pde = a.GetFile(j); + + if (pde) { + // if we are deleting from a sub-directory, + if (nPath) { + // and this file is in the sub-directory, + if (strnicmp(pde->name, sPath, nPath) == 0) { + // and this file matches the pattern: + if (match(pde->name+nPath+1, sPatt)) { + char sName[256]; + strcpy(sName, pde->name); + a.Remove(sName); + } + } + } + + // if we are deleting from the main directory, + else { + // and this file is in the main directory, + if (strchr(pde->name, '/') == 0) { + // and this file matches the pattern: + if (match(pde->name, sPatt)) { + char sName[256]; + strcpy(sName, pde->name); + a.Remove(sName); + } + } + } + } + } + } + + else { + a.Remove(argv[i]); + } + } +} + + +// +--------------------------------------------------------------------+ + +void Usage() +{ + printf("Usage: datafile -option \n"); + printf("options: -ins (insert files into datafile)\n"); + printf(" -ext (extract files from datafile)\n"); + printf(" -del (delete files from datafile)\n"); + printf(" -mak (insert all files in current directory and all subdirectories)\n"); + printf(" -list (display list of entries in datafile)\n"); + + exit(-1); +} + +#define OPT_NONE 0 +#define OPT_INS 1 +#define OPT_EXT 2 +#define OPT_DEL 3 +#define OPT_MAK 4 +#define OPT_LIST 5 + +int main(int argc, char* argv[]) +{ +#ifdef MOD_MAKER + printf("MODFILE\n"); + + if (argc < 2) { + printf("Usage: modfile \n"); + return 0; + } + + ::unlink(argv[1]); + DataArchive a(argv[1]); + mak(a); + + return 0; +#else + printf("DATAFILE\n"); + + if (argc < 3) + Usage(); + + DataArchive a(argv[1]); + int option = OPT_NONE; + + if (!stricmp(argv[2], "-ins")) option = OPT_INS; + else if (!stricmp(argv[2], "-ext")) option = OPT_EXT; + else if (!stricmp(argv[2], "-del")) option = OPT_DEL; + else if (!stricmp(argv[2], "-mak")) option = OPT_MAK; + else if (!stricmp(argv[2], "-list")) option = OPT_LIST; + + argc -= 3; + argv += 3; + + switch (option) { + default: + case OPT_NONE: Usage(); break; + case OPT_INS: ins(a, argc, argv); break; + case OPT_EXT: ext(a, argc, argv); break; + case OPT_DEL: del(a, argc, argv); break; + case OPT_MAK: mak(a); break; + case OPT_LIST: a.List(); break; + } +#endif + + return 0; +} + -- cgit v1.1