From: Petteri Aimonen Date: Wed, 6 Feb 2013 18:54:25 +0000 (+0200) Subject: Add compile-time option PB_BUFFER_ONLY. X-Git-Tag: 5.0.2~186^2~418 X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=commitdiff_plain;ds=inline;h=4ba6a3027d7a5d8c17abeb031622389f8be234fe;p=apps%2Fagl-service-can-low-level.git Add compile-time option PB_BUFFER_ONLY. This allows slight optimizations if only memory buffer support (as opposed to stream callbacks) is wanted. On ARM difference is -12% execution time, -4% code size when enabled. --- diff --git a/docs/reference.rst b/docs/reference.rst index 2b10c2ee..fee1b702 100644 --- a/docs/reference.rst +++ b/docs/reference.rst @@ -22,6 +22,8 @@ PB_FIELD_32BIT Add support for tag numbers > 65535 and fields la Increases code size 9 bytes per each field. Compiler error will tell if you need this. PB_NO_ERRMSG Disables the support for error messages; only error information is the true/false return value. Decreases the code size by a few hundred bytes. +PB_BUFFER_ONLY Disables the support for custom streams. Only supports encoding to memory buffers. + Speeds up execution and decreases code size slightly. ============================ ================================================================================================ The PB_MAX_REQUIRED_FIELDS, PB_FIELD_16BIT and PB_FIELD_32BIT settings allow raising some datatype limits to suit larger messages. diff --git a/pb_decode.c b/pb_decode.c index 9faceca2..b664fe14 100644 --- a/pb_decode.c +++ b/pb_decode.c @@ -52,6 +52,7 @@ static bool checkreturn buf_read(pb_istream_t *stream, uint8_t *buf, size_t coun bool checkreturn pb_read(pb_istream_t *stream, uint8_t *buf, size_t count) { +#ifndef PB_BUFFER_ONLY if (buf == NULL && stream->callback != buf_read) { /* Skip input bytes */ @@ -66,12 +67,18 @@ bool checkreturn pb_read(pb_istream_t *stream, uint8_t *buf, size_t count) return pb_read(stream, tmp, count); } +#endif if (stream->bytes_left < count) PB_RETURN_ERROR(stream, "end-of-stream"); +#ifndef PB_BUFFER_ONLY if (!stream->callback(stream, buf, count)) PB_RETURN_ERROR(stream, "io error"); +#else + if (!buf_read(stream, buf, count)) + return false; +#endif stream->bytes_left -= count; return true; @@ -80,7 +87,11 @@ bool checkreturn pb_read(pb_istream_t *stream, uint8_t *buf, size_t count) pb_istream_t pb_istream_from_buffer(uint8_t *buf, size_t bufsize) { pb_istream_t stream; +#ifdef PB_BUFFER_ONLY + stream.callback = NULL; +#else stream.callback = &buf_read; +#endif stream.state = buf; stream.bytes_left = bufsize; #ifndef PB_NO_ERRMSG diff --git a/pb_decode.h b/pb_decode.h index e9f8ced8..35de0a22 100644 --- a/pb_decode.h +++ b/pb_decode.h @@ -32,7 +32,16 @@ extern "C" { */ struct _pb_istream_t { +#ifdef PB_BUFFER_ONLY + /* Callback pointer is not used in buffer-only configuration. + * Having an int pointer here allows binary compatibility but + * gives an error if someone tries to assign callback function. + */ + int *callback; +#else bool (*callback)(pb_istream_t *stream, uint8_t *buf, size_t count); +#endif + void *state; /* Free field for use by callback implementation */ size_t bytes_left; diff --git a/pb_encode.c b/pb_encode.c index 95223cb6..bba5dc19 100644 --- a/pb_encode.c +++ b/pb_encode.c @@ -48,7 +48,11 @@ static bool checkreturn buf_write(pb_ostream_t *stream, const uint8_t *buf, size pb_ostream_t pb_ostream_from_buffer(uint8_t *buf, size_t bufsize) { pb_ostream_t stream; +#ifdef PB_BUFFER_ONLY + stream.callback = (void*)1; /* Just some marker value */ +#else stream.callback = &buf_write; +#endif stream.state = buf; stream.max_size = bufsize; stream.bytes_written = 0; @@ -61,9 +65,14 @@ bool checkreturn pb_write(pb_ostream_t *stream, const uint8_t *buf, size_t count { if (stream->bytes_written + count > stream->max_size) return false; - + +#ifdef PB_BUFFER_ONLY + if (!buf_write(stream, buf, count)) + return false; +#else if (!stream->callback(stream, buf, count)) return false; +#endif } stream->bytes_written += count; diff --git a/pb_encode.h b/pb_encode.h index 85a82973..69b88e86 100644 --- a/pb_encode.h +++ b/pb_encode.h @@ -32,7 +32,17 @@ extern "C" { */ struct _pb_ostream_t { +#ifdef PB_BUFFER_ONLY + /* Callback pointer is not used in buffer-only configuration. + * Having an int pointer here allows binary compatibility but + * gives an error if someone tries to assign callback function. + * Also, NULL pointer marks a 'sizing stream' that does not + * write anything. + */ + int *callback; +#else bool (*callback)(pb_ostream_t *stream, const uint8_t *buf, size_t count); +#endif 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; diff --git a/tests/Makefile b/tests/Makefile index 63830999..38f10eae 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -3,8 +3,8 @@ DEPS=../pb_decode.h ../pb_encode.h ../pb.h person.pb.h \ callbacks2.pb.h callbacks.pb.h unittests.h unittestproto.pb.h \ alltypes.pb.h missing_fields.pb.h TESTS= decode_unittests encode_unittests \ - test_decode1 test_decode2 test_decode3 \ - test_encode1 test_encode2 test_encode3 \ + test_decode1 test_decode2 test_decode3 test_decode3_buf \ + test_encode1 test_encode2 test_encode3 test_encode3_buf \ test_decode_callbacks test_encode_callbacks \ test_missing_fields test_no_messages \ test_multiple_files test_cxxcompile test_options \ @@ -39,11 +39,26 @@ pb_encode.o: ../pb_encode.c $(DEPS) pb_decode.o: ../pb_decode.c $(DEPS) $(CC) $(CFLAGS) $(CFLAGS_CORE) -c -o $@ $< +# Test for compilability with c++ compiler + pb_encode.cxx.o: ../pb_encode.c $(DEPS) $(CXX) $(CFLAGS) $(CFLAGS_CORE) -c -o $@ $< pb_decode.cxx.o: ../pb_decode.c $(DEPS) $(CXX) $(CFLAGS) $(CFLAGS_CORE) -c -o $@ $< +# Test for PB_BUF_ONLY compilation option + +pb_encode.buf.o: ../pb_encode.c $(DEPS) + $(CC) -DPB_BUFFER_ONLY $(CFLAGS) $(CFLAGS_CORE) -c -o $@ $< +pb_decode.buf.o: ../pb_decode.c $(DEPS) + $(CC) -DPB_BUFFER_ONLY $(CFLAGS) $(CFLAGS_CORE) -c -o $@ $< +%.buf.o: %.c $(DEPS) + $(CC) -DPB_BUFFER_ONLY $(CFLAGS) -c -o $@ $< +test_encode3_buf: test_encode3.buf.o pb_encode.buf.o alltypes.pb.o + $(CC) $(LDFLAGS) $^ -o $@ +test_decode3_buf: test_decode3.buf.o pb_decode.buf.o alltypes.pb.o + $(CC) $(LDFLAGS) $^ -o $@ + test_cxxcompile: pb_encode.cxx.o pb_decode.cxx.o test_decode1: test_decode1.o pb_decode.o person.pb.o test_decode2: test_decode2.o pb_decode.o person.pb.o @@ -98,6 +113,7 @@ run_unittests: $(TESTS) ./test_encode3 | ./test_decode3 ./test_encode3 1 | ./test_decode3 1 ./test_encode3 1 | protoc --decode=AllTypes -I. -I../generator -I/usr/include alltypes.proto >/dev/null + ./test_encode3_buf 1 | ./test_decode3_buf 1 ./bc_encode | ./bc_decode ./test_missing_fields