boost::iostreams -> fread?
-
Hi.
Ich versuche grade ein Dateiformat zu erstellen um Shader in einer einzigen Datei unterzubringen. Dazu habe ich mir boost::iostreams angeschaut, da der auch zippen kann und das eine gute Möglichkeit ist den Code ein wenig zu verstecken ohne viel Aufwand.
Nur stehe ich grade a bissl aufm Schlauch:namespace bi = boost::iostreams; bool NLShaderLoader::saveShader( const std::string& filename, const std::string& vertex, const std::string& fragment ) { // Create standard ofstream std::ofstream file(filename.c_str(), std::ios_base::out|std::ios_base::binary); assert(file.good()); if ( file.is_open() ) { // Create filter bi::filtering_ostream out; out.push(bi::zlib_compressor()); out.push(file); // Write Length out << vertex.length() << "\n"; out << fragment.length() << "\n"; // Write source out << vertex << "\n"; out << fragment << "\n"; } return true; }Die Funktion ist sehr einfach. Sie speichert die Länge des SourceCodes und schreibt diese in die Datei, damit man später das einfacher auslesen kann. Und genau da liegt mein Verständnisproblem grade^^.
namespace bi = boost::iostreams; NLShader* NLShaderLoader::loadShader( const std::string& name, const std::string& filename ) { std::ifstream file(filename.c_str(), std::ios_base::in|std::ios_base::binary); assert(file.good()); if ( file.is_open() ) { std::string vertex, fragment; int vert_len = 0; int frag_len = 0; // Create filter bi::filtering_istream in; in.push(bi::zlib_decompressor()); in.push(file); in >> vert_len; in>> frag_len; NLShader* s = this->createFromMemory(name.c_str(), vertex.c_str(), fragment.c_str()); return s; } return NULL; }boost::filtering_istream hat jetzt kein fread. Jetzt stehe ich a bissl aufm Schlauch. Ich kann ja nicht einfach aus dem std::ifstream lesen, denn dann lese ich ja das gezippte zeug.
Hmm, hoffe es kann wer ein wenig helfen.
Danke.
-
Hab jetzt eine relativ einfache Lösung gefunden:
bool NLShaderLoader::saveShader( const char* filename, const std::string& vertex, const std::string& fragment ) { // Create standard ofstream std::ofstream file(filename, std::ios_base::out|std::ios_base::binary); assert(file.good()); if ( file.is_open() ) { // Create filter bi::filtering_ostream out; out.push(bi::zlib_compressor()); out.push(file); // Write source out << vertex << "\n"; out << "//--[[]]--\n"; out << fragment << "\n"; } return true; } bool NLShaderLoader::loadShader( const std::string& name, const char* filename, std::string& o_vertex, std::string& o_fragment ) { std::ifstream file(filename, std::ios_base::in|std::ios_base::binary); assert(file.good()); if ( file.is_open() ) { std::stringstream vertex, fragment; // Create filter bi::filtering_istream in; in.push(bi::zlib_decompressor()); in.push(file); std::stringstream ss; bi::copy( in, ss ); // Read Vertex Shader { std::string line; do { std::getline(ss, line); if ( line != "//--[[]]--") { vertex << line << "\n"; } }while( line != "//--[[]]--"); } // Read Fragment Shader { std::string line; do { std::getline(ss, line); fragment << line << "\n"; }while( !ss.eof() ); } o_vertex = vertex.str(); o_fragment = fragment.str(); return true; } return false; }Die Herausforderung ist, zwischen den beiden Teilen zu unterscheiden. Das einfachste schien es mir, einen "Tag", in dem Fall "//--[[]]--" zu reservieren, der im normalen Code nicht vorkommen sollte.
Falls jemand noch bessere Lösungen hat, immer her damit :).