mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-07-20 03:08:28 +08:00
new Stream for StreamView
This commit is contained in:
@ -73,7 +73,7 @@ void CFStream::CopyFrom(const Stream &input)
|
||||
|
||||
// if (input.CanSeek)
|
||||
{
|
||||
input->seekg(0, std::ios::beg);
|
||||
input->seek(0, std::ios::beg);
|
||||
}
|
||||
|
||||
input->read(reinterpret_cast<char*>(buffer.data()), Length(input));
|
||||
|
||||
@ -100,7 +100,7 @@ void CompoundFile::Commit(bool releaseMemory)
|
||||
if (header->majorVersion != (ushort)CFSVersion::Ver_3)
|
||||
CheckForLockSector();
|
||||
|
||||
sourceStream->seekp(0, std::ios::beg);
|
||||
sourceStream->seek(0, std::ios::beg);
|
||||
|
||||
std::vector<char> zeroArray(sSize, 0);
|
||||
sourceStream->write(zeroArray.data(), zeroArray.size());
|
||||
@ -122,7 +122,7 @@ void CompoundFile::Commit(bool releaseMemory)
|
||||
if (s.get() != nullptr && s->dirtyFlag)
|
||||
{
|
||||
if (gap)
|
||||
sourceStream->seekp((long)((long)(sSize) + (long)i * (long)sSize), std::ios::beg);
|
||||
sourceStream->seek((long)((long)(sSize) + (long)i * (long)sSize), std::ios::beg);
|
||||
|
||||
sourceStream->write(reinterpret_cast<char*>(s->GetData().data()), sSize);
|
||||
sourceStream->flush();
|
||||
@ -146,7 +146,7 @@ void CompoundFile::Commit(bool releaseMemory)
|
||||
|
||||
|
||||
// Seek to beginning position and save header (first 512 or 4096 bytes)
|
||||
sourceStream->seekg(0, std::ios::beg);
|
||||
sourceStream->seek(0, std::ios::beg);
|
||||
header->Write(sourceStream);
|
||||
|
||||
// sourceStream-> SetLength((long)(sectors.Count + 1) * sSize);
|
||||
@ -208,7 +208,6 @@ void CompoundFile::Load(Stream stream)
|
||||
|
||||
|
||||
sectors.Clear();
|
||||
auto pos = stream->tellg();
|
||||
//sectors = new ArrayList();
|
||||
for (int i = 0; i < n_sector; i++)
|
||||
{
|
||||
@ -221,9 +220,9 @@ void CompoundFile::Load(Stream stream)
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
if (std::dynamic_pointer_cast<std::fstream>(stream) != nullptr && stream.get() != nullptr && closeStream)
|
||||
if (stream && closeStream)
|
||||
{
|
||||
std::static_pointer_cast<std::fstream>(stream)->close();
|
||||
stream->close();
|
||||
}
|
||||
|
||||
throw;
|
||||
@ -235,12 +234,7 @@ void CompoundFile::Save(std::wstring wFileName)
|
||||
if (_disposed)
|
||||
throw CFException("Compound File closed: cannot save data");
|
||||
|
||||
BYTE* pUtf8 = NULL;
|
||||
LONG lLen = 0;
|
||||
NSFile::CUtf8Converter::GetUtf8StringFromUnicode(wFileName.c_str(), wFileName.length(), pUtf8, lLen, false);
|
||||
std::string utf8FileName = std::string(pUtf8, pUtf8 + lLen);
|
||||
delete [] pUtf8;
|
||||
Stream fs(new std::fstream(utf8FileName, std::ios::out));
|
||||
Stream fs = OpenFileStream(wFileName, std::ios::out);
|
||||
|
||||
try
|
||||
{
|
||||
@ -256,7 +250,7 @@ void CompoundFile::Save(std::wstring wFileName)
|
||||
fs->flush();
|
||||
|
||||
if (fs.get() != nullptr)
|
||||
static_cast<std::fstream*>(fs.get())->close();
|
||||
fs->close();
|
||||
|
||||
}
|
||||
}
|
||||
@ -304,7 +298,7 @@ void CompoundFile::Save(Stream stream)
|
||||
|
||||
}
|
||||
|
||||
stream->seekp(0, std::ios::beg);
|
||||
stream->seek(0, std::ios::beg);
|
||||
header->Write(stream);
|
||||
}
|
||||
catch (std::exception &ex)
|
||||
@ -369,7 +363,7 @@ SVector<Sector> CompoundFile::GetFatSectorChain()
|
||||
|
||||
while ((int)result.size() < header->fatSectorsNumber)
|
||||
{
|
||||
difatStream->Read(nextDIFATSectorBuffer, 0, 4); // IsLittleEndian ?
|
||||
difatStream->read(nextDIFATSectorBuffer, 4); // IsLittleEndian ?
|
||||
nextSecID = *reinterpret_cast<int*>(nextDIFATSectorBuffer);
|
||||
|
||||
EnsureUniqueSectorIndex(nextSecID, processedSectors);
|
||||
@ -386,14 +380,14 @@ SVector<Sector> CompoundFile::GetFatSectorChain()
|
||||
|
||||
result.push_back(s);
|
||||
|
||||
//difatStream.Read(nextDIFATSectorBuffer, 0, 4);
|
||||
//difatStream.Read(nextDIFATSectorBuffer, 4);
|
||||
//nextSecID = BitConverter.ToInt32(nextDIFATSectorBuffer, 0);
|
||||
|
||||
|
||||
if (difatStream->position == ((GetSectorSize() - 4) + i * GetSectorSize()))
|
||||
{
|
||||
// Skip DIFAT chain fields considering the possibility that the last FAT entry has been already read
|
||||
difatStream->Read(nextDIFATSectorBuffer, 0, 4);
|
||||
difatStream->read(nextDIFATSectorBuffer, 4);
|
||||
if (*reinterpret_cast<const int*>(nextDIFATSectorBuffer) == Sector::ENDOFCHAIN)
|
||||
break;
|
||||
else
|
||||
@ -507,7 +501,7 @@ SVector<Sector> CompoundFile::GetNormalSectorChain(int secID)
|
||||
|
||||
result.push_back(s);
|
||||
|
||||
fatStream.Seek(nextSecID * 4, std::ios::beg);
|
||||
fatStream.seek(nextSecID * 4, std::ios::beg);
|
||||
int next = fatStream.ReadInt32();
|
||||
|
||||
EnsureUniqueSectorIndex(next, processedSectors);
|
||||
@ -550,12 +544,12 @@ SVector<Sector> CompoundFile::GetMiniSectorChain(int secID)
|
||||
ms->id = nextSecID;
|
||||
ms->type = SectorType::Mini;
|
||||
|
||||
miniStreamView.Seek(nextSecID * Sector::MINISECTOR_SIZE, std::ios::beg);
|
||||
miniStreamView.Read(reinterpret_cast<char*>(ms->GetData().data()), 0, Sector::MINISECTOR_SIZE);
|
||||
miniStreamView.seek(nextSecID * Sector::MINISECTOR_SIZE, std::ios::beg);
|
||||
miniStreamView.read(reinterpret_cast<char*>(ms->GetData().data()), Sector::MINISECTOR_SIZE);
|
||||
|
||||
result.push_back(ms);
|
||||
|
||||
miniFATView.Seek(nextSecID * 4, std::ios::beg);
|
||||
miniFATView.seek(nextSecID * 4, std::ios::beg);
|
||||
int next = miniFATView.ReadInt32();
|
||||
|
||||
nextSecID = next;
|
||||
@ -853,8 +847,8 @@ void CompoundFile::FreeMiniChain(SVector<Sector> §orChain, int nth_sector_to
|
||||
if (s->id != -1)
|
||||
{
|
||||
// Overwrite
|
||||
miniStreamView.Seek(Sector::MINISECTOR_SIZE * s->id, std::ios::beg);
|
||||
miniStreamView.Write(ZEROED_MINI_SECTOR.data(), 0, Sector::MINISECTOR_SIZE);
|
||||
miniStreamView.seek(Sector::MINISECTOR_SIZE * s->id, std::ios::beg);
|
||||
miniStreamView.write(ZEROED_MINI_SECTOR.data(), Sector::MINISECTOR_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -864,21 +858,21 @@ void CompoundFile::FreeMiniChain(SVector<Sector> §orChain, int nth_sector_to
|
||||
{
|
||||
int currentId = sectorChain[i]->id;
|
||||
|
||||
miniFATView.Seek(currentId * 4, std::ios::beg);
|
||||
miniFATView.seek(currentId * 4, std::ios::beg);
|
||||
const int freesec = Sector::FREESECT;
|
||||
miniFATView.Write(reinterpret_cast<const char*>(&freesec), 0, 4);
|
||||
miniFATView.write(reinterpret_cast<const char*>(&freesec), 4);
|
||||
}
|
||||
|
||||
// Write End of Chain in MiniFAT ---------------------------------------
|
||||
//miniFATView.Seek(sectorChain[(sectorChain.Count - 1) - nth_sector_to_remove].Id * SIZE_OF_SID, SeekOrigin.Begin);
|
||||
//miniFATView.Write(BitConverter.GetBytes(Sector.ENDOFCHAIN), 0, 4);
|
||||
//miniFATView.Write(BitConverter.GetBytes(Sector.ENDOFCHAIN), 4);
|
||||
|
||||
// Write End of Chain in MiniFAT ---------------------------------------
|
||||
if (nth_sector_to_remove > 0 && sectorChain.size() > 0)
|
||||
{
|
||||
miniFATView.Seek(sectorChain[nth_sector_to_remove - 1]->id * 4, std::ios::beg);
|
||||
miniFATView.seek(sectorChain[nth_sector_to_remove - 1]->id * 4, std::ios::beg);
|
||||
const int endofchain = Sector::ENDOFCHAIN;
|
||||
miniFATView.Write(reinterpret_cast<const char*>(&endofchain), 0, 4);
|
||||
miniFATView.write(reinterpret_cast<const char*>(&endofchain), 4);
|
||||
}
|
||||
|
||||
// Update sector chains ---------------------------------------
|
||||
@ -919,17 +913,17 @@ void CompoundFile::FreeChain(SVector<Sector> §orChain, int nth_sector_to_rem
|
||||
{
|
||||
int currentId = sectorChain[i]->id;
|
||||
|
||||
FATView.Seek(currentId * 4, std::ios::beg);
|
||||
FATView.seek(currentId * 4, std::ios::beg);
|
||||
const int freesec = Sector::FREESECT;
|
||||
FATView.Write(reinterpret_cast<const char*>(&freesec), 0, 4);
|
||||
FATView.write(reinterpret_cast<const char*>(&freesec), 4);
|
||||
}
|
||||
|
||||
// Write new end of chain if partial free ----------
|
||||
if (nth_sector_to_remove > 0 && sectorChain.size() > 0)
|
||||
{
|
||||
FATView.Seek(sectorChain[nth_sector_to_remove - 1]->id * 4, std::ios::beg);
|
||||
FATView.seek(sectorChain[nth_sector_to_remove - 1]->id * 4, std::ios::beg);
|
||||
const int endofchain = Sector::ENDOFCHAIN;
|
||||
FATView.Write(reinterpret_cast<const char*>(&endofchain), 0, 4);
|
||||
FATView.write(reinterpret_cast<const char*>(&endofchain), 4);
|
||||
}
|
||||
}
|
||||
|
||||
@ -974,13 +968,13 @@ void CompoundFile::AllocateFATSectorChain(SVector<Sector> §orChain)
|
||||
auto sN = sectorChain[i + 1];
|
||||
auto sC = sectorChain[i];
|
||||
|
||||
fatStream.Seek(sC->id * 4, std::ios::beg);
|
||||
fatStream.Write(reinterpret_cast<const char*>(&(sN->id)), 0, 4);
|
||||
fatStream.seek(sC->id * 4, std::ios::beg);
|
||||
fatStream.write(reinterpret_cast<const char*>(&(sN->id)), 4);
|
||||
}
|
||||
|
||||
fatStream.Seek(sectorChain[sectorChain.size() - 1]->id * 4, std::ios::beg);
|
||||
fatStream.seek(sectorChain[sectorChain.size() - 1]->id * 4, std::ios::beg);
|
||||
const int endofchain = Sector::ENDOFCHAIN;
|
||||
fatStream.Write(reinterpret_cast<const char*>(&endofchain), 0, 4);
|
||||
fatStream.write(reinterpret_cast<const char*>(&endofchain), 4);
|
||||
|
||||
// Merge chain to CFS
|
||||
AllocateDIFATSectorChain(fatStream.BaseSectorChain());
|
||||
@ -1061,10 +1055,10 @@ void CompoundFile::AllocateDIFATSectorChain(SVector<Sector> &FATsectorChain)
|
||||
// room for DIFAT chaining at the end of any DIFAT sector (4 bytes)
|
||||
if (i != HEADER_DIFAT_ENTRIES_COUNT && (i - HEADER_DIFAT_ENTRIES_COUNT) % DIFAT_SECTOR_FAT_ENTRIES_COUNT == 0)
|
||||
{
|
||||
difatStream.Write(reinterpret_cast<const char*>(0L), 0, sizeof(int));
|
||||
difatStream.write(reinterpret_cast<const char*>(0L), sizeof(int));
|
||||
}
|
||||
|
||||
difatStream.Write(reinterpret_cast<const char*>(&FATsectorChain[i]->id), 0, sizeof(int));
|
||||
difatStream.write(reinterpret_cast<const char*>(&FATsectorChain[i]->id), sizeof(int));
|
||||
|
||||
}
|
||||
}
|
||||
@ -1115,20 +1109,20 @@ void CompoundFile::AllocateDIFATSectorChain(SVector<Sector> &FATsectorChain)
|
||||
|
||||
for (int i = 0; i < (int)header->difatSectorsNumber; i++)
|
||||
{
|
||||
fatSv.Seek(difatStream.BaseSectorChain()[i]->id * 4, std::ios::beg);
|
||||
fatSv.seek(difatStream.BaseSectorChain()[i]->id * 4, std::ios::beg);
|
||||
const int difsect = Sector::DIFSECT;
|
||||
fatSv.Write(reinterpret_cast<const char*>(&difsect), 0, 4);
|
||||
fatSv.write(reinterpret_cast<const char*>(&difsect), 4);
|
||||
}
|
||||
|
||||
for (int i = 0; i < header->fatSectorsNumber; i++)
|
||||
{
|
||||
fatSv.Seek(fatSv.BaseSectorChain()[i]->id * 4, std::ios::beg);
|
||||
fatSv.seek(fatSv.BaseSectorChain()[i]->id * 4, std::ios::beg);
|
||||
const int fatsect = Sector::FATSECT;
|
||||
fatSv.Write(reinterpret_cast<const char*>(&fatsect), 0, 4);
|
||||
fatSv.write(reinterpret_cast<const char*>(&fatsect), 4);
|
||||
}
|
||||
|
||||
//fatSv.Seek(fatSv.BaseSectorChain[fatSv.BaseSectorChain.Count - 1].Id * 4, SeekOrigin.Begin);
|
||||
//fatSv.Write(BitConverter.GetBytes(Sector.ENDOFCHAIN), 0, 4);
|
||||
//fatSv.Write(BitConverter.GetBytes(Sector.ENDOFCHAIN), 4);
|
||||
|
||||
header->fatSectorsNumber = fatSv.BaseSectorChain().size();
|
||||
}
|
||||
@ -1170,7 +1164,7 @@ void CompoundFile::AllocateMiniSectorChain(SVector<Sector> §orChain)
|
||||
// Allocate, position ministream at the end of already allocated
|
||||
// ministream's sectors
|
||||
|
||||
miniStreamView.Seek(rootStorage->size() + Sector::MINISECTOR_SIZE, std::ios::beg);
|
||||
miniStreamView.seek(rootStorage->size() + Sector::MINISECTOR_SIZE, std::ios::beg);
|
||||
//miniStreamView.Write(s.GetData(), 0, Sector.MINISECTOR_SIZE);
|
||||
s->id = (int)(miniStreamView.position - Sector::MINISECTOR_SIZE) / Sector::MINISECTOR_SIZE;
|
||||
|
||||
@ -1184,14 +1178,14 @@ void CompoundFile::AllocateMiniSectorChain(SVector<Sector> §orChain)
|
||||
int currentId = sectorChain[i]->id;
|
||||
int nextId = sectorChain[i + 1]->id;
|
||||
|
||||
miniFATView.Seek(currentId * 4, std::ios::beg);
|
||||
miniFATView.Write(reinterpret_cast<const char*>(&nextId), 0, 4);
|
||||
miniFATView.seek(currentId * 4, std::ios::beg);
|
||||
miniFATView.write(reinterpret_cast<const char*>(&nextId), 4);
|
||||
}
|
||||
|
||||
// Write End of Chain in MiniFAT
|
||||
miniFATView.Seek(sectorChain[sectorChain.size() - 1]->id * SIZE_OF_SID, std::ios::beg);
|
||||
miniFATView.seek(sectorChain[sectorChain.size() - 1]->id * SIZE_OF_SID, std::ios::beg);
|
||||
const int endofchain = Sector::ENDOFCHAIN;
|
||||
miniFATView.Write(reinterpret_cast<const char*>(&endofchain), 0, 4);
|
||||
miniFATView.write(reinterpret_cast<const char*>(&endofchain), 4);
|
||||
|
||||
// Update sector chains
|
||||
AllocateSectorChain(miniStreamView.BaseSectorChain());
|
||||
@ -1225,8 +1219,8 @@ void CompoundFile::PersistMiniStreamToStream(const SVector<Sector> &miniSectorCh
|
||||
throw CFException("Invalid minisector index");
|
||||
|
||||
// Ministream sectors already allocated
|
||||
miniStreamView.Seek(Sector::MINISECTOR_SIZE * s->id, std::ios::beg);
|
||||
miniStreamView.Write(reinterpret_cast<const char*>(s->GetData().data()), 0, Sector::MINISECTOR_SIZE);
|
||||
miniStreamView.seek(Sector::MINISECTOR_SIZE * s->id, std::ios::beg);
|
||||
miniStreamView.write(reinterpret_cast<const char*>(s->GetData().data()), Sector::MINISECTOR_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1472,13 +1466,13 @@ void CompoundFile::SetStreamLength(std::shared_ptr<CFItem> cfItem, std::streamsi
|
||||
//Copy old to new chain
|
||||
while (toRead > cnt)
|
||||
{
|
||||
cnt = sv->Read(buf.data(), 0, cnt);
|
||||
cnt = sv->read(buf.data(), cnt);
|
||||
toRead -= cnt;
|
||||
destSv.Write(buf.data(), 0, cnt);
|
||||
destSv.write(buf.data(), cnt);
|
||||
}
|
||||
|
||||
sv->Read(buf.data(), 0, (int)toRead);
|
||||
destSv.Write(buf.data(), 0, (int)toRead);
|
||||
sv->read(buf.data(), (int)toRead);
|
||||
destSv.write(buf.data(), (int)toRead);
|
||||
|
||||
//Free old chain
|
||||
FreeChain(oldChain, eraseFreeSectors);
|
||||
@ -1523,13 +1517,13 @@ void CompoundFile::SetStreamLength(std::shared_ptr<CFItem> cfItem, std::streamsi
|
||||
//Copy old to new chain
|
||||
while (toRead > cnt)
|
||||
{
|
||||
cnt = sv->Read(buf.data(), 0, cnt);
|
||||
cnt = sv->read(buf.data(), cnt);
|
||||
toRead -= cnt;
|
||||
destSv.Write(buf.data(), 0, cnt);
|
||||
destSv.write(buf.data(), cnt);
|
||||
}
|
||||
|
||||
sv->Read(buf.data(), 0, (int)toRead);
|
||||
destSv.Write(buf.data(), 0, (int)toRead);
|
||||
sv->read(buf.data(), (int)toRead);
|
||||
destSv.write(buf.data(), (int)toRead);
|
||||
|
||||
//Free old mini chain
|
||||
int oldChainCount = oldChain.size();
|
||||
@ -1614,8 +1608,8 @@ SList<Sector> CompoundFile::FindFreeSectors(SectorType sType)
|
||||
ms->id = idx;
|
||||
ms->type = SectorType::Mini;
|
||||
|
||||
miniStreamView.Seek(ms->id * Sector::MINISECTOR_SIZE, std::ios::beg);
|
||||
miniStreamView.Read(reinterpret_cast<char*>(ms->GetData().data()), 0, Sector::MINISECTOR_SIZE);
|
||||
miniStreamView.seek(ms->id * Sector::MINISECTOR_SIZE, std::ios::beg);
|
||||
miniStreamView.read(reinterpret_cast<char*>(ms->GetData().data()), Sector::MINISECTOR_SIZE);
|
||||
|
||||
freeList.enqueue(ms);
|
||||
}
|
||||
@ -1650,7 +1644,7 @@ std::vector<BYTE> CompoundFile::GetData(const CFStream *cFStream)
|
||||
sourceStream);
|
||||
|
||||
result.reserve(de.lock()->getSize());
|
||||
miniView.Read(reinterpret_cast<char*>(result.data()), 0, result.size());
|
||||
miniView.read(reinterpret_cast<char*>(result.data()), result.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1658,7 +1652,7 @@ std::vector<BYTE> CompoundFile::GetData(const CFStream *cFStream)
|
||||
|
||||
result.reserve((int)de.lock()->getSize());
|
||||
|
||||
sView.Read(reinterpret_cast<char*>(result.data()), 0, result.size());
|
||||
sView.read(reinterpret_cast<char*>(result.data()), result.size());
|
||||
|
||||
}
|
||||
|
||||
@ -1688,8 +1682,8 @@ int CompoundFile::ReadData(CFStream *cFStream, std::streamsize position, std::ve
|
||||
}
|
||||
|
||||
|
||||
sView->Seek(position, std::ios::beg);
|
||||
int result = sView->Read(reinterpret_cast<char*>(buffer.data()), 0, count);
|
||||
sView->seek(position, std::ios::beg);
|
||||
int result = sView->read(reinterpret_cast<char*>(buffer.data()), count);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -1713,8 +1707,8 @@ int CompoundFile::ReadData(CFStream *cFStream, std::streamsize position, std::ve
|
||||
}
|
||||
|
||||
|
||||
sView->Seek(position, std::ios::beg);
|
||||
int result = sView->Read(reinterpret_cast<char*>(buffer.data()), offset, count);
|
||||
sView->seek(position, std::ios::beg);
|
||||
int result = sView->read(reinterpret_cast<char*>(buffer.data() + offset), count);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -1734,13 +1728,13 @@ std::vector<BYTE> CompoundFile::GetDataBySID(int sid)
|
||||
{
|
||||
StreamView miniView(GetSectorChain(de->getStartSetc(), SectorType::Mini), Sector::MINISECTOR_SIZE, de->getSize(), zeroQueue, sourceStream);
|
||||
result.reserve(de->getSize());
|
||||
miniView.Read(reinterpret_cast<char*>(result.data()),0 , result.size());
|
||||
miniView.read(reinterpret_cast<char*>(result.data()), result.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
StreamView sView(GetSectorChain(de->getStartSetc(), SectorType::Normal), GetSectorSize(), de->getSize(), zeroQueue, sourceStream);
|
||||
result.reserve(de->getSize());
|
||||
sView.Read(reinterpret_cast<char*>(result.data()),0 , result.size());
|
||||
sView.read(reinterpret_cast<char*>(result.data()), result.size());
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
@ -1805,8 +1799,8 @@ void CompoundFile::WriteData(std::shared_ptr<CFItem> cfItem, const std::vector<B
|
||||
SList<Sector> zeroQueue;
|
||||
StreamView sv(sectorChain, _sectorSize, newLength, zeroQueue, sourceStream);
|
||||
|
||||
sv.Seek(position, std::ios::beg);
|
||||
sv.Write(reinterpret_cast<const char*>(buffer.data()), offset, count);
|
||||
sv.seek(position, std::ios::beg);
|
||||
sv.write(reinterpret_cast<const char*>(buffer.data() + offset), count);
|
||||
|
||||
if (cfItem->size() < header->minSizeStandardStream)
|
||||
{
|
||||
@ -1839,11 +1833,9 @@ void CompoundFile::Dispose(bool disposing)
|
||||
fileName.clear();
|
||||
}
|
||||
|
||||
if (std::dynamic_pointer_cast<std::fstream>(sourceStream) != nullptr &&
|
||||
closeStream && !(configuration & CFSConfiguration::LeaveOpen))
|
||||
{
|
||||
std::static_pointer_cast<std::fstream>(sourceStream)->close();
|
||||
}
|
||||
if (sourceStream && closeStream && !(configuration & CFSConfiguration::LeaveOpen))
|
||||
sourceStream->close();
|
||||
|
||||
}
|
||||
}
|
||||
//finally
|
||||
@ -1863,9 +1855,9 @@ void CompoundFile::CheckForLockSector()
|
||||
{
|
||||
StreamView fatStream(GetFatSectorChain(), GetSectorSize(), sourceStream);
|
||||
|
||||
fatStream.Seek(_lockSectorId * 4, std::ios::beg);
|
||||
fatStream.seek(_lockSectorId * 4, std::ios::beg);
|
||||
const int endofchain = Sector::ENDOFCHAIN;
|
||||
fatStream.Write(reinterpret_cast<const char*>(&endofchain), 0, 4);
|
||||
fatStream.write(reinterpret_cast<const char*>(&endofchain), 4);
|
||||
|
||||
_transactionLockAllocated = true;
|
||||
}
|
||||
@ -1878,7 +1870,7 @@ void CompoundFile::LoadFile(std::wstring fileName)
|
||||
|
||||
try
|
||||
{
|
||||
fs = OpenStream(fileName, updateMode != CFSUpdateMode::ReadOnly);
|
||||
fs = OpenFileStream(fileName, updateMode != CFSUpdateMode::ReadOnly);
|
||||
|
||||
Load(fs);
|
||||
|
||||
@ -1886,7 +1878,7 @@ void CompoundFile::LoadFile(std::wstring fileName)
|
||||
catch(...)
|
||||
{
|
||||
if (fs.get() != nullptr)
|
||||
fs->clear(); // close
|
||||
fs->close();
|
||||
|
||||
throw;
|
||||
}
|
||||
@ -1911,7 +1903,7 @@ void CompoundFile::LoadStream(Stream stream)
|
||||
throw CFException("Cannot load a non-seekable Stream");
|
||||
|
||||
|
||||
stream->seekp(0, std::ios::beg);
|
||||
stream->seek(0, std::ios::beg);
|
||||
|
||||
Load(stream);
|
||||
}
|
||||
|
||||
@ -76,7 +76,7 @@ std::vector<BYTE> &Sector::GetData()
|
||||
data = std::vector<BYTE>(size, 0);
|
||||
if (IsStreamed())
|
||||
{
|
||||
stream->seekg(size + id * size, std::ios_base::beg);
|
||||
stream->seek(size + id * size, std::ios_base::beg);
|
||||
stream->read(reinterpret_cast<char*>(data.data()), size);
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,15 +8,15 @@ std::streamsize CFCPP::Length(const CFCPP::Stream& st)
|
||||
if (st.get() == nullptr)
|
||||
return 0;
|
||||
|
||||
auto curPos = st->tellg();
|
||||
st->seekg(0, std::ios_base::end);
|
||||
auto ssize = st->tellg();
|
||||
st->seekg(curPos);
|
||||
auto curPos = st->tell();
|
||||
st->seek(0, std::ios_base::end);
|
||||
auto ssize = st->tell();
|
||||
st->seek(curPos);
|
||||
|
||||
return ssize;
|
||||
}
|
||||
|
||||
CFCPP::Stream CFCPP::OpenStream(std::wstring filename, bool bRewrite)
|
||||
CFCPP::Stream CFCPP::OpenFileStream(std::wstring filename, bool bRewrite)
|
||||
{
|
||||
BYTE* pUtf8 = nullptr;
|
||||
std::streamsize lLen = 0;
|
||||
@ -24,29 +24,26 @@ CFCPP::Stream CFCPP::OpenStream(std::wstring filename, bool bRewrite)
|
||||
std::string utf8filename(pUtf8, pUtf8 + lLen);
|
||||
delete [] pUtf8;
|
||||
|
||||
return OpenStream(utf8filename, bRewrite);
|
||||
return OpenFileStream(utf8filename, bRewrite);
|
||||
}
|
||||
|
||||
CFCPP::Stream CFCPP::OpenStream(std::string filename, bool bRewrite)
|
||||
CFCPP::Stream CFCPP::OpenFileStream(std::string filename, bool bRewrite)
|
||||
{
|
||||
filename = CorrectUnixPath(filename);
|
||||
|
||||
CFCPP::Stream st;
|
||||
if (bRewrite)
|
||||
st.reset(new std::fstream(filename, std::ios::app | std::ios::out | std::ios::binary | std::ios::in));
|
||||
st.reset(new FStreamWrapper(filename, std::ios::app | std::ios::out | std::ios::binary | std::ios::in));
|
||||
else
|
||||
st.reset(new std::fstream(filename, std::ios::in | std::ios::binary));
|
||||
st.reset(new FStreamWrapper(filename, std::ios::in | std::ios::binary));
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
bool CFCPP::IsOpen(const Stream &st)
|
||||
{
|
||||
if (std::dynamic_pointer_cast<std::fstream>(st))
|
||||
return std::static_pointer_cast<std::fstream>(st)->is_open();
|
||||
|
||||
if (std::dynamic_pointer_cast<std::stringstream>(st))
|
||||
return st != nullptr;
|
||||
if (std::dynamic_pointer_cast<FStreamWrapper>(st))
|
||||
return std::static_pointer_cast<FStreamWrapper>(st)->is_open();
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -61,3 +58,4 @@ std::string CFCPP::CorrectUnixPath(const std::string original)
|
||||
return str;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -8,12 +8,39 @@
|
||||
|
||||
namespace CFCPP
|
||||
{
|
||||
using Stream = std::shared_ptr<std::iostream>;
|
||||
|
||||
class IStream
|
||||
{
|
||||
public:
|
||||
virtual std::streamsize tell() = 0;
|
||||
virtual std::streamsize seek(std::streamsize offset, std::ios_base::seekdir mode = std::ios::beg) = 0;
|
||||
virtual std::streamsize read(char* buffer, std::streamsize len) = 0;
|
||||
virtual void write (const char* buffer, std::streamsize len) = 0;
|
||||
virtual void flush() = 0;
|
||||
virtual void close() = 0;
|
||||
};
|
||||
|
||||
using Stream = std::shared_ptr<IStream>;
|
||||
|
||||
class FStreamWrapper : public IStream, public std::fstream
|
||||
{
|
||||
public:
|
||||
FStreamWrapper(std::string filename, std::ios_base::openmode openmode) :
|
||||
std::fstream(filename, openmode) {}
|
||||
|
||||
inline std::streamsize tell() override { return std::fstream::tellg(); }
|
||||
inline std::streamsize seek(std::streamsize offset, std::ios_base::seekdir mode = std::ios::beg) override
|
||||
{ std::fstream::seekg(offset, mode); return tell();}
|
||||
inline std::streamsize read(char* buffer, std::streamsize len) override { std::fstream::read(buffer, len); return tell(); }
|
||||
inline void write (const char* buffer, std::streamsize len) override { std::fstream::write(buffer, len); }
|
||||
inline void flush() override { std::fstream::flush(); }
|
||||
inline void close() override { std::fstream::close(); }
|
||||
};
|
||||
|
||||
std::string CorrectUnixPath(const std::string original);
|
||||
|
||||
Stream OpenStream(std::wstring filename, bool bRewrite = false);
|
||||
Stream OpenStream(std::string filename, bool bRewrite = false);
|
||||
Stream OpenFileStream(std::wstring filename, bool bRewrite = false);
|
||||
Stream OpenFileStream(std::string filename, bool bRewrite = false);
|
||||
|
||||
bool IsOpen(const Stream& st);
|
||||
std::streamsize Length(const Stream& st);
|
||||
|
||||
@ -6,13 +6,12 @@ using namespace CFCPP;
|
||||
StreamRW::StreamRW(const Stream &stream)
|
||||
: stream(stream)
|
||||
{
|
||||
buffer.fill(0);
|
||||
}
|
||||
|
||||
T_LONG64 StreamRW::Seek(T_LONG64 offset)
|
||||
{
|
||||
stream->seekp(offset, std::ios::beg);
|
||||
return stream->tellp();
|
||||
stream->seek(offset, std::ios::beg);
|
||||
return stream->tell();
|
||||
}
|
||||
|
||||
void StreamRW::ReadArray(char *data, int lenght)
|
||||
|
||||
@ -38,7 +38,6 @@ public:
|
||||
inline void Close(){return;}
|
||||
|
||||
private:
|
||||
std::array<char,8> buffer;
|
||||
Stream stream;
|
||||
};
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ StreamView::StreamView(const SVector<Sector> §orChain, int sectorSize, Strea
|
||||
// if (sectorChain == null)
|
||||
// throw CFException("Sector Chain cannot be null");
|
||||
|
||||
auto pos = stream->tellg();
|
||||
auto pos = stream->tell();
|
||||
if (sectorSize <= 0)
|
||||
throw CFException("Sector size must be greater than zero");
|
||||
}
|
||||
@ -24,10 +24,16 @@ StreamView::StreamView(const SVector<Sector> §orChain, int sectorSize, std::
|
||||
|
||||
}
|
||||
|
||||
void StreamView::Write(const char *buffer, std::streamsize offset, std::streamsize count)
|
||||
std::streamsize StreamView::tell()
|
||||
{
|
||||
return position;
|
||||
}
|
||||
|
||||
void StreamView::write(const char *buffer, std::streamsize count)
|
||||
{
|
||||
int byteWritten = 0;
|
||||
int roundByteWritten = 0;
|
||||
int offset = 0;
|
||||
|
||||
// Assure length
|
||||
if ((position + count) > length)
|
||||
@ -84,10 +90,17 @@ void StreamView::Write(const char *buffer, std::streamsize offset, std::streamsi
|
||||
}
|
||||
}
|
||||
|
||||
std::streamsize StreamView::Read(char *buffer, std::streamsize offset, std::streamsize count)
|
||||
void StreamView::close()
|
||||
{
|
||||
if (std::dynamic_pointer_cast<std::iostream>(stream) != nullptr)
|
||||
stream->close();
|
||||
}
|
||||
|
||||
std::streamsize StreamView::read(char *buffer, std::streamsize len)
|
||||
{
|
||||
int nRead = 0;
|
||||
int nToRead = 0;
|
||||
int offset = 0;
|
||||
if (sectorChain.empty() == false && sectorChain.size() > 0)
|
||||
{
|
||||
// First sector
|
||||
@ -96,7 +109,7 @@ std::streamsize StreamView::Read(char *buffer, std::streamsize offset, std::stre
|
||||
// Bytes to read count is the min between request count
|
||||
// and sector border
|
||||
|
||||
nToRead = std::min((int)sectorChain[0]->GetData().size() - ((int)position % sectorSize), (int)count);
|
||||
nToRead = std::min((int)sectorChain[0]->GetData().size() - ((int)position % sectorSize), (int)len);
|
||||
|
||||
if (secIndex < (int)sectorChain.size())
|
||||
{
|
||||
@ -110,7 +123,7 @@ std::streamsize StreamView::Read(char *buffer, std::streamsize offset, std::stre
|
||||
secIndex++;
|
||||
|
||||
// Central sectors
|
||||
while (nRead < (count - sectorSize))
|
||||
while (nRead < (len - sectorSize))
|
||||
{
|
||||
nToRead = sectorSize;
|
||||
char* src = reinterpret_cast<char*>(sectorChain[secIndex]->GetData().data());
|
||||
@ -122,7 +135,7 @@ std::streamsize StreamView::Read(char *buffer, std::streamsize offset, std::stre
|
||||
}
|
||||
|
||||
// Last sector
|
||||
nToRead = count - nRead;
|
||||
nToRead = len - nRead;
|
||||
|
||||
if (nToRead != 0)
|
||||
{
|
||||
@ -143,9 +156,9 @@ std::streamsize StreamView::Read(char *buffer, std::streamsize offset, std::stre
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::streamsize StreamView::Seek(std::streamsize offset, int origin)
|
||||
std::streamsize StreamView::seek(std::streamsize offset, std::ios_base::seekdir mode)
|
||||
{
|
||||
switch (origin)
|
||||
switch (mode)
|
||||
{
|
||||
case std::ios_base::beg:
|
||||
position = offset;
|
||||
@ -156,8 +169,8 @@ std::streamsize StreamView::Seek(std::streamsize offset, int origin)
|
||||
break;
|
||||
|
||||
case std::ios_base::end:
|
||||
default:
|
||||
position = length - offset;
|
||||
break;
|
||||
}
|
||||
|
||||
adjustLength(position);
|
||||
@ -172,14 +185,14 @@ void StreamView::SetLength(std::streamsize value)
|
||||
|
||||
int StreamView::ReadInt32()
|
||||
{
|
||||
Read(reinterpret_cast<char*>(&buf), 0, 4);
|
||||
read(reinterpret_cast<char*>(&buf), 4);
|
||||
return buf;
|
||||
}
|
||||
|
||||
void StreamView::WriteInt32(int val)
|
||||
{
|
||||
buf = ((val & 0xFF) << 24) | ((val & 0x00FF) << 16) | ((val & 0x0000FF) << 8) | (val & 0x000000FF);
|
||||
Write(reinterpret_cast<char*>(&buf), 0, 4);
|
||||
write(reinterpret_cast<char*>(&buf), 4);
|
||||
}
|
||||
|
||||
void StreamView::adjustLength(std::streamsize value)
|
||||
|
||||
@ -8,16 +8,20 @@
|
||||
|
||||
namespace CFCPP
|
||||
{
|
||||
class StreamView
|
||||
class StreamView : public IStream
|
||||
{
|
||||
public:
|
||||
StreamView(const SVector<Sector> §orChain, int sectorSize, Stream stream);
|
||||
StreamView(const SVector<Sector> §orChain, int sectorSize, std::streamsize length,
|
||||
SList<Sector> &availableSectors, Stream stream, bool isFatStream = false);
|
||||
|
||||
void Write(const char *buffer, std::streamsize offset, std::streamsize count);
|
||||
std::streamsize Read(char *buffer, std::streamsize offset, std::streamsize count);
|
||||
std::streamsize Seek(std::streamsize offset, int origin);
|
||||
std::streamsize tell() override;
|
||||
std::streamsize seek(std::streamsize offset, std::ios_base::seekdir mode = std::ios::beg) override;
|
||||
std::streamsize read(char *buffer, std::streamsize count) override;
|
||||
void write(const char *buffer, std::streamsize count) override;
|
||||
void flush() override {}
|
||||
void close() override;
|
||||
|
||||
void SetLength(std::streamsize value);
|
||||
std::streamsize getLength() const;
|
||||
inline SVector<Sector>& BaseSectorChain() {return sectorChain;}
|
||||
|
||||
@ -18,7 +18,7 @@ struct DirEntryTest : testing::Test
|
||||
|
||||
DirEntryTest() :
|
||||
filename("../../../data/ex.ppt"),
|
||||
stream(OpenStream(filename))
|
||||
stream(OpenFileStream(filename))
|
||||
{
|
||||
}
|
||||
};
|
||||
@ -51,24 +51,24 @@ void test_dirEntry_read(const DirectoryEntry& de)
|
||||
TEST_F(DirEntryTest, test_directoryentry_read)
|
||||
{
|
||||
DirectoryEntry de(L"", StgInvalid, {});
|
||||
stream->seekg(0x400, std::ios::beg);
|
||||
stream->seek(0x400, std::ios::beg);
|
||||
de.Read(stream);
|
||||
|
||||
EXPECT_EQ(stream->tellg(), 0x480);
|
||||
EXPECT_EQ(stream->tell(), 0x480);
|
||||
test_dirEntry_read(de);
|
||||
}
|
||||
|
||||
TEST_F(DirEntryTest, test_directoryentry_write)
|
||||
{
|
||||
DirectoryEntry de(L"", StgInvalid, {});
|
||||
stream->seekg(0x400, std::ios::beg);
|
||||
stream->seek(0x400, std::ios::beg);
|
||||
de.Read(stream);
|
||||
|
||||
std::string other_filename("../../../data/types/direntry.bin");
|
||||
stream = OpenStream(other_filename, true);
|
||||
stream = OpenFileStream(other_filename, true);
|
||||
de.Write(stream);
|
||||
EXPECT_EQ(stream->tellg(), 0x80);
|
||||
stream->seekp(0, std::ios::beg);
|
||||
EXPECT_EQ(stream->tell(), 0x80);
|
||||
stream->seek(0, std::ios::beg);
|
||||
|
||||
DirectoryEntry other(L"", StgInvalid, {});
|
||||
other.Read(stream);
|
||||
|
||||
@ -19,7 +19,7 @@ struct HeaderTest : testing::Test
|
||||
|
||||
HeaderTest() :
|
||||
filename("../../../data/ex.ppt"),
|
||||
stream(OpenStream(filename, false))
|
||||
stream(OpenFileStream(filename, false))
|
||||
{
|
||||
}
|
||||
};
|
||||
@ -63,11 +63,11 @@ TEST_F(HeaderTest, test_header_write)
|
||||
hd.Read(stream);
|
||||
|
||||
std::string other_filename("../../../data/types/header.bin");
|
||||
stream = OpenStream(other_filename, true);
|
||||
stream = OpenFileStream(other_filename, true);
|
||||
hd.Write(stream);
|
||||
|
||||
Header other;
|
||||
stream->seekg(0, std::ios::beg);
|
||||
stream->seek(0, std::ios::beg);
|
||||
other.Read(stream);
|
||||
test_header_state(other);
|
||||
remove(other_filename.c_str());
|
||||
|
||||
@ -19,7 +19,7 @@ struct StreamRWTest : testing::Test
|
||||
|
||||
StreamRWTest() :
|
||||
filename("../../../data/types/types.bin"),
|
||||
stream(OpenStream(filename, true)),
|
||||
stream(OpenFileStream(filename, true)),
|
||||
rw(new StreamRW(stream))
|
||||
{
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user