Lo que debe hacer es escribir un streambuf que use QDataStream readBytes y writeBytes para implementar sus funciones. A continuación, registre el streambuf en un istream con rdbuf (también puede escribir un descendiente istream que lo hace cuando se inicializa).
Boost contiene una biblioteca con el objetivo de facilitar la escritura de streambuf. Podría ser más sencillo usarlo que entender la interfaz de streambuf (personalmente, nunca lo he usado, pero he escrito varios streambuf; veré si tengo un ejemplo que puedo publicar).
Editar: aquí hay algo (comentado en francés - proviene de las preguntas frecuentes en francés de fr.comp.lang.C++ -, no tengo tiempo para la traducción y creo que es mejor dejarlos que eliminarlos)) que envuelve la llamada FILE * en un streambuf. Este también es un ejemplo de uso de herencia privada: garantizar que lo que podría ser miembro se inicialice antes de una clase base. En el caso de IOStream, la clase base también podría recibir un puntero NULL y luego el miembro init() utilizado para establecer el streambuf.
#include <stdio.h>
#include <assert.h>
#include <iostream>
#include <streambuf>
// 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() >= 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 <assert.h>
int main(int argc, char* argv[])
{
FILE* ocstream = fopen("result", "w");
assert (ocstream != NULL);
oFILEstream ocppstream(ocstream);
ocppstream << "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 >> word1;
icppstream >> word2;
char buf[1024];
fgets(buf, 1024, icstream);
std::cout << "Got :" << word1 << ':' << word2 << ':' << buf << '\n';
}
se desea escribir su propia implementación de read_something, o está tratando de llamar a esta función? – Ropez