Sign in to follow this  

[C++] Seeking a good "buffer" class.

This topic is 2843 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

So basically, when I send/receive packets, I'd like to put the raw data (a sequence of 'char's) into a container within my data struct -- let's call it Packet -- for subsequent use. Some things I could theoretically place inside the Packet struct to store the raw data: 1. char buffer[X] - a char array... simple, but I would really like something that is more dynamic. i.e. I'd like to be able to use whatever size data I want and just specify a 'length' in the packet. Because C++ is cool, copying a Packet by-value will still work, because arrays within a struct are copied element-by-element (not just the pointer). 2. std::string - a string... really pretty - I can both easily store the raw data I read in into a string and easily get it back out using c_str(). Once again, copying a Packet by-value is still a breeze, because std::strings copy appropriately. The problem? If there are any 0's in my raw data - and there definitely can be - the string will terminate at that point. Basically, I was thinking of something like a string, but that specifies a length instead of being null-terminated. I have to imagine this would be a highly used class, and I would be shocked if something didn't exist for this purpose. Has anyone done socket programming and had a similar desire for a dynamically-sized buffer that copies by-value appropriately? I guess what I'm wondering is, does anyone know of a class like this, or have suggestions as to what would work well? To program this from scratch would be annoying.

Share this post


Link to post
Share on other sites
Yes, I should have put that (or std::list<char>) as one of the possibilities...
the problem with that is

A. it seems needlessly bulky and

B. I can neither easily do something like:
vec = some_c_string;
nor:
memcpy(buffer, &vec.c_str(), vec.length());
(both of which I can do with strings - and are incredibly useful when sending/receiving data)
I'd have to iterate which, again just seems very ... ugly

Share this post


Link to post
Share on other sites
Quote:
Yes, I should have put that (or std::list<char>) as one of the possibilities...
the problem with that is

std::vector is suitable for a buffer. std::list is not.

Quote:
A. it seems needlessly bulky

Really? std::vector has minimal overhead. The size of a vector is usually 3 pointers + the size of the contained buffer.

Quote:
B. I can neither easily do something like:
vec = some_c_string;
nor:
memcpy(buffer, &vec.c_str(), vec.length());
(both of which I can do with strings - and are incredibly useful when sending/receiving data)
I'd have to iterate which, again just seems very ... ugly

You can do:
memcpy(buffer, &vec[0], vec.length()); //requires vec.length() >= 1

Share this post


Link to post
Share on other sites
Quote:
Original post by Browser12
vec = some_c_string;

vec.resize(strlen(some_c_string));
std::copy(some_c_string, some_c_string + vec.size(), vec.begin());

Quote:
Original post by Browser12
memcpy(buffer, &vec.c_str(), vec.length());

std::copy(vec.begin(), vec.end(), buffer);

[EDIT]
See Antheus' post below for a better "vec = some_c_string" approach ;)

Share this post


Link to post
Share on other sites
Quote:
Original post by Browser12
(or std::list<char>) as one of the possibilities...

The worst imaginable option. list is a linked list, which would contain back and next pointers for each char.


Quote:
A. it seems needlessly bulky and

std::string is bulkier than std::vector.

Quote:
B. I can neither easily do something like:
vec = some_c_string;

vec.assign(some_c_string, some_c_string + strlen(some_c_string));


Quote:
memcpy(buffer, &vec.c_str(), vec.length());


	std::string s("Hello World");
std::vector<char> v;

v.assign(s.begin(), s.end()); // string to vector
s.assign(v.begin(), v.end()); // vector to string


Quote:
(both of which I can do with strings - and are incredibly useful when sending/receiving data)

Except for the 0 value in data received from network, which can quickly happen.

Share this post


Link to post
Share on other sites
Hmm, guess I'll be trying out std::vector, then. Chalk this one up to inexperience with vectors! (I thought they worked similarly to linked lists - oops.)

Thanks a bunch guys~

Share this post


Link to post
Share on other sites
std::string can handle embedded 0's just fine. C-style strings can't but std::string isn't a C-style string.

std::vector is still the better way to go though. If your data is not actually a string and you go sticking it in a std::string it will just confuse everybody.

Share this post


Link to post
Share on other sites
Quote:
Original post by Antheus
Quote:
A. it seems needlessly bulky and

std::string is bulkier than std::vector.
QFT! I was going to point that out if nobody else did.

I somehow knew the answer was std::vector before I even opened this thread.

Share this post


Link to post
Share on other sites
Why would you want to keep copying buffers by value all over the place? If anything you should have a buffer that does NOT copy by value, just a simple wrapper around a pointer. boost::asio has boost::asio::const_buffer and boost::asio::mutable_buffer for this purpose. You access it using a specific type using boost::asio::buffer_cast.

Share this post


Link to post
Share on other sites
Quote:
Original post by theOcelot
How is string bulkier than vector?


It typically includes a small char[] in its data layout to optimize for the common case where strings are short.

Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman
Quote:
Original post by theOcelot
How is string bulkier than vector?


It typically includes a small char[] in its data layout to optimize for the common case where strings are short.


Oh right, forgot about that.

Share this post


Link to post
Share on other sites
Quote:
Original post by cache_hit
Why would you want to keep copying buffers by value all over the place? If anything you should have a buffer that does NOT copy by value, just a simple wrapper around a pointer. boost::asio has boost::asio::const_buffer and boost::asio::mutable_buffer for this purpose. You access it using a specific type using boost::asio::buffer_cast.
Who said anything about passing vectors by value?

Share this post


Link to post
Share on other sites
Quote:
Original post by iMalc
Quote:
Original post by cache_hit
Why would you want to keep copying buffers by value all over the place? If anything you should have a buffer that does NOT copy by value, just a simple wrapper around a pointer. boost::asio has boost::asio::const_buffer and boost::asio::mutable_buffer for this purpose. You access it using a specific type using boost::asio::buffer_cast.
Who said anything about passing vectors by value?


I thought the OP did, unless I missed something.

Quote:
Has anyone done socket programming and had a similar desire for a dynamically-sized buffer that copies by-value appropriately?

Share this post


Link to post
Share on other sites
Quote:
Original post by cache_hit
Quote:
Original post by iMalc
Quote:
Original post by cache_hit
Why would you want to keep copying buffers by value all over the place? If anything you should have a buffer that does NOT copy by value, just a simple wrapper around a pointer. boost::asio has boost::asio::const_buffer and boost::asio::mutable_buffer for this purpose. You access it using a specific type using boost::asio::buffer_cast.
Who said anything about passing vectors by value?


I thought the OP did, unless I missed something.

Quote:
Has anyone done socket programming and had a similar desire for a dynamically-sized buffer that copies by-value appropriately?
Oh... that! (slaps forehead). I took that to mean that it copied the things being inserted into the container rather than just storing pointers in the container.
Perhaps the OP will clarify that one.

Share this post


Link to post
Share on other sites

This topic is 2843 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this