Commit 274eddf0 authored by Anders Blomdell's avatar Anders Blomdell
Browse files

First stab at propagating writer errors to caller.

parent 45c7b977
...@@ -351,7 +351,7 @@ aspect C_Declarations { ...@@ -351,7 +351,7 @@ aspect C_Declarations {
env.println("struct labcomm_encoder *e);"); env.println("struct labcomm_encoder *e);");
env.unindent(); env.unindent();
env.println("void labcomm_encode_" + env.prefix + getName() + "("); env.println("int labcomm_encode_" + env.prefix + getName() + "(");
env.indent(); env.indent();
env.println("struct labcomm_encoder *e,"); env.println("struct labcomm_encoder *e,");
env.println(env.prefix + getName() + " *v"); env.println(env.prefix + getName() + " *v");
...@@ -633,7 +633,7 @@ aspect C_Encoder { ...@@ -633,7 +633,7 @@ aspect C_Encoder {
public void SampleDecl.C_emitEncoder(C_env env) { public void SampleDecl.C_emitEncoder(C_env env) {
env = env.nestStruct("(*v)"); env = env.nestStruct("(*v)");
env.println("static void encode_" + getName() + "("); env.println("static int encode_" + getName() + "(");
env.indent(); env.indent();
env.println("labcomm_encoder_t *e,"); env.println("labcomm_encoder_t *e,");
env.println(env.prefix + getName() + " *v"); env.println(env.prefix + getName() + " *v");
...@@ -641,21 +641,23 @@ aspect C_Encoder { ...@@ -641,21 +641,23 @@ aspect C_Encoder {
env.println(")"); env.println(")");
env.println("{"); env.println("{");
env.indent(); env.indent();
env.println("int result;");
getType().C_emitEncoder(env); getType().C_emitEncoder(env);
env.println("return result;");
env.unindent(); env.unindent();
env.println("}"); env.println("}");
// Typesafe encode wrapper // Typesafe encode wrapper
env.println("void labcomm_encode_" + env.prefix + getName() + "("); env.println("int labcomm_encode_" + env.prefix + getName() + "(");
env.println("labcomm_encoder_t *e,"); env.println("labcomm_encoder_t *e,");
env.println(env.prefix + getName() + " *v"); env.println(env.prefix + getName() + " *v");
env.unindent(); env.unindent();
env.println(")"); env.println(")");
env.println("{"); env.println("{");
env.indent(); env.indent();
env.println("labcomm_internal_encode(e, &labcomm_signature_" + env.println("return labcomm_internal_encode(e, &labcomm_signature_" +
env.prefix + getName() + env.prefix + getName() +
", (labcomm_encode_typecast_t)encode_" + getName() + ", (labcomm_encoder_function)encode_" + getName() +
", v);"); ", v);");
env.unindent(); env.unindent();
env.println("}"); env.println("}");
...@@ -668,10 +670,13 @@ aspect C_Encoder { ...@@ -668,10 +670,13 @@ aspect C_Encoder {
} }
public void VoidType.C_emitEncoder(C_env env) { public void VoidType.C_emitEncoder(C_env env) {
env.println("result = 0;");
} }
public void PrimType.C_emitEncoder(C_env env) { public void PrimType.C_emitEncoder(C_env env) {
env.println("labcomm_encode_" + getName() + "(e, " + env.qualid + ");"); env.println("result = labcomm_encode_" + getName() +
"(e, " + env.qualid + ");");
env.println("if (result != 0) { return result; }");
} }
public void UserType.C_emitEncoder(C_env env) { public void UserType.C_emitEncoder(C_env env) {
...@@ -748,7 +753,7 @@ aspect C_Encoder { ...@@ -748,7 +753,7 @@ aspect C_Encoder {
env.indent(); env.indent();
env.println("e,"); env.println("e,");
env.println("&labcomm_signature_" + env.prefix + getName() + ","); env.println("&labcomm_signature_" + env.prefix + getName() + ",");
env.println("(labcomm_encode_typecast_t)encode_" + getName()); env.println("(labcomm_encoder_function)encode_" + getName());
env.unindent(); env.unindent();
env.println(");"); env.println(");");
env.unindent(); env.unindent();
......
...@@ -42,7 +42,7 @@ typedef struct labcomm_sample_entry { ...@@ -42,7 +42,7 @@ typedef struct labcomm_sample_entry {
labcomm_signature_t *signature; labcomm_signature_t *signature;
labcomm_decoder_typecast_t decoder; labcomm_decoder_typecast_t decoder;
labcomm_handler_typecast_t handler; labcomm_handler_typecast_t handler;
labcomm_encode_typecast_t encode; labcomm_encoder_function encode;
void *context; void *context;
} labcomm_sample_entry_t; } labcomm_sample_entry_t;
...@@ -224,32 +224,14 @@ static int get_encoder_index( ...@@ -224,32 +224,14 @@ static int get_encoder_index(
#endif #endif
} }
void labcomm_encoder_start(struct labcomm_encoder *e,
labcomm_signature_t *s)
{
int index = get_encoder_index(e, s);
e->writer.write(&e->writer, labcomm_writer_start, index);
}
void labcomm_encoder_end(struct labcomm_encoder *e,
labcomm_signature_t *s)
{
e->writer.write(&e->writer, labcomm_writer_end);
}
void labcomm_encode_type_index(labcomm_encoder_t *e, labcomm_signature_t *s)
{
int index = get_encoder_index(e, s);
labcomm_encode_packed32(e, index);
}
void labcomm_encode_signature(struct labcomm_encoder *e, void labcomm_encode_signature(struct labcomm_encoder *e,
labcomm_signature_t *signature) labcomm_signature_t *signature)
{ {
int i; int i;
e->writer.write(&e->writer, labcomm_writer_start_signature); e->writer.write(&e->writer, labcomm_writer_start_signature);
labcomm_encode_packed32(e, signature->type); labcomm_encode_packed32(e, signature->type);
labcomm_encode_type_index(e, signature); labcomm_encode_packed32(e, get_encoder_index(e, signature));
labcomm_encode_string(e, signature->name); labcomm_encode_string(e, signature->name);
for (i = 0 ; i < signature->size ; i++) { for (i = 0 ; i < signature->size ; i++) {
if (e->writer.pos >= e->writer.count) { if (e->writer.pos >= e->writer.count) {
...@@ -264,7 +246,7 @@ void labcomm_encode_signature(struct labcomm_encoder *e, ...@@ -264,7 +246,7 @@ void labcomm_encode_signature(struct labcomm_encoder *e,
#ifdef LABCOMM_ENCODER_LINEAR_SEARCH #ifdef LABCOMM_ENCODER_LINEAR_SEARCH
static int encoder_add_signature_by_search(struct labcomm_encoder *e, static int encoder_add_signature_by_search(struct labcomm_encoder *e,
labcomm_signature_t *signature, labcomm_signature_t *signature,
labcomm_encode_typecast_t encode) labcomm_encoder_function encode)
{ {
int result; int result;
labcomm_encoder_context_t *context = e->context; labcomm_encoder_context_t *context = e->context;
...@@ -289,7 +271,7 @@ static int encoder_add_signature_by_search(struct labcomm_encoder *e, ...@@ -289,7 +271,7 @@ static int encoder_add_signature_by_search(struct labcomm_encoder *e,
#ifndef LABCOMM_ENCODER_LINEAR_SEARCH #ifndef LABCOMM_ENCODER_LINEAR_SEARCH
static int encoder_add_signature_by_section(struct labcomm_encoder *e, static int encoder_add_signature_by_section(struct labcomm_encoder *e,
labcomm_signature_t *s, labcomm_signature_t *s,
labcomm_encode_typecast_t encode) labcomm_encoder_function encode)
{ {
int result = -ENOENT; int result = -ENOENT;
...@@ -319,7 +301,7 @@ out: ...@@ -319,7 +301,7 @@ out:
static int encoder_add_signature(struct labcomm_encoder *e, static int encoder_add_signature(struct labcomm_encoder *e,
labcomm_signature_t *signature, labcomm_signature_t *signature,
labcomm_encode_typecast_t encode) labcomm_encoder_function encode)
{ {
int index = -ENOENT; int index = -ENOENT;
...@@ -333,7 +315,7 @@ static int encoder_add_signature(struct labcomm_encoder *e, ...@@ -333,7 +315,7 @@ static int encoder_add_signature(struct labcomm_encoder *e,
static void do_encoder_register(struct labcomm_encoder *e, static void do_encoder_register(struct labcomm_encoder *e,
labcomm_signature_t *signature, labcomm_signature_t *signature,
labcomm_encode_typecast_t encode) labcomm_encoder_function encode)
{ {
if (signature->type == LABCOMM_SAMPLE) { if (signature->type == LABCOMM_SAMPLE) {
if (get_encoder_index(e, signature) == 0) { if (get_encoder_index(e, signature) == 0) {
...@@ -355,6 +337,7 @@ static void do_encoder_register(struct labcomm_encoder *e, ...@@ -355,6 +337,7 @@ static void do_encoder_register(struct labcomm_encoder *e,
} }
} }
/*
static labcomm_sample_entry_t *encoder_get_sample_by_signature_address( static labcomm_sample_entry_t *encoder_get_sample_by_signature_address(
labcomm_encoder_t *encoder, labcomm_encoder_t *encoder,
labcomm_signature_t *s) labcomm_signature_t *s)
...@@ -371,32 +354,30 @@ static labcomm_sample_entry_t *encoder_get_sample_by_signature_address( ...@@ -371,32 +354,30 @@ static labcomm_sample_entry_t *encoder_get_sample_by_signature_address(
#endif #endif
return result; return result;
} }
*/
static void do_encode( static int do_encode(
labcomm_encoder_t *encoder, labcomm_encoder_t *e,
labcomm_signature_t *signature, labcomm_signature_t *signature,
labcomm_encode_typecast_t encode, labcomm_encoder_function encode,
void *value) void *value)
{ {
labcomm_sample_entry_t *sample; int result;
sample = encoder_get_sample_by_signature_address(encoder, signature); labcomm_writer_start_t lws;
(void)sample;
labcomm_encoder_start(encoder, signature);
labcomm_encode_type_index(encoder, signature);
encode(encoder, value);
labcomm_encoder_end(encoder, signature);
/*
labcomm_sample_entry_t *sample;
sample = encoder_get_sample_by_signature_address(encoder, signature); lws.encoder = e;
if (sample && sample->encode) { lws.index = get_encoder_index(e, signature);
sample->encode(encoder, value); lws.signature = signature;
} else { lws.value = value;
encoder->on_error(LABCOMM_ERROR_ENC_NO_REG_SIGNATURE, 2, "No registration for %s.\n", signature->name); result = e->writer.write(&e->writer, labcomm_writer_start, &lws);
} if (result == -EALREADY) { result = 0; goto out; }
*/ if (result != 0) { goto out; }
result = labcomm_encode_packed32(e, lws.index);
if (result != 0) { goto out; }
result = encode(e, value);
out:
e->writer.write(&e->writer, labcomm_writer_end, &lws);
return result;
} }
labcomm_encoder_t *labcomm_encoder_new( labcomm_encoder_t *labcomm_encoder_new(
...@@ -435,7 +416,7 @@ labcomm_encoder_t *labcomm_encoder_new( ...@@ -435,7 +416,7 @@ labcomm_encoder_t *labcomm_encoder_new(
void labcomm_internal_encoder_register( void labcomm_internal_encoder_register(
labcomm_encoder_t *e, labcomm_encoder_t *e,
labcomm_signature_t *signature, labcomm_signature_t *signature,
labcomm_encode_typecast_t encode) labcomm_encoder_function encode)
{ {
// Will segfault if e == NULL. // Will segfault if e == NULL.
if (e->do_register) { if (e->do_register) {
...@@ -445,17 +426,18 @@ void labcomm_internal_encoder_register( ...@@ -445,17 +426,18 @@ void labcomm_internal_encoder_register(
} }
} }
void labcomm_internal_encode( int labcomm_internal_encode(
labcomm_encoder_t *e, labcomm_encoder_t *e,
labcomm_signature_t *signature, labcomm_signature_t *signature,
labcomm_encode_typecast_t encode, labcomm_encoder_function encode,
void *value) void *value)
{ {
if (e->do_encode) { if (e->do_encode) {
e->do_encode(e, signature, encode, value); return e->do_encode(e, signature, encode, value);
} else { } else {
e->on_error(LABCOMM_ERROR_ENC_MISSING_DO_ENCODE, 0); e->on_error(LABCOMM_ERROR_ENC_MISSING_DO_ENCODE, 0);
} }
return 0;
} }
void labcomm_encoder_free(labcomm_encoder_t* e) void labcomm_encoder_free(labcomm_encoder_t* e)
......
...@@ -11,7 +11,7 @@ struct labcomm_decoder; ...@@ -11,7 +11,7 @@ struct labcomm_decoder;
/* /*
* Signature entry * Signature entry
*/ */
typedef struct labcomm_signature{ typedef struct labcomm_signature {
int type; int type;
char *name; char *name;
int (*encoded_size)(struct labcomm_signature *, void *); // void * == encoded_sample * int (*encoded_size)(struct labcomm_signature *, void *); // void * == encoded_sample *
...@@ -115,12 +115,20 @@ void labcomm_decoder_free( ...@@ -115,12 +115,20 @@ void labcomm_decoder_free(
/* /*
* Encoder * Encoder
*/ */
typedef struct {
struct labcomm_encoder *encoder;
int index;
labcomm_signature_t *signature;
void *value;
} labcomm_writer_start_t;
typedef enum { typedef enum {
labcomm_writer_alloc, /* (..., char *labcomm_version) labcomm_writer_alloc, /* (..., char *labcomm_version)
Allocate all neccessary data */ Allocate all neccessary data */
labcomm_writer_free, /* Free all allocated data */ labcomm_writer_free, /* Free all allocated data */
labcomm_writer_start, /* Start writing an ordinary sample */ labcomm_writer_start, /* (..., labcomm_writer_start_t *s)
-EALREADY skips further encoding
Start writing an ordinary sample */
labcomm_writer_continue, /* Buffer full during ordinary sample */ labcomm_writer_continue, /* Buffer full during ordinary sample */
labcomm_writer_end, /* End writing ordinary sample */ labcomm_writer_end, /* End writing ordinary sample */
labcomm_writer_start_signature, /* Start writing signature */ labcomm_writer_start_signature, /* Start writing signature */
......
...@@ -203,7 +203,7 @@ static inline char *labcomm_decode_string(labcomm_decoder_t *d) ...@@ -203,7 +203,7 @@ static inline char *labcomm_decode_string(labcomm_decoder_t *d)
/* /*
* Semi private encoder declarations * Semi private encoder declarations
*/ */
typedef void (*labcomm_encode_typecast_t)( typedef int (*labcomm_encoder_function)(
struct labcomm_encoder *, struct labcomm_encoder *,
void *value); void *value);
...@@ -212,10 +212,10 @@ typedef struct labcomm_encoder { ...@@ -212,10 +212,10 @@ typedef struct labcomm_encoder {
labcomm_writer_t writer; labcomm_writer_t writer;
void (*do_register)(struct labcomm_encoder *encoder, void (*do_register)(struct labcomm_encoder *encoder,
labcomm_signature_t *signature, labcomm_signature_t *signature,
labcomm_encode_typecast_t); labcomm_encoder_function encode);
void (*do_encode)(struct labcomm_encoder *encoder, int (*do_encode)(struct labcomm_encoder *encoder,
labcomm_signature_t *signature, labcomm_signature_t *signature,
labcomm_encode_typecast_t encode, labcomm_encoder_function encode,
void *value); void *value);
labcomm_error_handler_callback on_error; labcomm_error_handler_callback on_error;
} labcomm_encoder_t; } labcomm_encoder_t;
...@@ -223,46 +223,52 @@ typedef struct labcomm_encoder { ...@@ -223,46 +223,52 @@ typedef struct labcomm_encoder {
void labcomm_internal_encoder_register( void labcomm_internal_encoder_register(
labcomm_encoder_t *encoder, labcomm_encoder_t *encoder,
labcomm_signature_t *signature, labcomm_signature_t *signature,
labcomm_encode_typecast_t encode); labcomm_encoder_function encode);
void labcomm_internal_encode( int labcomm_internal_encode(
labcomm_encoder_t *encoder, labcomm_encoder_t *encoder,
labcomm_signature_t *signature, labcomm_signature_t *signature,
labcomm_encode_typecast_t encode, labcomm_encoder_function encode,
void *value); void *value);
#if __BYTE_ORDER == __LITTLE_ENDIAN #if __BYTE_ORDER == __LITTLE_ENDIAN
#define LABCOMM_ENCODE(name, type) \ #define LABCOMM_ENCODE(name, type) \
static inline void labcomm_write_##name(labcomm_writer_t *w, type data) { \ static inline int labcomm_write_##name(labcomm_writer_t *w, type data) { \
int i; \ int i; \
for (i = sizeof(type) - 1 ; i >= 0 ; i--) { \ for (i = sizeof(type) - 1 ; i >= 0 ; i--) { \
if (w->pos >= w->count) { /*buffer is full*/ \ if (w->pos >= w->count) { /*buffer is full*/ \
w->write(w, labcomm_writer_continue); \ int err; \
err = w->write(w, labcomm_writer_continue); \
if (err != 0) { return err; } \
} \ } \
w->data[w->pos] = ((unsigned char*)(&data))[i]; \ w->data[w->pos] = ((unsigned char*)(&data))[i]; \
w->pos++; \ w->pos++; \
} \ } \
return 0; \
} \ } \
static inline void labcomm_encode_##name(labcomm_encoder_t *e, type data) { \ static inline int labcomm_encode_##name(labcomm_encoder_t *e, type data) { \
labcomm_write_##name(&e->writer, data); \ return labcomm_write_##name(&e->writer, data); \
} }
#else #else
#define LABCOMM_ENCODE(name, type) \ #define LABCOMM_ENCODE(name, type) \
static inline void labcomm_write_##name(labcomm_writer_t *w, type data) { \ static inline int labcomm_write_##name(labcomm_writer_t *w, type data) { \
int i; \ int i; \
for (i = 0 ; i < sizeof(type) ; i++) { \ for (i = 0 ; i < sizeof(type) ; i++) { \
if (w->pos >= w->count) { \ if (w->pos >= w->count) { \
w->write(w, labcomm_writer_continue); \ int err; \
err = w->write(w, labcomm_writer_continue); \
if (err != 0) { return err; } \
} \ } \
w->data[w->pos] = ((unsigned char*)(&data))[i]; \ w->data[w->pos] = ((unsigned char*)(&data))[i]; \
w->pos++; \ w->pos++; \
} \ } \
return 0; \
} \ } \
static inline void labcomm_encode_##name(labcomm_encoder_t *e, type data) { \ static inline int labcomm_encode_##name(labcomm_encoder_t *e, type data) { \
labcomm_write_##name(&e->writer, data); \ return labcomm_write_##name(&e->writer, data); \
} }
#endif #endif
...@@ -287,7 +293,8 @@ LABCOMM_ENCODE(double, double) ...@@ -287,7 +293,8 @@ LABCOMM_ENCODE(double, double)
* 0b1110 - 4 bytes (0x00200000 - 0x0fffffff) * 0b1110 - 4 bytes (0x00200000 - 0x0fffffff)
* 0b11110 - 5 bytes (0x10000000 - 0xffffffff) [4 bits unused] * 0b11110 - 5 bytes (0x10000000 - 0xffffffff) [4 bits unused]
*/ */
static inline void labcomm_pack32(labcomm_writer_t *w, unsigned int data) static inline int labcomm_write_packed32(labcomm_writer_t *w,
unsigned int data)
{ {
int n; int n;
unsigned char tag; unsigned char tag;
...@@ -311,68 +318,86 @@ static inline void labcomm_pack32(labcomm_writer_t *w, unsigned int data) ...@@ -311,68 +318,86 @@ static inline void labcomm_pack32(labcomm_writer_t *w, unsigned int data)
n = 5; n = 5;
tag = 0xf0; tag = 0xf0;
} }
if (w->pos + n - 1 >= w->count) { /* TODO: maybe?
if (w->pos + n - 1 >= w->count) {
w->write(w, labcomm_writer_continue, n); w->write(w, labcomm_writer_continue, n);
} }
*/
switch (n) { switch (n) {
case 5: { case 5: {
if (w->pos >= w->count) { if (w->pos >= w->count) {
w->write(w, labcomm_writer_continue); int err;
err = w->write(w, labcomm_writer_continue);
if (err != 0) { return err; }
} }
w->data[w->pos++] = tag; tag = 0; w->data[w->pos++] = tag; tag = 0;
} }
case 4: { case 4: {
if (w->pos >= w->count) { if (w->pos >= w->count) {
w->write(w, labcomm_writer_continue); int err;
err = w->write(w, labcomm_writer_continue);
if (err != 0) { return err; }
} }
w->data[w->pos++] = tmp[0] | tag; tag = 0; w->data[w->pos++] = tmp[0] | tag; tag = 0;
} }
case 3: { case 3: {
if (w->pos >= w->count) { if (w->pos >= w->count) {
w->write(w, labcomm_writer_continue); int err;
err = w->write(w, labcomm_writer_continue);
if (err != 0) { return err; }
} }
w->data[w->pos++] = tmp[1] | tag; tag = 0; w->data[w->pos++] = tmp[1] | tag; tag = 0;
} }
case 2: { case 2: {
if (w->pos >= w->count) { if (w->pos >= w->count) {
w->write(w, labcomm_writer_continue); int err;
err = w->write(w, labcomm_writer_continue);
if (err != 0) { return err; }
} }
w->data[w->pos++] = tmp[2] | tag; tag = 0; w->data[w->pos++] = tmp[2] | tag; tag = 0;
} }
case 1: { case 1: {
if (w->pos >= w->count) { if (w->pos >= w->count) {
w->write(w, labcomm_writer_continue); int err;
err = w->write(w, labcomm_writer_continue);
if (err != 0) { return err; }
} }
w->data[w->pos++] = tmp[3] | tag; w->data[w->pos++] = tmp[3] | tag;
} }
} }
return 0;
} }
static inline void labcomm_encode_packed32(labcomm_encoder_t *e, unsigned int data) static inline int labcomm_encode_packed32(labcomm_encoder_t *e,
unsigned int data)
{ {
labcomm_pack32(&e->writer, data); return labcomm_write_packed32(&e->writer, data);
} }
static inline void labcomm_write_string(labcomm_writer_t *w, char *s) static inline int labcomm_write_string(labcomm_writer_t *w, char *s)
{ {
int length, i; int length, i, err;
length = strlen((char*)s); length = strlen((char*)s);
labcomm_pack32(w, length); err = labcomm_write_packed32(w, length);
if (err != 0) { return err; }
for (i = 0 ; i < length ; i++) { for (i = 0 ; i < length ; i++) {
if (w->pos >= w->count) { if (w->pos >= w->count) {
w->write(w, labcomm_writer_continue); int err;
err = w->write(w, labcomm_writer_continue);
if (err != 0) { return err; }
} }
w->data[w->pos] = s[i]; w->data[w->pos] = s[i];
w->pos++; w->pos++;
} }