Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-

C++ - data serialization

Name: Anonymous 2011-07-06 7:44

I needed to serialize some simple data structures in C++ code and remembered how to do it in C#. It was like 9001 lines of code of boilerplate crap in .NET environment.

Well, in C++ it was of course hard because C++ is such crappy language, rite?


template<typename T>
bool serializeData(const T &data, std::ostream &os)
{
    os.write(reinterpret_cast<const char*>(&data), sizeof(data));
    return os.good();
}

template<typename T>
bool deserializeData(T &data, std::istream &is)
{
    is.read(reinterpret_cast<char*>(&data), sizeof(data));
    return is.good();
}

Name: Anonymous 2011-07-06 7:58

Enjoy your unportable data.

Name: Anonymous 2011-07-06 8:17

>>2
Fuck you,you fucking blindless virgin cocksucker,dicksucker,nigger,faggot,and probably you're a fatfuck fucking dickmouth you're really a fucking nigger faggot fucker

Name: 1 2011-07-06 8:59

>>2
Well it should work if the architecture is the same for serializing and deserializing, and that's enough for me

Name: >>1 2011-07-06 9:00

>>3
Go back to /b/

Name: Anonymous 2011-07-06 9:36

>>1
U FORGOT ABOUT POINTERS BRO

Fuck, I can't imagine how dumb you must be to come here with this shit. I'm even willing to bet one third of my anal virginity on the idea that you wouldn't immediately understand what I'm talking about. IHBT.

Name: Anonymous 2011-07-06 10:01

>>6
Go back to /faggot/, ``faggot"

Name: Anonymous 2011-07-06 10:06

>>6

you wouldn't immediately understand what I'm talking about.

That must be because /prog/ is not for programming?

Name: Anonymous 2011-07-06 10:25

>>8
No, that's because OP is a moron.

Also, go back to reddit and take your extra spacing after quote with you.

Name: Anonymous 2011-07-06 11:08

>>9
/prog/ is full of stupid threads. i don't see how OP is more moron than average poster.

Name: 1 2011-07-06 12:14

>>9
Op here,
How am I a moron?

Name: Anonymous 2011-07-06 12:35

The OP's code is so fucking awful it exhausts me just to consider replying to it.

Name: Anonymous 2011-07-06 13:25

>>4
well if that's a safe assumption...

Name: >>1 2011-07-06 13:31

>>12
Fuck you, and tell me how to improve my code.

Name: Anonymous 2011-07-06 13:32

>>14
write it in C with a function that takes a void pointer, a size, and a FILE*

I'm not kidding.

Name: 1 2011-07-06 13:59

>>15
I had that in the start (in C++ though), but I rewrote it using C++ streams. I think that stream solution is better because I can change serialization code easily just bu overriding serializeData function.

So if I need more portable data serialization (between different architectures) I would just need to rewrite that single function (well one for every data struct, but easier than C solution still).

Name: Anonymous 2011-07-06 14:00

>>15
Are you "implying" that code written after 1980 should still use void pointers?

Name: Anonymous 2011-07-06 14:24

>>17
Yes.

Name: Anonymous 2011-07-06 15:25

>>18
void *you()

Name: Anonymous 2011-07-06 19:58

Hey OP, expert C++ programmer here. If you're concerned about preformance, such as with games development, do not use C++ iostreams. They are bloated as hell, seriously, there's like a couple of dozen nested function calls, many of which are virtual, before it hits the native OS level functions. They also do not provide any facilities for asynchronous I/O. The standard C library file I/O functions are better, but they still needless extra buffering that the OS already does for you.

Most game programmers and other performance conscious people use the native OS file I/O functions directly. On POSIX/UNIX like systems, this is usually the POSIX open/close/read/write/lseek family of functions. On Windows, it's OpenFile, CloseFile ReadFile, WriteFile, etc. Game consoles have their own custom file system libraries.

What I do is write a very thin file_stream class which acts as a portable abstraction layer on top of these APIs. No virtual member functions, no extra buffering, and provide support for asynchronous streaming.

Since almost all of my IO is done asynchronously, I read entire files, or very large blocks from files, into memory first before parsing them. This allows me to separate my concerns much better and avoid polymorphic class heirarchies. I have a simple byte_stream class which just acts as a stream-like pointer abstraction over a contiguous block of memory, used for binary serialization. I also reuse this class for binary network packet serialization.

Name: Anonymous 2011-07-06 20:03

>>17
And yes. You shouldn't buy into the solution of C++ being a high-level language like Java or C#. It's not. It's a low-level programming language with a variety of higher-level abstractions at your disposal.

