2010-01-17 13 views
5

Estoy escribiendo una especie de biblioteca de sistema de archivos virtual para videojuegos de la talla de CRIS Middleware's ROFS (ver Wikipedia). Mi intención con la biblioteca es proporcionar medios naturales para acceder a los recursos de los juegos que desarrollo, que almacenan algunos datos incrustados en el ejecutable, algunos en los medios y otros en el disco duro del usuario local (preferencias, guardar archivos del juego, etc.) .¿Por qué std :: istream no asume la propiedad de su streambuf?

El acceso a estos recursos debe ser tan simple como hacer una llamada como

std::auto_ptr<std::istream> defaultConfigIStream(
    fslib.inputStream("self://defaultConfig.ini")); 
std::auto_ptr<std::ostream> defaultConfigOStream(
    fslib.outputStream("localappdata://config.ini")); 

// Copies default configuration to local user's appdata folder 
defaultConfigIStream >> defaultConfigOStream; 

La forma actual de hacer las cosas es en realidad diferente, con otra capa de abstracción usado para el fondo de carga, pero eso no es importante aquí.

Lo que quiero saber es ¿cómo puedo volver que auto_ptr<> (o unique_ptr<>, que usted elija) teniendo en cuenta que el std::streambuf<> asociado con el std::[i/o]stream<> no se elimina por él cuando es destruido.

Considero que std::[i/o]stream<> no asume la propiedad sobre el streambuf que se le pasó en la construcción ya que el constructor no presenta la semántica de transferencia de propiedad y la referencia STDCXX de Apache no menciona transer de propiedad (ni ninguno de los stdlib referencias que he encontrado en internet).

¿Qué alternativas tengo? También podría devolver un puntero compartido y seguir mirándolo hasta que el administrador de FSlib conserve una copia única del puntero compartido, en cuyo caso destruiría su copia única así como también el streambuf. Eso es práctico, teniendo en cuenta el modelo de organización de la biblioteca, pero esto no es muy elegante ni eficiente en ese sentido.

He intentado echar un vistazo a Boost.Iostreams, pero parece que las cosas son incluso peores para mí, ya que las transmisiones tienen sus tipos de dispositivos fuertemente vinculados a su tipo (el dispositivo para una secuencia debe definirse en su parámetro de plantilla). Este problema parece hacer que el uso de Boost.Iostreams sea inviable para mi biblioteca, ya que necesita abstraer la implementación concreta de "fuente/sumidero" de las secuencias para que las transmisiones se puedan usar a la perfección para abrir un archivo ubicado dentro del ejecutable, dentro de un archivo del sistema de archivos del sistema o dentro de un archivo de tipo archivo, por ejemplo.

Podría escribir una clase de contenedor que maneje estos problemas, pero preferiría hacerlo de forma más limpia (es decir, simplemente devolver la secuencia ya existente, ¡eso es todo lo que necesita!).

Sugerencias?

Respuesta

7

Puede derivar sus propias clases de flujo de istream resp. ostream, configure el buffer en el constructor y destrúyalo en el destructor.

Algo así como:

class config_istream : public std::istream { 
public: 
    config_istream(std::string name) : 
     std::istream(fslib.InputStream(name.c_str())) 
    { 
    } 

    ~config_istream() { delete rdbuf(); } 
}; 

echar un vistazo a cómo se implementan las fstream clases, que hacer frente a un problema similar (filebuf tiene que ser eliminado junto con fstream)

+0

Sí, como he dicho por al final de la pregunta, creo que tendré que hacer eso. Solo quería saber si había alguna forma más fácil de hacerlo. XD Gracias. –

Cuestiones relacionadas