I'm trying to go more to the C++ side of things and break away from plain old C and part of that is using fstream for file access instead of fread/fwrite. I know how to open a file for reading and/or writing, but when it comes to the actual reading and writing of binary files I am still not sure that I am coding it properly. Below is a chunk of code designed to read in a section of binary data from a GTA:SA save game. The code compiles without warning or error, but I just feel uneasy about it since everything has to be type-cast to char* just to read in. Can somebody offer me some advice on reading and writing data with fstream? I mean binary files, not text-mode.
[code]
//Read the car object data from the current stream location
pFile->read((char*)this->pPosition, 12); //float[3]
pFile->seekg(ios::cur, 4);
pFile->read((char*)&(this->ucFlags), 1); //unsigned char
pFile->seekg(ios::cur, 1);
pFile->read((char*)&(this->sModelID), 2); //short
pFile->read((char*)this->pMods, 30); //short[15]
pFile->read((char*)this->pColors[0], 1); //unsigned char[4]
pFile->read((char*)this->pColors[1], 1); //unsigned char[4]
pFile->read((char*)this->pColors[2], 1); //unsigned char[4]
pFile->read((char*)this->pColors[3], 1); //unsigned char[4]
pFile->read((char*)&(this->ucRadioStation), 1); //unsigned char
pFile->read((char*)this->pVariation, 2); unsigned char[2]
pFile->read((char*)&(this->ucBombType), 1); //unsigned char
pFile->read((char*)&(this->ucPaintJob), 1); //unsigned char
pFile->read((char*)&(this->ucNitrous), 1); //unsigned char
pFile->read((char*)this->pRotation, 3); //unsigned char[3]
pFile->read((char*)&(this->ucAlign), 1); //unsigned char
[/code]
I am specifically not sure whether or not I coded the color section properly since I am specifying a specific point in the color array. Thanks for any help you can offer.
-[italic][b][red]S[/red][purple]e[/purple][blue]p[/blue][green]h[/green][red]i[/red][purple]r[/purple][blue]o[/blue][green]t[/green][red]h[/red][/b][/italic]
Comments
[code]
...
pFile->read((char*)&this->pColor[0], 1);
pFile->read((char*)&this->pColor[1], 1);
pFile->read((char*)&this->pColor[2], 1);
pFile->read((char*)&this->pColor[3], 1);
...
[/code]
I think that you could code the reading of those four values like this as well:
[code]
...
pFile->read((char*)this->pColor, 4);
...
[/code]
Perhaps another thing to consider adding is some error checking after the read calls using fstream::fail.
What about the read calls? I am specifying a pointer to a char, but am reading in all kinds of stuff. Is that OK?
-[italic][b][red]S[/red][purple]e[/purple][blue]p[/blue][green]h[/green][red]i[/red][purple]r[/purple][blue]o[/blue][green]t[/green][red]h[/red][/b][/italic]
However, I'll make a point, forgive me if you know this already:
The issue with reading multi-byte values, like float, short or long for example, from a binary file or a binary data stream is [link=http://en.wikipedia.org/wiki/Endianness]endianness[/link]. So unless the file specification states a given endianness for its multi-byte values you may not read the correct values in the case where the file was written under one endian architecture and read under the other endian architecture.
There is no issue when reading 1 byte values, or an array of 1 byte values.
-[italic][b][red]S[/red][purple]e[/purple][blue]p[/blue][green]h[/green][red]i[/red][purple]r[/purple][blue]o[/blue][green]t[/green][red]h[/red][/b][/italic]
PC and Xbox have Intel CPUs = little endian. Playstation seems to use some custom-made CPU, I don't know whether it is big/little endian.
:I'm not sure if any Windows versions run on big-endian [b]HW[/b]...
Apparrently the XBox 360 is big-endian, interesting to hear that the original was little-endian.
Consoles aside, I myself have already deciphered much of the save format myself and upon looking at that link, I was right in my discoveries. I have a few things that the link doesn't, however. I'm building the UI around the class now, since my fstream question was answered.
-[italic][b][red]S[/red][purple]e[/purple][blue]p[/blue][green]h[/green][red]i[/red][purple]r[/purple][blue]o[/blue][green]t[/green][red]h[/red][/b][/italic]