473,396 Members | 2,003 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

more buffering

I am writing a function that:

1) checks the size of the a non c string being copied against the
available
buffer space; len should not be large enough to contain a nul
terminator (should I check for
this?)
2) if the space is too small, the function increases the buffer size by
a block and repeats as
necessary; there should be more effective ways to do this. I
started to experiment with this
in an earlier post here.
3) then memcpy's the string to the end of the written part of the
buffer
4) returns the current used amount (might want to return something
different; still undecided)

The buffer structure was built based on the advice I received here to
manage buffer information. What I want to know is if there is a better
way to approach this problem?
Ideally, I would also want a function that would tag a nul to the end
of the string to make it
a c string if I need that functionality. My goal is general use buffer
functions for network applications. If you see any c mistakes, please
tell me.

size_t
buffer_append(BUF *buffer, const char *string, size_t len) {

char *buf_temp = NULL;

allocate:

if (buffer_remaining(buffer) < len) {
buf_temp = realloc(buffer->buffer, buffer->size + 512);
if (buf_temp == NULL) {
free(buffer->buffer);
buffer->buffer = NULL;
errx(1, "realloc failed");
}
buffer->buffer = buf_temp;
buffer->size += 512;
if (buffer_remaining(buffer) < len)
goto allocate;
}

memcpy(buffer->buffer + buffer->end, string, len);
buffer->end += len;

return buffer->end;
}

size_t
buffer_remaining(BUF *buffer) {

return buffer->size - buffer->end;
}

And here's the BUF structure:

typedef struct {

char *buffer; /* buffer */
size_t size; /* allocated size of buffer */
size_t offset; /* offset of buffer -- used to walk the buffer*/
size_t end; /* end of buffer */
} BUF;

Sep 24 '06 #1
9 1710
1) What platform is this? Why is block size = 512 bytes? I'd rather
that realloc increments be = to the MMU page size which is probably 4
KB
2) use while loops
while (buffer_remaining(buffer) < len) {
buf_temp = realloc(buffer->buffer, buffer->size + 512);
if (buf_temp == NULL) {
free(buffer->buffer);
buffer->buffer = NULL;
errx(1, "realloc failed");
}
buffer->buffer = buf_temp;
buffer->size += 512;
}
3)
#define BLOCK_SIZE 512

buffer_append(BUF *buffer, const char *string, size_t len) {
unsigned long amount_needed
char *buf_temp = NULL;

if (buffer_remaining(buffer) < (len + 1))
{
amount_needed = (len - buffer_remaining(buffer)) + 1; /* 1 is for
zero terminator */
amount_needed += BLOCK_SIZE;
amount_needed &= (BLOCK_SIZE - 1); /* takes advantage of block size
being a power of 2 */

buf_temp = realloc(buffer->buffer, buffer->size + amount_needed);
if (buf_temp == NULL) {
free(buffer->buffer);
buffer->buffer = NULL;
errx(1, "realloc failed");
}
buffer->buffer = buf_temp;
buffer->size += amount_needed;
}

memcpy(buffer->buffer + buffer->end, string, len);
buffer->buffer[buffer->end + len] = 0; /* zero terminate */
buffer->end += len + 1;
return buffer->end
}

bw*****@yahoo.com wrote:
I am writing a function that:

1) checks the size of the a non c string being copied against the
available
buffer space; len should not be large enough to contain a nul
terminator (should I check for
this?)
2) if the space is too small, the function increases the buffer size by
a block and repeats as
necessary; there should be more effective ways to do this. I
started to experiment with this
in an earlier post here.
3) then memcpy's the string to the end of the written part of the
buffer
4) returns the current used amount (might want to return something
different; still undecided)

The buffer structure was built based on the advice I received here to
manage buffer information. What I want to know is if there is a better
way to approach this problem?
Ideally, I would also want a function that would tag a nul to the end
of the string to make it
a c string if I need that functionality. My goal is general use buffer
functions for network applications. If you see any c mistakes, please
tell me.

