Skip to main content
gamedev.net
🔒 Locked

Data block class

Started by Mithoric 1 reply 600+ views
Original Post
Mithoric
Mithoric
I've been creating an image loading lib, to increase my knowledge of file loading and data parsing and so on. I decided I'd like to just load all my data into kind of a smart memory block. Where you can move forward and backward and grab as many bytes as you need from wherever and it'd cleanup after itself. Probably not a good idea, but for the sake of a learning experience I still want to do it. I'm having trouble though. I've overloaded the [] operator for random access, easy. Now I'm having trouble grabbing as many bytes as I need though and shoving them into a type.
byte* DataBlock::readBytes(int n){
    if(this->pos+n <= this->size){
        byte* buffer = new byte[n];
        memcpy(buffer, &this->data[this->pos], n);
        this->pos+= n;
        return buffer;
    }
    return 0;
}


The pos member indicates the position within the buffer. byte is typedef unsigned char. So say I have loaded a bitmap file into this DataBlock class, if I read the first 2 bytes I'd have 'BM', but if I were to say, move 4 bytes and read another 4 I should have 0 for the first reserved bit in the file header. I'm not getting this though, however if I use the random access operator and move to that point I get the correct value? This is what I was doing:

cout << data.readBytes(2) << endl;
data.move(4);
cout << (int)data.readBytes(4) << endl;



I should have got 0 but I get some massive number instead. I know this isn't exactly a useful idea, in some circumstances you'd just read only a bit of the file stream in the first place, especially if it's like a bitmap and you just need the texture data you can skip half the junk you don't need... But not understanding why this didn't work in the first place is driving me insane.
ToohrVyk
ToohrVyk
You're converting a pointer to an integer, which yields a large value. Use:

*reinterpret_cast(data.readBytes())

Also note that you're leaking memory this way, since the buffer returned by readBytes must be deleted.
Zahlman
Zahlman
Please abandon the current design. It has many problems. As noted, you are leaking memory, and you can't expect casting a byte* to an int to *magically* turn the first sizeof(int) *pointed-at* bytes into an int. Oh, and don't use memcpy() in C++; use std::copy. And why do you have a 'byte' typedef, anyway? In C++, chars *are* bytes *by definition*. (But bytes aren't necessarily octets, and text characters might be again something different). That is to say, the standard *requires* that the expression 'sizeof(char)' evaluates as 1, no matter whether you're compiling for a cell phone or a Cray supercomputer.

Something like this should serve your needs:

template <typename T>// set 'result' using the next however many bytes of the stream.// Return whether successful.bool DataBlock::read(T& result) {  int n = sizeof(T);  if (pos + n > size) { return false; }  char* ptr = reinterpret_cast<char*>(&result);  std::copy(ptr, ptr + n, data + pos);  pos += n;  return true;}

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.