Example #1
0
size_t wxGzipInputStream::OnSysRead(void *buffer, size_t size)
{
    wxASSERT_MSG(m_decomp, wxT("Gzip not open"));

    if (!m_decomp)
        m_lasterror = wxSTREAM_READ_ERROR;
    if (!IsOk() || !size)
        return 0;

    m_decomp->Read(buffer, size);
    m_crc = crc32(m_crc, (Byte*)buffer, m_decomp->LastRead());

    if (m_decomp->Eof()) {
        wxDataInputStream ds(*m_parent_i_stream);
        m_lasterror = wxSTREAM_READ_ERROR;

        if (m_parent_i_stream->IsOk()) {
            if (ds.Read32() != m_crc)
                wxLogError(_("reading Gzip stream: bad crc"));
            else if (ds.Read32() != (wxUint32)TellI())
                wxLogError(_("reading Gzip stream: incorrect length"));
            else
                m_lasterror = wxSTREAM_EOF;
        }
    } 
    else if (!*m_decomp) {
        m_lasterror = wxSTREAM_READ_ERROR;
    }

    return m_decomp->LastRead();
}
Example #2
0
wxFileOffset wxInputStream::SeekI(wxFileOffset pos, wxSeekMode mode)
{
    // RR: This code is duplicated in wxBufferedInputStream. This is
    // not really a good design, but buffered stream are different
    // from all others in that they handle two stream-related objects:
    // the stream buffer and parent stream.

    // I don't know whether it should be put as well in wxFileInputStream::OnSysSeek
    if (m_lasterror==wxSTREAM_EOF)
        m_lasterror=wxSTREAM_NO_ERROR;

    // avoid unnecessary seek operations (optimization)
    wxFileOffset currentPos = TellI(), size = GetLength();
    if ((mode == wxFromStart && currentPos == pos) ||
        (mode == wxFromCurrent && pos == 0) ||
        (mode == wxFromEnd && size != wxInvalidOffset && currentPos == size-pos))
        return currentPos;

    if (!IsSeekable() && mode == wxFromCurrent && pos > 0)
    {
        // rather than seeking, we can just read data and discard it;
        // this allows to forward-seek also non-seekable streams!
        char buf[BUF_TEMP_SIZE];
        size_t bytes_read;

        // read chunks of BUF_TEMP_SIZE bytes until we reach the new position
        for ( ; pos >= BUF_TEMP_SIZE; pos -= bytes_read)
        {
            bytes_read = Read(buf, WXSIZEOF(buf)).LastRead();
            if ( m_lasterror != wxSTREAM_NO_ERROR )
                return wxInvalidOffset;

            wxASSERT(bytes_read == WXSIZEOF(buf));
        }

        // read the last 'pos' bytes
        bytes_read = Read(buf, (size_t)pos).LastRead();
        if ( m_lasterror != wxSTREAM_NO_ERROR )
            return wxInvalidOffset;

        wxASSERT(bytes_read == (size_t)pos);

        // we should now have sought to the right position...
        return TellI();
    }

    /* RR: A call to SeekI() will automatically invalidate any previous
       call to Ungetch(), otherwise it would be possible to SeekI() to
       one position, unread some bytes there, SeekI() to another position
       and the data would be corrupted.

       GRG: Could add code here to try to navigate within the wback
       buffer if possible, but is it really needed? It would only work
       when seeking in wxFromCurrent mode, else it would invalidate
       anyway... */

    if (m_wback)
    {
        wxLogDebug( wxT("Seeking in stream which has data written back to it.") );

        free(m_wback);
        m_wback = NULL;
        m_wbacksize = 0;
        m_wbackcur = 0;
    }

    return OnSysSeek(pos, mode);
}