[CRIU] [PATCH 01/15] protobuf: generic show function introduced
Kinsbursky Stanislav
skinsbursky at openvz.org
Wed Jul 18 05:04:49 EDT 2012
From: Stanislav Kinsbursky <skinsbursky at openvz.org>
This function can be used for any protobuf message which contains required,
repeated and even nested messages fields.
The functions doesn't support yet:
1) Optional fields (skipped)
2) Fields types: PROTOBUF_C_TYPE_FLOAT, PROTOBUF_C_TYPE_DOUBLE,
PROTOBUF_C_TYPE_BOOL, PROTOBUF_C_TYPE_ENUM, PROTOBUF_C_TYPE_BYTES.
These are show as unknown objects.
IOW, it supports only existent proto files.
Inspired-by: Cyrill Gorcunov <gorcunov at openvz.org>
Signed-off-by: Stanislav Kinsbursky <skinsbursky at openvz.org>
---
include/protobuf.h | 2 +
protobuf.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 127 insertions(+), 0 deletions(-)
-------------- next part --------------
diff --git a/include/protobuf.h b/include/protobuf.h
index 7770116..8ce854a 100644
--- a/include/protobuf.h
+++ b/include/protobuf.h
@@ -54,4 +54,6 @@ extern int pb_write_object_with_header(int fd, void *obj,
#define pb_repeated_size(__obj, __member) \
(sizeof(*(__obj)->__member) * (__obj)->n_ ##__member)
+extern void pb_show_msg(const void *msg, const void *msg_desc);
+
#endif /* PROTOBUF_H__ */
diff --git a/protobuf.c b/protobuf.c
index 4d97b7a..bbbef43 100644
--- a/protobuf.c
+++ b/protobuf.c
@@ -4,6 +4,8 @@
#include <fcntl.h>
#include <stdlib.h>
+#include <google/protobuf-c/protobuf-c.h>
+
#include "compiler.h"
#include "types.h"
#include "log.h"
@@ -18,6 +20,129 @@
*/
#define PB_PKOBJ_LOCAL_SIZE 1024
+typedef void (pb_pr_field_t)(void *obj, void *arg);
+
+static void pb_msg_int32x(void *obj, void *arg)
+{
+ pr_msg("0x%08x", *(int *)obj);
+}
+
+static void pb_msg_int64x(void *obj, void *arg)
+{
+ pr_msg("0x%016lx", *(long *)obj);
+}
+
+static void pb_msg_string(void *obj, void *arg)
+{
+ pr_msg("\"%s\"", *(char **)obj);
+}
+
+static void pb_msg_unk(void *obj, void *arg)
+{
+ pr_msg("unknown object %p\n", obj);
+}
+
+static void __pb_show_msg(const void *msg, const ProtobufCMessageDescriptor *md);
+
+static void show_nested_message(void *msg, void *md)
+{
+ pr_msg("[ ");
+ __pb_show_msg(msg, md);
+ pr_msg(" ] ");
+}
+
+
+static void pb_show_field(const ProtobufCFieldDescriptor *fd, void *where,
+ unsigned long nr_fields)
+{
+ pb_pr_field_t *show;
+ unsigned long counter;
+ size_t fsize;
+ void *arg;
+
+ pr_msg("%s: ", fd->name);
+
+ switch (fd->type) {
+ case PROTOBUF_C_TYPE_INT32:
+ case PROTOBUF_C_TYPE_SINT32:
+ case PROTOBUF_C_TYPE_UINT32:
+ case PROTOBUF_C_TYPE_SFIXED32:
+ show = pb_msg_int32x;
+ fsize = 4;
+ break;
+ case PROTOBUF_C_TYPE_INT64:
+ case PROTOBUF_C_TYPE_SINT64:
+ case PROTOBUF_C_TYPE_SFIXED64:
+ case PROTOBUF_C_TYPE_FIXED32:
+ case PROTOBUF_C_TYPE_UINT64:
+ case PROTOBUF_C_TYPE_FIXED64:
+ show = pb_msg_int64x;
+ fsize = 8;
+ break;
+ case PROTOBUF_C_TYPE_STRING:
+ show = pb_msg_string;
+ fsize = sizeof (void *);
+ break;
+ case PROTOBUF_C_TYPE_MESSAGE:
+ where = (void *)(*(long *)where);
+ arg = (void *)fd->descriptor;
+ show = show_nested_message;
+ fsize = sizeof (void *);
+ break;
+ case PROTOBUF_C_TYPE_FLOAT:
+ case PROTOBUF_C_TYPE_DOUBLE:
+ case PROTOBUF_C_TYPE_BOOL:
+ case PROTOBUF_C_TYPE_ENUM:
+ case PROTOBUF_C_TYPE_BYTES:
+ default:
+ show = pb_msg_unk;
+ nr_fields = 1;
+ break;
+ }
+
+ show(where, arg);
+ where += fsize;
+
+ for (counter = 0; counter < nr_fields - 1; counter++, where += fsize) {
+ pr_msg(":");
+ show(where, arg);
+ }
+
+ pr_msg(" ");
+}
+
+static void __pb_show_msg(const void *msg, const ProtobufCMessageDescriptor *md)
+{
+ int i;
+
+ BUG_ON(md == NULL);
+
+ for (i = 0; i < md->n_fields; i++) {
+ const ProtobufCFieldDescriptor fd = md->fields[i];
+ unsigned long *data;
+ size_t nr_fields;
+
+ if (fd.label == PROTOBUF_C_LABEL_OPTIONAL)
+ continue;
+
+ nr_fields = 1;
+ data = (unsigned long *)(msg + fd.offset);
+
+ if (fd.label == PROTOBUF_C_LABEL_REPEATED) {
+ nr_fields = *(size_t *)(msg + fd.quantifier_offset);
+ data = (unsigned long *)*data;
+ }
+
+ pb_show_field(&fd, data, nr_fields);
+ }
+}
+
+void pb_show_msg(const void *msg, const void *msg_desc)
+{
+ __pb_show_msg(msg, msg_desc);
+ pr_msg("\n");
+}
+
/*
* Reads PB record (header + packed object) from file @fd and unpack
* it with @unpack procedure to the pointer @pobj
More information about the CRIU
mailing list