size_t
buffer_append(BUF *buffer, const char *string, size_t len) {

char *buf_temp = NULL;

allocate:

if (buffer_remaining(buffer) < len) {
buf_temp = realloc(buffer->buffer, buffer->size + 512);
if (buf_temp == NULL) {
free(buffer->buffer);
buffer->buffer = NULL;
errx(1, "realloc failed");
}
buffer->buffer = buf_temp;
buffer->size += 512;
if (buffer_remaining(buffer) < len)
goto allocate;
}

memcpy(buffer->buffer + buffer->end, string, len);
buffer->end += len;

return buffer->end;
Sep 24 '06 #2
1) What platform is this? Why is block size = 512 bytes? I'd rather
that realloc increments be = to the MMU page size which is probably 4
KB
2) use while loops
while (buffer_remaining(buffer) < len) {
buf_temp = realloc(buffer->buffer, buffer->size + 512);
if (buf_temp == NULL) {
free(buffer->buffer);
buffer->buffer = NULL;
errx(1, "realloc failed");
}
buffer->buffer = buf_temp;
buffer->size += 512;
}
3)
#define BLOCK_SIZE 512

buffer_append(BUF *buffer, const char *string, size_t len) {
unsigned long amount_needed
char *buf_temp = NULL;

if (buffer_remaining(buffer) < (len + 1))
{
amount_needed = (len - buffer_remaining(buffer)) + 1; /* 1 is for
zero terminator */
amount_needed += BLOCK_SIZE;
amount_needed &= (BLOCK_SIZE - 1); /* takes advantage of block size
being a power of 2 */
}

buf_temp = realloc(buffer->buffer, buffer->size + amount_needed);
if (buf_temp == NULL) {
free(buffer->buffer);
buffer->buffer = NULL;
errx(1, "realloc failed");
}
buffer->buffer = buf_temp;
buffer->size += amount_needed;

memcpy(buffer->buffer + buffer->end, string, len);
buffer->buffer[buffer->end + len] = 0; /* zero terminate */
buffer->end += len + 1;
return buffer->end
}

bw*****@yahoo.com wrote:
I am writing a function that:

1) checks the size of the a non c string being copied against the
available
buffer space; len should not be large enough to contain a nul
terminator (should I check for
this?)
2) if the space is too small, the function increases the buffer size by
a block and repeats as
necessary; there should be more effective ways to do this. I
started to experiment with this
in an earlier post here.
3) then memcpy's the string to the end of the written part of the
buffer
4) returns the current used amount (might want to return something
different; still undecided)

The buffer structure was built based on the advice I received here to
manage buffer information. What I want to know is if there is a better
way to approach this problem?
Ideally, I would also want a function that would tag a nul to the end
of the string to make it
a c string if I need that functionality. My goal is general use buffer
functions for network applications. If you see any c mistakes, please
tell me.

size_t
buffer_append(BUF *buffer, const char *string, size_t len) {

char *buf_temp = NULL;

allocate:

if (buffer_remaining(buffer) < len) {
buf_temp = realloc(buffer->buffer, buffer->size + 512);
if (buf_temp == NULL) {
free(buffer->buffer);
buffer->buffer = NULL;
errx(1, "realloc failed");
}
buffer->buffer = buf_temp;
buffer->size += 512;
if (buffer_remaining(buffer) < len)
goto allocate;
}

memcpy(buffer->buffer + buffer->end, string, len);
buffer->end += len;

return buffer->end;
Sep 24 '06 #3
quick fix:

amount_needed &= (BLOCK_SIZE - 1)

should be

amount_needed &= ~(BLOCK_SIZE - 1)
Samuel Stearley wrote:
1) What platform is this? Why is block size = 512 bytes? I'd rather
that realloc increments be = to the MMU page size which is probably 4
KB
2) use while loops
while (buffer_remaining(buffer) < len) {
buf_temp = realloc(buffer->buffer, buffer->size + 512);
if (buf_temp == NULL) {
free(buffer->buffer);
buffer->buffer = NULL;
errx(1, "realloc failed");
}
buffer->buffer = buf_temp;
buffer->size += 512;
}
3)
#define BLOCK_SIZE 512

