Sliding Window Buffer
Sep 17, 2009
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!
Sep 18, 2009 - 3:48 pm
Ben
//WHY ARE YOUR COMMENTS ALWAYS YELLING//I MEAN I KINDA UNDERSTAND IT IMPLIES SIGNIFICANCE//BUT IT MAKES IT A TAD HARD TO READ
 
Sep 18, 2009 - 5:32 pm
Andrew
Oh Ben.... your comments are so helpful. Thank you!***Laden with sarcasm***

Im not sure that qualifies as constructive but thanks anyway... jackass.
 
Sep 19, 2009 - 8:21 am
Ben
Just because I'm a jackass doesn't change the fact that I'm right :p
 
Sep 19, 2009 - 8:50 am
Andrew
Actually, what is "hard to read" is matter of opinion and its impossible to be "right" or "wrong."

In fact, I think it makes them easier to read because it is obvious what is comment and what is code.

thanks

 
Sep 19, 2009 - 8:58 am
Ben
Alright so maybe it was opinion and not fact, but I don't post merely on a whim here :p I'm not the only one that said it.Also as an aside I'd argue there is code that is by its very nature hard to read, such asinclude int main() int i, c; for (i=0; (c = i"Hello, Worldn");i) putchar(c); return 0;And that children is why, even though its legal in C, you don't use the square brackets like that.Either way, you might consider a code highlighting module or something for watchihisbeardgrow, or alternately putting it on pastebin or the like. Syntax highlighting makes life a heck of a lot easier for the reader.
 
Sep 19, 2009 - 9:32 am
Andrew
Ben, congratulations, much of what you just said was actually constructive :) I am very proud of you.

I knew you could do it

 
Oct 16, 2009 - 9:25 am
Blake
I have a habit of capitalizing my comments as well.
 
Leave a Comment
 
Links
Recent Posts Archive