You have a weird conceptual problem with functions.
Typically... in the most simplistic casts.... Parameters are for
input and the return value is for
output. You are trying to use parameters for both input and output from a function -- and while this can be done, it should be avoided because it makes code harder to write, more error prone, and more confusing.
Your function is conceptually very simple. It has some input:
input 1) A stream
input 2) A position in that stream
input 3) Number of bytes to read from that stream (although this is questionable -- I'll get more into this later)
And it has some output:
output 1) The boot signature
output 2) Whether or not the boot signature is valid.
Now... here's the thing.... Those 2 outputs are contained in your mbr_t struct. So you really only have 1 output: an mbr_t. Since you only have 1 output, use the return value to output it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
mbr_t checkBootSignature( const char* filename, uint offset, uint bytes )
{
mbr_t output;
// fill 'output' with the desired data from the given filename.
return output; // <- return it as the output of this function
}
int main(int argc, char** argv)
{
mbr_t mbr = checkBootSignature( argv[1], 510, 2 ); // <- check the boot signature
// returned output is stored in our 'mbr' variable.
// (also note I made it local to main instead of being global because globals are
// yukky)
}
|
So you can consolidate your output there to make your function more practical. But your input is questionable as well.
For starters... your function will utterly fail unless 'bytes' is 2. Any other value will totally screw up the works. Unless you are planning for this function to do more work than it currently does, the bytes parameter doesn't really make a lot of sense.
Furthermore... as you mentioned, the function is opening/closing the file which is inefficient, especially if you are going to be reading several blocks from this file. Therefore you should probably pass the stream itself to the function by reference, rather than the filename.
So let's touch this up a bit more:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
mbr_t checkBootSignature( istream& stream, uint offset )
{
mbr_t output;
// fill 'output' with the desired data from the given stream+offset
return output; // <- return it as the output of this function
}
int main(int argc, char** argv)
{
ifstream bootfile( argv[1] ); // now main is responsible for opening/closing the file
mbr_t mbr = checkBootSignature( bootfile, 510 ); // <- pass that file to our function
// now you can do it repeatedly without closing/reopening the same file:
mbr_t foobar = checkBootSignature( bootfile, 620 );
}
|
Lastly... I would consider removing the 'offset' parameter as well... and leave it up to the calling code to put the stream where it needs to be... but that's a judgement call.
Generally you want functions to do 1 thing. If you overreach they tend to get clunky. Here, the function is gathering information about the boot header. That's it's job. When you start having it do other things that aren't really related to that (opening/seeking through a file), then it gets weird.