|
rpm-build |
6f7582 |
/* -*- Mode: C++; c-default-style: "k&r"; indent-tabs-mode: nil; tab-width: 2; c-basic-offset: 2 -*- */
|
|
rpm-build |
6f7582 |
|
|
rpm-build |
6f7582 |
/* libmwaw: tools
|
|
rpm-build |
6f7582 |
* Version: MPL 2.0 / LGPLv2+
|
|
rpm-build |
6f7582 |
*
|
|
rpm-build |
6f7582 |
* The contents of this file are subject to the Mozilla Public License Version
|
|
rpm-build |
6f7582 |
* 2.0 (the "License"); you may not use this file except in compliance with
|
|
rpm-build |
6f7582 |
* the License or as specified alternatively below. You may obtain a copy of
|
|
rpm-build |
6f7582 |
* the License at http://www.mozilla.org/MPL/
|
|
rpm-build |
6f7582 |
*
|
|
rpm-build |
6f7582 |
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
rpm-build |
6f7582 |
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
rpm-build |
6f7582 |
* for the specific language governing rights and limitations under the
|
|
rpm-build |
6f7582 |
* License.
|
|
rpm-build |
6f7582 |
*
|
|
rpm-build |
6f7582 |
* Major Contributor(s):
|
|
rpm-build |
6f7582 |
* Copyright (C) 2011, 2012 Alonso Laurent (alonso@loria.fr)
|
|
rpm-build |
6f7582 |
*
|
|
rpm-build |
6f7582 |
*
|
|
rpm-build |
6f7582 |
* All Rights Reserved.
|
|
rpm-build |
6f7582 |
*
|
|
rpm-build |
6f7582 |
* For minor contributions see the git repository.
|
|
rpm-build |
6f7582 |
*
|
|
rpm-build |
6f7582 |
* Alternatively, the contents of this file may be used under the terms of
|
|
rpm-build |
6f7582 |
* the GNU Lesser General Public License Version 2 or later (the "LGPLv2+"),
|
|
rpm-build |
6f7582 |
* in which case the provisions of the LGPLv2+ are applicable
|
|
rpm-build |
6f7582 |
* instead of those above.
|
|
rpm-build |
6f7582 |
*/
|
|
rpm-build |
6f7582 |
|
|
rpm-build |
6f7582 |
#include <string.h>
|
|
rpm-build |
6f7582 |
#include <iostream>
|
|
rpm-build |
6f7582 |
|
|
rpm-build |
6f7582 |
#include "file_internal.h"
|
|
rpm-build |
6f7582 |
#include "input.h"
|
|
rpm-build |
6f7582 |
|
|
rpm-build |
6f7582 |
namespace libmwaw_tools
|
|
rpm-build |
6f7582 |
{
|
|
rpm-build |
6f7582 |
//
|
|
rpm-build |
6f7582 |
// InputStream
|
|
rpm-build |
6f7582 |
//
|
|
rpm-build |
6f7582 |
InputStream::~InputStream()
|
|
rpm-build |
6f7582 |
{
|
|
rpm-build |
6f7582 |
}
|
|
rpm-build |
6f7582 |
|
|
rpm-build |
6f7582 |
unsigned char InputStream::readU8()
|
|
rpm-build |
6f7582 |
{
|
|
rpm-build |
6f7582 |
unsigned long nRead;
|
|
rpm-build |
6f7582 |
unsigned char const *data = read(1, nRead);
|
|
rpm-build |
6f7582 |
if (!data || nRead != 1) return 0;
|
|
rpm-build |
6f7582 |
return data[0];
|
|
rpm-build |
6f7582 |
}
|
|
rpm-build |
6f7582 |
unsigned short InputStream::readU16()
|
|
rpm-build |
6f7582 |
{
|
|
rpm-build |
6f7582 |
unsigned long nRead;
|
|
rpm-build |
6f7582 |
unsigned char const *data = read(2, nRead);
|
|
rpm-build |
6f7582 |
if (!data || nRead != 2) return 0;
|
|
rpm-build |
6f7582 |
return static_cast<unsigned short>((data[0]<<8)+data[1]);
|
|
rpm-build |
6f7582 |
}
|
|
rpm-build |
6f7582 |
unsigned int InputStream::readU32()
|
|
rpm-build |
6f7582 |
{
|
|
rpm-build |
6f7582 |
unsigned long nRead;
|
|
rpm-build |
6f7582 |
unsigned char const *data = read(4, nRead);
|
|
rpm-build |
6f7582 |
if (!data || nRead != 4) return 0;
|
|
rpm-build |
6f7582 |
return static_cast<unsigned int>((data[0]<<24)+(data[1]<<16)+(data[2]<<8)+data[3]);
|
|
rpm-build |
6f7582 |
}
|
|
rpm-build |
6f7582 |
char InputStream::read8()
|
|
rpm-build |
6f7582 |
{
|
|
rpm-build |
6f7582 |
unsigned long nRead;
|
|
rpm-build |
6f7582 |
unsigned char const *data = read(1, nRead);
|
|
rpm-build |
6f7582 |
if (!data || nRead != 1) return 0;
|
|
rpm-build |
6f7582 |
return static_cast<char>(data[0]);
|
|
rpm-build |
6f7582 |
}
|
|
rpm-build |
6f7582 |
short InputStream::read16()
|
|
rpm-build |
6f7582 |
{
|
|
rpm-build |
6f7582 |
unsigned long nRead;
|
|
rpm-build |
6f7582 |
unsigned char const *data = read(2, nRead);
|
|
rpm-build |
6f7582 |
if (!data || nRead != 2) return 0;
|
|
rpm-build |
6f7582 |
return static_cast<short>((data[0]<<8)+data[1]);
|
|
rpm-build |
6f7582 |
}
|
|
rpm-build |
6f7582 |
int InputStream::read32()
|
|
rpm-build |
6f7582 |
{
|
|
rpm-build |
6f7582 |
unsigned long nRead;
|
|
rpm-build |
6f7582 |
unsigned char const *data = read(4, nRead);
|
|
rpm-build |
6f7582 |
if (!data || nRead != 4) return 0;
|
|
rpm-build |
6f7582 |
return static_cast<int>((data[0]<<24)+(data[1]<<16)+(data[2]<<8)+data[3]);
|
|
rpm-build |
6f7582 |
}
|
|
rpm-build |
6f7582 |
|
|
rpm-build |
6f7582 |
int InputStream::seek(long _offset, SeekType seekType)
|
|
rpm-build |
6f7582 |
{
|
|
rpm-build |
6f7582 |
long sz = length();
|
|
rpm-build |
6f7582 |
if (seekType == SK_CUR)
|
|
rpm-build |
6f7582 |
m_offset += _offset;
|
|
rpm-build |
6f7582 |
else if (seekType == SK_SET)
|
|
rpm-build |
6f7582 |
m_offset = _offset;
|
|
rpm-build |
6f7582 |
else if (seekType == SK_END)
|
|
rpm-build |
6f7582 |
m_offset = sz+_offset;
|
|
rpm-build |
6f7582 |
|
|
rpm-build |
6f7582 |
if (m_offset < 0) {
|
|
rpm-build |
6f7582 |
m_offset = 0;
|
|
rpm-build |
6f7582 |
return 1;
|
|
rpm-build |
6f7582 |
}
|
|
rpm-build |
6f7582 |
if (m_offset > sz) {
|
|
rpm-build |
6f7582 |
m_offset = sz;
|
|
rpm-build |
6f7582 |
return 1;
|
|
rpm-build |
6f7582 |
}
|
|
rpm-build |
6f7582 |
return 0;
|
|
rpm-build |
6f7582 |
}
|
|
rpm-build |
6f7582 |
|
|
rpm-build |
6f7582 |
//
|
|
rpm-build |
6f7582 |
// StringStream
|
|
rpm-build |
6f7582 |
//
|
|
rpm-build |
6f7582 |
StringStream::StringStream(const unsigned char *data, const unsigned long dataSize)
|
|
rpm-build |
6f7582 |
: InputStream()
|
|
rpm-build |
6f7582 |
, m_buffer(dataSize)
|
|
rpm-build |
6f7582 |
{
|
|
rpm-build |
6f7582 |
memcpy(&m_buffer[0], data, dataSize);
|
|
rpm-build |
6f7582 |
}
|
|
rpm-build |
6f7582 |
|
|
rpm-build |
6f7582 |
const unsigned char *StringStream::read(unsigned long numBytes, unsigned long &numBytesRead)
|
|
rpm-build |
6f7582 |
{
|
|
rpm-build |
6f7582 |
numBytesRead = 0;
|
|
rpm-build |
6f7582 |
|
|
rpm-build |
6f7582 |
if (numBytes == 0)
|
|
rpm-build |
6f7582 |
return 0;
|
|
rpm-build |
6f7582 |
|
|
rpm-build |
6f7582 |
unsigned long numBytesToRead;
|
|
rpm-build |
6f7582 |
|
|
rpm-build |
6f7582 |
if ((static_cast<unsigned long>(m_offset)+numBytes) < m_buffer.size())
|
|
rpm-build |
6f7582 |
numBytesToRead = numBytes;
|
|
rpm-build |
6f7582 |
else
|
|
rpm-build |
6f7582 |
numBytesToRead = static_cast<unsigned long>(static_cast<long>(m_buffer.size()) - m_offset);
|
|
rpm-build |
6f7582 |
|
|
rpm-build |
6f7582 |
numBytesRead = numBytesToRead; // about as paranoid as we can be..
|
|
rpm-build |
6f7582 |
|
|
rpm-build |
6f7582 |
if (numBytesToRead == 0)
|
|
rpm-build |
6f7582 |
return 0;
|
|
rpm-build |
6f7582 |
|
|
rpm-build |
6f7582 |
long oldOffset = m_offset;
|
|
rpm-build |
6f7582 |
m_offset += numBytesToRead;
|
|
rpm-build |
6f7582 |
|
|
rpm-build |
6f7582 |
return &m_buffer[size_t(oldOffset)];
|
|
rpm-build |
6f7582 |
}
|
|
rpm-build |
6f7582 |
//
|
|
rpm-build |
6f7582 |
// FileStream
|
|
rpm-build |
6f7582 |
//
|
|
rpm-build |
6f7582 |
FileStream::FileStream(char const *path)
|
|
rpm-build |
6f7582 |
: InputStream()
|
|
rpm-build |
6f7582 |
, m_file(0)
|
|
rpm-build |
6f7582 |
, m_isOk(true)
|
|
rpm-build |
6f7582 |
, m_buffer()
|
|
rpm-build |
6f7582 |
, m_bufferPos(0)
|
|
rpm-build |
6f7582 |
{
|
|
rpm-build |
6f7582 |
m_file = fopen(path,"r");
|
|
rpm-build |
6f7582 |
if (m_file)
|
|
rpm-build |
6f7582 |
return;
|
|
rpm-build |
6f7582 |
#ifdef DEBUG
|
|
rpm-build |
6f7582 |
std::cerr << "FileStream:FileStream can not open " << path << "\n";
|
|
rpm-build |
6f7582 |
#endif
|
|
rpm-build |
6f7582 |
m_isOk = false;
|
|
rpm-build |
6f7582 |
}
|
|
rpm-build |
6f7582 |
|
|
rpm-build |
6f7582 |
FileStream::~FileStream()
|
|
rpm-build |
6f7582 |
{
|
|
rpm-build |
6f7582 |
if (!m_isOk) return;
|
|
rpm-build |
6f7582 |
if (m_file) fclose(m_file);
|
|
rpm-build |
6f7582 |
}
|
|
rpm-build |
6f7582 |
|
|
rpm-build |
6f7582 |
unsigned char const *FileStream::read(unsigned long numBytes, unsigned long &numBytesRead)
|
|
rpm-build |
6f7582 |
{
|
|
rpm-build |
6f7582 |
numBytesRead = 0;
|
|
rpm-build |
6f7582 |
if (!m_isOk || !m_file)
|
|
rpm-build |
6f7582 |
return 0;
|
|
rpm-build |
6f7582 |
long lastPos = m_offset+long(numBytes);
|
|
rpm-build |
6f7582 |
long fileLength = length();
|
|
rpm-build |
6f7582 |
if (lastPos > fileLength) lastPos = fileLength;
|
|
rpm-build |
6f7582 |
// check if the buffer is or not ok
|
|
rpm-build |
6f7582 |
auto bufSize = long(m_buffer.size());
|
|
rpm-build |
6f7582 |
if (m_offset < m_bufferPos || lastPos > m_bufferPos+bufSize) {
|
|
rpm-build |
6f7582 |
auto numToRead = size_t(numBytes);
|
|
rpm-build |
6f7582 |
if (numToRead < 4096 && m_offset+4096 <= fileLength)
|
|
rpm-build |
6f7582 |
numToRead = 4096;
|
|
rpm-build |
6f7582 |
else if (numToRead < 4096)
|
|
rpm-build |
6f7582 |
numToRead = size_t(fileLength-m_offset);
|
|
rpm-build |
6f7582 |
if (numToRead==0)
|
|
rpm-build |
6f7582 |
return 0;
|
|
rpm-build |
6f7582 |
// try to read numToRead bytes
|
|
rpm-build |
6f7582 |
m_bufferPos = m_offset;
|
|
rpm-build |
6f7582 |
m_buffer.resize(size_t(numToRead));
|
|
rpm-build |
6f7582 |
|
|
rpm-build |
6f7582 |
#if 0
|
|
rpm-build |
6f7582 |
MWAW_DEBUG_MSG(("FileStream::read called with %ld[%ld]: read %ld bytes\n", m_offset, numBytes, numToRead));
|
|
rpm-build |
6f7582 |
#endif
|
|
rpm-build |
6f7582 |
if (fseek(m_file, m_offset, SEEK_SET)==-1) {
|
|
rpm-build |
6f7582 |
MWAW_DEBUG_MSG(("FileStream::read get error when doing a seek\n"));
|
|
rpm-build |
6f7582 |
m_buffer.clear();
|
|
rpm-build |
6f7582 |
return 0;
|
|
rpm-build |
6f7582 |
}
|
|
rpm-build |
6f7582 |
size_t nRead = fread(&(m_buffer[0]), 1, numToRead, m_file);
|
|
rpm-build |
6f7582 |
if (nRead != numToRead) {
|
|
rpm-build |
6f7582 |
MWAW_DEBUG_MSG(("FileStream::read get error when reading data\n"));
|
|
rpm-build |
6f7582 |
m_buffer.resize(size_t(nRead));
|
|
rpm-build |
6f7582 |
}
|
|
rpm-build |
6f7582 |
}
|
|
rpm-build |
6f7582 |
|
|
rpm-build |
6f7582 |
bufSize = long(m_buffer.size());
|
|
rpm-build |
6f7582 |
if (!bufSize)
|
|
rpm-build |
6f7582 |
return 0;
|
|
rpm-build |
6f7582 |
numBytesRead = static_cast<unsigned long>(m_bufferPos + bufSize - m_offset);
|
|
rpm-build |
6f7582 |
if (numBytesRead > numBytes)
|
|
rpm-build |
6f7582 |
numBytesRead = numBytes;
|
|
rpm-build |
6f7582 |
unsigned char const *res = &(m_buffer[size_t(m_offset-m_bufferPos)]);
|
|
rpm-build |
6f7582 |
m_offset += long(numBytesRead);
|
|
rpm-build |
6f7582 |
return res;
|
|
rpm-build |
6f7582 |
}
|
|
rpm-build |
6f7582 |
|
|
rpm-build |
6f7582 |
long FileStream::length()
|
|
rpm-build |
6f7582 |
{
|
|
rpm-build |
6f7582 |
if (!m_isOk || !m_file) return 0;
|
|
rpm-build |
6f7582 |
if (fseek(m_file, 0, SEEK_END)==-1) {
|
|
rpm-build |
6f7582 |
MWAW_DEBUG_MSG(("FileStream::length get error when reading data\n"));
|
|
rpm-build |
6f7582 |
return 0;
|
|
rpm-build |
6f7582 |
}
|
|
rpm-build |
6f7582 |
return long(ftell(m_file));
|
|
rpm-build |
6f7582 |
}
|
|
rpm-build |
6f7582 |
}
|
|
rpm-build |
6f7582 |
// vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab:
|