fix write compaund files

This commit is contained in:
ElenaSubbotina
2017-10-20 15:52:09 +03:00
parent 1e0f4d6fdb
commit e299e59d11
14 changed files with 221 additions and 176 deletions

View File

@ -399,13 +399,13 @@ void Header::save( unsigned char* buffer )
{
memset( buffer, 0, 0x4c );
memcpy( buffer, pole_magic, 8 ); // ole signature
writeU32( buffer + 8, 0 ); // unknown
writeU32( buffer + 12, 0 ); // unknown
writeU32( buffer + 16, 0 ); // unknown
writeU16( buffer + 24, 0x003e ); // revision ?
writeU16( buffer + 26, 3 ); // version ?
writeU16( buffer + 28, 0xfffe ); // unknown
writeU16( buffer + 0x1e, (uint32) b_shift );
writeU32( buffer + 8, 0 ); // reserved must be zero
writeU32( buffer + 12, 0 ); // reserved must be zero
writeU32( buffer + 16, 0 ); // reserved must be zero
writeU16( buffer + 24, 0x003e ); // minor version of the format: 33
writeU16( buffer + 26, 3 ); // major version (512 clasters)
writeU16( buffer + 28, 0xfffe ); // indicates Intel byte-ordering
writeU16( buffer + 0x1e, (uint32) b_shift ); //size of sectors in power-of-two
writeU16( buffer + 0x20, (uint32) s_shift );
writeU32( buffer + 0x2c, (uint32) num_bat );
writeU32( buffer + 0x30, (uint32) dirent_start );
@ -415,8 +415,8 @@ void Header::save( unsigned char* buffer )
writeU32( buffer + 0x44, (uint32) mbat_start );
writeU32( buffer + 0x48, (uint32) num_mbat );
for( unsigned int i=0; i<109; i++ )
writeU32( buffer + 0x4C+i*4, (uint32) bb_blocks[i] );
for( unsigned int i = 0; i < 109; i++ )
writeU32( buffer + 0x4C + i * 4, (uint32) bb_blocks[i] );
dirty = false;
}
@ -711,7 +711,7 @@ int64 DirTree::parent( uint64 index )
for( uint64 j=0; j<entryCount(); j++ )
{
std::vector<uint64> chi = children( j );
for( unsigned i=0; i<chi.size();i++ )
for( size_t i=0; i<chi.size();i++ )
if( chi[i] == index )
return j;
}
@ -748,7 +748,7 @@ std::string DirTree::fullName( uint64 index )
// if create is true, a new entry is returned
DirEntry* DirTree::entry( const std::string& name, bool create, int64 bigBlockSize, StorageIO *const io, int64 streamSize)
{
if( !name.length() ) return (DirEntry*)0;
if( name.empty() ) return (DirEntry*)0;
// quick check for "/" (that's root)
if( name == "/" ) return entry( 0 );
@ -778,23 +778,21 @@ DirEntry* DirTree::entry( const std::string& name, bool create, int64 bigBlockSi
{
// find among the children of index
levelsLeft--;
uint64 child = 0;
uint64 child = 0;
/*
// dima: this block is really inefficient
std::vector<unsigned> chi = children( index );
for( unsigned i = 0; i < chi.size(); i++ )
{
DirEntry* ce = entry( chi[i] );
if( ce )
if( ce->valid && ( ce->name.length()>1 ) )
if( ce->name == *it ) {
child = chi[i];
break;
}
}
*/
//std::vector<uint64> chi = children( index );
//for( size_t i = 0; i < chi.size(); i++ )
//{
// DirEntry* ce = entry( chi[i] );
// if( ce )
// if( ce->valid && ( ce->name !="/" ) )
// if( ce->name == *it ) {
// child = chi[i];
// break;
// }
//}
// dima: performance optimisation of the previous
uint64 closest = End;
child = find_child( index, *it, closest );
@ -804,14 +802,14 @@ DirEntry* DirTree::entry( const std::string& name, bool create, int64 bigBlockSi
{
index = child;
}
else
else if( !create || !io->writeable)
{
std::vector<uint64> chi = children( index );
for( unsigned i = 0; i < chi.size(); i++ )
for( size_t i = 0; i < chi.size(); i++ )
{
DirEntry* ce = entry( chi[i] );
if( ce )
if( ce->valid && ( ce->name.length()>1 ) )
if( ce->valid && ( ce->name !="/" )/*( ce->name.length()>1 )*/ )
if( ce->name == *it )
{
child = chi[i];
@ -1502,13 +1500,28 @@ void StorageIO::flush()
void StorageIO::close()
{
if( !opened ) return;
if (writeable)
{
file.seekg(0, std::ios::end );
filesize = static_cast<uint64>(file.tellg());
if (filesize % 512 != 0)
{
char padding[512];
memset(padding, 0, 512);
file.write(padding, (filesize / 512 + 1 ) * 512 - filesize);
fileCheck(file);
}
}
file.close();
opened = false;
std::list<Stream*>::iterator it;
for( it = streams.begin(); it != streams.end(); ++it )
delete *it;
streams.clear();
}
@ -1595,8 +1608,7 @@ bool StorageIO::deleteLeaf(DirEntry *entry, const std::string& fullName)
return true;
}
uint64 StorageIO::loadBigBlocks( std::vector<uint64> blocks,
unsigned char* data, uint64 maxlen )
uint64 StorageIO::loadBigBlocks( std::vector<uint64> blocks, unsigned char* data, uint64 maxlen )
{
// sentinel
if( !data ) return 0;
@ -1624,8 +1636,7 @@ uint64 StorageIO::loadBigBlocks( std::vector<uint64> blocks,
return bytes;
}
uint64 StorageIO::loadBigBlock( uint64 block,
unsigned char* data, uint64 maxlen )
uint64 StorageIO::loadBigBlock( uint64 block, unsigned char* data, uint64 maxlen )
{
// sentinel
if( !data ) return 0;
@ -1651,7 +1662,7 @@ uint64 StorageIO::saveBigBlocks( std::vector<uint64> blocks, uint64 offset, unsi
// write block one by one, seems fast enough
uint64 bytes = 0;
for( unsigned int i=0; (i < blocks.size() ) & ( bytes<len ); i++ )
for( size_t i=0; (i < blocks.size() ) & ( bytes<len ); i++ )
{
uint64 block = blocks[i];
uint64 pos = (bbat->blockSize * ( block+1 ) ) + offset;
@ -1686,8 +1697,7 @@ uint64 StorageIO::saveBigBlock( uint64 block, uint64 offset, unsigned char* data
}
// return number of bytes which has been read
uint64 StorageIO::loadSmallBlocks( std::vector<uint64> blocks,
unsigned char* data, uint64 maxlen )
uint64 StorageIO::loadSmallBlocks( std::vector<uint64> blocks, unsigned char* data, uint64 maxlen )
{
// sentinel
if( !data ) return 0;
@ -1725,8 +1735,7 @@ uint64 StorageIO::loadSmallBlocks( std::vector<uint64> blocks,
return bytes;
}
uint64 StorageIO::loadSmallBlock( uint64 block,
unsigned char* data, uint64 maxlen )
uint64 StorageIO::loadSmallBlock( uint64 block, unsigned char* data, uint64 maxlen )
{
// sentinel
if( !data ) return 0;

View File

@ -189,17 +189,17 @@ bool AddFile2Storage(POLE::Storage* storage, std::string inFile, std::string nam
return true;
}
void AddDir2Storage(POLE::Storage* storage, std::wstring inDir, std::wstring name, int &nFolders, int &nFiles)
void AddDir2Storage(POLE::Storage* storage, std::string inDir, std::string name, int &nFolders, int &nFiles)
{
WIN32_FIND_DATA ffd;
WIN32_FIND_DATAA ffd;
HANDLE h;
std::wstring inDirLcl = inDir + "*";
std::wstring outNameLcl = name;
std::string inDirLcl = inDir + "*";
std::string outNameLcl = name;
const wchar_t *cInDir = inDirLcl.c_str();
h = FindFirstFile(cInDir, &ffd);
const char *cInDir = inDirLcl.c_str();
h = FindFirstFileA(cInDir, &ffd);
if (h == INVALID_HANDLE_VALUE)
return;
nFolders++;
@ -249,7 +249,7 @@ void AddDir2Storage(POLE::Storage* storage, std::wstring inDir, std::wstring nam
nFiles++;
}
}
while (FindNextFile(h, &ffd) != 0);
while (FindNextFileA(h, &ffd) != 0);
}
@ -264,7 +264,10 @@ void cmdOpen(std::list<std::string> &entries)
storage->close();
std::string ssName = entries.front();
entries.pop_front();
storage = new POLE::Storage(ssName.c_str());
std::wstring sName(ssName.begin(), ssName.end());
storage = new POLE::Storage(sName.c_str());
bool bWrite = false;
bool bCreate = false;
if (entries.size() > 0)
@ -313,7 +316,7 @@ void cmdStats(std::list<std::string> &entries)
{
if (storage)
{
unsigned int nDirs, nUUDirs, nBBs, nUUBBs, nSBs, nUUSBs;
unsigned __int64 nDirs, nUUDirs, nBBs, nUUBBs, nSBs, nUUSBs;
storage->GetStats(&nDirs, &nUUDirs, &nBBs, &nUUBBs, &nSBs, &nUUSBs);
printf("%d Directory Entries, %d unused.\n", nDirs, nUUDirs);
printf("%d Big Blocks, %d unused.\n", nBBs, nUUBBs);
@ -334,7 +337,7 @@ void cmdVisit(std::list<std::string> &entries)
}
}
void cmdExtract(std::list<std::wstring> &entries)
void cmdExtract(std::list<std::string> &entries)
{
if (!storage)
std::cout << "No storage is opened." << std::endl;
@ -342,9 +345,9 @@ void cmdExtract(std::list<std::wstring> &entries)
std::cout << "You must specify a path in the open storage to be extracted, and a destination file or folder." << std::endl;
else
{
std::wstring ssPath = entries.front();
std::string ssPath = entries.front();
entries.pop_front();
std::wstring filePath = entries.front();
std::string filePath = entries.front();
if (storage->isDirectory(ssPath))
{
if (filePath[filePath.size()-1] != '/')
@ -366,7 +369,7 @@ void cmdExtract(std::list<std::wstring> &entries)
}
}
void cmdAdd(std::list<std::wstring> &entries)
void cmdAdd(std::list<std::string> &entries)
{
if (!storage)
std::cout << "No storage is opened." << std::endl;
@ -378,9 +381,9 @@ void cmdAdd(std::list<std::wstring> &entries)
std::cout << "The specified storage node already exists - to save it again, first delete it." << std::endl;
else
{
std::wstring ssPath = entries.front();
std::string ssPath = entries.front();
entries.pop_front();
std::wstring filePath = entries.front();
std::string filePath = entries.front();
if (DirectoryExists(filePath.c_str()))
{
if (filePath[filePath.size()-1] != '/')
@ -481,67 +484,77 @@ std::list<std::string> clineParse(std::string inCmd)
return outWords;
}
//int main(int argc, char* argv[])
//{
// if( argc > 1 )
// {
// std::cout << "Usage:" << std::endl;
// std::cout << argv[0] << " This takes no arguments - type help in the console window for information. " << std::endl;
// return 0;
// }
//
// std::string command;
// while (true)
// {
// std::getline(std::cin, command);
// std::list<std::string> entries = clineParse(command);
// if (entries.size() == 0)
// continue;
// std::string cmdWord = entries.front();
// entries.pop_front();
// if (cmdWord.compare("open") == 0)
// cmdOpen(entries);
// else if (cmdWord.compare("visit") == 0)
// cmdVisit(entries);
// else if (cmdWord.compare("extract") == 0)
// cmdExtract(entries);
// else if (cmdWord.compare("add") == 0)
// cmdAdd(entries);
// else if (cmdWord.compare("delete") == 0)
// cmdDelete(entries);
// else if (cmdWord.compare("stats") == 0)
// cmdStats(entries);
// else if (cmdWord.compare("close") == 0)
// cmdClose(entries);
// else if (cmdWord.compare("quit") == 0)
// {
// if (cmdQuit(entries))
// break;
// }
// else
// cmdHelp(entries);
// }
//#if 0
// std::list<std::string>::iterator it;
// for( it = entries.begin(); it != entries.end(); ++it )
// std::cout << *it << std::endl;
// open filename [modifier] (modifier can be r, w, c)
//visit [sspath]
//extract sspath fpath
//add sspath fpath
//delete sspath
//close
//
// std::string indir = argv[1];
// char* outfile = argv[2];
// if (indir[indir.length()-1] != '\\')
// indir += "\\";
// POLE::Storage* storage = new POLE::Storage(outfile);
// storage->open(true, true);
// AddDir2Storage(storage, indir, "/");
// storage->close();
// storage->open();
// visit(0, storage, "/");
// storage->close();
//#endif
//}
int main(int argc, char* argv[])
{
//if( argc > 1 )
//{
// std::cout << "Usage:" << std::endl;
// std::cout << argv[0] << " This takes no arguments - type help in the console window for information. " << std::endl;
// return 0;
//}
std::list<std::string> entries;
entries.push_back("open");
entries.push_back(argv[2]);
entries.push_back("cw");
entries.push_back("add");
entries.push_back("/");
entries.push_back(argv[1]);
entries.push_back("close");
std::string command;
while (true)
{
//std::getline(std::cin, command);
//std::list<std::string> entries = clineParse(command);
if (entries.size() == 0)
continue;
std::string cmdWord = entries.front();
entries.pop_front();
if (cmdWord.compare("open") == 0)
cmdOpen(entries);
else if (cmdWord.compare("visit") == 0)
cmdVisit(entries);
else if (cmdWord.compare("extract") == 0)
cmdExtract(entries);
else if (cmdWord.compare("add") == 0)
cmdAdd(entries);
else if (cmdWord.compare("delete") == 0)
cmdDelete(entries);
else if (cmdWord.compare("stats") == 0)
cmdStats(entries);
else if (cmdWord.compare("close") == 0)
cmdClose(entries);
else if (cmdWord.compare("quit") == 0)
{
if (cmdQuit(entries))
break;
}
else
cmdHelp(entries);
}
#if 0
std::list<std::string>::iterator it;
for( it = entries.begin(); it != entries.end(); ++it )
std::cout << *it << std::endl;
open filename [modifier] (modifier can be r, w, c)
visit [sspath]
extract sspath fpath
add sspath fpath
delete sspath
close
std::string indir = argv[1];
char* outfile = argv[2];
if (indir[indir.length()-1] != '\\')
indir += "\\";
POLE::Storage* storage = new POLE::Storage(outfile);
storage->open(true, true);
AddDir2Storage(storage, indir, "/");
storage->close();
storage->open();
visit(0, storage, "/");
storage->close();
#endif
}