tl;dr: What are necessary control characters that custom file must have in order not to trigger [or trigger] badbit, failbit, badbit, eofbit
dependant on OS?
I am working with Cygwin and Notepad++, using Windows 7 on an x64 laptop.
I have an file called genesis.o
that I typed in hex editor that is in same directory as sandbox.cpp
from which I am doing reading/writing. The file "genesis.o" contains:
genesis.o
-----------------
58 - 4f - 58 - 4f
58 - 58 - 58 - 58
3f - 3f - 3f - 3f
00 - 00 - 00 - 3f
00 - 00 - 3f - 00
00 - 3f - 00 - 00
3f - 00 - 00 - 00
00 - 00 - 00 - 58
00 - 00 - 58 - 00
00 - 58 - 00 - 00
58 - 00 - 00 - 00
48 - 45 - 4c - 4c
So far, I have read and manipulated custom structures without any regard of validity of the file. I used stat
to check if file is accessible and that was enough.
This file (with and without extension ".o") passes all check ups I made except file.rdstate
in which it always returns 4
(std::ios::failbit
).
Error doesn't show itself on any other normal file, so I am guessing that some sort of control character sequence before/after or in file actually tells the std::fstream
that file is valid.
Since no other file (except those typed in a hex editor) triggers this behaviour, is there a way to structure an custom binary file to be recognised by fstream? Some sort of control characters, preset flags etc.?
I am using std::ios:in | std::ios:binary
. I am reading it by getting stat buffer.st_size
-> divide it by 4 (since I read 4 byte integers) and:
uitn32_t temp = 0;
file.read( (char *)(&temp), sizeof(uint32_t) );
It is notable to mention, that I can read that binary file even if file.rdstate
returns an failbit
.
Minimal testable example. Just make an "genesis.o" file with character specification above.
#include <fstream>
#include <iostream>
#include <string>
#include <sys\types.h>
#include <sys\stat.h>
#include <vector>
struct handl{
std::string name = "genesis";
std::string ext = "o";
std::vector<uint32_t> mem;
bool acces = false;
struct stat buffer;
handl():mem(0),name("genesis"),ext("o"){}
const char *f_name(){
std::string f_n = this->name;
f_n.append(".");
f_n.append(this->ext);
return f_n.c_str();
}
void recheck(){
this->acces = ( stat(this->f_name(), &this->buffer ) == 0 );
}
virtual bool header( std::fstream &file )
{return true;}
virtual bool footer( std::fstream &file )
{return true;}
void operator()(){ this->recheck(); }
void operator()( const char *name, const char *ext ){
this->name = std::string(name);
this->ext = std::string(ext);
this->recheck();
}
void prefix( const char* pre ){
std::string pn(pre);
pn.append( this->name );
this->name = pn;
}
void suffix( const char *su ){
this->name.append(su);
this->recheck();
}
int read(){
this->recheck();
if( !this->acces ){return 0;}
std::fstream file;
file = std::fstream( this->f_name(), std::ios::in | std::ios::binary );
if( this->header(file) && this->footer(file) ){
int byte_size = this->buffer.st_size;
std::cout << file.rdstate() << std::endl;
std::cout << "gb\t" << std::ios::goodbit << std::endl;
std::cout << "bb\t" << std::ios::badbit << std::endl;
std::cout << "eb\t" << std::ios::eofbit << std::endl;
std::cout << "fb\t" << std::ios::failbit << std::endl;
file.close();
return 1;
}else{
file.close();
return 0;
}
}
};
int main(){
handl f;
std::cout << f.read() << std::endl;
return 0;
}