Commit 2d23900b authored by Anders Blomdell's avatar Anders Blomdell
Browse files

Some refactorings and initial try at O(1) lookup of

encoder indices (linker magic provided). 
parent 5d8c7d37
......@@ -803,8 +803,8 @@ aspect C_Signature {
}
}
env.println("};");
env.println("labcomm_signature_t labcomm_signature_" +
env.prefix + getName() + " = {");
env.println("LABCOMM_DECLARE_SIGNATURE(labcomm_signature_" +
env.prefix + getName() + ") = {");
env.indent();
env.println("LABCOMM_SAMPLE, \"" + getName() + "\",");
env.println("(int (*)(labcomm_signature_t *, void *))labcomm_sizeof_" +
......
......@@ -2,15 +2,15 @@
# Use LLVM clang if it's found.
CC = $(shell hash clang 2>/dev/null && echo clang || echo gcc)
CFLAGS = -g -Wall -Werror -O3 -I. -Itest
CFLAGS = -g -Wall -Werror -O3 -I. -Itest -DLABCOMM_ENCODER_LINEAR_SEARCH
LDFLAGS = -L.
LDLIBS_TEST = -lcunit -llabcomm
LDLIBS_TEST = -Tlabcomm.linkscript -lcunit -llabcomm
OBJS= labcomm.o labcomm_dynamic_buffer_writer.o labcomm_fd_reader_writer.o labcomm_mem_reader.o labcomm_mem_writer.o
OBJS= labcomm.o labcomm_dynamic_buffer_writer.o labcomm_fd_reader.o labcomm_fd_writer.o labcomm_mem_reader.o labcomm_mem_writer.o
LABCOMMC_PATH=../../compiler
LABCOMMC_JAR=$(LABCOMMC_PATH)/labComm.jar
TESTS=test_labcomm_private test_labcomm test_labcomm_errors
TESTS=test_labcomm_basic_type_encoding test_labcomm test_labcomm_errors
TEST_DIR=test
TESTDATA_DIR=$(TEST_DIR)/testdata
TEST_GEN_DIR=$(TESTDATA_DIR)/gen
......@@ -42,9 +42,9 @@ labcomm.o : labcomm.c labcomm.h labcomm_private.h
labcomm_fd_reader_writer.o : labcomm_fd_reader_writer.c labcomm_fd_reader_writer.h labcomm.h labcomm_private.h
$(TEST_DIR)/labcomm_mem_reader.o: labcomm_fd_reader_writer.c labcomm_fd_reader_writer.h
#$(TEST_DIR)/labcomm_mem_reader.o: labcomm_fd_reader_writer.c labcomm_fd_reader_writer.h
$(TEST_DIR)/labcomm_mem_writer.o: labcomm_mem_writer.c labcomm_mem_writer.h cppmacros.h
#$(TEST_DIR)/labcomm_mem_writer.o: labcomm_mem_writer.c labcomm_mem_writer.h cppmacros.h
ethaddr.o: ethaddr.c
......
......@@ -7,11 +7,15 @@
#include <errno.h>
#include <string.h>
#include <stdarg.h>
#include "labcomm.h"
#include "labcomm_private.h"
#include "labcomm_ioctl.h"
#include "labcomm_dynamic_buffer_writer.h"
#define LABCOMM_VERSION "LabComm2013"
typedef struct labcomm_sample_entry {
struct labcomm_sample_entry *next;
int index;
......@@ -146,6 +150,8 @@ static labcomm_sample_entry_t *get_sample_by_index(
return p;
}
#ifdef LABCOMM_ENCODER_LINEAR_SEARCH
static int get_encoder_index(
labcomm_encoder_t *e,
labcomm_signature_t *s)
......@@ -163,6 +169,25 @@ static int get_encoder_index(
return result;
}
#else
static int get_encoder_index(
labcomm_encoder_t *e,
labcomm_signature_t *s)
{
int result = 0;
extern labcomm_signature_t labcomm_first_signature;
extern labcomm_signature_t labcomm_last_signature;
if (&labcomm_first_signature <= s && s <= &labcomm_last_signature) {
//fprintf(stderr, "%d\n", (int)(s - &labcomm_start));
result = s - &labcomm_first_signature + LABCOMM_USER;
}
return result;
}
#endif
void labcomm_encoder_start(struct labcomm_encoder *e,
labcomm_signature_t *s)
{
......@@ -301,12 +326,6 @@ void labcomm_internal_encode(
}
}
void labcomm_internal_encoder_user_action(labcomm_encoder_t *e,
int action)
{
e->writer.write(&e->writer, action);
}
void labcomm_encoder_free(labcomm_encoder_t* e)
{
e->writer.write(&e->writer, labcomm_writer_free);
......@@ -501,7 +520,7 @@ static int do_decode_one(labcomm_decoder_t *d)
}
labcomm_decoder_t *labcomm_decoder_new(
int (*reader)(labcomm_reader_t *, labcomm_reader_action_t),
int (*reader)(labcomm_reader_t *, labcomm_reader_action_t, ...),
void *reader_context)
{
labcomm_decoder_t *result = malloc(sizeof(labcomm_decoder_t));
......@@ -522,7 +541,7 @@ labcomm_decoder_t *labcomm_decoder_new(
result->do_decode_one = do_decode_one;
result->on_error = on_error_fprintf;
result->on_new_datatype = on_new_datatype;
result->reader.read(&result->reader, labcomm_reader_alloc);
result->reader.read(&result->reader, labcomm_reader_alloc, LABCOMM_VERSION);
}
return result;
}
......
#ifndef _LABCOMM_H_
#define _LABCOMM_H_
#ifdef ARM_CORTEXM3_CODESOURCERY
#include <machine/endian.h>
#else
#include <endian.h>
#endif
// Some projects can not use stdio.h.
#ifndef LABCOMM_NO_STDIO
#include <stdio.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
/* Forward declaration */
struct labcomm_encoder;
......@@ -94,7 +82,8 @@ void labcomm_decoder_register_new_datatype_handler(struct labcomm_decoder *d,
*/
typedef enum {
labcomm_reader_alloc,
labcomm_reader_alloc, /* (..., char *labcomm_version)
Allocate all neccessary data */
labcomm_reader_free,
labcomm_reader_start,
labcomm_reader_continue,
......@@ -108,13 +97,13 @@ typedef struct labcomm_reader {
int data_size;
int count;
int pos;
int (*read)(struct labcomm_reader *, labcomm_reader_action_t);
int (*read)(struct labcomm_reader *, labcomm_reader_action_t, ...);
int (*ioctl)(struct labcomm_reader *, int, va_list);
labcomm_error_handler_callback on_error;
} labcomm_reader_t;
struct labcomm_decoder *labcomm_decoder_new(
int (*reader)(labcomm_reader_t *, labcomm_reader_action_t),
int (*reader)(labcomm_reader_t *, labcomm_reader_action_t, ...),
void *reader_context);
int labcomm_decoder_decode_one(
struct labcomm_decoder *decoder);
......@@ -128,7 +117,8 @@ void labcomm_decoder_free(
*/
typedef enum {
labcomm_writer_alloc, /* Allocate all neccessary data */
labcomm_writer_alloc, /* (..., char *labcomm_version)
Allocate all neccessary data */
labcomm_writer_free, /* Free all allocated data */
labcomm_writer_start, /* Start writing an ordinary sample */
labcomm_writer_continue, /* Buffer full during ordinary sample */
......
SECTIONS {
labcomm : {
labcomm_first_signature = ABSOLUTE(.) ;
*(labcomm)
labcomm_last_signature = ABSOLUTE(.) ;
}
}
INSERT AFTER .data;
#include <errno.h>
#include <stdlib.h>
#include <stdarg.h>
#include "labcomm_ioctl.h"
#include "labcomm_dynamic_buffer_writer.h"
......
#include <errno.h>
#include <unistd.h>
#include "labcomm_fd_reader_writer.h"
#include <stdlib.h>
#include <string.h>
#include "labcomm_fd_reader.h"
#define BUFFER_SIZE 2048
int labcomm_fd_reader(
labcomm_reader_t *r,
labcomm_reader_action_t action)
labcomm_reader_action_t action,
...)
{
int result = -EINVAL;
int *fd = r->context;
switch (action) {
case labcomm_reader_alloc: {
va_list ap;
va_start(ap, action);
char *version = va_arg(ap, char *);
char *tmp = strdup(version);
read(*fd, tmp, strlen(version));
free(tmp);
r->data = malloc(BUFFER_SIZE);
if (r->data) {
r->data_size = BUFFER_SIZE;
......@@ -23,6 +34,7 @@ int labcomm_fd_reader(
}
r->count = 0;
r->pos = 0;
va_end(ap);
} break;
case labcomm_reader_start:
case labcomm_reader_continue: {
......@@ -60,48 +72,3 @@ int labcomm_fd_reader(
return result;
}
int labcomm_fd_writer(
labcomm_writer_t *w,
labcomm_writer_action_t action, ...)
{
int result = 0;
int *fd = w->context;
switch (action) {
case labcomm_writer_alloc: {
w->data = malloc(BUFFER_SIZE);
if (! w->data) {
result = -ENOMEM;
w->data_size = 0;
w->count = 0;
w->pos = 0;
} else {
w->data_size = BUFFER_SIZE;
w->count = BUFFER_SIZE;
w->pos = 0;
}
} break;
case labcomm_writer_free: {
free(w->data);
w->data = 0;
w->data_size = 0;
w->count = 0;
w->pos = 0;
} break;
case labcomm_writer_start:
case labcomm_writer_start_signature: {
w->pos = 0;
} break;
case labcomm_writer_continue:
case labcomm_writer_continue_signature: {
result = write(*fd, w->data, w->pos);
w->pos = 0;
} break;
case labcomm_writer_end:
case labcomm_writer_end_signature: {
result = write(*fd, w->data, w->pos);
w->pos = 0;
} break;
}
return result;
}
#ifndef _LABCOMM_FD_READER_H_
#define _LABCOMM_FD_READER_H_
#include "labcomm.h"
extern int labcomm_fd_reader(
labcomm_reader_t *reader,
labcomm_reader_action_t action,
...);
#endif
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include "labcomm_fd_writer.h"
#define BUFFER_SIZE 2048
int labcomm_fd_writer(
labcomm_writer_t *w,
labcomm_writer_action_t action,
...)
{
int result = 0;
int *fd = w->context;
switch (action) {
case labcomm_writer_alloc: {
va_list ap;
va_start(ap, action);
char *version = va_arg(ap, char *);
write(*fd, version, strlen(version));
w->data = malloc(BUFFER_SIZE);
if (! w->data) {
result = -ENOMEM;
w->data_size = 0;
w->count = 0;
w->pos = 0;
} else {
w->data_size = BUFFER_SIZE;
w->count = BUFFER_SIZE;
w->pos = 0;
}
va_end(ap);
} break;
case labcomm_writer_free: {
free(w->data);
w->data = 0;
w->data_size = 0;
w->count = 0;
w->pos = 0;
} break;
case labcomm_writer_start:
case labcomm_writer_start_signature: {
w->pos = 0;
} break;
case labcomm_writer_continue:
case labcomm_writer_continue_signature: {
result = write(*fd, w->data, w->pos);
w->pos = 0;
} break;
case labcomm_writer_end:
case labcomm_writer_end_signature: {
result = write(*fd, w->data, w->pos);
w->pos = 0;
} break;
}
return result;
}
#ifndef _LABCOMM_FD_READER_WRITER_H_
#define _LABCOMM_FD_READER_WRITER_H_
#ifndef _LABCOMM_FD_WRITER_H_
#define _LABCOMM_FD_WRITER_H_
#include "labcomm.h"
extern int labcomm_fd_reader(
labcomm_reader_t *reader,
labcomm_reader_action_t action);
extern int labcomm_fd_writer(
labcomm_writer_t *writer,
labcomm_writer_action_t action,
......
......@@ -38,6 +38,12 @@
*/
#define LABCOMM_USER 0x40
/*
*
*/
#define LABCOMM_DECLARE_SIGNATURE(name) \
labcomm_signature_t name __attribute__((section("labcomm")))
/*
* Semi private decoder declarations
*/
......@@ -194,34 +200,6 @@ static inline char *labcomm_decode_string(labcomm_decoder_t *d)
return labcomm_read_string(&d->reader);
}
static inline int labcomm_buffer_read(struct labcomm_reader *r,
labcomm_reader_action_t action)
{
// If this gets called, it is an error,
// so note error and let producer proceed
r->context = r;
r->pos = 0;
return 0;
}
static inline int labcomm_buffer_reader_error(struct labcomm_reader *r)
{
return r->context != NULL;
}
static inline void labcomm_buffer_reader_setup(
labcomm_reader_t *r,
void *data,
int length)
{
r->context = NULL; // Used as error flag
r->data = data;
r->data_size = length;
r->count = length;
r->pos = 0;
r->read = labcomm_buffer_read;
}
/*
* Semi private encoder declarations
*/
......
#include "labcomm_mem_reader.h"
#include <errno.h>
#include <stdlib.h>
#include <string.h>
/* This implementation assumes labcomm will call end exactly once after each start
* It is not allowed to save data in mcontext->enc_data,
......@@ -13,7 +15,9 @@
*/
// TODO make labcomm use result!
int labcomm_mem_reader(labcomm_reader_t *r, labcomm_reader_action_t action)
int labcomm_mem_reader(labcomm_reader_t *r,
labcomm_reader_action_t action,
...)
{
int result = -EINVAL;
labcomm_mem_reader_context_t *mcontext = (labcomm_mem_reader_context_t *) r->context;
......
......@@ -12,6 +12,8 @@ struct labcomm_mem_reader_context_t {
unsigned char *enc_data;
};
int labcomm_mem_reader( labcomm_reader_t *r, labcomm_reader_action_t action);
int labcomm_mem_reader(labcomm_reader_t *r,
labcomm_reader_action_t action,
...);
#endif
......@@ -2,6 +2,7 @@
#include <stddef.h> // For size_t.
#include <stdarg.h>
#include <stdlib.h>
#include <errno.h>
#include "labcomm.h"
......
......@@ -2,6 +2,7 @@
#include "CUnit/Basic.h"
#include "CUnit/Console.h"
#include <stdbool.h>
#include <stdlib.h>
#include <labcomm.h>
#include <labcomm_mem_writer.h>
......
......@@ -9,7 +9,7 @@ int test_write(struct labcomm_writer *w, labcomm_writer_action_t a, ...)
exit(1);
}
int test_read(struct labcomm_reader *r, labcomm_reader_action_t a)
int test_read(struct labcomm_reader *r, labcomm_reader_action_t a, ...)
{
fprintf(stderr, "test_read should not be called\n");
exit(1);
......@@ -40,7 +40,7 @@ static labcomm_decoder_t decoder = {
.context = NULL,
.data = buffer,
.data_size = sizeof(buffer),
.count = sizeof(buffer),
.count = 0,
.pos = 0,
.read = test_read,
.ioctl = NULL,
......@@ -60,6 +60,7 @@ typedef unsigned char byte;
encoder.writer.pos = 0; \
labcomm_encode_##type(&encoder, value); \
writer_assert(#type, __LINE__, expect_count, (uint8_t*)expect_bytes); \
decoder.reader.count = encoder.writer.pos; \
decoder.reader.pos = 0; \
decoded = labcomm_decode_##type(&decoder); \
if (decoded != value) { \
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment