Files
wagic/JGE/src/zipFS/zstream.cpp
Rolzad73 85f66a8fec X11 build fixups
- fixed -Werror=misleading-indentation warning
- fixed -Werror=nonnull-compare warning on xll and QT builds
- PNG_LIBPNG_VER backward compatibily changes
- giflib backward compatibily changes
- resolved some undefs for X11 build
- silenced some small compile warnings in JGE Makefile
- added -DTIXML_USE_STL to remaining build types (PSP had it added)
- fixed x11 Boost incompatibility issue part of #548
- reworked PrecompiledHeader.h platforms used
2017-01-28 04:19:46 -05:00

454 lines
9.6 KiB
C++

// zstream.cpp: implementation of the zstream class.
//
// Copyright (C) 2002 Tanguy Fautre
// For conditions of distribution and use,
// see copyright notice in zfsystem.h
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "zstream.h"
namespace zip_file_system {
using namespace std;
//////////////////////////////////////////////////////////////////////
// zstream Member Functions
//////////////////////////////////////////////////////////////////////
void izstream::open(const char * Filename, streamoff Offset, streamoff Size, int CompMethod)
{
// Change the buffer if need
if (m_CompMethod == CompMethod) {
if (rdbuf() != NULL)
static_cast<zbuffer *>(rdbuf())->close();
} else
SetCompMethod(CompMethod);
// clear up the file status
clear(ios::goodbit);
// open the buffer
switch (m_CompMethod) {
case STORED:
case DEFLATED:
if (! (static_cast<zbuffer *>(rdbuf())->open(Filename, Offset, Size))) {
setstate(ios::badbit);
SetCompMethod(-1);
}
break;
default:
setstate(ios::badbit);
}
}
zbuffer * izstream::GetRightBuffer(int CompMethod) const
{
switch (CompMethod) {
// stored
case STORED:
return new zbuffer_stored;
// deflated
case DEFLATED:
return new zbuffer_deflated;
// else not supported
default:
return NULL;
}
}
bool zbuffer::use(std::streamoff Offset, std::streamoff Size)
{
if (! m_ZipFile)
return false;
//Don't use a buffer already used;
if (m_Used)
return false;
// adjust file position
if (! m_ZipFile.seekg(Offset, ios::beg))
return false;
setg( m_Buffer, // beginning of putback area
m_Buffer, // read position
m_Buffer); // end of buffer
m_Buffer[0] = 0;
m_Pos = -1;
m_Size = Size;
m_Used = true;
return true;
}
//////////////////////////////////////////////////////////////////////
// zbuffer_stored Member Functions
//////////////////////////////////////////////////////////////////////
zbuffer_stored * zbuffer_stored::open(const char * Filename, streamoff Offset, streamoff Size)
{
// open main compressed file
m_ZipFile.open(Filename, ios::binary);
if (! m_ZipFile)
return NULL;
// adjust file position
if (! use(Offset, Size))
return NULL;
m_Opened = true;
m_Filename = Filename;
return this;
}
zbuffer_stored * zbuffer_stored::close()
{
if (! m_Opened)
return NULL;
else {
m_Opened = false;
m_Used = false;
m_ZipFile.close();
}
return this;
}
int zbuffer_stored::overflow(int)
{
return EOF;
}
int zbuffer_stored::underflow()
{
// Buffer Valid?
if (! m_Opened)
return EOF;
// Do we really need to refill it?
if (gptr() < egptr())
return static_cast<unsigned char>(* gptr());
// Refill de buffer.
// Set the real position of the beginning of the buffer.
if (m_Pos == streamoff(-1))
m_Pos = 0;
streamoff ToRead = ((m_Size - m_Pos) < BUFFERSIZE) ? (m_Size - m_Pos) : BUFFERSIZE;
if ((ToRead == 0) || (! m_ZipFile.read(m_Buffer, ToRead)))
return EOF;
m_Pos += ToRead;
// Reset buffer pointers.
setg( m_Buffer, // beginning of putback area
m_Buffer, // read position
m_Buffer + ToRead); // end of buffer
return static_cast<unsigned char>(m_Buffer[0]);
}
streampos zbuffer_stored::seekoff(streamoff off, ios::seekdir dir, ios::openmode nMode)
{
streamoff WantedPos = 0;
// Find out the wanted position.
switch (dir) {
case ios_base::cur:
WantedPos = m_Pos + streamoff(gptr() - eback()) + off;
break;
case ios_base::beg:
WantedPos = off;
break;
case ios_base::end:
WantedPos = m_Size + off;
break;
default:
assert(false);
}
// Is the position valid?
if ((WantedPos < 0) || (WantedPos > m_Size))
return streambuf::seekoff(off, dir, nMode); // return invalid streamoff
// Is the position already within the buffer?
if ((WantedPos >= m_Pos) && (WantedPos - m_Pos < egptr() - eback())) {
setg(eback(), eback() + (WantedPos - m_Pos), egptr());
return WantedPos;
}
// Fill up the buffer at the right position.
if (! m_ZipFile.seekg(WantedPos, ios::beg))
return streambuf::seekoff(off, dir, nMode);
m_Pos = WantedPos;
streamoff ToRead = ((m_Size - m_Pos) < BUFFERSIZE) ? (m_Size - m_Pos) : BUFFERSIZE;
if (ToRead == 0)
return WantedPos;
if (! m_ZipFile.read(m_Buffer, ToRead))
return streambuf::seekoff(off, dir, nMode);
// Set the buffer at the right position
setg(m_Buffer, m_Buffer, m_Buffer + ToRead);
return WantedPos;
}
int zbuffer_stored::sync()
{
return 0;
}
streambuf * zbuffer_stored::setbuf(char *, int)
{
return NULL;
}
//////////////////////////////////////////////////////////////////////
// zbuffer_deflated Member Functions
//////////////////////////////////////////////////////////////////////
zbuffer_deflated * zbuffer_deflated::open(const char * Filename, streamoff Offset, streamoff Size)
{
// open main compressed file
m_ZipFile.open(Filename, ios::binary);
if (! m_ZipFile)
return NULL;
// adjust file position
if (! use(Offset, Size))
return NULL;
// z_stream (NULL) Initialization
m_ZStream.next_in = Z_NULL;
m_ZStream.avail_in = 0;
m_ZStream.total_in = 0;
m_ZStream.next_out = Z_NULL;
m_ZStream.avail_out = 0;
m_ZStream.total_out = 0;
m_ZStream.zalloc = Z_NULL;
m_ZStream.zfree = Z_NULL;
m_ZStream.opaque = Z_NULL;
// inflate routine Initialization: Window Size = -MAX_WBITS tells there are no header
if (inflateInit2(&m_ZStream, -MAX_WBITS) != Z_OK)
return NULL;
m_Opened = true;
m_StreamEnd = false;
m_Pos = 0;
m_CompPos = 0;
m_Filename = Filename;
return this;
}
zbuffer_deflated * zbuffer_deflated::close()
{
if (! m_Opened)
return NULL;
else {
m_Opened = false;
m_Used = false;
m_ZipFile.close();
// z_stream unitialization.
if (inflateEnd(&m_ZStream) != Z_OK)
return NULL;
}
return this;
}
int zbuffer_deflated::overflow(int)
{
return EOF;
}
int zbuffer_deflated::underflow()
{
// Buffer Valid?
if (! m_Opened)
return EOF;
// Do we really need to refill it?
if (gptr() < egptr())
return static_cast<unsigned char>(* gptr());
// Can we refill?
if (m_StreamEnd)
return EOF;
streamoff ToRead;
streamoff OldPos;
bool BufferRefill = false;
// Check input (compressed) buffer status
if ((m_ZStream.avail_in == 0) && (m_CompPos < m_Size )) {
ToRead = ((m_Size - m_CompPos) > BUFFERSIZE) ? BUFFERSIZE : (m_Size - m_CompPos);
m_CompPos += ToRead;
if (! m_ZipFile.read(m_CompBuffer, ToRead))
return EOF;
m_ZStream.next_in = reinterpret_cast<unsigned char *>(m_CompBuffer);
m_ZStream.avail_in = ToRead;
}
// Ajust start read position in output buffer at the "old" end of buffer
ToRead = m_ZStream.total_out % BUFFERSIZE;
OldPos = m_ZStream.total_out;
// Check output (decompressed) buffer status
if (m_ZStream.avail_out == 0) {
BufferRefill = true;
m_ZStream.next_out = reinterpret_cast<unsigned char *>(m_Buffer);
m_ZStream.avail_out = BUFFERSIZE;
}
// Decompress (Inflate)
int Result = inflate(&m_ZStream, Z_SYNC_FLUSH);
// Check decompression result
if (Result == Z_STREAM_END)
m_StreamEnd = true;
else if (Result != Z_OK)
return EOF;
// Set the real position of the beginning of the buffer.
if (m_Pos == streamoff(-1))
m_Pos = 0;
else
if (BufferRefill)
m_Pos += m_ZStream.total_out - OldPos;
// Reset buffer pointers.
setg( m_Buffer, // beginning of putback area
m_Buffer + ToRead, // read position
m_Buffer + ((m_ZStream.total_out - 1) % (BUFFERSIZE)) + 1); // end of buffer
return static_cast<unsigned char>(m_Buffer[ToRead]);
}
streampos zbuffer_deflated::seekoff(std::streamoff off, std::ios::seekdir dir, std::ios::openmode nMode)
{
streamoff WantedPos = 0;
// Find out the wanted position.
switch (dir) {
case ios_base::cur:
WantedPos = m_Pos + streamoff(gptr() - eback()) + off;
break;
case ios_base::beg:
WantedPos = off;
break;
case ios_base::end:
WantedPos = m_Size + off;
break;
default:
assert(false);
}
// Is the position valid?
if ((WantedPos < 0) || (WantedPos > m_Size))
return streambuf::seekoff(off, dir, nMode); // return invalid streamoff
// Is the position already within the buffer?
if ((WantedPos >= m_Pos) && (WantedPos - m_Pos < egptr() - eback())) {
setg(eback(), eback() + (WantedPos - m_Pos), egptr());
return WantedPos;
}
// Found out whether we have to decompress further or if we have to reset the decompression.
if (WantedPos < m_Pos) {
// Reset the decompression.
if (inflateReset(&m_ZStream) != Z_OK)
return streambuf::seekoff(off, dir, nMode);
// z_stream Reset
m_ZStream.next_in = Z_NULL;
m_ZStream.avail_in = 0;
m_ZStream.total_in = 0;
m_ZStream.next_out = Z_NULL;
m_ZStream.avail_out = 0;
m_ZStream.total_out = 0;
}
// call underflow() untill the right position is within the buffer.
while (WantedPos - m_Pos >= egptr() - eback()) {
setg(eback(), egptr(), egptr());
if (underflow() == EOF)
return streambuf::seekoff(off, dir, nMode);
}
// now the position is within the buffer.
setg(eback(), eback() + (WantedPos - m_Pos), egptr());
return WantedPos;
}
int zbuffer_deflated::sync()
{
return 0;
}
streambuf * zbuffer_deflated::setbuf(char *, int)
{
return NULL;
}
} // namespace zip_file_system