basic_streambuf verwenden...



  • Mis2com schrieb:

    Nagut, aber da wird ja einfach von ostream und istream geerbt, hier habe ich ja eine völlig andere Funktionalität für operator<< und operator>>

    Wieso? Welche Funktionalität hast du denn? Ich dachte du willst sockets verwenden - da passt das doch.

    Nimm Josuttis Code und ersetze read() durch recv() und write() durch send() und 90% der Arbeit ist getan. Dann noch den Socket aufbauen und zerstören und die Sache ist schon fast fertig.

    Wobei ein socket natürlich ein read/write stream ist



  • Hm,

    wie ist das jetzt eigentlich mit Groß- und Kleinschreibung? Die Klassen der STL sind alle klein, aber ich schreibe meine groß, ist das nicht irgendwie scheiße?

    Außerdem geht der Code nicht, weil er eine Vorlageliste für basic_streambuf haben will.
    Hab mal <char, char_traits<char>> genommen...geht aber trotzdem nicht...

    Es ist völliger Blödsinn, was ist das für ein bescheuerter Code?

    class fdoutbuf : public std::streambuf {
      protected:
        int fd;    // file descriptor
      public:
        // constructor
        fdoutbuf (int _fd) : fd(_fd) {
        }
      protected:
        // write one character
        virtual int_type overflow (int_type c) { // Wieso wird hier bitte ein Zeichen geschrieben? Die Funktion heißt overflow, nicht writechar!
            if (c != EOF) {
                char z = c;
                if (write (fd, &z, 1) != 1) {
                    return EOF;
                }
            }
            return c;
        }
        // write multiple characters
        virtual
        std::streamsize xsputn (const char* s,
                                std::streamsize num) { // Was soll write hier bitte?  std::streamsize zurückgeben? Wozu das? Bei cout.write() kann ich 3 Parameter nicht übergebn. Außerdem macht diese Funktion die Funktion für das einzelne Schreiben von Zeichen doch total überflüssig!?
            return write(fd,s,num);
        }
    };
    

    Sorry, aber ich habe keine Ahnung, was ich da anstellen soll. *grummel*

    MfG Eisflamme



  • nur mal so als frage:
    versucht der wirklich eine funktion nachträglich virtual zu machen,oder irr ich mich da?



  • Du irrst, overflow und xputsn sind bereits in basic_streambuf virtuell.



  • wo bitte ist das Problem?
    Josuttis ist ein absoluter Profi. Der Code ist so vollkommen korrekt - warum die Funktion overflow und xsputn heisst weiss ich nicht - ist das wichtig? Gibt sicher gute Gründe warum das Standardisierungskomitee diese Namen gewählt hat.

    Der Code ist doch ansonsten leicht verständlich, oder?

    otze: natürlich nicht. Wie kommst du auf die Idee?



  • Hier nochmal ein Beispiel von mir, das nicht funktioniert:

    #include <iostream>
    #include <streambuf>
    
    using namespace std;
    
    class socket_iobuf : public streambuf
    {
    protected:
    	streamsize xsputn(char_type* s, streamsize n)
    	{
    		int xJSADFKLJ;
    		std::cout << s;
    		return n;
    	}
    
    public:	
    };
    
    class socket_stream : public ostream
    {
    protected:
    	socket_iobuf iobuf_;
    public:
    	socket_stream() : ostream(0) {}
    
    };
    
    int main()
    {
    	socket_stream foo;
    	foo << "Hallo";
    
    	return 0;
    }
    

    Ausgabe:

    PS: Die Ausgabe ist das Problem!

    MfG Eisflamme 😞



  • wo bitte ist das Problem?

    Ich verstehe den Code nicht, das Übernehmen funktioniert nicht.

    Josuttis ist ein absoluter Profi. Der Code ist so vollkommen korrekt - warum die Funktion overflow und xsputn heisst weiss ich nicht -

    ...

    ist das wichtig?

    Schon, denn wenn ich den Scheiß einfach so überlade, wie ich denke, dass es korrekt ist, dann läuft es nicht.

    Gibt sicher gute Gründe warum das Standardisierungskomitee diese Namen gewählt hat.

    Die nennen das Teil overflow und benutzen write, das ist in meinen Augen alles andere als ein gut gewählter Name, aber ich lasse mich gerne belehren...

    Der Code ist doch ansonsten leicht verständlich, oder?

    Ehrlichgesagt überhaupt nicht, wenn ich versuche ihn für das Umzusetzen, was ich machen will, kommt nichts bei raus. 😞

    MfG Eisflamme



  • Lies doch in einer Doku nach was diese beiden Funktionen machen:

    von Borland:

    int_type
    overflow(int_type c = traits::eof() );

    The member functions sputc() and sputn() call this function when not enough room can be found in the put buffer to accommodate the argument character sequence. The function returns traits::eof() if it fails to make more room available or if it fails to empty the buffer by writing the characters to their output device.

    streamsize
    xsputn(const char_type* s, streamsize n);

    Writes up to n characters to the output sequence. The characters written are obtained from successive elements of the array whose first element is designated by s. Writing stops when either n characters have been written or a call to sputc() would return traits::eof(). The function returns the number of characters written.

    damit macht der name overflow wieder Sinn 🙂
    ohne doku kommt man natuerlich nicht weit...



  • Gut, aber schaue dir bitte obigen Code an, der geht nach dem Prinzip, ich habe jetzt natürlich overflow nicht überladen, aber das sollte nicht so schlimm sein erstmal...
    Auf alle Fälle klappt es nicht und ich weiß nicht warum.



  • Mis2com schrieb:

    Auf alle Fälle klappt es nicht und ich weiß nicht warum.

    1. du hast das rdbuf() im Ctor der stream Klasse vergessen
    2. bei xsputn ist der 1. Parameter const

    folgender Code laeuft bei mir problemlos:

    #include <iostream> 
    #include <streambuf> 
    
    using namespace std; 
    
    class socket_iobuf : public streambuf 
    { 
    protected: 
        streamsize xsputn(char_type const* s, streamsize n) 
        { 
            int xJSADFKLJ; 
            std::cout << s; 
            return n; 
        }
    
    public:    
    }; 
    
    class socket_stream : public ostream 
    { 
    protected: 
        socket_iobuf iobuf_; 
    public: 
        socket_stream() : ostream(0) { rdbuf(&iobuf_); } 
    
    }; 
    
    int main() 
    { 
        socket_stream foo; 
        foo << "Hallo"; 
    
        return 0; 
    }
    


  • Ich verstehe gar nicht, was das rdbuf soll...

    Und das mit const char* stimmt, verdammt, dann denke ich immer, es liegt NICHT an solchen Kleinigkeiten, sondern an dicken Fehlern...

    Ja, aber das kommt, wenn man es nicht versteht, und ich kann es nicht verstehen, der Code sogut wie gar nicht kommentiert und daher unbrauchbar für Leute, die sich nicht auskennen.

    Danke jedenfalls,

    MfG Mis2com



  • Danke 🙂

    Jetzt versteh ich endlich wie ich meine Klasse über iostream implementieren kann 😋



  • Ich habe einfach keinerlei Hintergrundwissen zur STL, ich weiß jetzt so etwa, welche Klasse von welcher erbt, aber ich kapier char_traits und das ganze Template-Zeugs nicht, die ganzen Funktionen etc.pp.

    Wie kann ich das erlernen? Eine Dokumentation alleine offenbart die ganzen Zusammenhänge nicht gut.



  • Mis2com schrieb:

    Ich verstehe gar nicht, was das rdbuf soll...

    Das setzt einfach den buffer.
    Woher soll ostream denn sonst wissen, welchen buffer es verwenden soll?



  • und was heißt hier bitte verwenden?
    Was man mit dem, was durch << rein und >> raus geht, macht, entscheidet man doch selber, wozu braucht der dann einen buffer?



  • Mis2com schrieb:

    und was heißt hier bitte verwenden?
    Was man mit dem, was durch << rein und >> raus geht, macht, entscheidet man doch selber, wozu braucht der dann einen buffer?

    Der buffer erledigt die ganze Arbeit! Er puffert und er schreibt.

    der stream macht nur die formatierungen - er achtet auf setw, fill, etc. und er wandelt alles in strings um. Dann gibt er den fertigen string an den buffer weiter - dort wird dann eben gepuffert (oder auch nicht, bei deinem code wird nicht gepuffert) und schreibt die daten dann nach cout.

    woher soll ostream denn wissen, welchen buffer es verwenden soll, wenn man ihm mit rdbuf() nicht sagt welchen puffer er verwenden soll?

    das ganze konzept basiert darauf, dass ein stream 'dumm' ist. ostream macht die arbeit alleine - eine abgeleitete stream klasse ist nur dafuer da, den streambuffer automatisch zu setzen.

    man kann auch
    ostream s(0);
    s.rdbuf(&mein_puffer);

    schreiben - aber da das unpraktisch ist, leitet man eine klasse von ostream ab, die das uebernimmt.



  • Shade Of Mine schrieb:

    [...]weiter - dort wird dann eben gepuffert (oder auch nicht, bei deinem code wird nicht gepuffert) und schreibt die daten dann nach cout.
    [...]

    Jetzt verwirrst du mich, ich kann die Daten doch nicht nur nach cout schreiben
    sondern dorthin wo ich will, oder?



  • SirLant schrieb:

    Jetzt verwirrst du mich, ich kann die Daten doch nicht nur nach cout schreiben
    sondern dorthin wo ich will, oder?

    logisch. ich habe das jetzt nur mal auf den beispielcode bezogen.
    der streambuf ist fuer das verwalten (puffern, schreiben, uU komprimieren oder verschluesseln,...) zustaendig.



  • Mis2com schrieb:

    Ich habe einfach keinerlei Hintergrundwissen zur STL

    Das hat nichts mit der Standard Template Library zu tun - das sind nämlich nur die Container und Algorithmen, die man am einfachsten an den vernünftig gewählten Namen von den IOStreams unterscheiden kann 😉



  • Wieso gehört der streambuf nicht zur STL?
    Wozu denn dann? Es ist ja nichts, was einfach so optional dazu gebaut wird, weil es keine STL Implementierung gibt, die ohne basic_streambuf arbeitet, oder etwa doch?

    Mir ist das jetzt jedenfalls klar, danke.

    MfG Eisflamme


Anmelden zum Antworten