Byte by Byte Save and Load?

Started by
5 comments, last by deathkrush 17 years, 10 months ago
Okay here's my plan. I have made my game objects, and they have no pointers or resource members. So I think I can serialize just by copying byte by byte the data and putting it in a file. Then I would load the file into my game list. Here are my questions: Saving: -How would I read a object in the heap each byte, im not sure how to dereference that data, if I just "<<" a class into a file would it save it as a binary? Loading: -How would I be able to fill a pointer with this byte information? -Would the saves be portable? If someone saves under a P2 would the file load under a AMD? Thank you!
Advertisement
Saving:
1. Not sure about streams but you can definitely use the C API file stuff for this.
Loading:
1. You can't, unless you were to determine your program byte offset and then make sure the pointers load up with the 'new' byte offset when you run your program.

Otherwise, you might run your program at offset 0xABCD once and so you'll have the pointer 0xABCD + 1; the next time you run the program you might be at offset 0xADDD and so the pointer must be at 0xADDD + 1.

This assumes all of your data loads in exactly the same way again. This means that's a bad idea. Use named/numbered references (UID system perhaps).

2. This is portable between machines of the same endianness (Intel machines are little endian) but you'll be in development hell if you port to a machine with different endianness (PowerPC machines are big endian).

Binary writing is generally a good idea, but I'd be very careful about how you approach pointers and endianness. APIs like PhysicsFS can put out a single binary "virtual filesystem" that you can stock with text files (and they handle the endianness, etc); this might be a better idea.
Quote:Original post by MetaKnight
Okay here's my plan. I have made my game objects, and they have no pointers or resource members. So I think I can serialize just by copying byte by byte the data and putting it in a file. Then I would load the file into my game list.

Here are my questions:
Saving:

-How would I read a object in the heap each byte, im not sure how to dereference that data, if I just "<<" a class into a file would it save it as a binary?


You need to implement operator<< to stream a class into a file with it. To do this bytewise would look something like:

class foo {    int member;public:    friend std::ostream & operator<<( std::ostream & os , const foo & savee ) {        os.write( (const char *)&member , sizeof( member ) );        return os;    }};//std::cout << foo();


Note that streams, even in binary mode, typically save as text when using operator<<, so what I've done above is somewhat bad mojo. You'll note I didn't write "os << member;", which would have had this effect. Changing it to something like "write_to" might be more appropriate:

class foo {    int member;public:    std::ostream & write_to( std::ostream & os , const foo & savee ) {        os.write( (const char *)&member , sizeof( member ) );        return os;    }};//foo().write_to( std::cout );


Quote:Loading:

-How would I be able to fill a pointer with this byte information?


See operator>> and read() to compare to the above.

You might want to take a look at boost::serialization as well. It can automatically take care of some of the nasty confusing stuff that comes into play when you're trying to save things which have pointers every which way to each other :).
Ah thank you!
this stuff looks like a great place to start working on this.

Quote:Original post by MaulingMonkey
Changing it to something like "write_to" might be more appropriate:

class foo {    int member;public:    std::ostream & write_to( std::ostream & os , const foo & savee ) {        os.write( (const char *)&member , sizeof( member ) );        return os;    }};//foo().write_to( std::cout );


Um, I think you wanted to make that a static function since it's not an operator any more :)

Anyway, I keep the following on hand for just this purpose:

template <typename pod>// If you use this with a non-POD type, serious bad mojo occurs. So// don't even freakin think about it! :)void write_pod(std::ostream& os, const pod& p) {  os.write(reinterpret_cast<const char*>(&p), sizeof(pod));}


And by "on hand" I mean "in brain", because I've rewritten that so many times on the forums x.x
The << and >> operators are designed for formatted text and will not work with binary data. Take a look at this page for an introduction on binary file I/O in C++: C++ Binary File I/O
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
Boost has a serialization library that's designed to do these kinds of things.

deathkrushPS3/Xbox360 Graphics Programmer, Mass Media.Completed Projects: Stuntman Ignition (PS3), Saints Row 2 (PS3), Darksiders(PS3, 360)

This topic is closed to new replies.

Advertisement