diff --git a/lib/c/labcomm_bytearray_reader.c b/lib/c/labcomm_bytearray_reader.c new file mode 100644 index 0000000000000000000000000000000000000000..9752808d3505ecfaba1d22b2f670b24cb87c0677 --- /dev/null +++ b/lib/c/labcomm_bytearray_reader.c @@ -0,0 +1,110 @@ +/* + labcomm_bytearray_reader.c -- a reader for data in a byte array + + Copyright 2014 Sen GestegÄrd Robertz <sven.robertz@cs.lth.se> + + This file is part of LabComm. + + LabComm is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + LabComm is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <errno.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include "labcomm_private.h" +#include "labcomm_bytearray_reader.h" + + +struct labcomm_bytearray_reader { + struct labcomm_reader reader; + struct labcomm_reader_action_context action_context; + unsigned char *bytearray; + int bytearray_size; +}; + +static int bytearray_alloc(struct labcomm_reader *r, + struct labcomm_reader_action_context *action_context, + char *version) +{ + int result = 0; + + r->data = ((struct labcomm_bytearray_reader *)action_context->context)->bytearray; + r->count =((struct labcomm_bytearray_reader *)action_context->context)->bytearray_size; + r->pos = 0; + return result; +} + +static int bytearray_free(struct labcomm_reader *r, + struct labcomm_reader_action_context *action_context) +{ + struct labcomm_bytearray_reader *bytearray_reader = action_context->context; + struct labcomm_memory *memory = r->memory; + + //HERE BE DRAGONS labcomm_memory_free(memory, 0, r->data); + r->data = 0; + r->data_size = 0; + r->count = 0; + r->pos = 0; + + labcomm_memory_free(memory, 0, bytearray_reader); + return 0; +} + +static int bytearray_fill(struct labcomm_reader *r, + struct labcomm_reader_action_context *action_context) +{ + int result = 0; + + if (r->pos < r->count) { + //printf("BAreader.fill: pos %d count: %d\n", r->pos, r->count); + result = r->count - r->pos; + } else { + r->pos = 0; + r->error = -EPIPE; + result = -EPIPE; + } + return result; +} + +static const struct labcomm_reader_action action = { + .alloc = bytearray_alloc, + .free = bytearray_free, + .start = NULL, + .fill = bytearray_fill, + .end = NULL, + .ioctl = NULL +}; + +struct labcomm_reader *labcomm_bytearray_reader_new(struct labcomm_memory *memory, + unsigned char *data, int size) +{ + struct labcomm_bytearray_reader *result; + + result = labcomm_memory_alloc(memory, 0, sizeof(*result)); + if (result == NULL) { + return NULL; + } else { + result->action_context.next = NULL; + result->action_context.action = &action; + result->action_context.context = result; + result->reader.action_context = &result->action_context; + result->reader.memory = memory; + result->bytearray = data; + result->bytearray_size = size; + struct labcomm_reader * res = &result->reader; + // printf("reader: %p, size: %d\n", res, res->data_size); + return res; + } +} diff --git a/lib/c/labcomm_bytearray_reader.h b/lib/c/labcomm_bytearray_reader.h new file mode 100644 index 0000000000000000000000000000000000000000..e41257c4ba37fcaafcfe3b43ca116b6c05a4607b --- /dev/null +++ b/lib/c/labcomm_bytearray_reader.h @@ -0,0 +1,31 @@ +/* + labcomm_bytearray_reader.h -- a reader for data in a byte array + + Copyright 2014 Sen GestegÄrd Robertz <sven.robertz@cs.lth.se> + + This file is part of LabComm. + + LabComm is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + LabComm is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef _LABCOMM_BYTEARRAY_READER_H_ +#define _LABCOMM_BYTEARRAY_READER_H_ + +#include "labcomm.h" + +struct labcomm_reader *labcomm_bytearray_reader_new(struct labcomm_memory *memory, + unsigned char *data, int size); + +#endif + diff --git a/lib/c/labcomm_encoder.c b/lib/c/labcomm_encoder.c index e1386100a226fdae438f01a82c69b560b1686d9c..d7617a447a864fd39b36fe39988f260b22e59db5 100644 --- a/lib/c/labcomm_encoder.c +++ b/lib/c/labcomm_encoder.c @@ -25,12 +25,19 @@ #include "labcomm_private.h" #include "labcomm_ioctl.h" +#ifndef WITHOUT_PRAGMA +#include "labcomm_dynamic_buffer_writer.h" +#include "labcomm_bytearray_reader.h" +#endif + struct labcomm_encoder { struct labcomm_writer *writer; struct labcomm_error_handler *error; struct labcomm_memory *memory; struct labcomm_scheduler *scheduler; LABCOMM_SIGNATURE_ARRAY_DEF(registered, int); + int context_type; //type tag for context. Currently only LABCOMM_PRAGMA + void *context; // for, e.g. parent of pragma packet builder }; struct labcomm_encoder *labcomm_encoder_new( @@ -80,6 +87,123 @@ void labcomm_encoder_free(struct labcomm_encoder* e) labcomm_memory_free(memory, 0, e); } +#undef WITHOUT_PRAGMA +#ifndef WITHOUT_PRAGMA + +struct pragma_packet_builder { + char * pragma_type; + struct labcomm_encoder* parent; +}; + +struct labcomm_encoder *labcomm_pragma_builder_new( + struct labcomm_encoder *e, + char * pragma_type) { + struct labcomm_writer *dyn_writer = labcomm_dynamic_buffer_writer_new( + e->memory); + struct labcomm_encoder *mdt = labcomm_encoder_new(dyn_writer, + e->error, + e->memory, + e->scheduler); + struct pragma_packet_builder* ctxt = labcomm_memory_alloc( + e->memory, + 1, + sizeof(struct pragma_packet_builder)); + + if(ctxt){ + ctxt->pragma_type=pragma_type; + ctxt->parent=e; + } + mdt->context_type = LABCOMM_PRAGMA; + mdt->context = ctxt; + return mdt; +} + +//HERE BE DRAGONS! Copied from decoder.c +//Should this be moved to private_h? +static int writer_ioctl(struct labcomm_writer *writer, + uint32_t action, + ...) +{ + int result; + va_list va; + + if (LABCOMM_IOC_SIG(action) != LABCOMM_IOC_NOSIG) { + result = -EINVAL; + goto out; + } + + va_start(va, action); + result = labcomm_writer_ioctl(writer, writer->action_context, + 0, NULL, action, va); + va_end(va); +out: + return result; +} +int labcomm_pragma_send(struct labcomm_encoder* e) +{ +//HERE BE DRAGONS! +//We assume that the writer is a dynamic_buffer_writer + if(e->context_type != LABCOMM_PRAGMA) { + printf("context type != PRAGMA, bailing out\n"); + return 1; + } + if(!e->context) { + printf("context == NULL, bailing out\n"); + return 2; + } + struct pragma_packet_builder* ctx = e->context; + struct labcomm_encoder *p = ctx->parent; + char * pragma_type = ctx->pragma_type; + char* pragma_data; + int err,len; + labcomm_writer_end(e->writer, e->writer->action_context); + err = writer_ioctl(e->writer, + LABCOMM_IOCTL_WRITER_GET_BYTES_WRITTEN, + &len); + if (err < 0) { + +// HERE BE DRAGONS! +// What is the difference between error_handler (where is it defined?) +// and error_handler_callback. And why is the latter only in +// the decoder struct? +// +// e->on_error(LABCOMM_ERROR_BAD_WRITER, 2, +// "Failed to get size: %s\n", strerror(-err)); + fprintf(stderr, "BAD WRITER, Failed to get size> %s\n", strerror(-err)); + err = -ENOENT; + goto free_encoder; + } + err = writer_ioctl(e->writer, + LABCOMM_IOCTL_WRITER_GET_BYTE_POINTER, + &pragma_data); + if (err < 0) { +// e->on_error(LABCOMM_ERROR_BAD_WRITER, 2, +// "Failed to get pointer: %s\n", strerror(-err)); + fprintf(stderr, "BAD WRITER, Failed to get pointer> %s\n", strerror(-err)); + err = -ENOENT; + goto free_encoder; + } + { + int data_len = labcomm_size_string(pragma_type) + len; + int i; + labcomm_write_packed32(p->writer, LABCOMM_PRAGMA); + labcomm_write_packed32(p->writer, data_len); + labcomm_write_string(p->writer, pragma_type); + for(i=0; i<len;i++){ + labcomm_write_byte(p->writer, pragma_data[i]); + } + labcomm_writer_end(p->writer, p->writer->action_context); + err = p->writer->error; + } +free_encoder: + labcomm_memory_free(e->memory, 1, ctx); + labcomm_encoder_free(e); + return err; +} + +#endif + + int labcomm_internal_encoder_register( struct labcomm_encoder *e, struct labcomm_signature *signature,