buffer_append(BUF *buffer, const char *string, size_t len) {
unsigned long amount_needed
char *buf_temp = NULL;

if (buffer_remaining(buffer) < (len + 1))
{
amount_needed = (len - buffer_remaining(buffer)) + 1; /* 1 is for
zero terminator */
amount_needed += BLOCK_SIZE;
amount_needed &= (BLOCK_SIZE - 1); /* takes advantage of block size
being a power of 2 */

buf_temp = realloc(buffer->buffer, buffer->size + amount_needed);
if (buf_temp == NULL) {
free(buffer->buffer);
buffer->buffer = NULL;
errx(1, "realloc failed");
}
buffer->buffer = buf_temp;
buffer->size += amount_needed;
}

memcpy(buffer->buffer + buffer->end, string, len);
buffer->buffer[buffer->end + len] = 0; /* zero terminate */
buffer->end += len + 1;
return buffer->end
}

bw*****@yahoo.com wrote:
I am writing a function that:

1) checks the size of the a non c string being copied against the
available
buffer space; len should not be large enough to contain a nul
terminator (should I check for
this?)
2) if the space is too small, the function increases the buffer size by
a block and repeats as
necessary; there should be more effective ways to do this. I
started to experiment with this
in an earlier post here.
3) then memcpy's the string to the end of the written part of the
buffer
4) returns the current used amount (might want to return something
different; still undecided)

The buffer structure was built based on the advice I received here to
manage buffer information. What I want to know is if there is a better
way to approach this problem?
Ideally, I would also want a function that would tag a nul to the end
of the string to make it
a c string if I need that functionality. My goal is general use buffer
functions for network applications. If you see any c mistakes, please
tell me.

size_t
buffer_append(BUF *buffer, const char *string, size_t len) {

char *buf_temp = NULL;

allocate:

if (buffer_remaining(buffer) < len) {
buf_temp = realloc(buffer->buffer, buffer->size + 512);
if (buf_temp == NULL) {
free(buffer->buffer);
buffer->buffer = NULL;
errx(1, "realloc failed");
}
buffer->buffer = buf_temp;
buffer->size += 512;
if (buffer_remaining(buffer) < len)
goto allocate;
}

memcpy(buffer->buffer + buffer->end, string, len);
buffer->end += len;

return buffer->end;
Sep 24 '06 #4
P.S.

Sorry for the double post.
The one at 9:02 pm is not correct

Sep 24 '06 #5

Samuel Stearley wrote:
P.S.

Sorry for the double post.
The one at 9:02 pm is not correct
Is there an advantage of using the page size? If so, I can use
implementation functions to determine the size, but that would be
off-topic for this newsgroup. I know on my amd64 box that the OS is
paging at 4096 and that the block size is 512. But I should probably
use magic numbers for those values, so I can at least cross platform on
the same OS.

Sep 24 '06 #6

Samuel Stearley wrote:
1) What platform is this? Why is block size = 512 bytes? I'd rather
that realloc increments be = to the MMU page size which is probably 4
KB
<OT>
The platform is openBSD -current. I could use the page size, but I need
to know more to make that decision. Is there an advantage to using the
page size over the block size? I am not an expert in the page daemon
or uvm. But I get the gist of how it works.
</OT>
>

2) use while loops
while (buffer_remaining(buffer) < len) {
buf_temp = realloc(buffer->buffer, buffer->size + 512);
if (buf_temp == NULL) {
free(buffer->buffer);
buffer->buffer = NULL;
errx(1, "realloc failed");
}
buffer->buffer = buf_temp;
buffer->size += 512;
}
I could also use for loops. Is there any advantage of one approach
over the other? But I do agree that the goto was pretty lame.
>

3)
#define BLOCK_SIZE 512

buffer_append(BUF *buffer, const char *string, size_t len) {
unsigned long amount_needed
char *buf_temp = NULL;

if (buffer_remaining(buffer) < (len + 1))
{
amount_needed = (len - buffer_remaining(buffer)) + 1; /* 1 is for
zero terminator */
As I originally said, these are not c strings. If these were c
strings, I would be using strlcpy, rather than memcpy.

I also plan to write a separate function to handle c strings. I am
using this buffer function to create a packet to be sent over the wire.
I'll post a c string buffer function later. Of course, I do want to
avoid filling the buffer like:

'A', 'A', '\0', 'A', 'A', '\0'

If I was just handling individual strings, I would use a linked list or
an array of pointers to c strings.
amount_needed += BLOCK_SIZE;
amount_needed &= (BLOCK_SIZE - 1); /* takes advantage of block size
being a power of 2 */
Please explain the above. I have never used bitwise AND in this
fashion. Could you walk me through the math? I do hope learn
something new. I have been struggling with a good way to increment the
allocation. I have used the shift operator to do endian conversions
and simple multiplication.

Cheers,

Brian

Sep 24 '06 #7
1) Whenever I make my own allocation interface I prefer that it do its
allocations in the units the OS manages memory in.
2)
As I originally said, these are not c strings. If these were c
strings, I would be using strlcpy, rather than memcpy.
I know very jolly well that they are not c strings, but you did say
that you wanted to add a null at the end to turn it into a c string:
Ideally, I would also want a function that would tag a nul to the end
of the string to make it a c string if I need that functionality.

