Commit 1d1ad931 authored by lahiker42@gmail.com's avatar lahiker42@gmail.com

Add protobuf_c_message_check()


git-svn-id: https://protobuf-c.googlecode.com/svn/trunk@332 00440858-1255-0410-a3e6-75ea37f81c3a
parent 925c5675
......@@ -1007,6 +1007,7 @@ repeated_field_pack (const ProtobufCFieldDescriptor *field,
}
else
{
// not "packed" cased
/* CONSIDER: optimize this case a bit (by putting the loop inside the switch) */
size_t rv = 0;
unsigned siz = sizeof_elt_in_repeated_array (field->type);
......@@ -2503,6 +2504,56 @@ protobuf_c_message_init (const ProtobufCMessageDescriptor *descriptor,
descriptor->message_init((ProtobufCMessage*) (message));
}
protobuf_c_boolean protobuf_c_message_check (const ProtobufCMessage *message)
{
unsigned f;
for (f = 0; f < message->descriptor->n_fields; f++)
{
ProtobufCType type = message->descriptor->fields[f].type;
ProtobufCLabel label = message->descriptor->fields[f].label;
if (type == PROTOBUF_C_TYPE_MESSAGE)
{
unsigned offset = message->descriptor->fields[f].offset;
if (label == PROTOBUF_C_LABEL_REQUIRED)
{
ProtobufCMessage *sub = * (ProtobufCMessage**) ((char*)message + offset);
if (sub == NULL)
return FALSE;
if (!protobuf_c_message_check(sub))
return FALSE;
}
else if (label == PROTOBUF_C_LABEL_OPTIONAL)
{
ProtobufCMessage *sub = * (ProtobufCMessage**) ((char*)message + offset);
if (sub != NULL && !protobuf_c_message_check(sub))
return FALSE;
}
else if (label == PROTOBUF_C_LABEL_REPEATED)
{
unsigned n = * (unsigned *) ((char*)message + message->descriptor->fields[f].quantifier_offset);
ProtobufCMessage **subs = * (ProtobufCMessage***) ((char*)message + offset);
unsigned i;
for (i = 0; i < n; i++)
if (!protobuf_c_message_check (subs[i]))
return FALSE;
}
}
else if (type == PROTOBUF_C_TYPE_STRING)
{
if (label == PROTOBUF_C_LABEL_REQUIRED)
{
char *str = * (char **) ((char*)message + message->descriptor->fields[f].offset);
if (str == NULL)
return FALSE;
}
}
}
return TRUE;
}
/* === services === */
typedef void (*GenericHandler)(void *service,
const ProtobufCMessage *input,
......
......@@ -388,6 +388,9 @@ PROTOBUF_C_API ProtobufCMessage *
PROTOBUF_C_API void protobuf_c_message_free_unpacked (ProtobufCMessage *message,
ProtobufCAllocator *allocator);
PROTOBUF_C_API protobuf_c_boolean
protobuf_c_message_check (const ProtobufCMessage *message);
/* WARNING: 'message' must be a block of memory
of size descriptor->sizeof_message. */
PROTOBUF_C_API void protobuf_c_message_init (const ProtobufCMessageDescriptor *,
......@@ -493,7 +496,15 @@ struct _ProtobufCBufferSimple
do { if ((simp_buf)->must_free_data) \
protobuf_c_default_allocator.free (&protobuf_c_default_allocator.allocator_data, (simp_buf)->data); } while (0)
#ifdef PROTOBUF_C_PLEASE_INCLUDE_CTYPE
// This type is meant to reduce duplicated logic between
// various iterators. It tells what type to expect at
// the "offset" within the message (or, for repeated fields,
// the contents of the buffer.)
//
// Because the names are confusing, and because this mechanism tends to be
// seldom used, you have to specifically request
// this API via #define PROTOBUF_C_PLEASE_INCLUDE_CTYPE.
typedef enum
{
PROTOBUF_C_CTYPE_INT32,
......@@ -507,11 +518,12 @@ typedef enum
PROTOBUF_C_CTYPE_STRING,
PROTOBUF_C_CTYPE_BYTES,
PROTOBUF_C_CTYPE_MESSAGE,
} ProtobufCCType;
} ProtobufC_CType;
extern ProtobufCCType protobuf_c_type_to_ctype (ProtobufCType type);
extern ProtobufC_CType protobuf_c_type_to_ctype (ProtobufCType type);
#define protobuf_c_type_to_ctype(type) \
((ProtobufCCType)(protobuf_c_type_to_ctype_array[(type)]))
((ProtobufC_CType)(protobuf_c_type_to_ctype_array[(type)]))
#endif
/* ====== private ====== */
#include "protobuf-c-private.h"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment