2 Ekim 2019 Çarşamba

Streamler std::streambuf Sınıfı

Public Metodlar
sbumpc metodu
Bir karakter okur ve imleci ilerletir. Şöyle yaparız.
#include <sstream>
#include <iostream>
#include <cstdio>

int main()
{
    const std::istringstream strm("Const stream");
    std::streambuf* buf = strm.rdbuf();

    char c;
    while ((c = buf->sbumpc()) != EOF)
        std::cout << c;
}
sgetc metodu
Sadece bir karakter okur ve imleci ilerletmez..

sgetn metodu
Beliritlen sayıdaki karakteri bellek alanına kopyalar.

Virtual Protected Metodlar
overflow metodu
İmzası şöyle. Parametre olarak int almasına rağman aslında char geçilir. std::endl overflow() metodunu \n karakteri ile çağırabilir.
int overflow(int c);
Örnek
Stream'e yazmayı kontrol etmek için şöyle yaparız.
struct Output : std::ostream, std::streambuf
{
  Output(bool enabled) :
    std::ostream(this), m_enabled(enabled) {}

  int overflow(int c)  {
    if(m_enabled) std::cout.put(c);
    return 0;
  }

  bool m_enabled;
};
underflow metodu
Underflow okuma belleği boşalınca tekrar doldurmak için çağrılır. gptr (read poisiton) konumu egptr (enf of buffer) konumuna eşitse, bellekteki her karakter okunmuş demektir. Alttaki stream'den daha fazla veri okunur. Şöyle yaparız.
class compressbuf : public std::streambuf {
    std::streambuf* sbuf_;
    char*           buffer_;
    // context for the compression
public:
    compressbuf(std::streambuf* sbuf)
        : sbuf_(sbuf), buffer_(new char[1024]) {
        // initialize compression context
    }
    ~compressbuf() { delete[] this->buffer_; }
    int underflow() {
        if (this->gptr() == this->egptr()) {
            // decompress data into buffer_, obtaining its own input from
            // this->sbuf_; if necessary resize buffer
            // the next statement assumes "size" characters were produced (if
            // no more characters are available, size == 0.
            this->setg(this->buffer_, this->buffer_, this->buffer_ + size);
        }
        return this->gptr() == this->egptr()
             ? std::char_traits<char>::eof()
             : std::char_traits<char>::to_int_type(*this->gptr());
    }
};
xsputn ve xsgetn metodu
İmzası şöyle.
std::streamsize xsputn(char const* s, std::streamsize n);
Birden fazla karakteri yazıp okumaya yarar.
Örnek
Şöyle yaparız.
class socket_buf : public std::streambuf
{
public:
    //Socket is a class with std::stream-like read/write methods
  MyBuf( Socket& s ) : sock( s ) {}

protected:
  std::streamsize xsputn( const char* s, std::streamsize n )
  {
    return sock.write( s, n );
  }

  std::streamsize xsgetn( char* s, std::streamsize n )
  {
    return sock.read( s, n );
  }

private:
  Socket& sock;
};
Protected Metodlar
setg metodu
Okunabilecek verinin sınırlarını atamak için kullanılır. Metodun içi şöyle.
void setg(char_type* __gbeg, char_type* __gnext, char_type* __gend)
{
  _M_in_beg = __gbeg;//start of get area
  _M_in_cur = __gnext;//Current read area
  _M_in_end = __gend;//End of get area
}
Üye değişkenlerin anlamı şöyle.
char_type*      _M_in_beg;     ///< Start of get area.
char_type*      _M_in_cur;     ///< Current read area.
char_type*      _M_in_end;     ///< End of get area.
char_type*      _M_out_beg;    ///< Start of put area.
char_type*      _M_out_cur;    ///< Current put area.
char_type*      _M_out_end;    ///< End of put area.
Örnek
Vector'ü stream ile okumak için bir streambuf nesnesinden kalıtır ve vector'ün bellek alanını okumak için streambuf'a setg() ile atarız. Şöyle yaparız.
template<typename CharT, typename TraitsT = std::char_traits<CharT> >
class vectorwrapbuf : public std::basic_streambuf<CharT, TraitsT> {
public:
  vectorwrapbuf(std::vector<CharT> &vec) {
    setg(vec.data(), vec.data(), vec.data() + vec.size());
  }
};

std::vector<char> data;
// ...
vectorwrapbuf<char> databuf(data)
std::istream is(&databuf);
Örnek
Burada vector yerine pointer kullanılıyor. Şöyle yaparız.
struct membuf : std::streambuf
{
  membuf(char* begin, char* end) {
    this->setg(begin, begin, end);
  }
};




Hiç yorum yok:

Yorum Gönder