3) the math:
amount_needed += BLOCK_SIZE;
amount_needed &= ~(BLOCK_SIZE - 1); /* takes advantage of block size being a power of 2 */
Suppose you need 560 bytes which means 2 BLOCK_SIZE allocation. The
code adds BLOCK_SIZE to amount_needed and now you need 1072 bytes.

But 1072 bytes is not a multiple of 512 bytes. The &= ~(BLOCK_SIZE -
1) turns the 1072 bytes into 1024 bytes.

About the math: 512 is a power of 2, ie only 1 bit is set.
When you subtract 1 from a number that has only one set bit, all bits
beneath that bit get set. All bits above and including the original
bit are cleared. This creates a bit mask. That bit mask is then
inverted.

The final mask in binary is:

11111111_11111111_11111110_00000000

Anding this mask against 1072 turns 1072 into 1024
bw*****@yahoo.com wrote:
Samuel Stearley wrote:
1) What platform is this? Why is block size = 512 bytes? I'd rather
that realloc increments be = to the MMU page size which is probably 4
KB

<OT>
The platform is openBSD -current. I could use the page size, but I need
to know more to make that decision. Is there an advantage to using the
page size over the block size? I am not an expert in the page daemon
or uvm. But I get the gist of how it works.
</OT>


2) use while loops
while (buffer_remaining(buffer) < len) {
buf_temp = realloc(buffer->buffer, buffer->size + 512);
if (buf_temp == NULL) {
free(buffer->buffer);
buffer->buffer = NULL;
errx(1, "realloc failed");
}
buffer->buffer = buf_temp;
buffer->size += 512;
}

I could also use for loops. Is there any advantage of one approach
over the other? But I do agree that the goto was pretty lame.


3)
#define BLOCK_SIZE 512

buffer_append(BUF *buffer, const char *string, size_t len) {
unsigned long amount_needed
char *buf_temp = NULL;

if (buffer_remaining(buffer) < (len + 1))
{
amount_needed = (len - buffer_remaining(buffer)) + 1; /* 1 is for
zero terminator */

As I originally said, these are not c strings. If these were c
strings, I would be using strlcpy, rather than memcpy.

I also plan to write a separate function to handle c strings. I am
using this buffer function to create a packet to be sent over the wire.
I'll post a c string buffer function later. Of course, I do want to
avoid filling the buffer like:

'A', 'A', '\0', 'A', 'A', '\0'

If I was just handling individual strings, I would use a linked list or
an array of pointers to c strings.
amount_needed += BLOCK_SIZE;
amount_needed &= (BLOCK_SIZE - 1); /* takes advantage of block size
being a power of 2 */

Please explain the above. I have never used bitwise AND in this
fashion. Could you walk me through the math? I do hope learn
something new. I have been struggling with a good way to increment the
allocation. I have used the shift operator to do endian conversions
and simple multiplication.

Cheers,

Brian
Sep 24 '06 #8

bw*****@yahoo.com wrote:
Samuel Stearley wrote:
1) What platform is this? Why is block size = 512 bytes? I'd rather
that realloc increments be = to the MMU page size which is probably 4
KB

<OT>
The platform is openBSD -current. I could use the page size, but I need
to know more to make that decision. Is there an advantage to using the
page size over the block size? I am not an expert in the page daemon
or uvm. But I get the gist of how it works.
</OT>
Page size is relevant only on mmu based operating systems. It would be
good to know the page sizes of the operating systems during the
programming phase but do not make it mandatory.
2) use while loops
while (buffer_remaining(buffer) < len) {
buf_temp = realloc(buffer->buffer, buffer->size + 512);
if (buf_temp == NULL) {
free(buffer->buffer);
buffer->buffer = NULL;
errx(1, "realloc failed");
}
buffer->buffer = buf_temp;
buffer->size += 512;
}