In fact, I would say people who strive hard to eliminate all instances of void* in the name of "type safety" are following a practice that should be considered harmful. Type safety good, but it's just an illusion. And when you end up sacrificing performance in the name of "type safety," and the end result is code that is just as easy to break with a few pointer casts anyway, what really are you gained?

Name: Anonymous 2011-07-07 1:34

>>21
It's a low-level programming language with a variety of bullshit masquerading as higher-level abstractions at your disposal.

fify

Name: Anonymous 2011-07-07 2:43

>>22
low-level
You can't fuck up the call stack.

Name: Anonymous 2011-07-07 2:45

>>21
A properly typed program enables a whole new world of optimizations. That requires a decent type system.

Name: Anonymous 2011-07-07 3:47

Trivial code for a trivial problem. Come back when you figure out how to serialize entire object graphs.

Name: Anonymous 2011-07-07 5:22

>>11
How am I a moron?
When you saw "9001 lines of code of boilerplate crap in .NET environment", it was because proper serialization involves serializing object graphs. Put an std::string in your structure and watch the shit blow up spectacularly. And no, that's not something you could possibly implement in C++ with any number of props and crutches.

What you achieved is mindnumbingly trivial (even in C#, see Marshal class and 'fixed' statement), which, combined with your smugness about the whole deal, makes for a rather comical view.

Name: Anonymous 2011-07-07 5:31

>>23
Are you saying you can't fuck up the call stack in C++? Are you dumb? Of course you can!

>>24
Yes, I'm not saying type-safety is bad, just that the "all-or-nothing" approach isn't the correct way.

Name: Anonymous 2011-07-07 6:12

>>27
Are you saying you can't fuck up the call stack in C++? Are you dumb? Of course you can!
Manually optimize a tail call by dropping one return address from the return stack. The code must be portable. You can't do assumptions on the calling convention, the stack arrangement and direction. (unless you can prove that it can be detected portably)

Basically, do a RDROP.

Name: Anonymous 2011-07-07 7:14

>>27
C++ does not specify a call stack!

Name: Anonymous 2011-07-07 8:15

>>28
That can't be done portably. It can't be done portably in C either. I won't fall for your strawman, you Lisp devil! Just because you can't do that doesn't mean you can't ``fuck'' with the call stack as you originally put it.
>>29
Yes, it does. See Section 15 of latest publicly available C++ draft standard, ISO/IEC 14882:2011 N3242.

Name: Anonymous 2011-07-07 8:35

>>30
you Lisp devil!
But RDROP is Forth!

Show me how you can fuck a non-existing (>>29) call stack.

Name: Anonymous 2011-07-07 8:41

>>31
Didn't read the second part,
Yes, it does. See Section 15 of latest publicly available C++ draft standard, ISO/IEC 14882:2011 N3242.
Now, do some stack sex.

Name: Anonymous 2011-07-07 8:41

>>31
Show me how you can fuck aan non-existing (>>29) call stack.


unsigned char payload[256] = { /* some malicious data with function addresses at the correct offset*/ };

void hax_my_stack() {
    unsigned char buffer[16];
    memcpy(buffer, payload, 256);
    // return address is now seriously ``fucked'' on most architectures with descending call stacks
}

Name: Anonymous 2011-07-07 8:47

>>33
on most architectures with descending call stacks
>>28
You can't do assumptions on the calling convention, the stack arrangement and direction.

Name: Anonymous 2011-07-07 8:48

>>33
Guess what bro, I gave your mother a malicious unsigned char *payload the other night, and she loved it.

Name: Anonymous 2011-07-07 8:51

>>34
You're invoking requirements which constitute the strawman argument that >>28 misconstrued and that I called him out on (which might be you). I have ``fucked'' the stack. The stack is ``fucked''. End of story.

Name: Anonymous 2011-07-07 8:52

>>33
Why not just cast a buffer to a function pointer and just call that. You don't have to go that far into undefined territory by making a (stack) buffer overflow and asking the user to exploit it (which depends on compiler(version, optimization settings used, ...), OS, CPU, ...). Calling a buffer directly is undefined territory, but at it's much closer to using inline assembly or linking some code object.

Name: >>34 2011-07-07 8:53

I forgot, you can't rely on undefined behaviours.

Name: Anonymous 2011-07-07 9:01

>>37
You don't know what happens, it's not defined, it's not standard, and ultimately not portable.

Name: Anonymous 2011-07-07 10:05

>>39
It may not be standard, but one can say with a fairly good degree of confidence what happens for any given compiler (and the majority of them treat it very similarly) and platform.

Don't change these.
Name: Email:
Entire Thread Thread List