//---------------------------------------------------------------------------// #ifndef IMCRAW #define IMCRAW #include // #include #include "hexshow.hpp" #include "imc_key.hpp" #include "imc_block.hpp" //---------------------------------------------------------------------------// namespace imc { class raw { // (path of) raw-file and its basename std::string raw_file_, file_name_; // buffer of raw-file std::vector buffer_; // list of imc-blocks std::vector rawblocks_; public: // constructor raw() {}; raw(std::string raw_file): raw_file_(raw_file) { this->parse(); }; // provide new raw-file void set_file(std::string raw_file) { raw_file_ = raw_file; this->parse(); } // list all blocks in buffer void parse() { // open file and put data in buffer try { std::ifstream fin(raw_file_.c_str(),std::ifstream::binary); if ( !fin.good() ) throw std::runtime_error("failed to open file"); std::vector buffer((std::istreambuf_iterator(fin)), (std::istreambuf_iterator())); buffer_ = buffer; fin.close(); } catch ( const std::exception& e ) { throw std::runtime_error( std::string("failed to open raw-file and stream data in buffer: ") + e.what() ); } // start parsing raw-blocks in buffer for ( std::vector::iterator it=buffer_.begin(); it!=buffer_.end(); ++it ) { // check for "magic byte" if ( *it == ch_bgn_ ) { // check for (non)critical key if ( *(it+1) == 0x43 || *(it+1) == 0x4e ) { // compose entire key std::string newkey = { (char)*(it+1), (char)*(it+2) }; // check for known keys if ( keys.count(newkey) == 1 ) { // expecting ch_sep_ after key if ( *(it+3) == ch_sep_ ) { // extract key version std::string vers(""); unsigned long int pos = 4; while ( *(it+pos) != ch_sep_ ) { vers.push_back((char)*(it+pos)); pos++; } int version = std::stoi(vers); // get block length std::string leng(""); pos++; while ( *(it+pos) != ch_sep_ ) { leng.push_back((char)*(it+pos)); pos++; } unsigned long length = std::stoul(leng); // declare corresponding key and block imc::key bkey( (*(it+1)-0x43)==0, newkey, imc::keys.at(newkey).description_, version ); imc::block blk(bkey,it-buffer_.begin(), it-buffer_.begin()+8+length, raw_file_, &buffer_); // add block to list rawblocks_.push_back(blk); } else { throw std::runtime_error( std::string("invalid block or corrupt buffer at byte: ") + std::to_string(it-buffer_.begin()) ); } } else { throw std::runtime_error(std::string("unknown IMC key: ") + newkey); } } } } } // get blocks std::vector& blocks() { return rawblocks_; } }; } #endif //---------------------------------------------------------------------------//