I could also use for loops. Is there any advantage of one approach
over the other? But I do agree that the goto was pretty lame.
Using while and for loop does not make much difference, you can use
either of them.
Regarding goto, it is just not cleaner way to write a probram. I've
seen programs that extensively use goto with good results and
increasing readiablity. If you see the code when converted to assembly
you would see that most of the code would be with jmp instructions
analogus to goto in C language.

3)
#define BLOCK_SIZE 512

buffer_append(BUF *buffer, const char *string, size_t len) {
unsigned long amount_needed
char *buf_temp = NULL;

if (buffer_remaining(buffer) < (len + 1))
{
amount_needed = (len - buffer_remaining(buffer)) + 1; /* 1 is for
zero terminator */

As I originally said, these are not c strings. If these were c
strings, I would be using strlcpy, rather than memcpy.

I also plan to write a separate function to handle c strings. I am
using this buffer function to create a packet to be sent over the wire.
I'll post a c string buffer function later. Of course, I do want to
avoid filling the buffer like:

'A', 'A', '\0', 'A', 'A', '\0'

If I was just handling individual strings, I would use a linked list or
an array of pointers to c strings.
In most of the networking protocols strings are appended/prepended with
a length. This is required for variable string options. If this is not
specified then there would be delimeters given specifing the end of the
string. I am very much interested to know what network protocol you are
programing (unless it is not propritory).
amount_needed += BLOCK_SIZE;
amount_needed &= (BLOCK_SIZE - 1); /* takes advantage of block size
being a power of 2 */

Please explain the above. I have never used bitwise AND in this
fashion. Could you walk me through the math? I do hope learn
something new. I have been struggling with a good way to increment the
allocation. I have used the shift operator to do endian conversions
and simple multiplication.
This reminds me of my initial days of programing. In most institutions
teach bitwise operations at the end because it takes time :) I myself
weak in it taking a lot of time to craft one :( Internet is the biggest
library in the world, use it.

-kondal

Sep 24 '06 #9
Samuel Stearley wrote:
P.S.

Sorry for the double post.
The one at 9:02 pm is not correct
You mean the one at 1:02 AM UTC, I guess. Or 9:02 PM -0700. Most news
readers display times converted to the reader's time zone. That's 11:02
AM +1000 for me.

--
Simon.
Sep 24 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Shaun Jackman | last post by:
I'm reading from a tcpdump pipe. I want to receive one line from the pipe as soon as its available from tcpdump. Something is buffering the pipe though, so I am receiving nothing, then multiple...
3
by: Alex Glass | last post by:
I have read plenty about applying double buffering for animation and self drawn forms. Is there a way to apply it to a form with many standard controls on it (textboxes, labels etc) ?? I have...
2
by: MPowell | last post by:
Gents/Ladies, I'm doing (at least plan on ) lots of Reads and Writes across a communication channel. I'm told that for the 'receive side' it'd be prudent to implement a double buffering scheme to...
7
by: Mathias Herrmann | last post by:
Hi. I have the following problem: Using popen() to execute a program and read its stdout works usually fine. Now I try to do this with a program called xsupplicant (maybe one knows), but I dont...
2
by: Jason | last post by:
I have created a 2d isometric game map using tiles and now I'm trying to move around my map..when i go near the edge of the map I want to redraw the map to show new parts of the map however the...
0
by: Just D. | last post by:
Who knows and could explain the ASPX understanding of caching, buffering, etc.? Each ASPX page has the property "buffer=true" by default. We also can include this tag to the page header: <meta...
1
by: TyBreaker | last post by:
I notice in VB 2005 that I can set a form to be double-buffered just by setting that option to true in the Form properties. I have a panel on that form but there doesn't appear to be a...
3
by: ssoffline | last post by:
hi i have an app in which i can drop objects onto a form and move them, it consists of graphics (lines), i am using double buffering to avoid filckering in the parent control which is a panel,but...
11
by: japhy | last post by:
Is there a way to read a line (a series of characters ending in a newline) from a file (either by descriptor or stream) atomically, without buffering additional contents of the file?
2
by: jimxoch | last post by:
Dear list, I have recently implemented a generic sequence searching template function, named single_pass_search, which is more generic than std::search and has better worst case complexity at...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.