83 MixFilename = mix_filename;
85 FilenameList.Set_Growth_Step (1000);
101 MIXFILE_HEADER header = { 0 };
102 IsValid = (file->
Read( &header,
sizeof( header ) ) ==
sizeof( header ));
108 IsValid = (::memcmp( header.signature,
"MIX1", sizeof ( header.signature ) ) == 0);
117 IsValid = ( file->
Read( &FileCount,
sizeof( FileCount ) ) ==
sizeof( FileCount ) );
124 FileInfo.Resize( FileCount );
125 int size = FileCount *
sizeof( FileInfoStruct );
126 IsValid = ( file->
Read( &FileInfo[0], size ) == size );
134 NamesOffset = header.names_offset;
135 WWDEBUG_SAY((
"MixFileFactory( %s ) loaded successfully %d files\n", MixFilename, FileInfo.Length() ));
143 WWDEBUG_SAY((
"MixFileFactory( %s ) FAILED\n", mix_filename ));
154 if (IsValid ==
false) {
176 if (file->
Read( &file_count,
sizeof( file_count) ) ==
sizeof( file_count )) {
181 bool keep_going =
true;
182 for (
int index = 0; index < file_count && keep_going; index ++) {
189 if (file->
Read( &name_len,
sizeof( name_len ) ) ==
sizeof( name_len )) {
195 if (file->
Read( filename.
Get_Buffer( name_len ), name_len ) == name_len ) {
200 list.
Add( filename );
210 Factory->Return_File( file );
218 if ( FileInfo.Length() == 0 ) {
229 FileInfoStruct * info =
NULL;
230 FileInfoStruct * base = &FileInfo[0];
231 int stride = FileInfo.Length();
233 int pivot = stride / 2;
234 FileInfoStruct * tryptr = base + pivot;
235 if (crc < tryptr->
CRC) {
238 if (tryptr->CRC == crc) {
249 file = (
RawFileClass *)Factory->Get_File( MixFilename );
251 file->
Bias( BaseOffset + info->Offset, info->Size );
263 if ( file !=
NULL ) {
264 Factory->Return_File( file );
276 info.FullPath = full_path;
277 info.Filename = filename;
278 PendingAddFileList.Add (info);
293 for (
int list_index = 0; list_index < FilenameList.Count (); list_index ++) {
294 if (FilenameList[list_index].Compare_No_Case (filename) == 0) {
295 FilenameList.Delete (list_index);
314 if (IsModified ==
false) {
321 char drive[_MAX_DRIVE] = { 0 };
322 char dir[_MAX_DIR] = { 0 };
331 if (Get_Temp_Filename (path, full_path)) {
337 for (
int index = 0; index < FilenameList.Count (); index ++) {
344 if (file_data !=
NULL) {
346 new_mix_file.
Add_File (filename, file_data);
352 for (
int temp_index = 0; temp_index < PendingAddFileList.Count (); temp_index ++) {
353 if (filename.
Compare_No_Case (PendingAddFileList[temp_index].Filename) == 0) {
354 PendingAddFileList.Delete (temp_index);
364 for (index = 0; index < PendingAddFileList.Count (); index ++) {
365 new_mix_file.
Add_File (PendingAddFileList[index].FullPath, PendingAddFileList[index].Filename);
372 ::DeleteFile (MixFilename);
373 ::MoveFile (full_path, MixFilename);
379 PendingAddFileList.Delete_All ();
388MixFileFactoryClass::Get_Temp_Filename (
const char *path,
StringClass &full_path)
393 temp_path +=
"_tmpmix";
398 for (
int index = 0; index < 20; index ++) {
399 full_path.
Format (
"%s%.2d.dat", (
const char *)temp_path, index + 1);
400 if (GetFileAttributes (full_path) == 0xFFFFFFFF) {
413int MixFileFactoryClass::File_Offset_Compare(
const void * a,
const void * b)
415 unsigned int OffsetA = ((FileOffsetStruct*)a)->Offset;
416 unsigned int OffsetB = ((FileOffsetStruct*)b)->Offset;
417 if ( OffsetA < OffsetB )
return -1;
418 if ( OffsetA > OffsetB )
return 1;
428 if (IsValid ==
false) {
441 for (
int i = 0; i < name_list.
Count(); ++i) {
445 temp.
Offset = FileInfo[i].Offset;
446 local_file_info.
Add( temp );
450 if (local_file_info.
Count() > 1) {
451 qsort( &local_file_info[0], local_file_info.
Count(),
sizeof(local_file_info[0]), &File_Offset_Compare);
457 for (i = 0; i < local_file_info.
Count(); ++i) {
458 list.
Add(local_file_info[i].Filename);
471 WWDEBUG_SAY((
"Creating Mix File %s\n", filename ));
474 if ( MixFile !=
NULL ) {
476 MixFile->Write(
"MIX1", 4 );
477 long header_offset = 0;
478 MixFile->Write( &header_offset,
sizeof( header_offset ) );
479 long names_offset = 0;
480 MixFile->Write( &names_offset,
sizeof( names_offset ) );
482 MixFile->Write( &unused,
sizeof( unused ) );
486int MixFileCreator::File_Info_Compare(
const void * a,
const void * b)
488 unsigned int CRCA = ((FileInfoStruct*)a)->CRC;
489 unsigned int CRCB = ((FileInfoStruct*)b)->CRC;
490 if ( CRCA < CRCB )
return -1;
491 if ( CRCA > CRCB )
return 1;
498 if ( MixFile !=
NULL ) {
501 int header_offset = MixFile->Tell();
504 int i,num_files = FileInfo.Count();
505 WWDEBUG_SAY((
"Closing with %d files\n", num_files ));
506 MixFile->Write( &num_files,
sizeof( num_files ) );
508 if ( num_files > 1 ) {
509 qsort( &FileInfo[0], num_files,
sizeof(FileInfo[0]), &File_Info_Compare);
513 for ( i = 0; i < num_files; i++ ) {
514 MixFile->Write( &FileInfo[i].
CRC, 4 );
515 MixFile->Write( &FileInfo[i].Offset, 4 );
516 MixFile->Write( &FileInfo[i].Size, 4 );
523 int names_offset = MixFile->Tell();
526 MixFile->Write( &num_files,
sizeof( num_files ) );
529 for ( i = 0; i < num_files; i++ ) {
530 const char * filename = FileInfo[i].Filename;
531 int size = FileInfo[i].Filename.Get_Length()+1;
533 unsigned char csize = size;
534 MixFile->Write( &csize, 1 );
535 MixFile->Write( filename, size );
543 WWDEBUG_SAY((
"Writing header offset %d (%08X)\n", header_offset, header_offset ));
544 MixFile->Write( &header_offset,
sizeof( header_offset ) );
547 WWDEBUG_SAY((
"Writing names offset %d (%08X)\n", names_offset, names_offset ));
548 MixFile->Write( &names_offset,
sizeof( names_offset ) );
560 if ( saved_filename ==
NULL ) {
561 saved_filename = source_filename;
564 if ( MixFile !=
NULL ) {
572 MixFileCreator::FileInfoStruct info;
574 info.Offset = MixFile->Tell();
575 info.Size = file->
Size();
576 FileInfo.Add( info );
577 FileInfo[ FileInfo.Count()-1 ].Filename = saved_filename;
579 WWDEBUG_SAY((
"Saving File %s CRC %08X Offset %d (0x%08X) Size %d (0x%08X)\n",
580 saved_filename, info.CRC, info.Offset, info.Offset, info.Size, info.Size ));
582 int size = file->
Size();
585 int amount =
MIN(
sizeof( buffer ), size );
587 file->
Read( buffer, amount );
588 if ( MixFile->Write( buffer, amount ) != amount ) {
594 int offset = MixFile->Tell();
595 offset = (8-(offset & 7)) & 7;
597 char zeros[8] = {0,0,0,0,0,0,0,0};
598 if ( MixFile->Write( zeros, offset ) != offset ) {
607 WWDEBUG_SAY((
"MixFileCreator::Failed to open \"%s\"\n", source_filename ));
615 if ( MixFile !=
NULL ) {
617 MixFileCreator::FileInfoStruct info;
619 info.Offset = MixFile->Tell();
620 info.Size = file->
Size();
621 FileInfo.Add( info );
622 FileInfo[ FileInfo.Count()-1 ].Filename = filename;
624 WWDEBUG_SAY((
"Saving File %s CRC %08X Offset %d (0x%08X) Size %d (0x%08X)\n",
625 filename, info.CRC, info.Offset, info.Offset, info.Size, info.Size ));
627 int size = file->
Size();
630 int amount =
MIN(
sizeof( buffer ), size );
632 file->
Read( buffer, amount );
633 if ( MixFile->Write( buffer, amount ) != amount ) {
639 int offset = MixFile->Tell();
640 offset = (8-(offset & 7)) & 7;
642 char zeros[8] = {0,0,0,0,0,0,0,0};
643 if ( MixFile->Write( zeros, offset ) != offset ) {
660 WIN32_FIND_DATA find_info = {0};
662 path.
Format(
"data\\makemix\\%s*.*",
dir );
665 for (hfile_find = ::FindFirstFile( path, &find_info);
666 (hfile_find != INVALID_HANDLE_VALUE) && bcontinue;
667 bcontinue = ::FindNextFile(hfile_find, &find_info)) {
668 if ( find_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
669 if ( find_info.cFileName[0] !=
'.' ) {
671 path.
Format(
"%s%s\\",
dir, find_info.cFileName );
676 name.
Format(
"%s%s",
dir, find_info.cFileName );
678 source.
Format(
"makemix\\%s", name );
unsigned long CRC_Stringi(const char *string, unsigned long crc)
virtual bool Resize(int newsize, T const *array=0)
bool Add(T const &object)
virtual int Seek(int pos, int dir=SEEK_CUR)=0
virtual bool Is_Available(int forced=false)=0
virtual int Read(void *buffer, int size)=0
virtual void Close(void)=0
virtual int Open(char const *filename, int rights=READ)=0
virtual void Return_File(FileClass *file)=0
virtual FileClass * Get_File(char const *filename)=0
MixFileCreator(const char *filename)
void Add_File(const char *source_filename, const char *saved_filename=NULL)
void Delete_File(const char *filename)
virtual void Return_File(FileClass *file)
virtual FileClass * Get_File(char const *filename)
bool Build_Ordered_Filename_List(DynamicVectorClass< StringClass > &list)
void Add_File(const char *full_path, const char *filename)
bool Build_Filename_List(DynamicVectorClass< StringClass > &list)
virtual ~MixFileFactoryClass(void)
MixFileFactoryClass(const char *mix_filename, FileFactoryClass *factory)
virtual void Bias(int start, int length=-1)
virtual int Open(char const *filename, int rights=READ)
virtual int Seek(int pos, int dir=SEEK_CUR)
virtual int Read(void *buffer, int size)
int _cdecl Format(const TCHAR *format,...)
TCHAR * Get_Buffer(int new_length)
int Compare_No_Case(const TCHAR *string) const
void Add_Files(const char *dir, MixFileCreator &mix)
void Setup_Mix_File(void)
SimpleFileFactoryClass _SimpleFileFactory
bool operator!=(const FileOffsetStruct &src)
bool operator==(const FileOffsetStruct &src)