Created
January 14, 2013 21:15
-
-
Save mharju/4533567 to your computer and use it in GitHub Desktop.
No. There was no doubly linked list implementation that I could have used ;)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
typedef struct buffer_t { | |
void *data; | |
int length; | |
struct buffer_t* next; | |
struct buffer_t* prev; | |
} buffer_t; | |
buffer_t* bufferlist_alloc() { | |
buffer_t* root = (buffer_t*)malloc(sizeof(buffer_t)); | |
memset(root, 0, sizeof(buffer_t)); | |
return root; | |
} | |
void bufferlist_free(buffer_t* root) { | |
buffer_t* current = root; | |
while(current != NULL) { | |
free(current->data); | |
free(current); | |
buffer_t* p = current->next; | |
current = p; | |
} | |
} | |
buffer_t* bufferlist_append(buffer_t* tail, void* data, int length) { | |
buffer_t* new = (buffer_t*)malloc(sizeof(buffer_t)); | |
new->data = data; | |
new->length = length; | |
new->next = NULL; | |
new->prev = tail; | |
tail->next = new; | |
return new; | |
} | |
buffer_t* bufferlist_pop(buffer_t* root) { | |
buffer_t* new_root = root->next; | |
free(root->data); | |
free(root); | |
return new_root; | |
} | |
int bufferlist_length(const buffer_t* root) { | |
const buffer_t* current = root; | |
int count = 0; | |
while(current != NULL) { | |
count ++; | |
current = current->next; | |
} | |
return count; | |
} | |
void bufferlist_memcpy(void *destination, buffer_t* root, int offset, int length) { | |
buffer_t* current = root; | |
int current_offset = 0; | |
int bytes_left = length; | |
while(current != NULL) { | |
if(current_offset + current->length < offset) { | |
current_offset += current->length; | |
} else { | |
// We have everything in the current buffer | |
int buffer_offset = offset - current_offset; | |
if(bytes_left < current->length - buffer_offset) { | |
memcpy(destination + (length - bytes_left), | |
current->data + buffer_offset, | |
bytes_left); | |
bytes_left = 0; | |
} else { | |
memcpy(destination + (length - bytes_left), | |
current->data + buffer_offset, | |
current->length - buffer_offset); | |
bytes_left -= current->length - buffer_offset; | |
current_offset = offset; | |
} | |
} | |
if(bytes_left == 0) { | |
printf("Done and done"); | |
return; | |
} | |
current = current->next; | |
} | |
} | |
int main(void) { | |
buffer_t *root = bufferlist_alloc(); | |
buffer_t *tail = root; | |
int counter = 0; | |
unsigned char test[64] = {0}; | |
for(int i=0;i<64;i++) { | |
unsigned char *data = (unsigned char*)malloc(16); | |
tail = bufferlist_append(tail, data, 16); | |
for(int j=0;j<16;j++) { | |
*(data + j) = (counter++ % 255); | |
} | |
} | |
bufferlist_memcpy(&test[0], root, 129, sizeof(test)); | |
for(int i=0;i<sizeof(test);i++) { | |
printf("%u ", test[i]); | |
} | |
printf("\n"); | |
bufferlist_free(root); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment