Blame src/lib/FHInternalStream.cpp

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: */