diff options
author | Petteri Aimonen <jpa@git.mail.kapsi.fi> | 2013-03-09 14:49:15 +0200 |
---|---|---|
committer | Petteri Aimonen <jpa@git.mail.kapsi.fi> | 2013-03-09 14:49:15 +0200 |
commit | 03526471189711f6656dfa074fc6a8fd7f3d340b (patch) | |
tree | 12e1969b04909547bf32309cfcc4c9409e24fbbc | |
parent | 9b6641ac643af4f301e05421f2b228084dcc8693 (diff) |
Implement error message support for the encoder side.
Update issue 7
Status: FixedInGit
-rw-r--r-- | pb_encode.c | 37 | ||||
-rw-r--r-- | pb_encode.h | 11 | ||||
-rw-r--r-- | tests/test_encode1.c | 1 | ||||
-rw-r--r-- | tests/test_encode2.c | 5 | ||||
-rw-r--r-- | tests/test_encode3.c | 2 |
5 files changed, 41 insertions, 15 deletions
diff --git a/pb_encode.c b/pb_encode.c index fbeeacfc..fd4b6ba5 100644 --- a/pb_encode.c +++ b/pb_encode.c @@ -56,6 +56,9 @@ pb_ostream_t pb_ostream_from_buffer(uint8_t *buf, size_t bufsize) stream.state = buf; stream.max_size = bufsize; stream.bytes_written = 0; +#ifndef PB_NO_ERRMSG + stream.errmsg = NULL; +#endif return stream; } @@ -64,14 +67,14 @@ bool checkreturn pb_write(pb_ostream_t *stream, const uint8_t *buf, size_t count if (stream->callback != NULL) { if (stream->bytes_written + count > stream->max_size) - return false; + PB_RETURN_ERROR(stream, "stream full"); #ifdef PB_BUFFER_ONLY if (!buf_write(stream, buf, count)) - return false; + PB_RETURN_ERROR(stream, "io error"); #else if (!stream->callback(stream, buf, count)) - return false; + PB_RETURN_ERROR(stream, "io error"); #endif } @@ -111,7 +114,7 @@ static bool checkreturn encode_array(pb_ostream_t *stream, const pb_field_t *fie } else { - pb_ostream_t sizestream = {0,0,0,0}; + pb_ostream_t sizestream = PB_OSTREAM_SIZING; p = pData; for (i = 0; i < count; i++) { @@ -187,7 +190,7 @@ bool checkreturn encode_static_field(pb_ostream_t *stream, const pb_field_t *fie break; default: - return false; + PB_RETURN_ERROR(stream, "invalid field type"); } return true; @@ -199,7 +202,7 @@ bool checkreturn encode_callback_field(pb_ostream_t *stream, const pb_field_t *f if (callback->funcs.encode != NULL) { if (!callback->funcs.encode(stream, field, callback->arg)) - return false; + PB_RETURN_ERROR(stream, "callback error"); } return true; } @@ -235,7 +238,7 @@ bool checkreturn pb_encode(pb_ostream_t *stream, const pb_field_t fields[], cons break; default: - return false; + PB_RETURN_ERROR(stream, "invalid field type"); } field++; @@ -340,7 +343,7 @@ bool checkreturn pb_encode_tag_for_field(pb_ostream_t *stream, const pb_field_t break; default: - return false; + PB_RETURN_ERROR(stream, "invalid field type"); } return pb_encode_tag(stream, wiretype, field->tag); @@ -357,7 +360,7 @@ bool checkreturn pb_encode_string(pb_ostream_t *stream, const uint8_t *buffer, s bool checkreturn pb_encode_submessage(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct) { /* First calculate the message size using a non-writing substream. */ - pb_ostream_t substream = {0,0,0,0}; + pb_ostream_t substream = PB_OSTREAM_SIZING; size_t size; bool status; @@ -373,7 +376,7 @@ bool checkreturn pb_encode_submessage(pb_ostream_t *stream, const pb_field_t fie return pb_write(stream, NULL, size); /* Just sizing */ if (stream->bytes_written + size > stream->max_size) - return false; + PB_RETURN_ERROR(stream, "stream full"); /* Use a substream to verify that a callback doesn't write more than * what it did the first time. */ @@ -381,14 +384,20 @@ bool checkreturn pb_encode_submessage(pb_ostream_t *stream, const pb_field_t fie substream.state = stream->state; substream.max_size = size; substream.bytes_written = 0; +#ifndef PB_NO_ERRMSG + substream.errmsg = NULL; +#endif status = pb_encode(&substream, fields, src_struct); stream->bytes_written += substream.bytes_written; stream->state = substream.state; +#ifndef PB_NO_ERRMSG + stream->errmsg = substream.errmsg; +#endif if (substream.bytes_written != size) - return false; + PB_RETURN_ERROR(stream, "submsg size changed"); return status; } @@ -405,7 +414,7 @@ bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_t *field, co case 2: value = *(const uint16_t*)src; break; case 4: value = *(const uint32_t*)src; break; case 8: value = *(const uint64_t*)src; break; - default: return false; + default: PB_RETURN_ERROR(stream, "invalid data_size"); } return pb_encode_varint(stream, value); @@ -419,7 +428,7 @@ bool checkreturn pb_enc_svarint(pb_ostream_t *stream, const pb_field_t *field, c { case 4: value = *(const int32_t*)src; break; case 8: value = *(const int64_t*)src; break; - default: return false; + default: PB_RETURN_ERROR(stream, "invalid data_size"); } return pb_encode_svarint(stream, value); @@ -453,7 +462,7 @@ bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_t *field, co bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_t *field, const void *src) { if (field->ptr == NULL) - return false; + PB_RETURN_ERROR(stream, "invalid field descriptor"); return pb_encode_submessage(stream, (const pb_field_t*)field->ptr, src); } diff --git a/pb_encode.h b/pb_encode.h index 69b88e86..bd6132b6 100644 --- a/pb_encode.h +++ b/pb_encode.h @@ -46,11 +46,22 @@ struct _pb_ostream_t void *state; /* Free field for use by callback implementation */ size_t max_size; /* Limit number of output bytes written (or use SIZE_MAX). */ size_t bytes_written; + +#ifndef PB_NO_ERRMSG + const char *errmsg; +#endif }; pb_ostream_t pb_ostream_from_buffer(uint8_t *buf, size_t bufsize); bool pb_write(pb_ostream_t *stream, const uint8_t *buf, size_t count); +/* Stream type for use in computing message sizes */ +#ifndef PB_NO_ERRMSG +#define PB_OSTREAM_SIZING {0,0,0,0,0} +#else +#define PB_OSTREAM_SIZING {0,0,0,0} +#endif + /* Encode struct to given output stream. * Returns true on success, false on any failure. * The actual struct pointed to by src_struct must match the description in fields. diff --git a/tests/test_encode1.c b/tests/test_encode1.c index 2e978296..742c99f4 100644 --- a/tests/test_encode1.c +++ b/tests/test_encode1.c @@ -27,6 +27,7 @@ int main() } else { + fprintf(stderr, "Encoding failed: %s\n", PB_GET_ERROR(&stream)); return 1; /* Failure */ } } diff --git a/tests/test_encode2.c b/tests/test_encode2.c index b1105ce6..fd25c6cb 100644 --- a/tests/test_encode2.c +++ b/tests/test_encode2.c @@ -26,7 +26,12 @@ int main() /* Now encode it and check if we succeeded. */ if (pb_encode(&stream, Person_fields, &person)) + { return 0; /* Success */ + } else + { + fprintf(stderr, "Encoding failed: %s\n", PB_GET_ERROR(&stream)); return 1; /* Failure */ + } } diff --git a/tests/test_encode3.c b/tests/test_encode3.c index 4f6859ac..982ad3c8 100644 --- a/tests/test_encode3.c +++ b/tests/test_encode3.c @@ -124,7 +124,7 @@ int main(int argc, char **argv) } else { - fprintf(stderr, "Encoding failed!\n"); + fprintf(stderr, "Encoding failed: %s\n", PB_GET_ERROR(&stream)); return 1; /* Failure */ } } |