A
B
C
Ç
D
E
F
G
Ğ
H
I
İ
J
K
L
M
N
O
P
R
S
Ş
T
U
Ü
V
Y
Z
Q
W
X
+ Ekle
C++ İle Output Stream Tasarimi (İleri Duzey)

C++ İle Output Stream Tasarimi (İleri Duzey)
C++"da varolan stream class"larina ekleme nasil yapilir? Bu dokuman HTML formatlayan bir stream sinifinin ornek kodunu icerir.
C++"in stream class"lari Java kadar esnek olmasa da yine de genislemeye aciktir. C++"da output stream tasarlamak icin sirasiyla basic_streambuf sinifindan class turetmek ve overflow fonksiyonunu override etmek ardindan da basic_ostream class"indan tureyen bir class yaratip icerisinden basic_streambuf"tan tureyen sinifa refere etmek gereklidir.

Asagida HTML kodlarini ekrana guzel bir sekilde formatlayan bir stream ornegi goruyoruz. Bu stream"in ozelligi ++ operatoru ile bir adim iceri girmesi, -- operatoru ile ise bir adim disari cikmasidir.

Stream class"lari tasarlanirken C++ standard kutuphanelerindeki esnek template yapi aynen takip edilmistir, oyle ki stream"ler istenildigi takdirde char yerine wchar_t genis karakter tipini kullanabilmektedir.




Ayrica yine standard kutuphanedeki container yapisi ve typename reserve kelimesinin esnek tipler yaratmak icin nasil kullanildigina dikkat cekmek istiyorum.



#include <ostream>
#include <streambuf>
#include <string>
#include <list>
#include <utility>

template<typename charT = char,typename traits = std::char_traits<charT> >
class IndentFilter;

template<typename charT = char,typename traits = std::char_traits<charT> >
class IndentBuffer : public std::basic_streambuf<charT,traits> {
    friend class IndentFilter<charT,traits>;
protected:
    traits::int_type overflow(int c) {
        if (!traits::eq_int_type(c, traits_type::eof())) {
            if ( m_lastChar == "\n") {
                for(int i = 0; i < m_level; ++i) {
                    for(int j = 0; j < m_tabLength; ++j) {
                        m_sb->sputc(" ");
                    }
                }
            }
            m_lastChar = c;
            char_type cc = traits::to_char_type(c);
            m_sb->sputc(cc);
        }
        return traits_type::not_eof(c);
    }
private:
    void stepIn() {
        m_level++;
    }
    void stepOut() {
        m_level--;
    }
    std::basic_streambuf<charT,traits> *m_sb;
    int m_level;
    int m_tabLength;
    int m_lastChar;
public:
    IndentBuffer(std::basic_streambuf<charT,traits> *sb,int tabLength) :
        m_sb(sb), m_level(0), m_tabLength(tabLength), m_lastChar(traits_type::eof()){}

};


template<typename charT = char,typename traits = std::char_traits<charT> >
class IndentFilter : public std::basic_ostream<charT,traits> {
public:
    IndentFilter(std::basic_ostream<charT,traits>& os,int tabLength) :
        basic_ostream<charT,traits>(new IndentBuffer<charT,traits>(os.rdbuf(),tabLength)) {}
    void operator++() {
        static_cast<IndentBuffer<charT,traits> *>(rdbuf())->stepIn();
    }
    void operator++(int) {
        static_cast<IndentBuffer<charT,traits> *>(rdbuf())->stepIn();
    }
    void operator--() {
        static_cast<IndentBuffer<charT,traits> *>(rdbuf())->stepOut();
    }
    void operator--(int) {
        static_cast<IndentBuffer<charT,traits> *>(rdbuf())->stepOut();
    }
    IndentFilter() { delete rdbuf(); }
};

  Ad Soyad
  Yorum