Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • anders_blomdell/labcomm
  • klaren/labcomm
  • tommyo/labcomm
  • erikj/labcomm
  • sven/labcomm
5 results
Show changes
Showing
with 2189 additions and 162 deletions
/*
labcomm_dynamic_buffer_writer.c -- LabComm dynamic memory writer.
labcomm2014_dynamic_buffer_writer.c -- LabComm dynamic memory writer.
Copyright 2006-2013 Anders Blomdell <anders.blomdell@control.lth.se>
......@@ -22,18 +22,17 @@
#include <errno.h>
#include <stdlib.h>
#include <stdarg.h>
#include "labcomm.h"
#include "labcomm_private.h"
#include "labcomm_ioctl.h"
#include "labcomm_dynamic_buffer_writer.h"
static int dyn_alloc(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context,
char *labcomm_version)
#include "labcomm2014.h"
#include "labcomm2014_private.h"
#include "labcomm2014_ioctl.h"
#include "labcomm2014_dynamic_buffer_writer.h"
static int dyn_alloc(struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context)
{
w->data_size = 1000;
w->count = w->data_size;
w->data = labcomm_memory_alloc(w->memory, 1, w->data_size);
w->data = labcomm2014_memory_alloc(w->memory, 1, w->data_size);
if (w->data == NULL) {
w->error = -ENOMEM;
}
......@@ -42,29 +41,29 @@ static int dyn_alloc(struct labcomm_writer *w,
return w->error;
}
static int dyn_free(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context)
static int dyn_free(struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context)
{
labcomm_memory_free(w->memory, 1, w->data);
labcomm2014_memory_free(w->memory, 1, w->data);
w->data = 0;
w->data_size = 0;
w->count = 0;
w->pos = 0;
labcomm_memory_free(w->memory, 0, action_context->context);
labcomm2014_memory_free(w->memory, 0, action_context->context);
return 0;
}
static int dyn_start(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context,
static int dyn_start(struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context,
int index,
struct labcomm_signature *signature,
const struct labcomm2014_signature *signature,
void *value)
{
void *tmp;
w->data_size = 1000;
w->count = w->data_size;
tmp = labcomm_memory_realloc(w->memory, 1, w->data, w->data_size);
tmp = labcomm2014_memory_realloc(w->memory, 1, w->data, w->data_size);
if (tmp != NULL) {
w->data = tmp;
w->error = 0;
......@@ -76,20 +75,20 @@ static int dyn_start(struct labcomm_writer *w,
return w->error;
}
static int dyn_end(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context)
static int dyn_end(struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context)
{
return 0;
}
static int dyn_flush(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context)
static int dyn_flush(struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context)
{
void *tmp;
w->data_size += 1000;
w->count = w->data_size;
tmp = labcomm_memory_realloc(w->memory, 1, w->data, w->data_size);
tmp = labcomm2014_memory_realloc(w->memory, 1, w->data, w->data_size);
if (tmp != NULL) {
w->data = tmp;
w->error = 0;
......@@ -101,10 +100,10 @@ static int dyn_flush(struct labcomm_writer *w,
return w->error;
}
static int dyn_ioctl(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context,
static int dyn_ioctl(struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context,
int signature_index,
struct labcomm_signature *signature,
const struct labcomm2014_signature *signature,
uint32_t action, va_list arg)
{
int result = -ENOTSUP;
......@@ -123,7 +122,7 @@ static int dyn_ioctl(struct labcomm_writer *w,
return result;
}
static const struct labcomm_writer_action action = {
static const struct labcomm2014_writer_action action = {
.alloc = dyn_alloc,
.free = dyn_free,
.start = dyn_start,
......@@ -131,18 +130,18 @@ static const struct labcomm_writer_action action = {
.flush = dyn_flush,
.ioctl = dyn_ioctl
};
const struct labcomm_writer_action *labcomm_dynamic_buffer_writer_action =
const struct labcomm2014_writer_action *labcomm2014_dynamic_buffer_writer_action =
&action;
struct labcomm_writer *labcomm_dynamic_buffer_writer_new(
struct labcomm_memory *memory)
struct labcomm2014_writer *labcomm2014_dynamic_buffer_writer_new(
struct labcomm2014_memory *memory)
{
struct result {
struct labcomm_writer writer;
struct labcomm_writer_action_context action_context;
struct labcomm2014_writer writer;
struct labcomm2014_writer_action_context action_context;
} *result;
result = labcomm_memory_alloc(memory, 0, sizeof(*result));
result = labcomm2014_memory_alloc(memory, 0, sizeof(*result));
if (result != NULL) {
result->action_context.next = NULL;
result->action_context.context = result;
......
/*
labcomm_dynamic_buffer_writer.h -- LabComm dynamic memory writer.
labcomm2014_dynamic_buffer_writer.h -- LabComm dynamic memory writer.
Copyright 2006-2013 Anders Blomdell <anders.blomdell@control.lth.se>
......@@ -19,14 +19,14 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _LABCOMM_DYNAMIC_BUFFER_READER_WRITER_H_
#define _LABCOMM_DYNAMIC_BUFFER_READER_WRITER_H_
#ifndef __LABCOMM2014_DYNAMIC_BUFFER_READER_WRITER_H__
#define __LABCOMM2014_DYNAMIC_BUFFER_READER_WRITER_H__
#include "labcomm.h"
#include "labcomm2014.h"
extern const struct labcomm_writer_action *labcomm_dynamic_buffer_writer_action;
extern const struct labcomm2014_writer_action *labcomm2014_dynamic_buffer_writer_action;
struct labcomm_writer *labcomm_dynamic_buffer_writer_new(
struct labcomm_memory *memory);
struct labcomm2014_writer *labcomm2014_dynamic_buffer_writer_new(
struct labcomm2014_memory *memory);
#endif
/*
labcomm2014_encoder.c -- handling encoding of labcomm2014 samples.
Copyright 2006-2013 Anders Blomdell <anders.blomdell@control.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/>.
*/
#define CURRENT_VERSION "LabComm2014"
#include <errno.h>
#include "labcomm2014.h"
#include "labcomm2014_private.h"
#include "labcomm2014_ioctl.h"
#include "labcomm2014_dynamic_buffer_writer.h"
//define the following to disable encoding of typedefs
#undef LABCOMM_WITHOUT_TYPE_DEFS
#undef LABCOMM2014_WITH_SANITY_CHECKS
struct encoder {
struct labcomm2014_encoder encoder;
LABCOMM_SIGNATURE_ARRAY_DEF(registered, int);
LABCOMM_SIGNATURE_ARRAY_DEF(sample_ref, int);
LABCOMM_SIGNATURE_ARRAY_DEF(typedefs, int);
};
#ifdef LABCOMM2014_WITH_SANITY_CHECKS
static int expectedByteCount;
static void encoder_check_write_start(struct labcomm2014_encoder *e, int numBytes)
{
int previouslyWritten = 0;
int err = labcomm2014_encoder_ioctl(e, LABCOMM_IOCTL_WRITER_GET_BYTES_WRITTEN, &previouslyWritten);
if(err) {
printf("ERROR: get_bytes_written returned %d (%s)\n", err, strerror(err));
}
expectedByteCount = numBytes + previouslyWritten;
#ifdef LABCOMM2014_ENCODER_DEBUG
printf("previously written: %d bytes, length = %d bytes, expected = %d bytes\n",
previouslyWritten, numBytes, expectedByteCount);
#endif
}
static int encoder_check_write_end(struct labcomm2014_encoder *e)
{
int written = 0;
int err = labcomm2014_encoder_ioctl(e, LABCOMM_IOCTL_WRITER_GET_BYTES_WRITTEN, &written);
if(err) {
printf("ERROR: get_bytes_written returned %d (%s)\n", err, strerror(err));
}
int result = 0;
#ifdef LABCOMM2014_ENCODER_DEBUG
printf("DEBUG: encoder_check_write_end: expected: %d, was: %d\n",
expectedByteCount, written);
#endif
if(written != expectedByteCount) {
printf("WARNING! encoder_check_write_end: expected: %d, was: %d\n",
expectedByteCount, written);
result = -EINVAL;
}
return result;
}
#endif
/* XXX: TEMPORARY PLACEHOLDERS FOR INTENTIONS */
static int TODO_sizeof_intentions(const struct labcomm2014_signature *signature) {
int res = labcomm2014_size_string(signature->name) + 2;
return res;
}
static int TODO_encode_intentions(
struct labcomm2014_encoder *e,
const struct labcomm2014_signature *signature)
{
int result = -EINVAL;
labcomm2014_write_packed32(e->writer, 1); // one intention: the name
labcomm2014_write_packed32(e->writer, 0); // key: the empty string
labcomm2014_write_string(e->writer, signature->name);
result = e->writer->error;
return result;
}
static int do_sample_register(
struct labcomm2014_encoder *e,
const struct labcomm2014_signature *signature,
labcomm2014_encoder_function encode)
{
int result = -EINVAL;
struct encoder *ie = e->context;
int index, *done, err, i, length;
index = labcomm2014_get_local_index(signature);
labcomm2014_scheduler_writer_lock(e->scheduler);
if (index <= 0) { goto out; }
done = LABCOMM_SIGNATURE_ARRAY_REF(e->memory, ie->registered, int, index);
if (*done) {
goto out; }
*done = 1;
err = labcomm2014_writer_start(e->writer, e->writer->action_context,
index, signature, NULL);
if (err == -EALREADY) { result = 0; goto out; }
if (err != 0) { result = err; goto out; }
labcomm2014_write_packed32(e->writer, LABCOMM_SAMPLE_DEF);
length = (labcomm2014_size_packed32(index) +
TODO_sizeof_intentions(signature) +
labcomm2014_size_packed32(signature->size) +
signature->size);
labcomm2014_write_packed32(e->writer, length);
labcomm2014_write_packed32(e->writer, index);
TODO_encode_intentions(e, signature);
labcomm2014_write_packed32(e->writer, signature->size);
for (i = 0 ; i < signature->size ; i++) {
if (e->writer->pos >= e->writer->count) {
labcomm2014_writer_flush(e->writer, e->writer->action_context);
}
e->writer->data[e->writer->pos] = signature->signature[i];
e->writer->pos++;
}
labcomm2014_writer_end(e->writer, e->writer->action_context);
result = e->writer->error;
out:
labcomm2014_scheduler_writer_unlock(e->scheduler);
return result;
}
static int do_encode(
struct labcomm2014_encoder *e,
const struct labcomm2014_signature *signature,
labcomm2014_encoder_function encode,
void *value)
{
int result, index, length;
struct encoder *ie = e->context;
index = labcomm2014_get_local_index(signature);
length = (signature->encoded_size(signature, value));
labcomm2014_scheduler_writer_lock(e->scheduler);
if (! LABCOMM_SIGNATURE_ARRAY_GET(ie->registered, int, index, 0)) {
result = -EINVAL;
goto no_end;
}
result = labcomm2014_writer_start(e->writer, e->writer->action_context,
index, signature, value);
if (result == -EALREADY) { result = 0; goto no_end; }
if (result != 0) { goto out; }
result = labcomm2014_write_packed32(e->writer, index);
result = labcomm2014_write_packed32(e->writer, length);
if (result != 0) { goto out; }
result = encode(e->writer, value);
out:
labcomm2014_writer_end(e->writer, e->writer->action_context);
no_end:
labcomm2014_scheduler_writer_unlock(e->scheduler);
return result;
}
int labcomm2014_encoder_sample_ref_register(
struct labcomm2014_encoder *e,
const struct labcomm2014_signature *signature)
{
return e->ref_register(e, signature);
}
static int do_ref_register(
struct labcomm2014_encoder *e,
const struct labcomm2014_signature *signature)
{
int result = -EINVAL;
struct encoder *ie = e->context;
int index, *done, err, i, length;
index = labcomm2014_get_local_index(signature);
labcomm2014_scheduler_writer_lock(e->scheduler);
if (index <= 0) { goto out; }
done = LABCOMM_SIGNATURE_ARRAY_REF(e->memory, ie->sample_ref, int, index);
if (*done) { goto out; }
*done = 1;
err = labcomm2014_writer_start(e->writer, e->writer->action_context,
index, signature, NULL);
if (err == -EALREADY) { result = 0; goto out; }
if (err != 0) { result = err; goto out; }
labcomm2014_write_packed32(e->writer, LABCOMM_SAMPLE_REF);
length = (labcomm2014_size_packed32(index) +
TODO_sizeof_intentions(signature) +
labcomm2014_size_packed32(signature->size) +
signature->size);
labcomm2014_write_packed32(e->writer, length);
labcomm2014_write_packed32(e->writer, index);
TODO_encode_intentions(e, signature);
labcomm2014_write_packed32(e->writer, signature->size);
for (i = 0 ; i < signature->size ; i++) {
if (e->writer->pos >= e->writer->count) {
labcomm2014_writer_flush(e->writer, e->writer->action_context);
}
e->writer->data[e->writer->pos] = signature->signature[i];
e->writer->pos++;
}
labcomm2014_writer_end(e->writer, e->writer->action_context);
result = e->writer->error;
out:
labcomm2014_scheduler_writer_unlock(e->scheduler);
return result;
}
int labcomm2014_encoder_ioctl(struct labcomm2014_encoder *encoder,
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 = encoder->ioctl(encoder, NULL, action, va);
va_end(va);
out:
return result;
}
static int do_ioctl(
struct labcomm2014_encoder *encoder,
const struct labcomm2014_signature *signature,
uint32_t action, va_list va)
{
int result = -ENOTSUP;
int index;
index = labcomm2014_get_local_index(signature);
result = labcomm2014_writer_ioctl(encoder->writer,
encoder->writer->action_context,
index, signature, action, va);
return result;
}
static int do_sample_ref_to_index(
struct labcomm2014_encoder *e,
const struct labcomm2014_sample_ref *sample_ref)
{
/* writer_lock should be held at this point */
struct encoder *ie = e->context;
int index = 0;
if (sample_ref != NULL) {
index = labcomm2014_get_local_index(
(struct labcomm2014_signature *)sample_ref);
if (! LABCOMM_SIGNATURE_ARRAY_GET(ie->sample_ref, int, index, 0)) {
index = 0;
}
}
return index;
}
/**********************************************************
* Start of code related to sending (hierarchical)
* typedefs. Define LABCOMM_WITHOUT_TYPEDEFS to disable
**********************************************************/
#ifndef LABCOMM_WITHOUT_TYPE_DEFS
static void write_sig_tree_byte(char b, const struct labcomm2014_signature *signature,
void *context)
{
struct labcomm2014_encoder *e = context;
if(signature) {
labcomm2014_write_packed32(e->writer, labcomm2014_get_local_index(signature));
}else {
if (e->writer->pos >= e->writer->count) {
labcomm2014_writer_flush(e->writer, e->writer->action_context);
}
e->writer->data[e->writer->pos] = b;
e->writer->pos++;
}
}
static void do_write_signature(struct labcomm2014_encoder * e,
const struct labcomm2014_signature *signature,
unsigned char flatten)
{
map_signature(write_sig_tree_byte, e, signature, flatten);
}
static void sig_size(char b, const struct labcomm2014_signature *signature,
void *context)
{
int *result = context;
int diff;
if(signature) {
int idx = labcomm2014_get_local_index(signature);
diff = labcomm2014_size_packed32(idx);
}else {
diff = 1;
}
(*result)+=diff;
}
static int calc_sig_encoded_size(struct labcomm2014_encoder *e,
const struct labcomm2014_signature *sig)
{
int result=0;
map_signature(sig_size, &result, sig, LABCOMM2014_FALSE);
return result;
}
static int internal_reg_type(
struct labcomm2014_encoder *e,
const struct labcomm2014_signature *signature,
labcomm2014_bool flatten)
{
int result = -EINVAL;
int index, *done, err;
struct encoder *ie = e->context;
index = labcomm2014_get_local_index(signature);
labcomm2014_scheduler_writer_lock(e->scheduler);
if (index <= 0) { goto out; }
done = LABCOMM_SIGNATURE_ARRAY_REF(e->memory, ie->typedefs, int, index);
if (*done) { goto out; }
*done = 1;
err = labcomm2014_writer_start(e->writer, e->writer->action_context,
index, signature, NULL);
if (err == -EALREADY) { result = 0; goto out; }
if (err != 0) { result = err; goto out; }
printf("internal_reg_type: %s\n", signature->name);
int sig_size = calc_sig_encoded_size(e, signature);
int len_idx= labcomm2014_size_packed32(index);
int len_ints =TODO_sizeof_intentions(signature);
int len_sigsize =labcomm2014_size_packed32(sig_size);
int len_sig =sig_size;
int len = len_idx + len_ints + len_sigsize + len_sig;
labcomm2014_write_packed32(e->writer, LABCOMM_TYPE_DEF);
labcomm2014_write_packed32(e->writer, len);
#ifdef LABCOMM2014_WITH_SANITY_CHECKS
encoder_check_write_start(e, len);
#endif
labcomm2014_write_packed32(e->writer, index);
TODO_encode_intentions(e, signature);
labcomm2014_write_packed32(e->writer, sig_size);
do_write_signature(e, signature, LABCOMM2014_FALSE);
#ifdef LABCOMM2014_WITH_SANITY_CHECKS
encoder_check_write_end(e);
#endif
labcomm2014_writer_end(e->writer, e->writer->action_context);
result = e->writer->error;
out:
labcomm2014_scheduler_writer_unlock(e->scheduler);
return result;
}
#endif
static int do_type_register(
struct labcomm2014_encoder *e,
const struct labcomm2014_signature *signature)
{
#ifndef LABCOMM_WITHOUT_TYPE_DEFS
return internal_reg_type(e, signature, LABCOMM2014_FALSE);
#else
return 0;
#endif
}
static int do_type_bind(
struct labcomm2014_encoder *e,
const struct labcomm2014_signature *signature,
char has_deps)
{
#ifndef LABCOMM_WITHOUT_TYPE_DEFS
int result = -EINVAL;
int err;
int sindex = labcomm2014_get_local_index(signature);
int tindex = has_deps ? labcomm2014_get_local_type_index(signature) : LABCOMM_BIND_SELF;
labcomm2014_scheduler_writer_lock(e->scheduler);
if(sindex <= 0 || (has_deps && tindex <= 0)) {goto out;}
err = labcomm2014_writer_start(e->writer, e->writer->action_context,
LABCOMM_TYPE_BINDING, signature, NULL);
if (err == -EALREADY) { result = 0; goto out; }
if (err != 0) { result = err; goto out; }
int length = (labcomm2014_size_packed32(sindex) +
labcomm2014_size_packed32(tindex));
labcomm2014_write_packed32(e->writer, LABCOMM_TYPE_BINDING);
labcomm2014_write_packed32(e->writer, length);
labcomm2014_write_packed32(e->writer, sindex);
labcomm2014_write_packed32(e->writer, tindex);
labcomm2014_writer_end(e->writer, e->writer->action_context);
result = e->writer->error;
out:
labcomm2014_scheduler_writer_unlock(e->scheduler);
return result;
#else
return 0;
#endif
}
static const struct labcomm2014_sample_ref *do_ref_get(
struct labcomm2014_encoder *e,
const struct labcomm2014_signature *signature)
{
return (const struct labcomm2014_sample_ref *) signature;
}
void labcomm2014_encoder_free(struct labcomm2014_encoder* e)
{
e->free(e);
}
static void do_free(struct labcomm2014_encoder* e)
{
struct encoder *ie = e->context;
struct labcomm2014_memory *memory = e->memory;
labcomm2014_writer_free(e->writer, e->writer->action_context);
LABCOMM_SIGNATURE_ARRAY_FREE(e->memory, ie->registered, int);
LABCOMM_SIGNATURE_ARRAY_FREE(e->memory, ie->sample_ref, int);
LABCOMM_SIGNATURE_ARRAY_FREE(e->memory, ie->typedefs, int);
labcomm2014_memory_free(memory, 0, ie);
}
static struct labcomm2014_encoder *internal_encoder_new(
struct labcomm2014_writer *writer,
struct labcomm2014_error_handler *error,
struct labcomm2014_memory *memory,
struct labcomm2014_scheduler *scheduler,
labcomm2014_bool outputVer)
{
struct encoder *result;
result = labcomm2014_memory_alloc(memory, 0, sizeof(*result));
if (result) {
int length;
result->encoder.context = result;
result->encoder.writer = writer;
result->encoder.writer->encoder = &result->encoder;
result->encoder.writer->data = NULL;
result->encoder.writer->data_size = 0;
result->encoder.writer->count = 0;
result->encoder.writer->pos = 0;
result->encoder.writer->error = 0;
result->encoder.error = error;
result->encoder.memory = memory;
result->encoder.scheduler = scheduler;
result->encoder.free = do_free;
result->encoder.type_register = do_type_register;
result->encoder.type_bind = do_type_bind;
result->encoder.sample_register = do_sample_register;
result->encoder.ref_register = do_ref_register;
result->encoder.encode = do_encode;
result->encoder.ioctl = do_ioctl;
result->encoder.sample_ref_to_index = do_sample_ref_to_index;
result->encoder.ref_get = do_ref_get;
LABCOMM_SIGNATURE_ARRAY_INIT(result->registered, int);
LABCOMM_SIGNATURE_ARRAY_INIT(result->sample_ref, int);
LABCOMM_SIGNATURE_ARRAY_INIT(result->typedefs, int);
labcomm2014_writer_alloc(result->encoder.writer,
result->encoder.writer->action_context);
if(outputVer) {
labcomm2014_writer_start(result->encoder.writer,
result->encoder.writer->action_context,
LABCOMM_VERSION, NULL, CURRENT_VERSION);
labcomm2014_write_packed32(result->encoder.writer, LABCOMM_VERSION);
length = labcomm2014_size_string(CURRENT_VERSION);
labcomm2014_write_packed32(result->encoder.writer, length);
labcomm2014_write_string(result->encoder.writer, CURRENT_VERSION);
labcomm2014_writer_end(result->encoder.writer,
result->encoder.writer->action_context);
}
}
return &(result->encoder);
}
struct labcomm2014_encoder *labcomm2014_encoder_new(
struct labcomm2014_writer *writer,
struct labcomm2014_error_handler *error,
struct labcomm2014_memory *memory,
struct labcomm2014_scheduler *scheduler)
{
return internal_encoder_new(writer,error,memory,scheduler,LABCOMM2014_TRUE);
}
const struct labcomm2014_sample_ref *labcomm2014_encoder_get_sample_ref(
struct labcomm2014_encoder *encoder,
const struct labcomm2014_signature *signature)
{
return encoder->ref_get(encoder, signature);
}
/*
labcomm2014_error.c -- labcomm2014 error handling
Copyright 2013 Anders Blomdell <anders.blomdell@control.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 <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include "labcomm2014_error.h"
static char *description[] = {
#define LABCOMM2014_ERROR(name, description) description ,
#include "labcomm2014_error.h"
#undef LABCOMM2014_ERROR
};
void labcomm2014_error_fatal_global(enum labcomm2014_error error,
char *format,
...)
{
va_list args;
fprintf(stderr, "Fatal error %d (%s)\n", error, description[error]);
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
exit(1);
}
void labcomm2014_error_warning(struct labcomm2014_error_handler *e,
enum labcomm2014_error error,
char *format,
...)
{
va_list args;
fprintf(stderr, "Fatal warning %d (%s)\n", error, description[error]);
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
exit(1);
}
/*
labcomm_error.h -- labcomm error declarations
labcomm2014_error.h -- labcomm2014 error declarations
Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
......@@ -19,50 +19,55 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __LABCOMM_ERROR_H__
#define __LABCOMM_ERROR_H__
#ifndef __LABCOMM2014_ERROR_H___
#define __LABCOMM2014_ERROR_H___
enum labcomm_error {
#define LABCOMM_ERROR(name, description) name ,
#include "labcomm_error.h"
#undef LABCOMM_ERROR
enum labcomm2014_error {
#define LABCOMM2014_ERROR(name, description) name ,
#include "labcomm2014_error.h"
#undef LABCOMM2014_ERROR
};
struct labcomm_error_handler;
struct labcomm2014_error_handler;
void labcomm_error_warning(struct labcomm_error_handler *e,
enum labcomm_error,
void labcomm2014_error_warning(struct labcomm2014_error_handler *e,
enum labcomm2014_error,
char *format,
...);
void labcomm_error_fatal_global(enum labcomm_error error,
void labcomm2014_error_fatal_global(enum labcomm2014_error error,
char *format,
...);
#endif
#ifdef LABCOMM_ERROR
#ifdef LABCOMM2014_ERROR
LABCOMM_ERROR(LABCOMM_ERROR_SIGNATURE_ALREADY_SET,
"Signature has already been set")
LABCOMM_ERROR(LABCOMM_ERROR_SIGNATURE_NOT_SET,
"Signature has not been set")
LABCOMM2014_ERROR(LABCOMM2014_ERROR_SIGNATURE_ALREADY_SET,
"Signature has already been set")
LABCOMM2014_ERROR(LABCOMM2014_ERROR_SIGNATURE_NOT_SET,
"Signature has not been set")
LABCOMM_ERROR(LABCOMM_ERROR_ENC_NO_REG_SIGNATURE,
"Encoder has no registration for this signature")
LABCOMM_ERROR(LABCOMM_ERROR_ENC_BUF_FULL,
"The labcomm buffer is full")
LABCOMM_ERROR(LABCOMM_ERROR_DEC_UNKNOWN_DATATYPE,
"Decoder: Unknown datatype")
LABCOMM_ERROR(LABCOMM_ERROR_DEC_INDEX_MISMATCH,
"Decoder: index mismatch")
LABCOMM_ERROR(LABCOMM_ERROR_DEC_TYPE_NOT_FOUND,
"Decoder: type not found")
LABCOMM_ERROR(LABCOMM_ERROR_UNIMPLEMENTED_FUNC,
"This function is not yet implemented")
LABCOMM_ERROR(LABCOMM_ERROR_MEMORY,
"Could not allocate memory")
LABCOMM_ERROR(LABCOMM_ERROR_USER_DEF,
"User defined error")
LABCOMM2014_ERROR(LABCOMM2014_ERROR_ENC_NO_REG_SIGNATURE,
"Encoder has no registration for this signature")
LABCOMM2014_ERROR(LABCOMM2014_ERROR_ENC_BUF_FULL,
"The labcomm2014 buffer is full")
LABCOMM2014_ERROR(LABCOMM2014_ERROR_DEC_NO_REG_SIGNATURE,
"Decoder has no registration for this signature")
LABCOMM2014_ERROR(LABCOMM2014_ERROR_DEC_UNKNOWN_DATATYPE,
"Decoder: Unknown datatype")
LABCOMM2014_ERROR(LABCOMM2014_ERROR_DEC_INDEX_MISMATCH,
"Decoder: index mismatch")
LABCOMM2014_ERROR(LABCOMM2014_ERROR_DEC_TYPE_NOT_FOUND,
"Decoder: type not found")
LABCOMM2014_ERROR(LABCOMM2014_ERROR_UNIMPLEMENTED_FUNC,
"This function is not yet implemented")
LABCOMM2014_ERROR(LABCOMM2014_ERROR_MEMORY,
"Could not allocate memory")
LABCOMM2014_ERROR(LABCOMM2014_ERROR_USER_DEF,
"User defined error")
LABCOMM2014_ERROR(LABCOMM2014_ERROR_BAD_WRITER,
"Decoder: writer_ioctl() failed")
#endif
/*
labcomm_fd_reader.c -- LabComm reader for Unix file descriptors.
labcomm2014_fd_reader.c -- LabComm reader for Unix file descriptors.
Copyright 2006-2013 Anders Blomdell <anders.blomdell@control.lth.se>
......@@ -23,27 +23,26 @@
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include "labcomm_private.h"
#include "labcomm_fd_reader.h"
#include "labcomm2014_private.h"
#include "labcomm2014_fd_reader.h"
#define BUFFER_SIZE 2048
struct labcomm_fd_reader {
struct labcomm_reader reader;
struct labcomm_reader_action_context action_context;
struct labcomm2014_fd_reader {
struct labcomm2014_reader reader;
struct labcomm2014_reader_action_context action_context;
int fd;
int close_fd_on_free;
};
static int fd_alloc(struct labcomm_reader *r,
struct labcomm_reader_action_context *action_context,
char *version)
static int fd_alloc(struct labcomm2014_reader *r,
struct labcomm2014_reader_action_context *action_context)
{
int result = 0;
r->count = 0;
r->pos = 0;
r->data = labcomm_memory_alloc(r->memory, 0, BUFFER_SIZE);
r->data = labcomm2014_memory_alloc(r->memory, 0, BUFFER_SIZE);
if (! r->data) {
r->data_size = 0;
result = -ENOMEM;
......@@ -51,28 +50,17 @@ static int fd_alloc(struct labcomm_reader *r,
r->data_size = BUFFER_SIZE;
result = r->data_size;
if (version && version[0]) {
char *tmp;
tmp = labcomm_read_string(r);
if (strcmp(tmp, version) != 0) {
result = -EINVAL;
} else {
result = r->data_size;
}
labcomm_memory_free(r->memory, 1, tmp);
}
}
return result;
}
static int fd_free(struct labcomm_reader *r,
struct labcomm_reader_action_context *action_context)
static int fd_free(struct labcomm2014_reader *r,
struct labcomm2014_reader_action_context *action_context)
{
struct labcomm_fd_reader *fd_reader = action_context->context;
struct labcomm_memory *memory = r->memory;
struct labcomm2014_fd_reader *fd_reader = action_context->context;
struct labcomm2014_memory *memory = r->memory;
labcomm_memory_free(memory, 0, r->data);
labcomm2014_memory_free(memory, 0, r->data);
r->data = 0;
r->data_size = 0;
r->count = 0;
......@@ -81,16 +69,16 @@ static int fd_free(struct labcomm_reader *r,
if (fd_reader->close_fd_on_free) {
close(fd_reader->fd);
}
labcomm_memory_free(memory, 0, fd_reader);
labcomm2014_memory_free(memory, 0, fd_reader);
return 0;
}
static int fd_fill(struct labcomm_reader *r,
struct labcomm_reader_action_context *action_context)
static int fd_fill(struct labcomm2014_reader *r,
struct labcomm2014_reader_action_context *action_context)
{
int result = 0;
struct labcomm_fd_reader *fd_reader = action_context->context;
struct labcomm2014_fd_reader *fd_reader = action_context->context;
if (r->pos < r->count) {
result = r->count - r->pos;
......@@ -98,7 +86,7 @@ static int fd_fill(struct labcomm_reader *r,
int err;
r->pos = 0;
err = read(fd_reader->fd, r->data, r->data_size);
err = read(fd_reader->fd, (char *)r->data, r->data_size);
if (err <= 0) {
r->count = 0;
r->error = -EPIPE;
......@@ -111,7 +99,7 @@ static int fd_fill(struct labcomm_reader *r,
return result;
}
static const struct labcomm_reader_action action = {
static const struct labcomm2014_reader_action action = {
.alloc = fd_alloc,
.free = fd_free,
.start = NULL,
......@@ -120,12 +108,12 @@ static const struct labcomm_reader_action action = {
.ioctl = NULL
};
struct labcomm_reader *labcomm_fd_reader_new(struct labcomm_memory *memory,
struct labcomm2014_reader *labcomm2014_fd_reader_new(struct labcomm2014_memory *memory,
int fd, int close_fd_on_free)
{
struct labcomm_fd_reader *result;
struct labcomm2014_fd_reader *result;
result = labcomm_memory_alloc(memory, 0, sizeof(*result));
result = labcomm2014_memory_alloc(memory, 0, sizeof(*result));
if (result == NULL) {
return NULL;
} else {
......
/*
labcomm_fd_reader.c -- a reader for unix style file-descriptors
labcomm2014_fd_reader.c -- a reader for unix style file-descriptors
Copyright 2006-2013 Anders Blomdell <anders.blomdell@control.lth.se>
......@@ -19,12 +19,12 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _LABCOMM_FD_READER_H_
#define _LABCOMM_FD_READER_H_
#ifndef __LABCOMM2014_FD_READER_H__
#define __LABCOMM2014_FD_READER_H__
#include "labcomm.h"
#include "labcomm2014.h"
struct labcomm_reader *labcomm_fd_reader_new(struct labcomm_memory *memory,
struct labcomm2014_reader *labcomm2014_fd_reader_new(struct labcomm2014_memory *memory,
int fd, int close_fd_on_free);
#endif
......
/*
labcomm_fd_writer.c -- LabComm writer for Unix file descriptors.
labcomm2014_fd_writer.c -- LabComm writer for Unix file descriptors.
Copyright 2006-2013 Anders Blomdell <anders.blomdell@control.lth.se>
......@@ -24,26 +24,30 @@
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include "labcomm_private.h"
#include "labcomm_fd_writer.h"
#include "labcomm2014_private.h"
#include "labcomm2014_fd_writer.h"
#include "labcomm2014_ioctl.h"
#define BUFFER_SIZE 2048
struct labcomm_fd_writer {
struct labcomm_writer writer;
struct labcomm_writer_action_context action_context;
#ifdef LABCOMM_WITH_SANITY_CHECKS
static int bytecount_carry = 0;
#endif
struct labcomm2014_fd_writer {
struct labcomm2014_writer writer;
struct labcomm2014_writer_action_context action_context;
int fd;
int close_fd_on_free;
};
static int fd_flush(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context);
static int fd_flush(struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context);
static int fd_alloc(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context,
char *version)
static int fd_alloc(struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context)
{
w->data = labcomm_memory_alloc(w->memory, 0, BUFFER_SIZE);
w->data = labcomm2014_memory_alloc(w->memory, 0, BUFFER_SIZE);
if (! w->data) {
w->error = -ENOMEM;
w->data_size = 0;
......@@ -53,22 +57,18 @@ static int fd_alloc(struct labcomm_writer *w,
w->data_size = BUFFER_SIZE;
w->count = BUFFER_SIZE;
w->pos = 0;
if (version && version[0]) {
labcomm_write_string(w, version);
fd_flush(w, action_context);
}
}
return w->error;
}
static int fd_free(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context)
static int fd_free(struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context)
{
struct labcomm_fd_writer *fd_writer = action_context->context;
struct labcomm_memory *memory = w->memory;
struct labcomm2014_fd_writer *fd_writer = action_context->context;
struct labcomm2014_memory *memory = w->memory;
labcomm_memory_free(memory, 0, w->data);
labcomm2014_memory_free(memory, 0, w->data);
w->data = 0;
w->data_size = 0;
w->count = 0;
......@@ -77,31 +77,34 @@ static int fd_free(struct labcomm_writer *w,
if (fd_writer->close_fd_on_free) {
close(fd_writer->fd);
}
labcomm_memory_free(memory, 0, fd_writer);
labcomm2014_memory_free(memory, 0, fd_writer);
return 0;
}
static int fd_start(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context,
static int fd_start(struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context,
int index,
struct labcomm_signature *signature,
const struct labcomm2014_signature *signature,
void *value)
{
#ifdef LABCOMM_WITH_SANITY_CHECKS
bytecount_carry = w->pos;
#endif
w->pos = 0;
return w->error;
}
static int fd_flush(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context)
static int fd_flush(struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context)
{
struct labcomm_fd_writer *fd_context = action_context->context;
struct labcomm2014_fd_writer *fd_context = action_context->context;
int start, err;
start = 0;
err = 0;
while (start < w->pos) {
err = write(fd_context->fd, &w->data[start], w->pos - start);
err = write(fd_context->fd, (char *)&w->data[start], w->pos - start);
if (err <= 0) {
break;
}
......@@ -112,26 +115,53 @@ static int fd_flush(struct labcomm_writer *w,
} else if (err == 0) {
w->error = -EINVAL;
}
#ifdef LABCOMM_WITH_SANITY_CHECKS
bytecount_carry = w->pos;
#endif
w->pos = 0;
return w->error;
}
static const struct labcomm_writer_action action = {
#ifdef LABCOMM_WITH_SANITY_CHECKS
static int fd_ioctl(struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context,
int signature_index,
const struct labcomm2014_signature *signature,
uint32_t action, va_list arg)
{
int result = -ENOTSUP;
switch (action) {
case LABCOMM_IOCTL_WRITER_GET_BYTES_WRITTEN: {
int *value = va_arg(arg, int*);
*value = w->pos + bytecount_carry;
result = 0;
} break;
}
return result;
}
#endif
static const struct labcomm2014_writer_action action = {
.alloc = fd_alloc,
.free = fd_free,
.start = fd_start,
.end = fd_flush,
.flush = fd_flush,
#ifdef LABCOMM_WITH_SANITY_CHECKS
.ioctl = fd_ioctl
#else
.ioctl = NULL
#endif
};
struct labcomm_writer *labcomm_fd_writer_new(struct labcomm_memory *memory,
struct labcomm2014_writer *labcomm2014_fd_writer_new(struct labcomm2014_memory *memory,
int fd, int close_fd_on_free)
{
struct labcomm_fd_writer *result;
struct labcomm2014_fd_writer *result;
result = labcomm_memory_alloc(memory, 0, sizeof(*result));
result = labcomm2014_memory_alloc(memory, 0, sizeof(*result));
if (result == NULL) {
return NULL;
} else {
......
/*
labcomm_fd_writer.c -- a writer for unix style file-descriptors
labcomm2014_fd_writer.c -- a writer for unix style file-descriptors
Copyright 2006-2013 Anders Blomdell <anders.blomdell@control.lth.se>
......@@ -19,12 +19,12 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _LABCOMM_FD_WRITER_H_
#define _LABCOMM_FD_WRITER_H_
#ifndef __LABCOMM2014_FD_WRITER_H__
#define __LABCOMM2014_FD_WRITER_H__
#include "labcomm.h"
#include "labcomm2014.h"
struct labcomm_writer *labcomm_fd_writer_new(struct labcomm_memory *memory,
struct labcomm2014_writer *labcomm2014_fd_writer_new(struct labcomm2014_memory *memory,
int fd, int close_on_free);
#endif
......
/*
labcomm_ioctl.h -- labcomm ioctl declarations
labcomm2014_ioctl.h -- labcomm2014 ioctl declarations
Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
......@@ -19,10 +19,10 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __LABCOMM_IOCTL_H__
#define __LABCOMM_IOCTL_H__
#ifndef __LABCOMM2014_IOCTL_H___
#define __LABCOMM2014_IOCTL_H___
#include "labcomm.h"
#include "labcomm2014.h"
/*
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
......@@ -35,7 +35,7 @@
* | +----------------------------------------------- direction (2)
* +------------------------------------------------- signature (1)
*
* type 0-31 are reserved for labcomm library use
* type 0-31 are reserved for labcomm2014 library use
*/
......@@ -84,23 +84,14 @@
LABCOMM_IOC(LABCOMM_IOC_NOSIG,LABCOMM_IOC_NONE,type,nr,0)
#define LABCOMM_IOR(type,nr,size) \
LABCOMM_IOC(LABCOMM_IOC_NOSIG,LABCOMM_IOC_READ,type,nr,sizeof(size))
/* FIXME: add flag to differentiate between size and nargs */
#define LABCOMM_IORN(type,nr,nargs) \
LABCOMM_IOC(LABCOMM_IOC_NOSIG,LABCOMM_IOC_READ,type,nr,nargs)
#define LABCOMM_IOW(type,nr,size) \
LABCOMM_IOC(LABCOMM_IOC_NOSIG,LABCOMM_IOC_WRITE,type,nr,sizeof(size))
#define LABCOMM_IOWN(type,nr,nargs) \
LABCOMM_IOC(LABCOMM_IOC_NOSIG,LABCOMM_IOC_WRITE,type,nr,nargs)
#define LABCOMM_IOS(type,nr) \
#define LABCOMM_IOS(type,nr) \
LABCOMM_IOC(LABCOMM_IOC_USESIG,LABCOMM_IOC_READ,type,nr,0)
#define LABCOMM_IOSR(type,nr,size) \
LABCOMM_IOC(LABCOMM_IOC_USESIG,LABCOMM_IOC_READ,type,nr,sizeof(size))
#define LABCOMM_IOSRN(type,nr,nargs) \
LABCOMM_IOC(LABCOMM_IOC_USESIG,LABCOMM_IOC_READ,type,nr,nargs)
#define LABCOMM_IOSW(type,nr,size) \
LABCOMM_IOC(LABCOMM_IOC_USESIG,LABCOMM_IOC_WRITE,type,nr,sizeof(size))
#define LABCOMM_IOSWN(type,nr,nargs) \
LABCOMM_IOC(LABCOMM_IOC_USESIG,LABCOMM_IOC_WRITE,type,nr,nargs)
#define LABCOMM_IOCTL_WRITER_GET_BYTES_WRITTEN \
LABCOMM_IOR(0,1,int)
......
/*
labcomm_memory.c -- dynamic memory handlig dispatcher
labcomm2014_memory.c -- dynamic memory handlig dispatcher
Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
......@@ -19,21 +19,21 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "labcomm_private.h"
#include "labcomm2014_private.h"
void *labcomm_memory_alloc(struct labcomm_memory *m, int lifetime,
void *labcomm2014_memory_alloc(struct labcomm2014_memory *m, int lifetime,
size_t size)
{
return m->alloc(m, lifetime, size);
}
void *labcomm_memory_realloc(struct labcomm_memory *m, int lifetime,
void *labcomm2014_memory_realloc(struct labcomm2014_memory *m, int lifetime,
void *ptr, size_t size)
{
return m->realloc(m, lifetime, ptr, size);
}
void labcomm_memory_free(struct labcomm_memory *m, int lifetime,
void labcomm2014_memory_free(struct labcomm2014_memory *m, int lifetime,
void *ptr)
{
m->free(m, lifetime, ptr);
......
/*
labcomm_private.h -- semi private declarations for handling encoding and
decoding of labcomm samples.
labcomm2014_private.h -- semi private declarations for handling encoding and
decoding of labcomm2014 samples.
Copyright 2006-2013 Anders Blomdell <anders.blomdell@control.lth.se>
......@@ -20,50 +20,61 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _LABCOMM_PRIVATE_H_
#define _LABCOMM_PRIVATE_H_
#ifndef __LABCOMM2014_PRIVATE_H__
#define __LABCOMM2014_PRIVATE_H__
#ifdef LABCOMM_COMPAT
#include LABCOMM_COMPAT
#else
#include <endian.h>
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#endif
#include <stdint.h>
//#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "labcomm.h"
#include "labcomm2014.h"
/*
* Predeclared aggregate type indices
* Allowed packet tags
*/
#define LABCOMM_TYPEDEF 0x01
#define LABCOMM_SAMPLE 0x02
#define LABCOMM_ARRAY 0x10
#define LABCOMM_STRUCT 0x11
#define LABCOMM_VERSION 0x01
#define LABCOMM_SAMPLE_DEF 0x02
#define LABCOMM_SAMPLE_REF 0x03
#define LABCOMM_TYPE_DEF 0x04
#define LABCOMM_TYPE_BINDING 0x05
#define LABCOMM_PRAGMA 0x3f
#define LABCOMM_USER 0x40 /* ..0xffffffff */
/*
* Predeclared primitive type indices
* Predefined aggregate type indices
*/
#define LABCOMM_BOOLEAN 0x20
#define LABCOMM_BYTE 0x21
#define LABCOMM_SHORT 0x22
#define LABCOMM_INT 0x23
#define LABCOMM_LONG 0x24
#define LABCOMM_FLOAT 0x25
#define LABCOMM_DOUBLE 0x26
#define LABCOMM_STRING 0x27
#define LABCOMM_ARRAY 0x10
#define LABCOMM_STRUCT 0x11
/*
* Start index for user defined types
* Predefined primitive type indices
*/
#define LABCOMM_USER 0x40
#define LABCOMM_BOOLEAN 0x20
#define LABCOMM_BYTE 0x21
#define LABCOMM_SHORT 0x22
#define LABCOMM_INT 0x23
#define LABCOMM_LONG 0x24
#define LABCOMM_FLOAT 0x25
#define LABCOMM_DOUBLE 0x26
#define LABCOMM_STRING 0x27
#define LABCOMM_REF 0x28
/*
* other special values
*/
#define LABCOMM_BIND_SELF 0
/*
* Macro to automagically call constructors in modules compiled
* with the labcomm compiler. If __attribute__((constructor)) is
* with the labcomm2014 compiler. If __attribute__((constructor)) is
* not supported, these calls has to be done first in main program.
*/
#ifndef LABCOMM_CONSTRUCTOR
......@@ -74,39 +85,55 @@
* Semi private dynamic memory declarations
*/
struct labcomm_memory {
void *(*alloc)(struct labcomm_memory *m, int lifetime, size_t size);
void *(*realloc)(struct labcomm_memory *m, int lifetime,
struct labcomm2014_memory {
void *(*alloc)(struct labcomm2014_memory *m, int lifetime, size_t size);
void *(*realloc)(struct labcomm2014_memory *m, int lifetime,
void *ptr, size_t size);
void (*free)(struct labcomm_memory *m, int lifetime, void *ptr);
void (*free)(struct labcomm2014_memory *m, int lifetime, void *ptr);
void *context;
};
/*
* sample_ref/signature helpers
*/
static const inline
struct labcomm2014_signature *labcomm2014_sample_ref_to_signature(
const struct labcomm2014_sample_ref *sample_ref
)
{
return (struct labcomm2014_signature *)sample_ref;
}
static const inline
struct labcomm2014_sample_ref *labcomm2014_signature_to_sample_ref(
const struct labcomm2014_signature *signature
)
{
return (struct labcomm2014_sample_ref *)signature;
}
/*
* Semi private decoder declarations
*/
typedef void (*labcomm_handler_function)(void *value, void *context);
typedef void (*labcomm2014_handler_function)(void *value, void *context);
typedef void (*labcomm_decoder_function)(
struct labcomm_reader *r,
labcomm_handler_function handler,
typedef void (*labcomm2014_decoder_function)(
struct labcomm2014_reader *r,
labcomm2014_handler_function handler,
void *context);
struct labcomm_reader_action_context;
struct labcomm2014_reader_action_context;
struct labcomm_reader_action {
/* 'alloc' is called at the first invocation of 'labcomm_decoder_decode_one'
on the decoder containing the reader. If 'labcomm_version' != NULL
and non-empty the transport layer may use it to ensure that
compatible versions are used.
struct labcomm2014_reader_action {
/* 'alloc' is called at the first invocation of 'labcomm2014_decoder_decode_one'
on the decoder containing the reader.
Returned value:
> 0 Number of bytes allocated for buffering
<= 0 Error
*/
int (*alloc)(struct labcomm_reader *r,
struct labcomm_reader_action_context *action_context,
char *labcomm_version);
int (*alloc)(struct labcomm2014_reader *r,
struct labcomm2014_reader_action_context *action_context);
/* 'free' returns the resources claimed by 'alloc' and might have other
reader specific side-effects as well.
......@@ -114,8 +141,8 @@ struct labcomm_reader_action {
== 0 Success
!= 0 Error
*/
int (*free)(struct labcomm_reader *r,
struct labcomm_reader_action_context *action_context);
int (*free)(struct labcomm2014_reader *r,
struct labcomm2014_reader_action_context *action_context);
/* 'start' is called at the following instances:
1. When a sample is registered
(local_index != 0, remote_index == 0, value == NULL)
......@@ -124,33 +151,33 @@ struct labcomm_reader_action {
3. When a sample is received
(local_index != 0, remote_index != 0, value != NULL)
*/
int (*start)(struct labcomm_reader *r,
struct labcomm_reader_action_context *action_context,
int (*start)(struct labcomm2014_reader *r,
struct labcomm2014_reader_action_context *action_context,
int local_index, int remote_index,
struct labcomm_signature *signature,
const struct labcomm2014_signature *signature,
void *value);
int (*end)(struct labcomm_reader *r,
struct labcomm_reader_action_context *action_context);
int (*fill)(struct labcomm_reader *r,
struct labcomm_reader_action_context *action_context);
int (*ioctl)(struct labcomm_reader *r,
struct labcomm_reader_action_context *action_context,
int (*end)(struct labcomm2014_reader *r,
struct labcomm2014_reader_action_context *action_context);
int (*fill)(struct labcomm2014_reader *r,
struct labcomm2014_reader_action_context *action_context);
int (*ioctl)(struct labcomm2014_reader *r,
struct labcomm2014_reader_action_context *action_context,
int local_index, int remote_index,
struct labcomm_signature *signature,
const struct labcomm2014_signature *signature,
uint32_t ioctl_action, va_list args);
};
struct labcomm_reader_action_context {
struct labcomm_reader_action_context *next;
const struct labcomm_reader_action *action;
struct labcomm2014_reader_action_context {
struct labcomm2014_reader_action_context *next;
const struct labcomm2014_reader_action *action;
void *context;
};
struct labcomm_reader {
struct labcomm_reader_action_context *action_context;
struct labcomm_memory *memory;
/* The following fields are initialized by labcomm_decoder_new */
struct labcomm_decoder *decoder;
struct labcomm2014_reader {
struct labcomm2014_reader_action_context *action_context;
struct labcomm2014_memory *memory;
/* The following fields are initialized by labcomm2014_decoder_new */
struct labcomm2014_decoder *decoder;
unsigned char *data;
int data_size;
int count;
......@@ -158,49 +185,66 @@ struct labcomm_reader {
int error;
};
int labcomm_reader_alloc(struct labcomm_reader *r,
struct labcomm_reader_action_context *action_context,
char *labcomm_version);
int labcomm_reader_free(struct labcomm_reader *r,
struct labcomm_reader_action_context *action_context);
int labcomm_reader_start(struct labcomm_reader *r,
struct labcomm_reader_action_context *action_context,
int labcomm2014_reader_alloc(struct labcomm2014_reader *r,
struct labcomm2014_reader_action_context *action_context);
int labcomm2014_reader_free(struct labcomm2014_reader *r,
struct labcomm2014_reader_action_context *action_context);
int labcomm2014_reader_start(struct labcomm2014_reader *r,
struct labcomm2014_reader_action_context *action_context,
int local_index, int remote_index,
struct labcomm_signature *signature,
const struct labcomm2014_signature *signature,
void *value);
int labcomm_reader_end(struct labcomm_reader *r,
struct labcomm_reader_action_context *action_context);
int labcomm_reader_fill(struct labcomm_reader *r,
struct labcomm_reader_action_context *action_context);
int labcomm_reader_ioctl(struct labcomm_reader *r,
struct labcomm_reader_action_context *action_context,
int labcomm2014_reader_end(struct labcomm2014_reader *r,
struct labcomm2014_reader_action_context *action_context);
int labcomm2014_reader_fill(struct labcomm2014_reader *r,
struct labcomm2014_reader_action_context *action_context);
int labcomm2014_reader_ioctl(struct labcomm2014_reader *r,
struct labcomm2014_reader_action_context *action_context,
int local_index, int remote_index,
struct labcomm_signature *signature,
const struct labcomm2014_signature *signature,
uint32_t ioctl_action, va_list args);
/*
* Non typesafe registration function to be called from
* generated labcomm_decoder_register_* functions.
*/
int labcomm_internal_decoder_register(
struct labcomm_decoder *d,
struct labcomm_signature *s,
labcomm_decoder_function decoder,
labcomm_handler_function handler,
void *context);
int labcomm_internal_decoder_ioctl(struct labcomm_decoder *decoder,
struct labcomm_signature *signature,
uint32_t ioctl_action, va_list args);
struct labcomm2014_decoder {
void *context;
struct labcomm2014_reader *reader;
struct labcomm2014_error_handler *error;
struct labcomm2014_memory *memory;
struct labcomm2014_scheduler *scheduler;
int reader_allocated;
int version_ok;
labcomm2014_error_handler_callback on_error;
labcomm2014_handle_new_datatype_callback on_new_datatype;
void (*free)(struct labcomm2014_decoder *d);
int (*decode_one)(struct labcomm2014_decoder *d);
int (*ref_register)(struct labcomm2014_decoder *d,
const struct labcomm2014_signature *s);
/*
* Non typesafe registration function to be called from
* generated labcomm2014_decoder_register_* functions.
*/
int (*sample_register)(struct labcomm2014_decoder *d,
const struct labcomm2014_signature *s,
labcomm2014_decoder_function decoder,
labcomm2014_handler_function handler,
void *context);
int (*ioctl)(struct labcomm2014_decoder *d,
const struct labcomm2014_signature *s,
uint32_t ioctl_action, va_list args);
const struct labcomm2014_sample_ref *(*index_to_sample_ref)(
struct labcomm2014_decoder *decoder, int index);
const struct labcomm2014_sample_ref *(*ref_get)(
struct labcomm2014_decoder *d,
const struct labcomm2014_signature *signature);
};
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define LABCOMM_DECODE(name, type) \
static inline type labcomm_read_##name(struct labcomm_reader *r) { \
static inline type labcomm2014_read_##name(struct labcomm2014_reader *r) { \
type result; int i; \
for (i = sizeof(type) - 1 ; i >= 0 ; i--) { \
if (r->pos >= r->count) { \
labcomm_reader_fill(r, r->action_context); \
labcomm2014_reader_fill(r, r->action_context); \
if (r->error < 0) { \
return 0; \
} \
......@@ -214,15 +258,15 @@ int labcomm_internal_decoder_ioctl(struct labcomm_decoder *decoder,
#else
#define LABCOMM_DECODE(name, type) \
static inline type labcomm_read_##name(struct labcomm_reader *r) { \
static inline type labcomm2014_read_##name(struct labcomm2014_reader *r) { \
type result; int i; \
for (i = 0 ; i < sizeof(type) ; i++) { \
if (r->pos >= r->count) { \
labcomm_reader_fille(r, r->action_context); \
labcomm2014_reader_fille(r, r->action_context); \
if (r->error < 0) { \
return 0; \
} \
} \
} > \
((unsigned char*)(&result))[i] = r->data[r->pos]; \
r->pos++; \
} \
......@@ -239,7 +283,7 @@ LABCOMM_DECODE(long, long long)
LABCOMM_DECODE(float, float)
LABCOMM_DECODE(double, double)
static inline unsigned int labcomm_read_packed32(struct labcomm_reader *r)
static inline unsigned int labcomm2014_read_packed32(struct labcomm2014_reader *r)
{
unsigned int result = 0;
......@@ -247,7 +291,7 @@ static inline unsigned int labcomm_read_packed32(struct labcomm_reader *r)
unsigned char tmp;
if (r->pos >= r->count) {
labcomm_reader_fill(r, r->action_context);
labcomm2014_reader_fill(r, r->action_context);
if (r->error != 0) {
goto out;
}
......@@ -263,16 +307,21 @@ out:
return result;
}
static inline char *labcomm_read_string(struct labcomm_reader *r)
static inline char *labcomm2014_read_string(struct labcomm2014_reader *r)
{
char *result = NULL;
int length, pos;
length = labcomm_read_packed32(r);
result = labcomm_memory_alloc(r->memory, 1, length + 1);
length = labcomm2014_read_packed32(r);
result = labcomm2014_memory_alloc(r->memory, 1, length + 1);
if (!result) {
labcomm20142014_on_error_fprintf(LABCOMM2014_ERROR_MEMORY, 4, "%d byte at %s:%d",
length+1, __FUNCTION__, __LINE__);
return NULL;
}
for (pos = 0 ; pos < length ; pos++) {
if (r->pos >= r->count) {
labcomm_reader_fill(r, r->action_context);
labcomm2014_reader_fill(r, r->action_context);
if (r->error < 0) {
goto out;
}
......@@ -288,16 +337,15 @@ out:
/*
* Semi private encoder declarations
*/
typedef int (*labcomm_encoder_function)(struct labcomm_writer *,
typedef int (*labcomm2014_encoder_function)(struct labcomm2014_writer *,
void *value);
struct labcomm_writer_action_context;
struct labcomm_writer_action {
int (*alloc)(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context,
char *labcomm_version);
int (*free)(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context);
struct labcomm2014_writer_action_context;
struct labcomm2014_writer_action {
int (*alloc)(struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context);
int (*free)(struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context);
/* 'start' is called right before a sample is to be sent. In the
case of a sample or typedef, 'value' == NULL.
......@@ -307,31 +355,31 @@ struct labcomm_writer_action {
'end' will not be called
< 0 Error
*/
int (*start)(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context,
int index, struct labcomm_signature *signature,
int (*start)(struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context,
int index, const struct labcomm2014_signature *signature,
void *value);
int (*end)(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context);
int (*flush)(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context);
int (*ioctl)(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context,
int index, struct labcomm_signature *signature,
int (*end)(struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context);
int (*flush)(struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context);
int (*ioctl)(struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context,
int index, const struct labcomm2014_signature *signature,
uint32_t ioctl_action, va_list args);
};
struct labcomm_writer_action_context {
struct labcomm_writer_action_context *next;
const struct labcomm_writer_action *action;
struct labcomm2014_writer_action_context {
struct labcomm2014_writer_action_context *next;
const struct labcomm2014_writer_action *action;
void *context;
};
struct labcomm_writer {
struct labcomm_writer_action_context *action_context;
struct labcomm_memory *memory;
/* The following fields are initialized by labcomm_encoder_new */
struct labcomm_encoder *encoder;
struct labcomm2014_writer {
struct labcomm2014_writer_action_context *action_context;
struct labcomm2014_memory *memory;
/* The following fields are initialized by labcomm2014_encoder_new */
struct labcomm2014_encoder *encoder;
unsigned char *data;
int data_size;
int count;
......@@ -339,48 +387,68 @@ struct labcomm_writer {
int error;
};
int labcomm_writer_alloc(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context,
char *labcomm_version);
int labcomm_writer_free(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context);
int labcomm_writer_start(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context,
int index, struct labcomm_signature *signature,
struct labcomm2014_encoder {
void *context;
struct labcomm2014_writer *writer;
struct labcomm2014_error_handler *error;
struct labcomm2014_memory *memory;
struct labcomm2014_scheduler *scheduler;
void (*free)(struct labcomm2014_encoder *e);
int (*type_register)(struct labcomm2014_encoder *e,
const struct labcomm2014_signature *signature);
int (*type_bind)(struct labcomm2014_encoder *e,
const struct labcomm2014_signature *signature,
char has_deps);
int (*sample_register)(struct labcomm2014_encoder *e,
const struct labcomm2014_signature *signature,
labcomm2014_encoder_function encode);
int (*ref_register)(struct labcomm2014_encoder *e,
const struct labcomm2014_signature *signature);
int (*encode)(struct labcomm2014_encoder *e,
const struct labcomm2014_signature *signature,
labcomm2014_encoder_function encode,
void *value);
int (*ioctl)(struct labcomm2014_encoder *e,
const struct labcomm2014_signature *signature,
uint32_t ioctl_action, va_list args);
int (*sample_ref_to_index)(struct labcomm2014_encoder *e,
const struct labcomm2014_sample_ref *s);
const struct labcomm2014_sample_ref *(*ref_get)(
struct labcomm2014_encoder *e,
const struct labcomm2014_signature *signature);
};
int labcomm2014_writer_alloc(struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context);
int labcomm2014_writer_free(struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context);
int labcomm2014_writer_start(struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context,
int index, const struct labcomm2014_signature *signature,
void *value);
int labcomm_writer_end(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context);
int labcomm_writer_flush(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context);
int labcomm_writer_ioctl(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context,
int index, struct labcomm_signature *signature,
int labcomm2014_writer_end(struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context);
int labcomm2014_writer_flush(struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context);
int labcomm2014_writer_ioctl(struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context,
int index, const struct labcomm2014_signature *signature,
uint32_t ioctl_action, va_list args);
int labcomm_internal_encoder_register(
struct labcomm_encoder *encoder,
struct labcomm_signature *signature,
labcomm_encoder_function encode);
int labcomm2014_internal_sizeof(const struct labcomm2014_signature *signature,
void *v);
int labcomm_internal_encode(
struct labcomm_encoder *encoder,
struct labcomm_signature *signature,
labcomm_encoder_function encode,
void *value);
int labcomm_internal_encoder_ioctl(struct labcomm_encoder *encoder,
struct labcomm_signature *signature,
uint32_t ioctl_action, va_list args);
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define LABCOMM_ENCODE(name, type) \
static inline int labcomm_write_##name(struct labcomm_writer *w, type data) { \
static inline int labcomm2014_write_##name(struct labcomm2014_writer *w, type data) { \
int i; \
for (i = sizeof(type) - 1 ; i >= 0 ; i--) { \
if (w->pos >= w->count) { /*buffer is full*/ \
int err; \
err = labcomm_writer_flush(w, w->action_context); \
err = labcomm2014_writer_flush(w, w->action_context); \
if (err != 0) { return err; } \
} \
w->data[w->pos] = ((unsigned char*)(&data))[i]; \
......@@ -392,12 +460,12 @@ int labcomm_internal_encoder_ioctl(struct labcomm_encoder *encoder,
#else
#define LABCOMM_ENCODE(name, type) \
static inline int labcomm_write_##name(struct labcomm_writer *w, type data) { \
static inline int labcomm2014_write_##name(struct labcomm2014_writer *w, type data) { \
int i; \
for (i = 0 ; i < sizeof(type) ; i++) { \
if (w->pos >= w->count) { \
int err; \
err = labcomm_writer_flush(w, w->action_context); \
err = labcomm2014_writer_flush(w, w->action_context); \
if (err != 0) { return err; } \
} \
w->data[w->pos] = ((unsigned char*)(&data))[i]; \
......@@ -416,7 +484,7 @@ LABCOMM_ENCODE(long, long long)
LABCOMM_ENCODE(float, float)
LABCOMM_ENCODE(double, double)
static inline int labcomm_write_packed32(struct labcomm_writer *w,
static inline int labcomm2014_write_packed32(struct labcomm2014_writer *w,
unsigned int data)
{
unsigned char tmp[5];
......@@ -428,7 +496,7 @@ static inline int labcomm_write_packed32(struct labcomm_writer *w,
for (i = i - 1 ; i >= 0 ; i--) {
if (w->pos >= w->count) {
int err;
err = labcomm_writer_flush(w, w->action_context);
err = labcomm2014_writer_flush(w, w->action_context);
if (err != 0) { return err; }
}
w->data[w->pos++] = tmp[i] | (i?0x80:0x00);
......@@ -436,17 +504,17 @@ static inline int labcomm_write_packed32(struct labcomm_writer *w,
return 0;
}
static inline int labcomm_write_string(struct labcomm_writer *w, char *s)
static inline int labcomm2014_write_string(struct labcomm2014_writer *w, char *s)
{
int length, i, err;
length = strlen((char*)s);
err = labcomm_write_packed32(w, length);
length = strlen(s);
err = labcomm2014_write_packed32(w, length);
if (err != 0) { return err; }
for (i = 0 ; i < length ; i++) {
if (w->pos >= w->count) {
int err;
err = labcomm_writer_flush(w, w->action_context);
err = labcomm2014_writer_flush(w, w->action_context);
if (err != 0) { return err; }
}
w->data[w->pos] = s[i];
......@@ -455,6 +523,26 @@ static inline int labcomm_write_string(struct labcomm_writer *w, char *s)
return 0;
}
/* Size of packed32 variable */
static inline int labcomm2014_size_packed32(unsigned int data)
{
int result = 0;
int i;
for (i = 0 ; i == 0 || data ; i++, data = (data >> 7)) {
result++;
}
return result;
}
static inline int labcomm2014_size_string(char *s)
{
int length = strlen(s);
return labcomm2014_size_packed32(length) + length;
}
/*
* Macros for handling arrays indexed by signature index
*/
......@@ -474,10 +562,10 @@ static inline int labcomm_write_string(struct labcomm_writer *w, char *s)
name.data = (kind *)name.data; /* typechecking no-op */
#define LABCOMM_SIGNATURE_ARRAY_FREE(memory, name, kind) \
if (name.data) { labcomm_memory_free(memory, 0, name.data); } \
if (name.data) { labcomm2014_memory_free(memory, 0, name.data); } \
name.data = (kind *)NULL; /* typechecking */
void *labcomm_signature_array_ref(struct labcomm_memory * memory,
void *labcomm2014_signature_array_ref(struct labcomm2014_memory * memory,
int *first, int *last, void **data,
int size, int index);
/*
......@@ -489,19 +577,26 @@ void *labcomm_signature_array_ref(struct labcomm_memory * memory,
*/
#define LABCOMM_SIGNATURE_ARRAY_REF(memory, name, kind, index) \
(name.data = (kind *)name.data, /* typechecking no-op */ \
(kind *)(labcomm_signature_array_ref(memory, \
(kind *)(labcomm2014_signature_array_ref(memory, \
&name.first, &name.last, \
(void **)&name.data, \
sizeof(kind), index)))
#define LABCOMM_SIGNATURE_ARRAY_GET(name, kind, index, nomatch) \
(name.data = (kind *)name.data, /* typechecking no-op */ \
(name.first <= index && \
index < name.last) ? name.data[index - name.first] : nomatch)
#define LABCOMM_SIGNATURE_ARRAY_FOREACH(name, kind, var) \
for (name.data = (kind *)name.data, /* typechecking no-op */ \
var = name.first ; var < name.last ; var++)
/* Give signature a free local index, this may not be used concurrently */
void labcomm_set_local_index(struct labcomm_signature *signature);
void labcomm2014_set_local_index(struct labcomm2014_signature *signature);
/* Get the local index for a signature */
int labcomm_get_local_index(struct labcomm_signature *s);
int labcomm2014_get_local_index(const struct labcomm2014_signature *s);
int labcomm2014_get_local_type_index(const struct labcomm2014_signature *s);
#endif
/*
labcomm_pthread_scheduler.c -- labcomm pthread based task coordination
labcomm2014_pthread_scheduler.c -- labcomm2014 pthread based task coordination
Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
......@@ -18,22 +18,23 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define _POSIX_C_SOURCE (200112L)
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>
#include "labcomm.h"
#include "labcomm_scheduler.h"
#include "labcomm_scheduler_private.h"
#include "labcomm_pthread_scheduler.h"
#include "labcomm2014.h"
#include "labcomm2014_scheduler.h"
#include "labcomm2014_scheduler_private.h"
#include "labcomm2014_pthread_scheduler.h"
#ifdef LABCOMM_COMPAT
#include LABCOMM_COMPAT
#endif
struct pthread_time {
struct labcomm_time time;
struct labcomm_memory *memory;
struct labcomm2014_time time;
struct labcomm2014_memory *memory;
struct timespec abstime;
};
......@@ -46,8 +47,8 @@ struct pthread_deferred {
};
struct pthread_scheduler {
struct labcomm_scheduler scheduler;
struct labcomm_memory *memory;
struct labcomm2014_scheduler scheduler;
struct labcomm2014_memory *memory;
int wakeup;
pthread_mutex_t writer_mutex;
pthread_mutex_t data_mutex;
......@@ -57,14 +58,14 @@ struct pthread_scheduler {
struct pthread_deferred deferred_with_delay;
};
static struct labcomm_time_action time_action;
static struct labcomm2014_time_action time_action;
static int queue_empty(struct pthread_deferred *queue)
{
return queue->next == queue;
}
static void timespec_add_usec(struct timespec *t, useconds_t usec)
static void timespec_add_usec(struct timespec *t, uint32_t usec)
{
time_t sec = usec / 1000000;
long nsec = (usec % 1000000) * 1000;
......@@ -99,11 +100,11 @@ static int timespec_compare(struct timespec *t1, struct timespec *t2)
}
}
static struct labcomm_time *time_new(struct labcomm_memory *memory)
static struct labcomm2014_time *time_new(struct labcomm2014_memory *memory)
{
struct pthread_time *time;
time = labcomm_memory_alloc(memory, 0, sizeof(*time));
time = labcomm2014_memory_alloc(memory, 0, sizeof(*time));
if (time == NULL) {
return NULL;
} else {
......@@ -115,17 +116,17 @@ static struct labcomm_time *time_new(struct labcomm_memory *memory)
}
}
static int time_free(struct labcomm_time *t)
static int time_free(struct labcomm2014_time *t)
{
struct pthread_time *time = t->context;
struct labcomm_memory *memory = time->memory;
struct labcomm2014_memory *memory = time->memory;
labcomm_memory_free(memory, 0, time);
labcomm2014_memory_free(memory, 0, time);
return 0;
}
static int time_add_usec(struct labcomm_time *t, useconds_t usec)
static int time_add_usec(struct labcomm2014_time *t, uint32_t usec)
{
struct pthread_time *time = t->context;
......@@ -134,7 +135,7 @@ static int time_add_usec(struct labcomm_time *t, useconds_t usec)
return 0;
}
static struct labcomm_time_action time_action = {
static struct labcomm2014_time_action time_action = {
.free = time_free,
.add_usec = time_add_usec
};
......@@ -145,10 +146,10 @@ static int run_action(struct pthread_scheduler *scheduler,
/* Called with data_lock held */
element->prev->next = element->next;
element->next->prev = element->prev;
labcomm_scheduler_data_unlock(&scheduler->scheduler);
labcomm2014_scheduler_data_unlock(&scheduler->scheduler);
element->action(element->context);
labcomm_memory_free(scheduler->memory, 1, element);
labcomm_scheduler_data_lock(&scheduler->scheduler);
labcomm2014_memory_free(scheduler->memory, 1, element);
labcomm2014_scheduler_data_lock(&scheduler->scheduler);
return 0;
}
......@@ -174,44 +175,44 @@ out:
return 0;
}
static int scheduler_free(struct labcomm_scheduler *s)
static int scheduler_free(struct labcomm2014_scheduler *s)
{
struct pthread_scheduler *scheduler = s->context;
struct labcomm_memory *memory = scheduler->memory;
struct labcomm2014_memory *memory = scheduler->memory;
labcomm_memory_free(memory, 0, scheduler);
labcomm2014_memory_free(memory, 0, scheduler);
return 0;
}
static int scheduler_writer_lock(struct labcomm_scheduler *s)
static int scheduler_writer_lock(struct labcomm2014_scheduler *s)
{
struct pthread_scheduler *scheduler = s->context;
labcomm_scheduler_data_lock(&scheduler->scheduler);
labcomm2014_scheduler_data_lock(&scheduler->scheduler);
run_deferred(scheduler); /* Run deferred tasks before taking lock */
labcomm_scheduler_data_unlock(&scheduler->scheduler);
labcomm2014_scheduler_data_unlock(&scheduler->scheduler);
if (pthread_mutex_lock(&scheduler->writer_mutex) != 0) {
return -errno;
}
return 0;
}
static int scheduler_writer_unlock(struct labcomm_scheduler *s)
static int scheduler_writer_unlock(struct labcomm2014_scheduler *s)
{
struct pthread_scheduler *scheduler = s->context;
if (pthread_mutex_unlock(&scheduler->writer_mutex) != 0) {
return -errno;
}
labcomm_scheduler_data_lock(&scheduler->scheduler);
labcomm2014_scheduler_data_lock(&scheduler->scheduler);
run_deferred(scheduler); /* Run deferred tasks after releasing lock */
labcomm_scheduler_data_unlock(&scheduler->scheduler);
labcomm2014_scheduler_data_unlock(&scheduler->scheduler);
return 0;
}
static int scheduler_data_lock(struct labcomm_scheduler *s)
static int scheduler_data_lock(struct labcomm2014_scheduler *s)
{
struct pthread_scheduler *scheduler = s->context;
......@@ -222,7 +223,7 @@ static int scheduler_data_lock(struct labcomm_scheduler *s)
return 0;
}
static int scheduler_data_unlock(struct labcomm_scheduler *s)
static int scheduler_data_unlock(struct labcomm2014_scheduler *s)
{
struct pthread_scheduler *scheduler = s->context;
......@@ -234,20 +235,20 @@ static int scheduler_data_unlock(struct labcomm_scheduler *s)
return 0;
}
static struct labcomm_time *scheduler_now(struct labcomm_scheduler *s)
static struct labcomm2014_time *scheduler_now(struct labcomm2014_scheduler *s)
{
struct pthread_scheduler *scheduler = s->context;
return time_new(scheduler->memory);
}
static int scheduler_sleep(struct labcomm_scheduler *s,
struct labcomm_time *t)
static int scheduler_sleep(struct labcomm2014_scheduler *s,
struct labcomm2014_time *t)
{
struct pthread_scheduler *scheduler = s->context;
struct pthread_time *time = t?t->context:NULL;
labcomm_scheduler_data_lock(&scheduler->scheduler);
labcomm2014_scheduler_data_lock(&scheduler->scheduler);
while (1) {
struct timespec *wakeup, now;
......@@ -280,24 +281,24 @@ static int scheduler_sleep(struct labcomm_scheduler *s,
&scheduler->data_mutex);
}
}
labcomm_scheduler_data_unlock(&scheduler->scheduler);
labcomm2014_scheduler_data_unlock(&scheduler->scheduler);
return 0;
}
static int scheduler_wakeup(struct labcomm_scheduler *s)
static int scheduler_wakeup(struct labcomm2014_scheduler *s)
{
struct pthread_scheduler *scheduler = s->context;
labcomm_scheduler_data_lock(&scheduler->scheduler);
labcomm2014_scheduler_data_lock(&scheduler->scheduler);
scheduler->wakeup = 1;
pthread_cond_signal(&scheduler->data_cond);
labcomm_scheduler_data_unlock(&scheduler->scheduler);
labcomm2014_scheduler_data_unlock(&scheduler->scheduler);
return 0;
}
static int scheduler_enqueue(struct labcomm_scheduler *s,
useconds_t delay,
static int scheduler_enqueue(struct labcomm2014_scheduler *s,
uint32_t delay,
void (*deferred)(void *context),
void *context)
{
......@@ -305,7 +306,7 @@ static int scheduler_enqueue(struct labcomm_scheduler *s,
int result = 0;
struct pthread_deferred *element, *insert_before;
element = labcomm_memory_alloc(scheduler->memory, 1, sizeof(*element));
element = labcomm2014_memory_alloc(scheduler->memory, 1, sizeof(*element));
if (element == NULL) {
result = -ENOMEM;
goto out;
......@@ -313,7 +314,7 @@ static int scheduler_enqueue(struct labcomm_scheduler *s,
element->action = deferred;
element->context = context;
labcomm_scheduler_data_lock(&scheduler->scheduler);
labcomm2014_scheduler_data_lock(&scheduler->scheduler);
if (delay == 0) {
insert_before = &scheduler->deferred;
} else {
......@@ -329,13 +330,13 @@ static int scheduler_enqueue(struct labcomm_scheduler *s,
element->prev->next = element;
element->next->prev = element;
pthread_cond_signal(&scheduler->data_cond);
labcomm_scheduler_data_unlock(&scheduler->scheduler);
labcomm2014_scheduler_data_unlock(&scheduler->scheduler);
out:
return result;
}
static const struct labcomm_scheduler_action scheduler_action = {
static const struct labcomm2014_scheduler_action scheduler_action = {
.free = scheduler_free,
.writer_lock = scheduler_writer_lock,
.writer_unlock = scheduler_writer_unlock,
......@@ -347,13 +348,13 @@ static const struct labcomm_scheduler_action scheduler_action = {
.enqueue = scheduler_enqueue
};
struct labcomm_scheduler *labcomm_pthread_scheduler_new(
struct labcomm_memory *memory)
struct labcomm2014_scheduler *labcomm2014_pthread_scheduler_new(
struct labcomm2014_memory *memory)
{
struct labcomm_scheduler *result = NULL;
struct labcomm2014_scheduler *result = NULL;
struct pthread_scheduler *scheduler;
scheduler = labcomm_memory_alloc(memory, 0, sizeof(*scheduler));
scheduler = labcomm2014_memory_alloc(memory, 0, sizeof(*scheduler));
if (scheduler == NULL) {
goto out;
} else {
......@@ -385,7 +386,7 @@ destroy_data_mutex:
destroy_writer_mutex:
pthread_mutex_destroy(&scheduler->writer_mutex);
free_scheduler:
labcomm_memory_free(memory, 0, scheduler);
labcomm2014_memory_free(memory, 0, scheduler);
out:
return result;
......
/*
labcomm_pthread_scheduler.h -- labcomm pthread based task coordination
labcomm2014_pthread_scheduler.h -- labcomm2014 pthread based task coordination
Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
......@@ -19,13 +19,13 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _LABCOMM_PTHREAD_SCHEDULER_H_
#define _LABCOMM_PTHREAD_SCHEDULER_H_
#ifndef __LABCOMM2014_PTHREAD_SCHEDULER_H__
#define __LABCOMM2014_PTHREAD_SCHEDULER_H__
#include "labcomm.h"
#include "labcomm2014.h"
struct labcomm_scheduler *labcomm_pthread_scheduler_new(
struct labcomm_memory *memory);
struct labcomm2014_scheduler *labcomm2014_pthread_scheduler_new(
struct labcomm2014_memory *memory);
#endif
/*
labcomm_error.c -- labcomm error handling
labcomm2014_renaming.c -- functions intended for renaming
encoders and decoders
Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
Copyright 2015 Anders Blomdell <anders.blomdell@control.lth.se>
This file is part of LabComm.
......@@ -19,14 +20,28 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include "labcomm_error.h"
void labcomm_error_fatal_global(enum labcomm_error error,
char *format,
...)
#include "labcomm2014_renaming.h"
#include <string.h>
char *labcomm2014_renaming_prefix(struct labcomm2014_memory *m,
char *name, void *context)
{
char *result, *prefix = context;
int length;
length = strlen(name) + strlen(prefix) + 1;
result = labcomm2014_memory_alloc(m, 0, length);
if (result != NULL) {
strcpy(result, prefix);
strcat(result, name);
}
return result;
}
char *labcomm2014_renaming_suffix(struct labcomm2014_memory *m,
char *name, void *context)
{
fprintf(stderr, "Fatal error %d\n", error);
exit(1);
return labcomm2014_renaming_prefix(m, context, name);
}
/*
labcomm2014_renaming.h -- functions intended for renaming
encoders and decoders
Copyright 2015 Anders Blomdell <anders.blomdell@control.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 __LABCOMM2014_RENAMING_H__
#define __LABCOMM2014_RENAMING_H__
#include "labcomm2014.h"
char *labcomm2014_renaming_prefix(struct labcomm2014_memory *m,
char *name, void *context);
char *labcomm2014_renaming_suffix(struct labcomm2014_memory *m,
char *name, void *context);
struct labcomm2014_renaming_registry *labcomm2014_renaming_registry_new(
struct labcomm2014_error_handler *error,
struct labcomm2014_memory *memory,
struct labcomm2014_scheduler *scheduler);
void labcomm2014_renaming_registry_free(
struct labcomm2014_renaming_registry *r);
#endif
/*
labcomm2014_renaming_decoder.c -- a stacked decoder that renames samples
Copyright 2015 Anders Blomdell <anders.blomdell@control.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 "labcomm2014_renaming_decoder.h"
#include "labcomm2014.h"
#include "labcomm2014_private.h"
#include "labcomm2014_renaming_private.h"
struct decoder {
struct labcomm2014_decoder decoder;
struct labcomm2014_decoder *next;
struct labcomm2014_renaming_registry *registry;
char *(*rename_func)(struct labcomm2014_memory *m, char *name, void *context);
void *context;
LABCOMM_SIGNATURE_ARRAY_DEF(renamed,
struct labcomm2014_renaming_rename *);
};
static struct labcomm2014_renaming_rename *get_renamed(
struct labcomm2014_decoder *d,
const struct labcomm2014_signature *signature)
{
struct labcomm2014_renaming_rename *result;
struct decoder *id = d->context;
int index;
index = labcomm2014_get_local_index(signature);
labcomm2014_scheduler_data_lock(d->scheduler);
result = LABCOMM_SIGNATURE_ARRAY_GET(id->renamed,
struct labcomm2014_renaming_rename *,
index, NULL);
labcomm2014_scheduler_data_unlock(d->scheduler);
return result;
}
static struct labcomm2014_renaming_rename *set_renamed(
struct labcomm2014_decoder *d,
const struct labcomm2014_signature *signature)
{
struct labcomm2014_renaming_rename *result = NULL;
result = get_renamed(d, signature);
if (result == NULL) {
struct decoder *id = d->context;
struct labcomm2014_renaming_rename **renamed;
struct labcomm2014_renaming_rename *entry = NULL;
int index;
index = labcomm2014_get_local_index(signature);
entry = labcomm2014_renaming_rename_new(id->registry, signature,
id->rename_func, id->context);
if (entry == NULL) { goto out; }
labcomm2014_scheduler_data_lock(d->scheduler);
renamed = LABCOMM_SIGNATURE_ARRAY_REF(d->memory, id->renamed,
struct labcomm2014_renaming_rename *,
index);
if (renamed == NULL) { goto free_unlock; }
if (*renamed != NULL) { result = *renamed; goto free_unlock; }
*renamed = entry;
result = entry;
goto unlock;
free_unlock:
labcomm2014_renaming_rename_free(id->registry, entry);
unlock:
labcomm2014_scheduler_data_unlock(d->scheduler);
out:
;
}
return result;
}
static int do_sample_register(struct labcomm2014_decoder *d,
const struct labcomm2014_signature *signature,
labcomm2014_decoder_function decoder,
labcomm2014_handler_function handler,
void *context)
{
const struct labcomm2014_renaming_rename *renamed;
struct decoder *id = d->context;
renamed = set_renamed(d, signature);
return id->next->sample_register(
id->next, labcomm2014_renaming_rename_signature(renamed),
decoder, handler, context);
}
static int do_ref_register(struct labcomm2014_decoder *d,
const struct labcomm2014_signature *signature)
{
const struct labcomm2014_renaming_rename *renamed;
struct decoder *id = d->context;
renamed = set_renamed(d, signature);
return id->next->ref_register(
id->next, labcomm2014_renaming_rename_signature(renamed));
}
static int do_ioctl(struct labcomm2014_decoder *d,
const struct labcomm2014_signature *signature,
uint32_t ioctl_action, va_list args)
{
const struct labcomm2014_renaming_rename *renamed;
struct decoder *id = d->context;
renamed = get_renamed(d, signature);
return id->next->ioctl(
id->next, labcomm2014_renaming_rename_signature(renamed),
ioctl_action, args);
}
static int do_decode_one(struct labcomm2014_decoder *d)
{
struct decoder *id = d->context;
return id->next->decode_one(id->next);
}
static const struct labcomm2014_sample_ref *do_index_to_sample_ref(
struct labcomm2014_decoder *d, int index)
{
struct decoder *id = d->context;
return id->next->index_to_sample_ref(id->next, index);
}
static const struct labcomm2014_sample_ref *do_ref_get(
struct labcomm2014_decoder *d,
const struct labcomm2014_signature *signature)
{
const struct labcomm2014_renaming_rename *renamed;
struct decoder *id = d->context;
renamed = get_renamed(d, signature);
if (renamed == NULL) {
return id->next->ref_get(id->next, signature);
} else {
return id->next->ref_get(id->next,
labcomm2014_renaming_rename_signature(renamed));
}
}
static void do_free(struct labcomm2014_decoder *d)
{
struct decoder *id = d->context;
int i;
LABCOMM_SIGNATURE_ARRAY_FOREACH(id->renamed,
struct labcomm2014_renaming_rename *,
i) {
struct labcomm2014_renaming_rename *r;
r = LABCOMM_SIGNATURE_ARRAY_GET(id->renamed,
struct labcomm2014_renaming_rename *,
i, NULL);
if (r) {
labcomm2014_renaming_rename_free(id->registry, r);
}
}
LABCOMM_SIGNATURE_ARRAY_FREE(d->memory, id->renamed,
struct labcomm2014_renaming_rename *);
labcomm2014_memory_free(d->memory, 0, id);
}
struct labcomm2014_decoder *labcomm2014_renaming_decoder_new(
struct labcomm2014_decoder *d,
struct labcomm2014_renaming_registry *registry,
char *(*rename)(struct labcomm2014_memory *m, char *name, void *context),
void *context)
{
struct decoder *result;
result = labcomm2014_memory_alloc(d->memory, 0, sizeof(*result));
if (!result) {
return NULL;
} else {
result->decoder.context = result;
result->decoder.reader = d->reader;
result->decoder.error = d->error;
result->decoder.memory = d->memory;
result->decoder.scheduler = d->scheduler;
result->decoder.free = do_free;
result->decoder.decode_one = do_decode_one;
result->decoder.sample_register = do_sample_register;
result->decoder.ref_register = do_ref_register;
result->decoder.ioctl = do_ioctl;
result->decoder.index_to_sample_ref = do_index_to_sample_ref;
result->decoder.ref_get = do_ref_get;
result->next = d;
result->registry = registry;
result->rename_func = rename;
result->context = context;
LABCOMM_SIGNATURE_ARRAY_INIT(result->renamed,
struct labcomm2014_renaming_rename *);
return &(result->decoder);
}
}
/*
labcomm2014_renaming_decoder.h -- a stacked decoder that renames samples
Copyright 2015 Anders Blomdell <anders.blomdell@control.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 __LABCOMM2014_RENAMING_DECODER_H__
#define __LABCOMM2014_RENAMING_DECODER_H__
#include "labcomm2014.h"
#include "labcomm2014_renaming.h"
struct labcomm2014_decoder *labcomm2014_renaming_decoder_new(
struct labcomm2014_decoder *d,
struct labcomm2014_renaming_registry *r,
char *(*rename)(struct labcomm2014_memory *m, char *name, void *context),
void *context);
#endif
/*
labcomm2014_renaming_encoder.c -- a stacked encoder that renames samples
Copyright 2015 Anders Blomdell <anders.blomdell@control.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 "labcomm2014_renaming_encoder.h"
#include "labcomm2014.h"
#include "labcomm2014_private.h"
#include "labcomm2014_renaming_private.h"
struct encoder {
struct labcomm2014_encoder encoder;
struct labcomm2014_encoder *next;
struct labcomm2014_renaming_registry *registry;
char *(*rename_func)(struct labcomm2014_memory *m, char *name, void *context);
void *context;
LABCOMM_SIGNATURE_ARRAY_DEF(renamed,
struct labcomm2014_renaming_rename *);
};
static struct labcomm2014_renaming_rename *get_renamed(
struct labcomm2014_encoder *e,
const struct labcomm2014_signature *signature)
{
struct labcomm2014_renaming_rename *result;
struct encoder *ie = e->context;
int index;
index = labcomm2014_get_local_index(signature);
labcomm2014_scheduler_writer_lock(e->scheduler);
result = LABCOMM_SIGNATURE_ARRAY_GET(ie->renamed,
struct labcomm2014_renaming_rename *,
index, NULL);
labcomm2014_scheduler_writer_unlock(e->scheduler);
return result;
}
static struct labcomm2014_renaming_rename *set_renamed(
struct labcomm2014_encoder *e,
const struct labcomm2014_signature *signature)
{
struct labcomm2014_renaming_rename *result = NULL;
result = get_renamed(e, signature);
if (result == NULL) {
struct encoder *ie = e->context;
struct labcomm2014_renaming_rename **renamed;
struct labcomm2014_renaming_rename *entry = NULL;
int index;
index = labcomm2014_get_local_index(signature);
entry = labcomm2014_renaming_rename_new(ie->registry, signature,
ie->rename_func, ie->context);
if (entry == NULL) { goto out; }
labcomm2014_scheduler_writer_lock(e->scheduler);
renamed = LABCOMM_SIGNATURE_ARRAY_REF(e->memory, ie->renamed,
struct labcomm2014_renaming_rename *,
index);
if (renamed == NULL) { goto free_unlock; }
if (*renamed != NULL) { result = *renamed; goto free_unlock; }
*renamed = entry;
result = entry;
goto unlock;
free_unlock:
labcomm2014_renaming_rename_free(ie->registry, entry);
unlock:
labcomm2014_scheduler_writer_unlock(e->scheduler);
out:
;
}
return result;
}
static int do_type_register(struct labcomm2014_encoder *e,
const struct labcomm2014_signature *signature)
{
const struct labcomm2014_renaming_rename *renamed;
struct encoder *ie = e->context;
renamed = get_renamed(e, signature);
if (renamed) {
/* Register base type and renamed type */
ie->next->type_register(ie->next, signature);
return ie->next->type_register(
ie->next, labcomm2014_renaming_rename_signature(renamed));
} else {
return ie->next->type_register(ie->next, signature);
}
}
static int do_type_bind(struct labcomm2014_encoder *e,
const struct labcomm2014_signature *signature,
char has_deps)
{
const struct labcomm2014_renaming_rename *renamed;
struct encoder *ie = e->context;
renamed = get_renamed(e, signature);
if (renamed) {
return ie->next->type_bind(
ie->next, labcomm2014_renaming_rename_signature(renamed), 1);
} else {
return ie->next->type_bind(ie->next, signature, has_deps);
}
}
static int do_sample_register(struct labcomm2014_encoder *e,
const struct labcomm2014_signature *signature,
labcomm2014_encoder_function encode)
{
const struct labcomm2014_renaming_rename *renamed;
struct encoder *ie = e->context;
renamed = set_renamed(e, signature);
return ie->next->sample_register(
ie->next, labcomm2014_renaming_rename_signature(renamed), encode);
}
static int do_ref_register(struct labcomm2014_encoder *e,
const struct labcomm2014_signature *signature)
{
const struct labcomm2014_renaming_rename *renamed;
struct encoder *ie = e->context;
renamed = set_renamed(e, signature);
return ie->next->ref_register(ie->next,
labcomm2014_renaming_rename_signature(renamed));
}
static int do_encode(struct labcomm2014_encoder *e,
const struct labcomm2014_signature *signature,
labcomm2014_encoder_function encode,
void *value)
{
const struct labcomm2014_renaming_rename *renamed;
struct encoder *ie = e->context;
renamed = get_renamed(e, signature);
if (renamed == NULL) {
return -EINVAL;
} else {
return ie->next->encode(ie->next,
labcomm2014_renaming_rename_signature(renamed),
encode, value);
}
}
static int do_ioctl(struct labcomm2014_encoder *e,
const struct labcomm2014_signature *signature,
uint32_t ioctl_action, va_list args)
{
const struct labcomm2014_renaming_rename *renamed;
struct encoder *ie = e->context;
renamed = get_renamed(e, signature);
if (renamed != NULL) {
signature = labcomm2014_renaming_rename_signature(renamed);
}
return ie->next->ioctl(ie->next, signature, ioctl_action, args);
}
static int do_sample_ref_to_index(
struct labcomm2014_encoder *e,
const struct labcomm2014_sample_ref *sample_ref)
{
struct encoder *ie = e->context;
return ie->next->sample_ref_to_index(ie->next,sample_ref);
}
static const struct labcomm2014_sample_ref *do_ref_get(
struct labcomm2014_encoder *e,
const struct labcomm2014_signature *signature)
{
const struct labcomm2014_renaming_rename *renamed;
struct encoder *ie = e->context;
renamed = get_renamed(e, signature);
if (renamed == NULL) {
return ie->next->ref_get(ie->next, signature);
} else {
return ie->next->ref_get(
ie->next, labcomm2014_renaming_rename_signature(renamed));
}
}
static void do_free(struct labcomm2014_encoder *e)
{
struct encoder *ie = e->context;
int i;
LABCOMM_SIGNATURE_ARRAY_FOREACH(ie->renamed,
struct labcomm2014_renaming_rename *, i) {
struct labcomm2014_renaming_rename *r;
r = LABCOMM_SIGNATURE_ARRAY_GET(ie->renamed,
struct labcomm2014_renaming_rename *, i,
NULL);
if (r) {
labcomm2014_renaming_rename_free(ie->registry, r);
}
}
LABCOMM_SIGNATURE_ARRAY_FREE(e->memory, ie->renamed, struct labcomm2014_renaming_rename *);
labcomm2014_memory_free(e->memory, 0, ie);
}
struct labcomm2014_encoder *labcomm2014_renaming_encoder_new(
struct labcomm2014_encoder *e,
struct labcomm2014_renaming_registry *registry,
char *(*rename)(struct labcomm2014_memory *m, char *name, void *context),
void *context)
{
struct encoder *result;
result = labcomm2014_memory_alloc(e->memory, 0, sizeof(*result));
if (!result) {
return NULL;
} else {
result->encoder.context = result;
result->encoder.writer = e->writer;
result->encoder.error = e->error;
result->encoder.memory = e->memory;
result->encoder.scheduler = e->scheduler;
result->encoder.free = do_free;
result->encoder.type_register = do_type_register;
result->encoder.type_bind = do_type_bind;
result->encoder.sample_register = do_sample_register;
result->encoder.ref_register = do_ref_register;
result->encoder.encode = do_encode;
result->encoder.ioctl = do_ioctl;
result->encoder.sample_ref_to_index = do_sample_ref_to_index;
result->encoder.ref_get = do_ref_get;
result->next = e;
result->registry = registry;
result->rename_func = rename;
result->context = context;
LABCOMM_SIGNATURE_ARRAY_INIT(result->renamed,
struct labcomm2014_renaming_rename *);
return &(result->encoder);
}
}
/*
labcomm2014_renaming_encoder.h -- a stacked encoder that renames samples
Copyright 2015 Anders Blomdell <anders.blomdell@control.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 __LABCOMM2014_RENAMING_ENCODER_H__
#define __LABCOMM2014_RENAMING_ENCODER_H__
#include "labcomm2014.h"
#include "labcomm2014_renaming.h"
struct labcomm2014_encoder *labcomm2014_renaming_encoder_new(
struct labcomm2014_encoder *e,
struct labcomm2014_renaming_registry *r,
char *(*rename)(struct labcomm2014_memory *m, char *name, void *context),
void *context);
#endif