108 lines
2.0 KiB
C++
108 lines
2.0 KiB
C++
// WormFile.cpp compressed WORM file using Snappy or Brotli
|
|
// Copyright 2017/3/14 Robin.Rowe@CinePaint.org
|
|
// License open source MIT
|
|
|
|
#include "WormFile.h"
|
|
|
|
namespace portable
|
|
{
|
|
|
|
bool WormFile::WriteFileHeader()
|
|
{ if(!ioFile.Write(fileSig))
|
|
{ lastError = WRITE_ERROR;
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool WormFile::ReadFileHeader()
|
|
{ const unsigned length = 8;
|
|
char buffer[length+1];
|
|
if(!ioFile.Read(buffer,length))
|
|
{ lastError = READ_ERROR;
|
|
return false;
|
|
}
|
|
buffer[length] = 0;
|
|
if(strcmp(buffer,fileSig))
|
|
{ lastError = INVALID_FORMAT;
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool WormFile::WriteBlockHeader(unsigned size,unsigned crc)
|
|
{ if(!ioFile.Write(blockSig,4))
|
|
{ lastError = WRITE_ERROR;
|
|
return false;
|
|
}
|
|
if (!ioFile.Write(size))
|
|
{ lastError = WRITE_ERROR;
|
|
return false;
|
|
}
|
|
if(!ioFile.Write(crc))
|
|
{ lastError = WRITE_ERROR;
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
unsigned WormFile::ReadBlockHeader()
|
|
{ char buffer[5];
|
|
if (!ioFile.Read(buffer, 4))
|
|
{ lastError = READ_ERROR;
|
|
return false;
|
|
}
|
|
buffer[4]=0;
|
|
if(strcmp(blockSig,buffer))
|
|
{ lastError = BLOCK_ERROR;
|
|
return false;
|
|
}
|
|
unsigned size = 0;
|
|
if (!ioFile.Read(size))
|
|
{ lastError = READ_ERROR;
|
|
return false;
|
|
}
|
|
unsigned crc = 0;
|
|
if (!ioFile.Read(crc))
|
|
{ lastError = READ_ERROR;
|
|
return false;
|
|
}
|
|
return size;
|
|
}
|
|
|
|
unsigned WormFile::Write(const char* data,size_t length)
|
|
{ // returns blob offset
|
|
offset = ioFile.Tell();
|
|
if(!offset)
|
|
{ if(!WriteFileHeader())
|
|
{ return 0;
|
|
} }
|
|
if(!WriteBlockHeader((unsigned)length))
|
|
{ return 0;
|
|
}
|
|
if(!ioFile.Write(data,length))
|
|
{ lastError=WRITE_ERROR;
|
|
return false;
|
|
}
|
|
return offset;
|
|
}
|
|
|
|
unsigned WormFile::Seek(unsigned offset)
|
|
{ // returns blob size
|
|
if(!ioFile.Seek(offset))
|
|
{ lastError = SEEK_ERROR;
|
|
return 0;
|
|
}
|
|
return ReadBlockHeader();
|
|
}
|
|
|
|
bool WormFile::Read(char* buffer,size_t len)
|
|
{ // uncompressed data
|
|
if(!ioFile.Read(buffer,len))
|
|
{ lastError = READ_ERROR;
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
} |