Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>What you should do is write a streambuf which uses the QDataStream readBytes and writeBytes to implement its functions. Then register the streambuf into a istream with rdbuf (you can also write an istream descendant which does this when initialized).</p> <p>Boost contains a library aiming at facilitating the writing of streambuf. It could be simpler to use it than understanding the streambuf interface (personally I never have used it but I've written multiple streambuf; I'll see if I've a example that I can post).</p> <p>Edit: here is something (commented in French -- it comes from the french FAQ of fr.comp.lang.c++ --, I have no time for translation and think it is better to leave them than to remove them) which wraps FILE* call into a streambuf. This also is a show case of a use of private inheritance: ensuring that what could be a member is initialized before a base class. In the case of IOStream, the base class could as well receive a NULL pointer and then the member init() used to set the streambuf.</p> <pre><code>#include &lt;stdio.h&gt; #include &lt;assert.h&gt; #include &lt;iostream&gt; #include &lt;streambuf&gt; // streambuf minimal encapsulant un FILE* // - utilise les tampons de FILE donc n'a pas de tampon interne en // sortie et a un tampon interne de taille 1 en entree car l'interface // de streambuf ne permet pas de faire moins; // - ne permet pas la mise en place d'un tampon // - une version plus complete devrait permettre d'acceder aux // informations d'erreur plus precises de FILE* et interfacer aussi // les autres possibilites de FILE* (entre autres synchroniser les // sungetc/sputbackc avec la possibilite correspondante de FILE*) class FILEbuf: public std::streambuf { public: explicit FILEbuf(FILE* cstream); // cstream doit etre non NULL. protected: std::streambuf* setbuf(char_type* s, std::streamsize n); int_type overflow(int_type c); int sync(); int_type underflow(); private: FILE* cstream_; char inputBuffer_[1]; }; FILEbuf::FILEbuf(FILE* cstream) : cstream_(cstream) { // le constructeur de streambuf equivaut a // setp(NULL, NULL); // setg(NULL, NULL, NULL); assert(cstream != NULL); } std::streambuf* FILEbuf::setbuf(char_type* s, std::streamsize n) { // ne fait rien, ce qui est autorise. Une version plus complete // devrait vraissemblablement utiliser setvbuf return NULL; } FILEbuf::int_type FILEbuf::overflow(int_type c) { if (traits_type::eq_int_type(c, traits_type::eof())) { // la norme ne le demande pas exactement, mais si on nous passe eof // la coutume est de faire la meme chose que sync() return (sync() == 0 ? traits_type::not_eof(c) : traits_type::eof()); } else { return ((fputc(c, cstream_) != EOF) ? traits_type::not_eof(c) : traits_type::eof()); } } int FILEbuf::sync() { return (fflush(cstream_) == 0 ? 0 : -1); } FILEbuf::int_type FILEbuf::underflow() { // Assurance contre des implementations pas strictement conformes a la // norme qui guaranti que le test est vrai. Cette guarantie n'existait // pas dans les IOStream classiques. if (gptr() == NULL || gptr() &gt;= egptr()) { int gotted = fgetc(cstream_); if (gotted == EOF) { return traits_type::eof(); } else { *inputBuffer_ = gotted; setg(inputBuffer_, inputBuffer_, inputBuffer_+1); return traits_type::to_int_type(*inputBuffer_); } } else { return traits_type::to_int_type(*inputBuffer_); } } // ostream minimal facilitant l'utilisation d'un FILEbuf // herite de maniere privee de FILEbuf, ce qui permet de s'assurer // qu'il est bien initialise avant std::ostream class oFILEstream: private FILEbuf, public std::ostream { public: explicit oFILEstream(FILE* cstream); }; oFILEstream::oFILEstream(FILE* cstream) : FILEbuf(cstream), std::ostream(this) { } // istream minimal facilitant l'utilisation d'un FILEbuf // herite de maniere privee de FILEbuf, ce qui permet de s'assurer // qu'il est bien initialise avant std::istream class iFILEstream: private FILEbuf, public std::istream { public: explicit iFILEstream(FILE* cstream); }; iFILEstream::iFILEstream(FILE* cstream) : FILEbuf(cstream), std::istream(this) { } // petit programme de test #include &lt;assert.h&gt; int main(int argc, char* argv[]) { FILE* ocstream = fopen("result", "w"); assert (ocstream != NULL); oFILEstream ocppstream(ocstream); ocppstream &lt;&lt; "Du texte"; fprintf(ocstream, " melange"); fclose(ocstream); FILE* icstream = fopen("result", "r"); assert (icstream != NULL); iFILEstream icppstream(icstream); std::string word1; std::string word2; icppstream &gt;&gt; word1; icppstream &gt;&gt; word2; char buf[1024]; fgets(buf, 1024, icstream); std::cout &lt;&lt; "Got :" &lt;&lt; word1 &lt;&lt; ':' &lt;&lt; word2 &lt;&lt; ':' &lt;&lt; buf &lt;&lt; '\n'; } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload