C and C++

Moderators: None (Apply to moderate this forum)
Number of threads: 28629
Number of posts: 94611

This Forum Only
Post New Thread
Single Post View       Linear View       Threaded View      f

Report
C++ fstream.read() question... Posted by Sephiroth on 26 Feb 2009 at 9:30 AM
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.
//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

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.

-Sephiroth
Report
Re: C++ fstream.read() question... Posted by richfell on 26 Feb 2009 at 9:57 AM
Sephiroth, one thing about pColors. I am assuming from your comment that it is of type "unsigned char[4]"? If that is correct then you would need:

...
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);
...


I think that you could code the reading of those four values like this as well:

...
pFile->read((char*)this->pColor, 4);
...


Perhaps another thing to consider adding is some error checking after the read calls using fstream::fail.
Report
Re: C++ fstream.read() question... Posted by Sephiroth on 26 Feb 2009 at 10:13 AM
You know, I can read it as a pointer to the array and reading in four bytes. I did that up top with the float array, so I don't know what I was thinking when I coded the colors section. It was late last night, so I must have been shutting my brain down. Thanks for pointing it out though.

What about the read calls? I am specifying a pointer to a char, but am reading in all kinds of stuff. Is that OK?

-Sephiroth
Report
Re: C++ fstream.read() question... Posted by richfell on 26 Feb 2009 at 2:13 PM
That is OK, essentially all that does is give the starting memory address that read is supposed to use.

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 endianness. 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.
Report
Re: C++ fstream.read() question... Posted by Sephiroth on 26 Feb 2009 at 4:10 PM
I've actually never run into a problem with endianness. I am writing a program that will edit a GTA:SA save and allow the user to modify, add, or remove vehicles from his or her garages in the game. GTA:SA runs on the PS2, XBox, and PC, but I am using my PC version for this project. Assuming a person could get a PS2 or XBox save onto a Windows machine, that may be the only place I could see a problem with endianness. That said, is there a way to detect this, or is it something that must be known beforehand?

-Sephiroth
Report
Re: C++ fstream.read() question... Posted by richfell on 26 Feb 2009 at 11:34 PM
In general there is no way to detect the endianness unless there is a (1 byte) field purposefully stored in the file to indicate the byte order. I did a quick google for the GTA:SA save game file format and I don't see that they built that into the structure. I'm not sure if any Windows versions run on big-endian HW but if you give you program to a friend you may want to make sure they are running on a compatible architecture :)

Report
Re: C++ fstream.read() question... Posted by Lundin on 27 Feb 2009 at 12:34 AM
This has nothing to do with the OS, but the processor.

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.
Report
Re: C++ fstream.read() question... Posted by richfell on 27 Feb 2009 at 8:37 AM
Yes, it's the processor. Please read my post more carefully...

:I'm not sure if any Windows versions run on big-endian HW...

Apparrently the XBox 360 is big-endian, interesting to hear that the original was little-endian.
Report
Re: C++ fstream.read() question... Posted by Sephiroth on 27 Feb 2009 at 8:42 PM
Yes, that is huge reason that the 360 is an epic failure. It can't play 90% of the games that were for the XBox. All of the Playstations are little-endian as far as I know, and they all play old games. You can even play PS1 games on a PS3!

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.

-Sephiroth



 

Recent Jobs

Official Programmer's Heaven Blogs
Web Hosting | Browser and Social Games | Gadgets

Popular resources on Programmersheaven.com
Assembly | Basic | C | C# | C++ | Delphi | Flash | Java | JavaScript | Pascal | Perl | PHP | Python | Ruby | Visual Basic
© Copyright 2011 Programmersheaven.com - All rights reserved.
Reproduction in whole or in part, in any form or medium without express written permission is prohibited.
Violators of this policy may be subject to legal action. Please read our Terms Of Use and Privacy Statement for more information.
Operated by CommunityHeaven, a BootstrapLabs company.