stream.cpp

来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 1,286 行 · 第 1/3 页

CPP
1,286
字号
        Ungetch(c);
        return c;
    }

    return 0;
}

wxInputStream& wxInputStream::Read(wxOutputStream& stream_out)
{
    char buf[BUF_TEMP_SIZE];

    for ( ;; )
    {
        size_t bytes_read = Read(buf, WXSIZEOF(buf)).LastRead();
        if ( !bytes_read )
            break;

        if ( stream_out.Write(buf, bytes_read).LastWrite() != bytes_read )
            break;
    }

    return *this;
}

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 other 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;

    /* 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);
}

wxFileOffset wxInputStream::TellI() const
{
    wxFileOffset pos = OnSysTell();

    if (pos != wxInvalidOffset)
        pos -= (m_wbacksize - m_wbackcur);

    return pos;
}


// ----------------------------------------------------------------------------
// wxOutputStream
// ----------------------------------------------------------------------------

wxOutputStream::wxOutputStream()
{
}

wxOutputStream::~wxOutputStream()
{
}

size_t wxOutputStream::OnSysWrite(const void * WXUNUSED(buffer),
                                  size_t WXUNUSED(bufsize))
{
    return 0;
}

void wxOutputStream::PutC(char c)
{
    Write(&c, sizeof(c));
}

wxOutputStream& wxOutputStream::Write(const void *buffer, size_t size)
{
    m_lastcount = OnSysWrite(buffer, size);
    return *this;
}

wxOutputStream& wxOutputStream::Write(wxInputStream& stream_in)
{
    stream_in.Read(*this);
    return *this;
}

wxFileOffset wxOutputStream::TellO() const
{
    return OnSysTell();
}

wxFileOffset wxOutputStream::SeekO(wxFileOffset pos, wxSeekMode mode)
{
    return OnSysSeek(pos, mode);
}

void wxOutputStream::Sync()
{
}


// ----------------------------------------------------------------------------
// wxCountingOutputStream
// ----------------------------------------------------------------------------

wxCountingOutputStream::wxCountingOutputStream ()
{
     m_currentPos = 0;
}

wxFileOffset wxCountingOutputStream::GetLength() const
{
    return m_lastcount;
}

size_t wxCountingOutputStream::OnSysWrite(const void *WXUNUSED(buffer),
                                          size_t size)
{
    m_currentPos += size;
    if (m_currentPos > m_lastcount)
        m_lastcount = m_currentPos;

    return m_currentPos;
}

wxFileOffset wxCountingOutputStream::OnSysSeek(wxFileOffset pos, wxSeekMode mode)
{
    ssize_t new_pos = (ssize_t)pos;

    switch ( mode )
    {
        case wxFromStart:
            wxCHECK_MSG( (wxFileOffset)new_pos == pos, wxInvalidOffset, wxT("huge position not supported") );
            break;

        case wxFromEnd:
            new_pos = m_lastcount + new_pos;
            wxCHECK_MSG( (wxFileOffset)new_pos == (wxFileOffset)(m_lastcount + pos), wxInvalidOffset, wxT("huge position not supported") );
            break;

        case wxFromCurrent:
            new_pos = m_currentPos + new_pos;
            wxCHECK_MSG( (wxFileOffset)new_pos == (wxFileOffset)(m_currentPos + pos), wxInvalidOffset, wxT("huge position not supported") );
            break;

        default:
            wxFAIL_MSG( _T("invalid seek mode") );
            return wxInvalidOffset;
    }

    m_currentPos = new_pos;

    if (m_currentPos > m_lastcount)
        m_lastcount = m_currentPos;

    return m_currentPos;
}

wxFileOffset wxCountingOutputStream::OnSysTell() const
{
    return m_currentPos;
}

// ----------------------------------------------------------------------------
// wxFilterInputStream
// ----------------------------------------------------------------------------

wxFilterInputStream::wxFilterInputStream()
{
    m_parent_i_stream = NULL;
}

wxFilterInputStream::wxFilterInputStream(wxInputStream& stream)
{
    m_parent_i_stream = &stream;
}

wxFilterInputStream::~wxFilterInputStream()
{
}

// ----------------------------------------------------------------------------
// wxFilterOutputStream
// ----------------------------------------------------------------------------

wxFilterOutputStream::wxFilterOutputStream()
{
    m_parent_o_stream = NULL;
}

wxFilterOutputStream::wxFilterOutputStream(wxOutputStream& stream)
{
    m_parent_o_stream = &stream;
}

wxFilterOutputStream::~wxFilterOutputStream()
{
}

// ----------------------------------------------------------------------------
// wxBufferedInputStream
// ----------------------------------------------------------------------------

wxBufferedInputStream::wxBufferedInputStream(wxInputStream& s,
                                             wxStreamBuffer *buffer)
                     : wxFilterInputStream(s)
{
    if ( buffer )
    {
        // use the buffer provided by the user
        m_i_streambuf = buffer;
    }
    else // create a default buffer
    {
        m_i_streambuf = new wxStreamBuffer(*this, wxStreamBuffer::read);

        m_i_streambuf->SetBufferIO(1024);
    }
}

wxBufferedInputStream::~wxBufferedInputStream()
{
    m_parent_i_stream->SeekI(-(wxFileOffset)m_i_streambuf->GetBytesLeft(),
                             wxFromCurrent);

    delete m_i_streambuf;
}

char wxBufferedInputStream::Peek()
{
    return m_i_streambuf->Peek();
}

wxInputStream& wxBufferedInputStream::Read(void *buf, size_t size)
{
    // reset the error flag
    Reset();

    // first read from the already cached data
    m_lastcount = GetWBack(buf, size);

    // do we have to read anything more?
    if ( m_lastcount < size )
    {
        size -= m_lastcount;
        buf = (char *)buf + m_lastcount;

        // the call to wxStreamBuffer::Read() below will reset our m_lastcount,
        // so save it
        size_t countOld = m_lastcount;

        m_i_streambuf->Read(buf, size);

        m_lastcount += countOld;
    }

    return *this;
}

wxFileOffset wxBufferedInputStream::SeekI(wxFileOffset pos, wxSeekMode mode)
{
    // RR: Look at wxInputStream for comments.

    if (m_lasterror==wxSTREAM_EOF)
        Reset();

    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 m_i_streambuf->Seek(pos, mode);
}

wxFileOffset wxBufferedInputStream::TellI() const
{
    wxFileOffset pos = m_i_streambuf->Tell();

    if (pos != wxInvalidOffset)
        pos -= (m_wbacksize - m_wbackcur);

    return pos;
}

size_t wxBufferedInputStream::OnSysRead(void *buffer, size_t bufsize)
{
    return m_parent_i_stream->Read(buffer, bufsize).LastRead();
}

wxFileOffset wxBufferedInputStream::OnSysSeek(wxFileOffset seek, wxSeekMode mode)
{
    return m_parent_i_stream->SeekI(seek, mode);
}

wxFileOffset wxBufferedInputStream::OnSysTell() const
{
    return m_parent_i_stream->TellI();
}

void wxBufferedInputStream::SetInputStreamBuffer(wxStreamBuffer *buffer)
{
    wxCHECK_RET( buffer, _T("wxBufferedInputStream needs buffer") );

    delete m_i_streambuf;
    m_i_streambuf = buffer;
}

// ----------------------------------------------------------------------------
// wxBufferedOutputStream
// ----------------------------------------------------------------------------

wxBufferedOutputStream::wxBufferedOutputStream(wxOutputStream& s,
                                               wxStreamBuffer *buffer)
                      : wxFilterOutputStream(s)
{
    if ( buffer )
    {
        m_o_streambuf = buffer;
    }
    else // create a default one
    {
        m_o_streambuf = new wxStreamBuffer(*this, wxStreamBuffer::write);

        m_o_streambuf->SetBufferIO(1024);
    }
}

wxBufferedOutputStream::~wxBufferedOutputStream()
{
    Sync();
    delete m_o_streambuf;
}

bool wxBufferedOutputStream::Close()
{
    Sync();
    return IsOk();
}


wxOutputStream& wxBufferedOutputStream::Write(const void *buffer, size_t size)
{
    m_lastcount = 0;
    m_o_streambuf->Write(buffer, size);
    return *this;
}

wxFileOffset wxBufferedOutputStream::SeekO(wxFileOffset pos, wxSeekMode mode)
{
    Sync();
    return m_o_streambuf->Seek(pos, mode);
}

wxFileOffset wxBufferedOutputStream::TellO() const
{
    return m_o_streambuf->Tell();
}

void wxBufferedOutputStream::Sync()
{
    m_o_streambuf->FlushBuffer();
    m_parent_o_stream->Sync();
}

size_t wxBufferedOutputStream::OnSysWrite(const void *buffer, size_t bufsize)
{
    return m_parent_o_stream->Write(buffer, bufsize).LastWrite();
}

wxFileOffset wxBufferedOutputStream::OnSysSeek(wxFileOffset seek, wxSeekMode mode)
{
    return m_parent_o_stream->SeekO(seek, mode);
}

wxFileOffset wxBufferedOutputStream::OnSysTell() const
{
    return m_parent_o_stream->TellO();
}

wxFileOffset wxBufferedOutputStream::GetLength() const
{
   return m_parent_o_stream->GetLength() + m_o_streambuf->GetIntPosition();
}

void wxBufferedOutputStream::SetOutputStreamBuffer(wxStreamBuffer *buffer)
{
    wxCHECK_RET( buffer, _T("wxBufferedOutputStream needs buffer") );

    delete m_o_streambuf;
    m_o_streambuf = buffer;
}

// ----------------------------------------------------------------------------
// Some IOManip function
// ----------------------------------------------------------------------------

wxOutputStream& wxEndL(wxOutputStream& stream)
{
    static const wxChar *eol = wxTextFile::GetEOL();

    return stream.Write(eol, wxStrlen(eol));
}

#endif // wxUSE_STREAMS

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?