|
Packit Service |
db749c |
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
Packit Service |
db749c |
/*
|
|
Packit Service |
db749c |
* This file is part of the libfreehand project.
|
|
Packit Service |
db749c |
*
|
|
Packit Service |
db749c |
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
Packit Service |
db749c |
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
Packit Service |
db749c |
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
Packit Service |
db749c |
*/
|
|
Packit Service |
db749c |
|
|
Packit Service |
db749c |
|
|
Packit Service |
db749c |
#include <zlib.h>
|
|
Packit Service |
db749c |
#include "FHInternalStream.h"
|
|
Packit Service |
db749c |
#include "libfreehand_utils.h"
|
|
Packit Service |
db749c |
#include <string.h> // for memcpy
|
|
Packit Service |
db749c |
|
|
Packit Service |
db749c |
|
|
Packit Service |
db749c |
#define CHUNK 16384
|
|
Packit Service |
db749c |
|
|
Packit Service |
db749c |
libfreehand::FHInternalStream::FHInternalStream(librevenge::RVNGInputStream *input, unsigned long size, bool compressed) :
|
|
Packit Service |
db749c |
librevenge::RVNGInputStream(),
|
|
Packit Service |
db749c |
m_offset(0),
|
|
Packit Service |
db749c |
m_buffer()
|
|
Packit Service |
db749c |
{
|
|
Packit Service |
db749c |
if (!size)
|
|
Packit Service |
db749c |
return;
|
|
Packit Service |
db749c |
|
|
Packit Service |
db749c |
if (!compressed)
|
|
Packit Service |
db749c |
{
|
|
Packit Service |
db749c |
unsigned long tmpNumBytesRead = 0;
|
|
Packit Service |
db749c |
const unsigned char *tmpBuffer = input->read(size, tmpNumBytesRead);
|
|
Packit Service |
db749c |
|
|
Packit Service |
db749c |
if (size != tmpNumBytesRead)
|
|
Packit Service |
db749c |
return;
|
|
Packit Service |
db749c |
|
|
Packit Service |
db749c |
m_buffer = std::vector<unsigned char>(size);
|
|
Packit Service |
db749c |
memcpy(&m_buffer[0], tmpBuffer, size);
|
|
Packit Service |
db749c |
}
|
|
Packit Service |
db749c |
else
|
|
Packit Service |
db749c |
{
|
|
Packit Service |
db749c |
int ret;
|
|
Packit Service |
db749c |
unsigned have;
|
|
Packit Service |
db749c |
z_stream strm;
|
|
Packit Service |
db749c |
unsigned char out[CHUNK];
|
|
Packit Service |
db749c |
|
|
Packit Service |
db749c |
/* allocate inflate state */
|
|
Packit Service |
db749c |
strm.zalloc = Z_NULL;
|
|
Packit Service |
db749c |
strm.zfree = Z_NULL;
|
|
Packit Service |
db749c |
strm.opaque = Z_NULL;
|
|
Packit Service |
db749c |
strm.avail_in = 0;
|
|
Packit Service |
db749c |
strm.next_in = Z_NULL;
|
|
Packit Service |
db749c |
ret = inflateInit(&strm;;
|
|
Packit Service |
db749c |
if (ret != Z_OK)
|
|
Packit Service |
db749c |
return;
|
|
Packit Service |
db749c |
|
|
Packit Service |
db749c |
unsigned long tmpNumBytesRead = 0;
|
|
Packit Service |
db749c |
const unsigned char *tmpBuffer = input->read(size, tmpNumBytesRead);
|
|
Packit Service |
db749c |
|
|
Packit Service |
db749c |
if (size != tmpNumBytesRead)
|
|
Packit Service |
db749c |
{
|
|
Packit Service |
db749c |
(void)inflateEnd(&strm;;
|
|
Packit Service |
db749c |
return;
|
|
Packit Service |
db749c |
}
|
|
Packit Service |
db749c |
|
|
Packit Service |
db749c |
strm.avail_in = (uInt)tmpNumBytesRead;
|
|
Packit Service |
db749c |
strm.next_in = (Bytef *)tmpBuffer;
|
|
Packit Service |
db749c |
|
|
Packit Service |
db749c |
do
|
|
Packit Service |
db749c |
{
|
|
Packit Service |
db749c |
strm.avail_out = CHUNK;
|
|
Packit Service |
db749c |
strm.next_out = out;
|
|
Packit Service |
db749c |
ret = inflate(&strm, Z_NO_FLUSH);
|
|
Packit Service |
db749c |
switch (ret)
|
|
Packit Service |
db749c |
{
|
|
Packit Service |
db749c |
case Z_NEED_DICT:
|
|
Packit Service |
db749c |
case Z_DATA_ERROR:
|
|
Packit Service |
db749c |
case Z_MEM_ERROR:
|
|
Packit Service |
db749c |
(void)inflateEnd(&strm;;
|
|
Packit Service |
db749c |
m_buffer.clear();
|
|
Packit Service |
db749c |
return;
|
|
Packit Service |
db749c |
}
|
|
Packit Service |
db749c |
|
|
Packit Service |
db749c |
have = CHUNK - strm.avail_out;
|
|
Packit Service |
db749c |
|
|
Packit Service |
db749c |
for (unsigned long i=0; i
|
|
Packit Service |
db749c |
m_buffer.push_back(out[i]);
|
|
Packit Service |
db749c |
|
|
Packit Service |
db749c |
}
|
|
Packit Service |
db749c |
while (strm.avail_out == 0);
|
|
Packit Service |
db749c |
(void)inflateEnd(&strm;;
|
|
Packit Service |
db749c |
}
|
|
Packit Service |
db749c |
}
|
|
Packit Service |
db749c |
|
|
Packit Service |
db749c |
const unsigned char *libfreehand::FHInternalStream::read(unsigned long numBytes, unsigned long &numBytesRead)
|
|
Packit Service |
db749c |
{
|
|
Packit Service |
db749c |
numBytesRead = 0;
|
|
Packit Service |
db749c |
|
|
Packit Service |
db749c |
if (numBytes == 0)
|
|
Packit Service |
db749c |
return nullptr;
|
|
Packit Service |
db749c |
|
|
Packit Service |
db749c |
unsigned numBytesToRead;
|
|
Packit Service |
db749c |
|
|
Packit Service |
db749c |
if ((m_offset+numBytes) < m_buffer.size())
|
|
Packit Service |
db749c |
numBytesToRead = numBytes;
|
|
Packit Service |
db749c |
else
|
|
Packit Service |
db749c |
numBytesToRead = m_buffer.size() - m_offset;
|
|
Packit Service |
db749c |
|
|
Packit Service |
db749c |
numBytesRead = numBytesToRead; // about as paranoid as we can be..
|
|
Packit Service |
db749c |
|
|
Packit Service |
db749c |
if (numBytesToRead == 0)
|
|
Packit Service |
db749c |
return nullptr;
|
|
Packit Service |
db749c |
|
|
Packit Service |
db749c |
long oldOffset = m_offset;
|
|
Packit Service |
db749c |
m_offset += numBytesToRead;
|
|
Packit Service |
db749c |
|
|
Packit Service |
db749c |
return &m_buffer[oldOffset];
|
|
Packit Service |
db749c |
}
|
|
Packit Service |
db749c |
|
|
Packit Service |
db749c |
int libfreehand::FHInternalStream::seek(long offset, librevenge::RVNG_SEEK_TYPE seekType)
|
|
Packit Service |
db749c |
{
|
|
Packit Service |
db749c |
if (seekType == librevenge::RVNG_SEEK_CUR)
|
|
Packit Service |
db749c |
m_offset += offset;
|
|
Packit Service |
db749c |
else if (seekType == librevenge::RVNG_SEEK_SET)
|
|
Packit Service |
db749c |
m_offset = offset;
|
|
Packit Service |
db749c |
else if (seekType == librevenge::RVNG_SEEK_END)
|
|
Packit Service |
db749c |
m_offset = long(static_cast<unsigned long>(m_buffer.size())) + offset;
|
|
Packit Service |
db749c |
|
|
Packit Service |
db749c |
if (m_offset < 0)
|
|
Packit Service |
db749c |
{
|
|
Packit Service |
db749c |
m_offset = 0;
|
|
Packit Service |
db749c |
return 1;
|
|
Packit Service |
db749c |
}
|
|
Packit Service |
db749c |
if ((long)m_offset > (long)m_buffer.size())
|
|
Packit Service |
db749c |
{
|
|
Packit Service |
db749c |
m_offset = m_buffer.size();
|
|
Packit Service |
db749c |
return 1;
|
|
Packit Service |
db749c |
}
|
|
Packit Service |
db749c |
|
|
Packit Service |
db749c |
return 0;
|
|
Packit Service |
db749c |
}
|
|
Packit Service |
db749c |
|
|
Packit Service |
db749c |
long libfreehand::FHInternalStream::tell()
|
|
Packit Service |
db749c |
{
|
|
Packit Service |
db749c |
return m_offset;
|
|
Packit Service |
db749c |
}
|
|
Packit Service |
db749c |
|
|
Packit Service |
db749c |
bool libfreehand::FHInternalStream::isEnd()
|
|
Packit Service |
db749c |
{
|
|
Packit Service |
db749c |
if ((long)m_offset >= (long)m_buffer.size())
|
|
Packit Service |
db749c |
return true;
|
|
Packit Service |
db749c |
|
|
Packit Service |
db749c |
return false;
|
|
Packit Service |
db749c |
}
|
|
Packit Service |
db749c |
/* vim:set shiftwidth=2 softtabstop=2 expandtab: */
|