mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-04-07 13:55:33 +08:00
fix write compaund files
This commit is contained in:
@ -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;
|
||||
|
||||
@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user