271 lines
8.3 KiB
C++
271 lines
8.3 KiB
C++
#include <mediapak/mediapak.hpp>
|
|
#include <mediapak/entryinf.hpp>
|
|
#include <mediapak/entryhdr.hpp>
|
|
#include <common/profile.hpp>
|
|
|
|
MediaPak::MediaPak(void)
|
|
: mEntries(0), mOffsetEntries(0)
|
|
{
|
|
}
|
|
|
|
MediaPak::MediaPak(const MediaPak &mediaPak)
|
|
{
|
|
*this=mediaPak;
|
|
}
|
|
|
|
MediaPak::~MediaPak()
|
|
{
|
|
close();
|
|
}
|
|
|
|
MediaPak &MediaPak::operator=(const MediaPak &/*mediaPak*/)
|
|
{ // private implementation
|
|
return *this;
|
|
}
|
|
|
|
BOOL MediaPak::open(const String &pathFileName,Mode openMode)
|
|
{
|
|
DWORD magic;
|
|
|
|
mPakFile.close();
|
|
mEntries=0;
|
|
if(CreateAlways==openMode)
|
|
{
|
|
mPakFile.open(pathFileName,FileHandle::ReadWrite,FileHandle::ShareRead,FileHandle::Overwrite);
|
|
if(!mPakFile.isOkay())return FALSE;
|
|
magic=HeaderMagic;
|
|
mEntries=0;
|
|
mPakFile.write((unsigned char*)&magic,sizeof(magic));
|
|
mOffsetEntries=mPakFile.tell();
|
|
mPakFile.write((unsigned char*)&mEntries,sizeof(mEntries));
|
|
}
|
|
else if(OpenExisting==openMode)
|
|
{
|
|
mPakFile.open(pathFileName,FileHandle::ReadWrite,FileHandle::ShareRead,FileHandle::Open);
|
|
if(!mPakFile.isOkay())return FALSE;
|
|
mPakFile.read((unsigned char*)&magic,sizeof(magic));
|
|
mOffsetEntries=mPakFile.tell();
|
|
if(magic!=HeaderMagic){mPakFile.close();return FALSE;}
|
|
mPakFile.read((unsigned char*)&mEntries,sizeof(mEntries));
|
|
}
|
|
else // OpenAlways
|
|
{
|
|
if(mPakFile.open(pathFileName,FileHandle::ReadWrite,FileHandle::ShareRead,FileHandle::Open))
|
|
{
|
|
if(!mPakFile.isOkay())return FALSE;
|
|
mPakFile.read((unsigned char*)&magic,sizeof(magic));
|
|
mOffsetEntries=mPakFile.tell();
|
|
if(magic!=HeaderMagic){mPakFile.close();return FALSE;}
|
|
mPakFile.read((unsigned char*)&mEntries,sizeof(mEntries));
|
|
}
|
|
else
|
|
{
|
|
mPakFile.open(pathFileName,FileHandle::ReadWrite,FileHandle::ShareRead,FileHandle::Mode(FileHandle::Create));
|
|
if(!mPakFile.isOkay())return FALSE;
|
|
magic=HeaderMagic;
|
|
mEntries=0;
|
|
mPakFile.write((unsigned char*)&magic,sizeof(magic));
|
|
mOffsetEntries=mPakFile.tell();
|
|
mPakFile.write((unsigned char*)&mEntries,sizeof(mEntries));
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void MediaPak::close(void)
|
|
{
|
|
if(!mPakFile.isOkay())return;
|
|
mPakFile.close();
|
|
}
|
|
|
|
BOOL MediaPak::add(const String &strPathFileName)
|
|
{
|
|
PakEntry::EntryType entryType;
|
|
PakEntry pakEntry;
|
|
String strExtension;
|
|
String strName;
|
|
FileHandle inFile;
|
|
Profile iniProfile;
|
|
|
|
if(!isOkay()||strPathFileName.isNull())return FALSE;
|
|
strExtension=strPathFileName.betweenString('.',0);
|
|
if(strExtension.isNull())return FALSE;
|
|
inFile.open(strPathFileName);
|
|
if(!inFile.isOkay())return FALSE;
|
|
strExtension.upper();
|
|
if(strExtension==String("BMP"))pakEntry.type(PakEntry::Bitmap);
|
|
else if(strExtension==String("WAV"))pakEntry.type(PakEntry::Sound);
|
|
else pakEntry.type(PakEntry::Blob);
|
|
strName=strPathFileName;
|
|
iniProfile.makeFileName(strName);
|
|
pakEntry.name(strName);
|
|
pakEntry.id(entries()+1);
|
|
pakEntry.rawData().size(inFile.size());
|
|
inFile.read((BYTE*)&(pakEntry.rawData()[0]),pakEntry.rawData().size());
|
|
inFile.close();
|
|
return add(pakEntry);
|
|
}
|
|
|
|
BOOL MediaPak::add(const PakEntry &pakEntry)
|
|
{
|
|
DWORD entryLength;
|
|
|
|
if(!isOkay())return FALSE;
|
|
mPakFile.seek(mOffsetEntries,FileHandle::SeekBegin);
|
|
mPakFile.read((unsigned char*)&mEntries,sizeof(mEntries));
|
|
for(int index=0;index<mEntries;index++)
|
|
{
|
|
mPakFile.read((unsigned char*)&entryLength,sizeof(entryLength));
|
|
mPakFile.seek(entryLength,FileHandle::SeekCurrent);
|
|
}
|
|
entryLength=sizeof(int)+sizeof(int)+sizeof(int)+sizeof(int)+pakEntry.name().length()+((PakEntry&)pakEntry).rawData().size(); // sizeof(int)+
|
|
mPakFile.write((unsigned char*)&entryLength,sizeof(entryLength));
|
|
mPakFile.write((DWORD)pakEntry.type());
|
|
mPakFile.write((DWORD)pakEntry.id());
|
|
mPakFile.write((DWORD)pakEntry.name().length());
|
|
mPakFile.write((unsigned char*)(char*)pakEntry.name(),pakEntry.name().length());
|
|
mPakFile.write(((PakEntry&)pakEntry).rawData().size());
|
|
mPakFile.write((unsigned char*)(BYTE*)&(((PakEntry&)pakEntry).rawData()[0]),((PakEntry&)pakEntry).rawData().size());
|
|
mEntries++;
|
|
mPakFile.seek(mOffsetEntries,FileHandle::SeekBegin);
|
|
mPakFile.write(mEntries);
|
|
return FALSE;
|
|
}
|
|
|
|
DWORD MediaPak::entries(void)const
|
|
{
|
|
return mEntries;
|
|
}
|
|
|
|
BOOL MediaPak::getEntry(PakEntry &pakEntry,DWORD entryIndex)
|
|
{
|
|
EntryHeader entryHeader;
|
|
String entryName;
|
|
int entryLength;
|
|
int workData;
|
|
|
|
if(!mPakFile.isOkay())return FALSE;
|
|
mPakFile.seek(mOffsetEntries,FileHandle::SeekBegin);
|
|
mPakFile.read((unsigned char*)&mEntries,sizeof(mEntries));
|
|
if(entryIndex>=mEntries)return FALSE;
|
|
for(int index=0;index<entryIndex;index++)
|
|
{
|
|
mPakFile.read((unsigned char*)&entryLength,sizeof(entryLength));
|
|
mPakFile.seek(entryLength,FileHandle::SeekCurrent);
|
|
}
|
|
if(!mEntries)return FALSE;
|
|
entryHeader.read(mPakFile);
|
|
pakEntry.type(PakEntry::EntryType(entryHeader.entryType()));
|
|
pakEntry.id(entryHeader.entryID());
|
|
entryName.reserve(entryHeader.entryNameLength()+1);
|
|
mPakFile.read((unsigned char *)(char*)entryName,entryHeader.entryNameLength());
|
|
pakEntry.name(entryName);
|
|
mPakFile.read((unsigned char*)&workData,sizeof(workData));
|
|
pakEntry.rawData().size(workData);
|
|
mPakFile.read((unsigned char*)(BYTE*)&(pakEntry.rawData()[0]),workData);
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL MediaPak::getEntry(WaveForm &waveForm,DWORD entryIndex)
|
|
{
|
|
EntryHeader entryHeader;
|
|
PakEntry pakEntry;
|
|
String entryName;
|
|
int entryLength;
|
|
int workData;
|
|
|
|
if(!mPakFile.isOkay())return FALSE;
|
|
mPakFile.seek(mOffsetEntries,FileHandle::SeekBegin);
|
|
mPakFile.read((unsigned char*)&mEntries,sizeof(mEntries));
|
|
if(entryIndex>=mEntries)return FALSE;
|
|
for(int index=0;index<entryIndex;index++)
|
|
{
|
|
mPakFile.read((unsigned char*)&entryLength,sizeof(entryLength));
|
|
mPakFile.seek(entryLength,FileHandle::SeekCurrent);
|
|
}
|
|
if(!mEntries)return FALSE;
|
|
entryHeader.read(mPakFile);
|
|
pakEntry.type(PakEntry::EntryType(entryHeader.entryType()));
|
|
pakEntry.id(entryHeader.entryID());
|
|
entryName.reserve(entryHeader.entryNameLength()+1);
|
|
if(PakEntry::Sound!=pakEntry.type())return FALSE;
|
|
mPakFile.read((unsigned char *)(char*)entryName,entryHeader.entryNameLength());
|
|
pakEntry.name(entryName);
|
|
mPakFile.read((unsigned char*)&workData,sizeof(workData));
|
|
pakEntry.rawData().size(workData);
|
|
return waveForm.read(mPakFile);
|
|
/// return waveForm<<mPakFile;
|
|
}
|
|
|
|
BOOL MediaPak::isOkay(void)const
|
|
{
|
|
return mPakFile.isOkay();
|
|
}
|
|
|
|
// ***********************
|
|
|
|
BOOL MediaPak::getInfo(EntryInfo &entryInfo,DWORD entryIndex)
|
|
{
|
|
String entryName;
|
|
int entryLength;
|
|
int workData;
|
|
|
|
if(!mPakFile.isOkay())return FALSE;
|
|
mPakFile.seek(mOffsetEntries,FileHandle::SeekBegin);
|
|
mPakFile.read((unsigned char*)&mEntries,sizeof(mEntries));
|
|
if(entryIndex>=mEntries)return FALSE;
|
|
for(int index=0;index<entryIndex;index++)
|
|
{
|
|
mPakFile.read((unsigned char*)&entryLength,sizeof(entryLength));
|
|
mPakFile.seek(entryLength,FileHandle::SeekCurrent);
|
|
}
|
|
if(!mEntries)return FALSE;
|
|
mPakFile.read((unsigned char*)&entryLength,sizeof(entryLength));
|
|
mPakFile.read((unsigned char*)&workData,sizeof(workData));
|
|
entryInfo.type(PakEntry::EntryType(workData));
|
|
mPakFile.read((unsigned char*)&workData,sizeof(workData));
|
|
mPakFile.read((unsigned char*)&workData,sizeof(workData));
|
|
entryName.reserve(workData+1);
|
|
mPakFile.read((unsigned char *)(char*)entryName,workData);
|
|
entryInfo.name(entryName);
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL MediaPak::getInfo(Array<EntryInfo> &entryInfoArray)
|
|
{
|
|
String entryName;
|
|
int entryLength;
|
|
int workData;
|
|
|
|
if(!mPakFile.isOkay())return FALSE;
|
|
mPakFile.seek(mOffsetEntries,FileHandle::SeekBegin);
|
|
mPakFile.read((unsigned char*)&mEntries,sizeof(mEntries));
|
|
if(!mEntries)return FALSE;
|
|
entryInfoArray.size(mEntries);
|
|
for(int index=0;index<mEntries;index++)
|
|
{
|
|
mPakFile.read((unsigned char*)&entryLength,sizeof(entryLength));
|
|
mPakFile.read((unsigned char*)&workData,sizeof(workData));
|
|
entryInfoArray[index].type(PakEntry::EntryType(workData));
|
|
mPakFile.read((unsigned char*)&workData,sizeof(workData));
|
|
mPakFile.read((unsigned char*)&workData,sizeof(workData));
|
|
entryName.reserve(workData+1);
|
|
mPakFile.read((unsigned char *)(char*)entryName,workData);
|
|
entryInfoArray[index].name(entryName);
|
|
if(index==mEntries-1)break;
|
|
mPakFile.read((unsigned char*)&workData,sizeof(workData));
|
|
mPakFile.seek(workData,FileHandle::SeekCurrent);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
// "MPAK0100" 40h,50h,41h,4Bh
|
|
// ENTRIES DD
|
|
// SIZE DD { THIS IS SIZEOF(TYPE)+SIZEOF(OFFSET)+SIZEOF(NAME)+SIZEOF(DATA)
|
|
// TYPE DD {SOUND=0,BITMAP=1,BLOB=2}
|
|
// OFFSET DD
|
|
// NAME { LENGTH DD, NAMEBYTES DB }
|
|
// DATA
|
|
|
|
|