mirror of
https://github.com/protobuf-c/protobuf-c.git
synced 2024-12-27 13:31:02 +08:00
protoc-c: add string as bytes option
Allows treating proto strings as ProtobufCBinaryData to work around limitations such as NULL characters in strings, which are allowed in protobuf, but not allowed in 'char *' types. Fixes #203
This commit is contained in:
parent
6962695641
commit
cebe3d03f9
@ -67,6 +67,8 @@ extend google.protobuf.MessageOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message ProtobufCFieldOptions {
|
message ProtobufCFieldOptions {
|
||||||
|
// Treat string as bytes in generated code
|
||||||
|
optional bool string_as_bytes = 1 [default = false];
|
||||||
}
|
}
|
||||||
|
|
||||||
extend google.protobuf.FieldOptions {
|
extend google.protobuf.FieldOptions {
|
||||||
|
@ -203,11 +203,15 @@ FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field) {
|
FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field) {
|
||||||
|
const ProtobufCFieldOptions opt = field->options().GetExtension(pb_c_field);
|
||||||
switch (field->type()) {
|
switch (field->type()) {
|
||||||
case FieldDescriptor::TYPE_MESSAGE:
|
case FieldDescriptor::TYPE_MESSAGE:
|
||||||
return new MessageFieldGenerator(field);
|
return new MessageFieldGenerator(field);
|
||||||
case FieldDescriptor::TYPE_STRING:
|
case FieldDescriptor::TYPE_STRING:
|
||||||
return new StringFieldGenerator(field);
|
if (opt.string_as_bytes())
|
||||||
|
return new BytesFieldGenerator(field);
|
||||||
|
else
|
||||||
|
return new StringFieldGenerator(field);
|
||||||
case FieldDescriptor::TYPE_BYTES:
|
case FieldDescriptor::TYPE_BYTES:
|
||||||
return new BytesFieldGenerator(field);
|
return new BytesFieldGenerator(field);
|
||||||
case FieldDescriptor::TYPE_ENUM:
|
case FieldDescriptor::TYPE_ENUM:
|
||||||
|
@ -463,6 +463,7 @@ GenerateMessageDescriptor(io::Printer* printer, bool gen_init) {
|
|||||||
|
|
||||||
for (int i = 0; i < descriptor_->field_count(); i++) {
|
for (int i = 0; i < descriptor_->field_count(); i++) {
|
||||||
const FieldDescriptor *fd = descriptor_->field(i);
|
const FieldDescriptor *fd = descriptor_->field(i);
|
||||||
|
const ProtobufCFieldOptions opt = fd->options().GetExtension(pb_c_field);
|
||||||
if (fd->has_default_value()) {
|
if (fd->has_default_value()) {
|
||||||
|
|
||||||
bool already_defined = false;
|
bool already_defined = false;
|
||||||
@ -501,7 +502,7 @@ GenerateMessageDescriptor(io::Printer* printer, bool gen_init) {
|
|||||||
GOOGLE_LOG(DFATAL) << "Messages can't have default values!";
|
GOOGLE_LOG(DFATAL) << "Messages can't have default values!";
|
||||||
break;
|
break;
|
||||||
case FieldDescriptor::CPPTYPE_STRING:
|
case FieldDescriptor::CPPTYPE_STRING:
|
||||||
if (fd->type() == FieldDescriptor::TYPE_BYTES)
|
if (fd->type() == FieldDescriptor::TYPE_BYTES || opt.string_as_bytes())
|
||||||
{
|
{
|
||||||
vars["field_dv_ctype"] = "ProtobufCBinaryData";
|
vars["field_dv_ctype"] = "ProtobufCBinaryData";
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,8 @@ message SubMess {
|
|||||||
repeated int32 rep = 4;
|
repeated int32 rep = 4;
|
||||||
optional bytes bytes1 = 2 [default = "a \0 char"];
|
optional bytes bytes1 = 2 [default = "a \0 char"];
|
||||||
optional string str1 = 3 [default = "hello world\n"];
|
optional string str1 = 3 [default = "hello world\n"];
|
||||||
|
optional string str2 = 5 [default = "hello\0world\n",
|
||||||
|
(pb_c_field).string_as_bytes = true];
|
||||||
}
|
}
|
||||||
optional SubSubMess sub1 = 9;
|
optional SubSubMess sub1 = 9;
|
||||||
optional SubSubMess sub2 = 10;
|
optional SubSubMess sub2 = 10;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user