Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
protobuf-c
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
protobuf-c
Commits
453f39e6
Commit
453f39e6
authored
Nov 24, 2014
by
Robert Edmonds
Browse files
Options
Browse Files
Download
Plain Diff
Merge oneof support
parents
8f23163f
6090d9a9
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
829 additions
and
88 deletions
+829
-88
configure.ac
configure.ac
+1
-1
protobuf-c/protobuf-c.c
protobuf-c/protobuf-c.c
+262
-65
protobuf-c/protobuf-c.h
protobuf-c/protobuf-c.h
+4
-1
protoc-c/c_bytes_field.cc
protoc-c/c_bytes_field.cc
+2
-1
protoc-c/c_enum_field.cc
protoc-c/c_enum_field.cc
+2
-1
protoc-c/c_field.cc
protoc-c/c_field.cc
+9
-1
protoc-c/c_message.cc
protoc-c/c_message.cc
+52
-3
protoc-c/c_primitive_field.cc
protoc-c/c_primitive_field.cc
+2
-1
t/generated-code2/cxx-generate-packed-data.cc
t/generated-code2/cxx-generate-packed-data.cc
+112
-14
t/generated-code2/test-generated-code2.c
t/generated-code2/test-generated-code2.c
+352
-0
t/test-full.proto
t/test-full.proto
+31
-0
No files found.
configure.ac
View file @
453f39e6
...
...
@@ -47,7 +47,7 @@ AC_ARG_ENABLE([protoc],
AS_HELP_STRING([--disable-protoc], [Disable building protoc_c (also disables tests)]))
if test "x$enable_protoc" != "xno"; then
AC_LANG_PUSH([C++])
PKG_CHECK_MODULES([protobuf], [protobuf >= 2.
5
.0])
PKG_CHECK_MODULES([protobuf], [protobuf >= 2.
6
.0])
save_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$save_CPPFLAGS $protobuf_CFLAGS"
...
...
protobuf-c/protobuf-c.c
View file @
453f39e6
This diff is collapsed.
Click to expand it.
protobuf-c/protobuf-c.h
View file @
453f39e6
...
...
@@ -239,6 +239,9 @@ typedef enum {
/** Set if the field is marked with the `deprecated` option. */
PROTOBUF_C_FIELD_FLAG_DEPRECATED
=
(
1
<<
1
),
/** Set if the field is a member of a oneof (union). */
PROTOBUF_C_FIELD_FLAG_ONEOF
=
(
1
<<
2
),
}
ProtobufCFieldFlag
;
/**
...
...
@@ -545,7 +548,7 @@ struct ProtobufCFieldDescriptor {
/**
* The offset in bytes of the message's C structure's quantifier field
* (the `has_MEMBER` field for optional members or the `n_MEMBER` field
* for repeated members.
* for repeated members
or the case enum for oneofs)
.
*/
unsigned
quantifier_offset
;
...
...
protoc-c/c_bytes_field.cc
View file @
453f39e6
...
...
@@ -101,7 +101,8 @@ void BytesFieldGenerator::GenerateStructMembers(io::Printer* printer) const
printer
->
Print
(
variables_
,
"ProtobufCBinaryData $name$$deprecated$;
\n
"
);
break
;
case
FieldDescriptor
:
:
LABEL_OPTIONAL
:
printer
->
Print
(
variables_
,
"protobuf_c_boolean has_$name$$deprecated$;
\n
"
);
if
(
descriptor_
->
containing_oneof
()
==
NULL
)
printer
->
Print
(
variables_
,
"protobuf_c_boolean has_$name$$deprecated$;
\n
"
);
printer
->
Print
(
variables_
,
"ProtobufCBinaryData $name$$deprecated$;
\n
"
);
break
;
case
FieldDescriptor
:
:
LABEL_REPEATED
:
...
...
protoc-c/c_enum_field.cc
View file @
453f39e6
...
...
@@ -106,7 +106,8 @@ void EnumFieldGenerator::GenerateStructMembers(io::Printer* printer) const
printer
->
Print
(
variables_
,
"$type$ $name$$deprecated$;
\n
"
);
break
;
case
FieldDescriptor
:
:
LABEL_OPTIONAL
:
printer
->
Print
(
variables_
,
"protobuf_c_boolean has_$name$$deprecated$;
\n
"
);
if
(
descriptor_
->
containing_oneof
()
==
NULL
)
printer
->
Print
(
variables_
,
"protobuf_c_boolean has_$name$$deprecated$;
\n
"
);
printer
->
Print
(
variables_
,
"$type$ $name$$deprecated$;
\n
"
);
break
;
case
FieldDescriptor
:
:
LABEL_REPEATED
:
...
...
protoc-c/c_field.cc
View file @
453f39e6
...
...
@@ -114,6 +114,9 @@ void FieldGenerator::GenerateDescriptorInitializerGeneric(io::Printer* printer,
variables
[
"proto_name"
]
=
descriptor_
->
name
();
variables
[
"descriptor_addr"
]
=
descriptor_addr
;
variables
[
"value"
]
=
SimpleItoa
(
descriptor_
->
number
());
const
OneofDescriptor
*
oneof
=
descriptor_
->
containing_oneof
();
if
(
oneof
!=
NULL
)
variables
[
"oneofname"
]
=
FullNameToLower
(
oneof
->
name
());
if
(
descriptor_
->
has_default_value
())
{
variables
[
"default_value"
]
=
string
(
"&"
)
...
...
@@ -133,6 +136,9 @@ void FieldGenerator::GenerateDescriptorInitializerGeneric(io::Printer* printer,
if
(
descriptor_
->
options
().
deprecated
())
variables
[
"flags"
]
+=
" | PROTOBUF_C_FIELD_FLAG_DEPRECATED"
;
if
(
oneof
!=
NULL
)
variables
[
"flags"
]
+=
" | PROTOBUF_C_FIELD_FLAG_ONEOF"
;
printer
->
Print
(
variables
,
"{
\n
"
"
\"
$proto_name$
\"
,
\n
"
...
...
@@ -144,7 +150,9 @@ void FieldGenerator::GenerateDescriptorInitializerGeneric(io::Printer* printer,
printer
->
Print
(
variables
,
" 0, /* quantifier_offset */
\n
"
);
break
;
case
FieldDescriptor
:
:
LABEL_OPTIONAL
:
if
(
optional_uses_has
)
{
if
(
oneof
!=
NULL
)
{
printer
->
Print
(
variables
,
" offsetof($classname$, $oneofname$_case),
\n
"
);
}
else
if
(
optional_uses_has
)
{
printer
->
Print
(
variables
,
" offsetof($classname$, has_$name$),
\n
"
);
}
else
{
printer
->
Print
(
variables
,
" 0, /* quantifier_offset */
\n
"
);
...
...
protoc-c/c_message.cc
View file @
453f39e6
...
...
@@ -147,6 +147,25 @@ GenerateStructDefinition(io::Printer* printer) {
vars
[
"dllexport"
]
=
dllexport_decl_
+
" "
;
}
// Generate the case enums for unions
for
(
int
i
=
0
;
i
<
descriptor_
->
oneof_decl_count
();
i
++
)
{
const
OneofDescriptor
*
oneof
=
descriptor_
->
oneof_decl
(
i
);
vars
[
"oneofname"
]
=
FullNameToUpper
(
oneof
->
name
());
vars
[
"foneofname"
]
=
FullNameToC
(
oneof
->
full_name
());
printer
->
Print
(
"typedef enum {
\n
"
);
printer
->
Indent
();
printer
->
Print
(
vars
,
"$ucclassname$__$oneofname$__NOT_SET = 0,
\n
"
);
for
(
int
j
=
0
;
j
<
oneof
->
field_count
();
j
++
)
{
const
FieldDescriptor
*
field
=
oneof
->
field
(
j
);
vars
[
"fieldname"
]
=
FullNameToUpper
(
field
->
name
());
vars
[
"fieldnum"
]
=
SimpleItoa
(
field
->
number
());
printer
->
Print
(
vars
,
"$ucclassname$__$oneofname$_$fieldname$ = $fieldnum$,
\n
"
);
}
printer
->
Outdent
();
printer
->
Print
(
vars
,
"} $foneofname$Case;
\n\n
"
);
}
printer
->
Print
(
vars
,
"struct $dllexport$ _$classname$
\n
"
"{
\n
"
...
...
@@ -156,7 +175,27 @@ GenerateStructDefinition(io::Printer* printer) {
printer
->
Indent
();
for
(
int
i
=
0
;
i
<
descriptor_
->
field_count
();
i
++
)
{
const
FieldDescriptor
*
field
=
descriptor_
->
field
(
i
);
field_generators_
.
get
(
field
).
GenerateStructMembers
(
printer
);
if
(
field
->
containing_oneof
()
==
NULL
)
{
field_generators_
.
get
(
field
).
GenerateStructMembers
(
printer
);
}
}
// Generate unions from oneofs.
for
(
int
i
=
0
;
i
<
descriptor_
->
oneof_decl_count
();
i
++
)
{
const
OneofDescriptor
*
oneof
=
descriptor_
->
oneof_decl
(
i
);
vars
[
"oneofname"
]
=
FullNameToLower
(
oneof
->
name
());
vars
[
"foneofname"
]
=
FullNameToC
(
oneof
->
full_name
());
printer
->
Print
(
vars
,
"$foneofname$Case $oneofname$_case;
\n
"
);
printer
->
Print
(
"union {
\n
"
);
printer
->
Indent
();
for
(
int
j
=
0
;
j
<
oneof
->
field_count
();
j
++
)
{
const
FieldDescriptor
*
field
=
oneof
->
field
(
j
);
field_generators_
.
get
(
field
).
GenerateStructMembers
(
printer
);
}
printer
->
Outdent
();
printer
->
Print
(
vars
,
"};
\n
"
);
}
printer
->
Outdent
();
...
...
@@ -173,8 +212,18 @@ GenerateStructDefinition(io::Printer* printer) {
" { PROTOBUF_C_MESSAGE_INIT (&$lcclassname$__descriptor)
\\\n
"
);
for
(
int
i
=
0
;
i
<
descriptor_
->
field_count
();
i
++
)
{
const
FieldDescriptor
*
field
=
descriptor_
->
field
(
i
);
printer
->
Print
(
", "
);
field_generators_
.
get
(
field
).
GenerateStaticInit
(
printer
);
if
(
field
->
containing_oneof
()
==
NULL
)
{
printer
->
Print
(
", "
);
field_generators_
.
get
(
field
).
GenerateStaticInit
(
printer
);
}
}
for
(
int
i
=
0
;
i
<
descriptor_
->
oneof_decl_count
();
i
++
)
{
const
OneofDescriptor
*
oneof
=
descriptor_
->
oneof_decl
(
i
);
vars
[
"foneofname"
]
=
FullNameToUpper
(
oneof
->
full_name
());
// Initialize the case enum
printer
->
Print
(
vars
,
", $foneofname$__NOT_SET"
);
// Initialize the enum
printer
->
Print
(
", {}"
);
}
printer
->
Print
(
" }
\n\n\n
"
);
...
...
protoc-c/c_primitive_field.cc
View file @
453f39e6
...
...
@@ -113,7 +113,8 @@ void PrimitiveFieldGenerator::GenerateStructMembers(io::Printer* printer) const
printer
->
Print
(
vars
,
"$c_type$ $name$$deprecated$;
\n
"
);
break
;
case
FieldDescriptor
:
:
LABEL_OPTIONAL
:
printer
->
Print
(
vars
,
"protobuf_c_boolean has_$name$$deprecated$;
\n
"
);
if
(
descriptor_
->
containing_oneof
()
==
NULL
)
printer
->
Print
(
vars
,
"protobuf_c_boolean has_$name$$deprecated$;
\n
"
);
printer
->
Print
(
vars
,
"$c_type$ $name$$deprecated$;
\n
"
);
break
;
case
FieldDescriptor
:
:
LABEL_REPEATED
:
...
...
t/generated-code2/cxx-generate-packed-data.cc
View file @
453f39e6
...
...
@@ -36,25 +36,35 @@ using namespace foo;
#define N_ELEMENTS(arr) (sizeof(arr)/sizeof((arr)[0]))
static
void
dump_message_bytes
(
google
::
protobuf
::
Message
*
message
,
const
char
*
label
)
{
std
::
string
rv
;
unsigned
char
*
bytes
;
unsigned
len
;
if
(
!
message
->
SerializeToString
(
&
rv
))
assert
(
0
);
bytes
=
(
unsigned
char
*
)
rv
.
data
();
len
=
rv
.
size
();
printf
(
"static const uint8_t %s[%u] = { "
,
label
,
len
);
for
(
unsigned
i
=
0
;
i
<
len
;
i
++
)
{
if
(
i
)
dump_messages_bytes
(
size_t
n_msgs
,
google
::
protobuf
::
Message
**
messages
,
const
char
*
label
)
{
printf
(
"static const uint8_t %s[] = { "
,
label
);
for
(
unsigned
m
=
0
;
m
<
n_msgs
;
m
++
)
{
std
::
string
rv
;
google
::
protobuf
::
Message
*
message
=
messages
[
m
];
if
(
m
)
printf
(
", "
);
printf
(
"0x%02x"
,
bytes
[
i
]);
if
(
!
message
->
SerializeToString
(
&
rv
))
assert
(
0
);
unsigned
char
*
bytes
=
(
unsigned
char
*
)
rv
.
data
();
for
(
unsigned
i
=
0
;
i
<
rv
.
size
();
i
++
)
{
if
(
i
)
printf
(
", "
);
printf
(
"0x%02x"
,
bytes
[
i
]);
}
}
printf
(
" };
\n
"
);
}
static
void
dump_message_bytes
(
google
::
protobuf
::
Message
*
message
,
const
char
*
label
)
{
dump_messages_bytes
(
1
,
&
message
,
label
);
}
static
void
dump_test_enum_small
(
void
)
{
...
...
@@ -564,6 +574,33 @@ static void dump_test_optional_message (void)
opt
.
mutable_test_message
()
->
set_test
(
42
);
dump_message_bytes
(
&
opt
,
"test_optional_submess_42"
);
}
static
void
dump_test_oneof_merge
(
void
)
{
#define SWAP(a, b) temp = a, a = b, b = temp
google
::
protobuf
::
Message
*
temp
;
TestMessOptional
opt
[
6
];
google
::
protobuf
::
Message
*
msgs
[
6
]
=
{
&
opt
[
0
],
&
opt
[
1
],
&
opt
[
2
],
&
opt
[
3
],
&
opt
[
4
],
&
opt
[
5
]
};
opt
[
0
].
set_test_bytes
(
"hello"
);
opt
[
1
].
mutable_test_message
()
->
set_test
(
42
);
opt
[
2
].
set_test_string
(
""
);
opt
[
3
].
set_test_int32
(
666
);
opt
[
4
].
set_test_float
(
333
);
opt
[
5
].
set_test_double
(
444455555
);
dump_messages_bytes
(
6
,
msgs
,
"test_oneof_merge_double"
);
SWAP
(
msgs
[
5
],
msgs
[
4
]);
dump_messages_bytes
(
6
,
msgs
,
"test_oneof_merge_float"
);
SWAP
(
msgs
[
5
],
msgs
[
3
]);
dump_messages_bytes
(
6
,
msgs
,
"test_oneof_merge_int32"
);
SWAP
(
msgs
[
5
],
msgs
[
2
]);
dump_messages_bytes
(
6
,
msgs
,
"test_oneof_merge_string"
);
SWAP
(
msgs
[
5
],
msgs
[
1
]);
dump_messages_bytes
(
6
,
msgs
,
"test_oneof_merge_submess"
);
SWAP
(
msgs
[
5
],
msgs
[
0
]);
dump_messages_bytes
(
6
,
msgs
,
"test_oneof_merge_bytes"
);
#undef SWAP
}
#define DUMP_STATIC_ARRAY_GENERIC(member, static_array, output_array_name) \
do{ \
...
...
@@ -978,6 +1015,65 @@ static void dump_test_unknown_fields (void)
dump_message_bytes
(
&
mess
,
"test_unknown_fields_1"
);
}
static
void
dump_test_submess_merge
(
void
)
{
TestMessSubMess
mess1
,
mess2
,
merged1
,
merged2
;
/* Repeated merge */
mess1
.
mutable_rep_mess
()
->
add_test_int32
(
1
);
mess1
.
mutable_rep_mess
()
->
add_test_int32
(
2
);
mess2
.
mutable_rep_mess
()
->
add_test_int32
(
3
);
mess2
.
mutable_rep_mess
()
->
add_test_int32
(
4
);
mess1
.
mutable_rep_mess
()
->
add_test_string
(
"hello "
);
mess2
.
mutable_rep_mess
()
->
add_test_string
(
"world"
);
mess1
.
mutable_rep_mess
()
->
add_test_bytes
(
"
\001\002\003
"
);
mess2
.
mutable_rep_mess
()
->
add_test_bytes
(
"
\004\005\006
"
);
mess1
.
mutable_rep_mess
()
->
add_test_message
()
->
set_test
(
111
);
mess2
.
mutable_rep_mess
()
->
add_test_message
()
->
set_test
(
222
);
/* Optional merge */
mess1
.
mutable_opt_mess
()
->
set_test_sint32
(
-
1
);
mess2
.
mutable_opt_mess
()
->
set_test_sint32
(
-
2
);
mess1
.
mutable_opt_mess
()
->
set_test_float
(
333
);
mess2
.
mutable_opt_mess
()
->
set_test_double
(
444
);
mess1
.
mutable_opt_mess
()
->
set_test_bytes
(
"
\001\002\003
"
);
mess1
.
mutable_opt_mess
()
->
mutable_test_message
()
->
set_test
(
111
);
mess2
.
mutable_opt_mess
()
->
set_test_string
(
"hello"
);
/* Oneof merge */
mess1
.
mutable_oneof_mess
()
->
set_opt_int
(
1
);
mess2
.
mutable_oneof_mess
()
->
mutable_test_message
()
->
set_test
(
111
);
/* Required merge */
mess1
.
mutable_req_mess
()
->
set_test
(
1
);
mess2
.
mutable_req_mess
()
->
set_test
(
2
);
/* Default value merge */
mess1
.
mutable_def_mess
()
->
set_v_int32
(
111
);
mess1
.
mutable_def_mess
()
->
set_v_string
(
"hello"
);
mess2
.
mutable_def_mess
()
->
set_v_bytes
(
"
\001\002\003
"
);
mess2
.
mutable_def_mess
()
->
set_v_double
(
444
);
/* Merge both ways and encode the merged and unmerged messages */
merged1
.
CopyFrom
(
mess1
);
merged1
.
MergeFrom
(
mess2
);
merged2
.
CopyFrom
(
mess2
);
merged2
.
MergeFrom
(
mess1
);
google
::
protobuf
::
Message
*
msgs
[]
=
{
&
mess1
,
&
mess2
};
dump_messages_bytes
(
2
,
msgs
,
"test_submess_unmerged1"
);
msgs
[
0
]
=
&
mess2
;
msgs
[
1
]
=
&
mess1
;
dump_messages_bytes
(
2
,
msgs
,
"test_submess_unmerged2"
);
dump_message_bytes
(
&
merged1
,
"test_submess_merged1"
);
dump_message_bytes
(
&
merged2
,
"test_submess_merged2"
);
}
int
main
()
{
dump_test_enum_small
();
...
...
@@ -1019,6 +1115,7 @@ int main()
dump_test_optional_string
();
dump_test_optional_bytes
();
dump_test_optional_message
();
dump_test_oneof_merge
();
dump_test_repeated_int32
();
dump_test_repeated_sint32
();
dump_test_repeated_uint32
();
...
...
@@ -1053,5 +1150,6 @@ int main()
dump_test_packed_repeated_enum_small
();
dump_test_packed_repeated_enum
();
dump_test_unknown_fields
();
dump_test_submess_merge
();
return
0
;
}
t/generated-code2/test-generated-code2.c
View file @
453f39e6
This diff is collapsed.
Click to expand it.
t/test-full.proto
View file @
453f39e6
...
...
@@ -132,6 +132,30 @@ message TestMessOptional {
optional
SubMess
test_message
=
18
;
}
message
TestMessOneof
{
oneof
test_oneof
{
int32
test_int32
=
1
;
sint32
test_sint32
=
2
;
sfixed32
test_sfixed32
=
3
;
int64
test_int64
=
4
;
sint64
test_sint64
=
5
;
sfixed64
test_sfixed64
=
6
;
uint32
test_uint32
=
7
;
fixed32
test_fixed32
=
8
;
uint64
test_uint64
=
9
;
fixed64
test_fixed64
=
10
;
float
test_float
=
11
;
double
test_double
=
12
;
bool
test_boolean
=
13
;
TestEnumSmall
test_enum_small
=
14
;
TestEnum
test_enum
=
15
;
string
test_string
=
16
;
bytes
test_bytes
=
17
;
SubMess
test_message
=
18
;
}
optional
int32
opt_int
=
19
;
}
message
TestMessRequiredInt32
{
required
int32
test
=
42
;
}
...
...
@@ -379,3 +403,10 @@ message TestMessageCheck {
optional
bytes
optional_bytes
=
9
;
}
message
TestMessSubMess
{
required
TestMess
rep_mess
=
1
;
required
TestMessOptional
opt_mess
=
2
;
required
TestMessOneof
oneof_mess
=
3
;
required
SubMess
req_mess
=
4
;
required
DefaultOptionalValues
def_mess
=
5
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment