Select Git revision
labcomm_mem_reader.c 2.11 KiB
#include "labcomm_mem_reader.h"
#include <errno.h>
#include <stdlib.h>
#include <string.h>
/* This implementation assumes labcomm will call end exactly once after each start
* It is not allowed to save data in mcontext->enc_data,
* this pointer will be set to NULL after decoding.
*/
/* NOTE!!!!
* start will be run first, once a signature or a data section is decoded
* end will be run and then start again. If end of encoded data is reached this
* must be handled in start.
*/
// TODO make labcomm use result!
int labcomm_mem_reader(labcomm_reader_t *r,
labcomm_reader_action_t action,
...)
{
int result = -EINVAL;
labcomm_mem_reader_context_t *mcontext = (labcomm_mem_reader_context_t *) r->context;
switch (action) {
case labcomm_reader_alloc: {
r->data = NULL;
r->data_size = 0;
r->pos = 0;
r->count = 0;
} break;
case labcomm_reader_start: {
if (r->data == NULL && mcontext->enc_data != NULL) {
r->data = (unsigned char *) malloc(mcontext->size);
if(r->data != NULL) {
memcpy(r->data, mcontext->enc_data, mcontext->size);
r->data_size = mcontext->size;
r->count = mcontext->size;
r->pos = 0;
result = r->data_size;
} else {
r->data_size = 0;
result = -ENOMEM;
}
} else if (r->data == NULL && mcontext->enc_data == NULL) {
result = -1;
} else {
result = r->count - r->pos;
}
} break;
case labcomm_reader_continue: {
if (r->pos < r->count) {
result = r->count - r->pos;
} else {
// TODO set some describing error here
result = -1;
}
} break;
case labcomm_reader_end: {
if (r->pos >= r->count) {
free(r->data);
r->data = NULL;
r->data_size = 0;
mcontext->enc_data = NULL;
mcontext->size = 0;
}
result = r->count - r->pos;
} break;
case labcomm_reader_free: {
r->count = 0;
r->pos = 0;
result = 0;
} break;
case labcomm_reader_ioctl: {
result = -ENOTSUP;
}
}
return result;
}