PageRenderTime 64ms CodeModel.GetById 16ms app.highlight 37ms RepoModel.GetById 0ms app.codeStats 1ms

/strigi-0.7.7/libstreams/lib/subinputstream.cpp

#
C++ | 125 lines | 94 code | 2 blank | 29 comment | 34 complexity | f4043f57a0b1df8f7181160bc77e98d7 MD5 | raw file
Possible License(s): LGPL-2.0
  1/* This file is part of Strigi Desktop Search
  2 *
  3 * Copyright (C) 2006 Jos van den Oever <jos@vandenoever.info>
  4 *
  5 * This library is free software; you can redistribute it and/or
  6 * modify it under the terms of the GNU Library General Public
  7 * License as published by the Free Software Foundation; either
  8 * version 2 of the License, or (at your option) any later version.
  9 *
 10 * This library is distributed in the hope that it will be useful,
 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 13 * Library General Public License for more details.
 14 *
 15 * You should have received a copy of the GNU Library General Public License
 16 * along with this library; see the file COPYING.LIB.  If not, write to
 17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 18 * Boston, MA 02110-1301, USA.
 19 */
 20#include <strigi/subinputstream.h>
 21#include <strigi/strigiconfig.h>
 22#include <iostream>
 23#include <cassert>
 24
 25using namespace std;
 26using namespace Strigi;
 27
 28SubInputStream::SubInputStream(InputStream *i, int64_t length)
 29        : m_offset(i->position()), m_input(i) {
 30    assert(length >= -1);
 31//    fprintf(stderr, "substream m_offset: %li\n", m_offset);
 32    m_size = length;
 33}
 34int32_t
 35SubInputStream::read(const char*& start, int32_t min, int32_t max) {
 36    if (m_size != -1) {
 37        const int64_t left = m_size - m_position;
 38        if (left == 0) {
 39            m_status = Eof;
 40            return -1;
 41        }
 42        // restrict the amount of data that can be read
 43        if (min > left) min = (int32_t)left;
 44        if (max < min || max > left) {
 45            max = (int32_t)left;
 46        }
 47    }
 48    int32_t nread = m_input->read(start, min, max);
 49    assert(max < min || nread <= max);
 50    if (nread < -1) {
 51        fprintf(stderr, "substream too short.\n");
 52        m_status = Error;
 53        m_error = m_input->error();
 54    } else if (nread < min) {
 55        if (m_size == -1) {
 56            m_status = Eof;
 57            if (nread > 0) {
 58                m_position += nread;
 59                m_size = m_position;
 60            }
 61        } else {
 62//            fprintf(stderr, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! nread %i min %i max %i m_size %li\n", nread, min, max, m_size);
 63//            fprintf(stderr, "pos %li parentpos %li\n", m_position, m_input->position());
 64//            fprintf(stderr, "status: %i error: %s\n", m_input->status(), m_input->error());
 65            // we expected data but didn't get enough so that's an error
 66            m_status = Error;
 67            m_error = "Premature end of stream\n";
 68            nread = -2;
 69        }
 70    } else {
 71        m_position += nread;
 72        if (m_position == m_size) {
 73            m_status = Eof;
 74        }
 75    }
 76    return nread;
 77}
 78int64_t
 79SubInputStream::reset(int64_t newpos) {
 80    assert(newpos >= 0);
 81//    fprintf(stderr, "subreset pos: %li newpos: %li m_offset: %li m_size: %li\n",
 82//         m_position, newpos, m_offset, m_size);
 83    m_position = m_input->reset(newpos + m_offset);
 84    if (m_position < m_offset) {
 85        cerr << "########### m_position " << m_position << " newpos " << newpos
 86            << endl;
 87        m_status = Error;
 88        m_error = m_input->error();
 89    } else {
 90        m_position -= m_offset;
 91        m_status = m_input->status();
 92    }
 93    return m_position;
 94}
 95int64_t
 96SubInputStream::skip(int64_t ntoskip) {
 97//    fprintf(stderr, "subskip pos: %li ntoskip: %li m_offset: %li m_size: %li\n", m_position, ntoskip, m_offset, m_size);
 98    if (m_size == m_position) {
 99        m_status = Eof;
100        return -1;
101    }
102    if (ntoskip == 0) return 0;
103    if (m_size != -1) {
104        const int64_t left = m_size - m_position;
105        // restrict the amount of data that can be skipped
106        if (ntoskip > left) {
107            ntoskip = left;
108        }
109    }
110    int64_t skipped = m_input->skip(ntoskip);
111    if (m_input->status() == Error) {
112        m_status = Error;
113        m_error = m_input->error();
114    } else {
115        m_position += skipped;
116        if (m_position == m_size) {
117            m_status = Eof;
118        } else if (skipped <= 0) {
119            m_status = Error;
120            m_error = "Premature end of stream\n";
121            skipped = -2;
122        }
123    }
124    return skipped;
125}