The last few days I have been writing some utilities and data structures for use in my STCP (Simplified Transport Control Protocal) Layer. I have never really done a code-review over blog before but I figure it cant hurt.
Nor have I posted much code here, so its a good test for my formatter.
What I have been working on most recently is the Sliding Window Buffer to keep track of data being passed to the application layer and to the network layer. It is not done because currently it does not have any of the reliability utilities it will require. eg production into specific locations in the buffer and the ability to peak into specific locations in the buffer. Anyway, here is the code: (oh, I have to warn you... It has been a while since C/C++ was my main language so some if this stuff may be bad ideas. I am happy to take any constructive criticism)
#include /
#include /
#include /
#include /
#define BUFFER_SIZE 3072
struct sliding_window_buffer{
int window_start;
int window_end;
char *buffer;
}to_application, to_network;
static void init_buffer(struct sliding_window_buffer *swbuffer, int start){
swbuffer->buffer = (char *)malloc(BUFFER_SIZE);
assert(swbuffer->buffer);
swbuffer->window_start = start;
swbuffer->window_end = swbuffer->window_start;
for(int i = 0; ibuffer[i] = '\0';
}
}
static void consume(struct sliding_window_buffer *swbuffer,
int bytes, void *ret){
if(swbuffer->window_start == swbuffer->window_end
&& swbuffer->buffer[swbuffer->window_start] == '\0'
&& swbuffer->buffer[swbuffer->window_start+1] == '\0'){
//IT APPEARS THE BUFFER IS EMPTY, THERE IS NO DATA TO CONSUME
}
else{
//IF THE DATA TO CONSUME DOES NOT CROSS FROM END TO BEGINNING
if(swbuffer->window_end+bytesbuffer+(swbuffer->window_end%BUFFER_SIZE), bytes);
//SET THE MOVED DATA TO THE NULL CHARACTER TO EMPTY THE BUFFER
memset(swbuffer->buffer+(swbuffer->window_end%BUFFER_SIZE), '\0', bytes);
//MOVE THE END OF THE WINDO TO ITS NEW LOCATION
swbuffer->window_end = (swbuffer->window_end + bytes)%BUFFER_SIZE;
}else{
//THE DATA STARTS AT TH END AND CROSSES TO THE BEGINNING OF THE BUFFER
//MUST CONSUME IN TWO PARTS AND THEN COMBINE THE PARTS TO RETURN
void *part_one, *part_two;
int size_of_part_one = BUFFER_SIZE-swbuffer->window_end;
int size_of_part_two = bytes-size_of_part_one;
part_one = malloc(size_of_part_one);
assert(part_one);
part_two = malloc(size_of_part_two);
assert(part_two);
//GET PEICES
//THIS RECURSIVE CALL SHOULD TAKE CARE OF MOVING OUR WINDOW
//AND RESETTING THE BYTES
consume(swbuffer, size_of_part_one, part_one);
consume(swbuffer, size_of_part_two, part_two);
//REASSEMBLE
memcpy(ret, part_one, size_of_part_one);
memcpy((char*)ret+size_of_part_one, part_two, size_of_part_two);
free(part_one);
free(part_two);
}
}
}
static void produce(struct sliding_window_buffer *swbuffer,
int bytes, void *prod){
//IF THE BYTES TO MOVE ARE NOT TOO LARGE FOR THE BUFFER
if(byteswindow_start == swbuffer->window_end
&& swbuffer->buffer[swbuffer->window_start] != '\0'
&& swbuffer->buffer[swbuffer->window_start+1] != '\0'){
//IT APPEARS THE BUFFER IS FULL, THERE IS NO ROOM FOR YOUR DATA
}
else{
int space_left;
//DECIDE HOW TO CALCULATE THE AMOUTN OF SPACE LEFT
//DEPENDS ON THE ORDER OF THE START AND END OF THE BUFFER
if(swbuffer->window_end>swbuffer->window_start){
space_left = swbuffer->window_end-swbuffer->window_start;
}else{
space_left = swbuffer->window_end-swbuffer->window_start+BUFFER_SIZE;
}
//IF THE BYTES TO MOVE IS GREATER THAN THE SPACE LEFT
if(bytes > space_left){
//FIT THE SIZE TO MOVE IN BYTES TO THE SIZE LEFT IN THE BUFFER
bytes = space_left;
}
//IF BYTES WILL FIT BEFORE THE END OF THE BUFFER
if(bytes+swbuffer->window_startbuffer+swbuffer->window_start, prod, bytes);
}else{
//BYTES SPAN FROM END TO BEGIN
//WILL REQUIRE TWO COPIES
memcpy(swbuffer->buffer+swbuffer->window_start,
prod,
(BUFFER_SIZE-swbuffer->window_start));
memcpy(swbuffer->buffer,
(char*)prod+(BUFFER_SIZE-swbuffer->window_start),
bytes-(BUFFER_SIZE-swbuffer->window_start));
}
swbuffer->window_start = (swbuffer->window_start+bytes)%BUFFER_SIZE;
}
}else{
printf("ERROR: BYTES ADDED WERE LARGER THAN THE BUFFER");
}
}
void destroy_buffer(struct sliding_window_buffer *swbuffer){
free(swbuffer->buffer);
}
int main(){
//SOME TESTING... NOT STRENUOUS
init_buffer(&to_application, 200);
void *half = malloc(strlen("some_bytes")/2);
consume(&to_application, strlen("some_bytes")/2, half);
printf("Empty: %s\n", half);
void * some_bytes = malloc(strlen("some_bytes"));
memcpy(some_bytes, "some_bytes", strlen("some_bytes"));
produce(&to_application, strlen("some_bytes"), some_bytes);
consume(&to_application, strlen("some_bytes")/2, half);
printf("first 5: %s\n", half);
consume(&to_application, strlen("some_bytes")/2, half);
printf("second 5: %s\n", half);
consume(&to_application, strlen("some_bytes")/2, half);
printf("third 5: %s\n", half);
destroy_buffer(&to_application);
return 0;
}
edit: I am not taking this down, but I just noticed that though it compiled nicely, I forgot to run it... haha. I got some nasty errors. I will replace the code here when I figure it out.
edit: It has been updated. It was pretty obvious. I was thinking I had malloc'ed the buffer struct, so when I went to destroy it, I tried to free it and well... that was illegal! |