summaryrefslogtreecommitdiffstats
path: root/example/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'example/common.c')
-rw-r--r--example/common.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/example/common.c b/example/common.c
new file mode 100644
index 00000000..9d93219b
--- /dev/null
+++ b/example/common.c
@@ -0,0 +1,49 @@
+/* Simple binding of nanopb streams to TCP sockets.
+ */
+
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <pb_encode.h>
+#include <pb_decode.h>
+
+#include "common.h"
+
+static bool write_callback(pb_ostream_t *stream, const uint8_t *buf, size_t count)
+{
+ int fd = (int)stream->state;
+ return send(fd, buf, count, 0) == count;
+}
+
+static bool read_callback(pb_istream_t *stream, uint8_t *buf, size_t count)
+{
+ int fd = (int)stream->state;
+ int result;
+
+ if (buf == NULL)
+ {
+ /* Well, this is a really inefficient way to skip input. */
+ /* It is only used when there are unknown fields. */
+ char dummy;
+ while (count-- && recv(fd, &dummy, 1, 0) == 1);
+ return count == 0;
+ }
+
+ result = recv(fd, buf, count, MSG_WAITALL);
+
+ if (result == 0)
+ stream->bytes_left = 0; /* EOF */
+
+ return result == count;
+}
+
+pb_ostream_t pb_ostream_from_socket(int fd)
+{
+ pb_ostream_t stream = {&write_callback, (void*)fd, SIZE_MAX, 0};
+ return stream;
+}
+
+pb_istream_t pb_istream_from_socket(int fd)
+{
+ pb_istream_t stream = {&read_callback, (void*)fd, SIZE_MAX};
+ return stream;
+}