aboutsummaryrefslogtreecommitdiff
path: root/php/ext/google/protobuf/def.c
diff options
context:
space:
mode:
Diffstat (limited to 'php/ext/google/protobuf/def.c')
-rw-r--r--php/ext/google/protobuf/def.c117
1 files changed, 62 insertions, 55 deletions
diff --git a/php/ext/google/protobuf/def.c b/php/ext/google/protobuf/def.c
index db6aec701..b14f59164 100644
--- a/php/ext/google/protobuf/def.c
+++ b/php/ext/google/protobuf/def.c
@@ -789,47 +789,44 @@ static bool is_reserved(const char *segment, int length) {
return result;
}
-static char* fill_prefix(const char *segment, int length,
- const char *prefix_given,
- const char *package_name, char *classname) {
+static void fill_prefix(const char *segment, int length,
+ const char *prefix_given,
+ const char *package_name,
+ stringsink *classname) {
size_t i;
if (prefix_given != NULL && strcmp(prefix_given, "") != 0) {
- size_t prefix_len = strlen(prefix_given);
- memcpy(classname, prefix_given, strlen(prefix_given));
- classname += prefix_len;
+ stringsink_string(classname, NULL, prefix_given,
+ strlen(prefix_given), NULL);
} else {
if (is_reserved(segment, length)) {
if (package_name != NULL &&
strcmp("google.protobuf", package_name) == 0) {
- memcpy(classname, "GPB", 3);
- classname += 3;
+ stringsink_string(classname, NULL, "GPB", 3, NULL);
} else {
- memcpy(classname, "PB", 2);
- classname += 2;
+ stringsink_string(classname, NULL, "PB", 2, NULL);
}
}
}
- return classname;
}
-static char* fill_segment(const char *segment, int length,
- char *classname, bool use_camel) {
- memcpy(classname, segment, length);
+static void fill_segment(const char *segment, int length,
+ stringsink *classname, bool use_camel) {
if (use_camel && (segment[0] < 'A' || segment[0] > 'Z')) {
- classname[0] += 'A' - 'a';
+ char first = segment[0] + ('A' - 'a');
+ stringsink_string(classname, NULL, &first, 1, NULL);
+ stringsink_string(classname, NULL, segment + 1, length - 1, NULL);
+ } else {
+ stringsink_string(classname, NULL, segment, length, NULL);
}
- return classname + length;
}
-static char* fill_namespace(const char *package, const char *namespace_given,
- char *classname) {
+static void fill_namespace(const char *package, const char *namespace_given,
+ stringsink *classname) {
if (namespace_given != NULL) {
- size_t namespace_len = strlen(namespace_given);
- memcpy(classname, namespace_given, namespace_len);
- classname += namespace_len;
- *classname = '\\';
- classname++;
+ stringsink_string(classname, NULL, namespace_given,
+ strlen(namespace_given), NULL);
+ stringsink_string(classname, NULL, "\\", 1, NULL);
} else if (package != NULL) {
int i = 0, j, offset = 0;
size_t package_len = strlen(package);
@@ -838,29 +835,27 @@ static char* fill_namespace(const char *package, const char *namespace_given,
while (j < package_len && package[j] != '.') {
j++;
}
- classname = fill_prefix(package + i, j - i, "", package, classname);
- classname = fill_segment(package + i, j - i, classname, true);
- classname[0] = '\\';
- classname++;
+ fill_prefix(package + i, j - i, "", package, classname);
+ fill_segment(package + i, j - i, classname, true);
+ stringsink_string(classname, NULL, "\\", 1, NULL);
i = j + 1;
}
}
- return classname;
}
-static char* fill_classname(const char *fullname,
- const char *package,
- const char *namespace_given,
- const char *prefix, char *classname) {
+static void fill_classname(const char *fullname,
+ const char *package,
+ const char *namespace_given,
+ const char *prefix,
+ stringsink *classname,
+ bool use_nested_submsg) {
int classname_start = 0;
if (package != NULL) {
size_t package_len = strlen(package);
classname_start = package_len == 0 ? 0 : package_len + 1;
}
size_t fullname_len = strlen(fullname);
- classname = fill_prefix(fullname + classname_start,
- fullname_len - classname_start,
- prefix, package, classname);
+ bool is_first_segment = true;
int i = classname_start, j;
while (i < fullname_len) {
@@ -868,22 +863,31 @@ static char* fill_classname(const char *fullname,
while (j < fullname_len && fullname[j] != '.') {
j++;
}
- classname = fill_segment(fullname + i, j - i, classname, false);
+ if (use_nested_submsg || is_first_segment && j == fullname_len) {
+ fill_prefix(fullname + i, j - i, prefix, package, classname);
+ }
+ is_first_segment = false;
+ fill_segment(fullname + i, j - i, classname, false);
if (j != fullname_len) {
- *classname = '_';
- classname++;
+ if (use_nested_submsg) {
+ stringsink_string(classname, NULL, "\\", 1, NULL);
+ } else {
+ stringsink_string(classname, NULL, "_", 1, NULL);
+ }
}
i = j + 1;
}
- return classname;
}
-static char* fill_qualified_classname(const char *fullname,
- const char *package,
- const char *namespace_given,
- const char *prefix, char *classname) {
- classname = fill_namespace(package, namespace_given, classname);
- return fill_classname(fullname, package, namespace_given, prefix, classname);
+static void fill_qualified_classname(const char *fullname,
+ const char *package,
+ const char *namespace_given,
+ const char *prefix,
+ stringsink *classname,
+ bool use_nested_submsg) {
+ fill_namespace(package, namespace_given, classname);
+ fill_classname(fullname, package, namespace_given, prefix,
+ classname, use_nested_submsg);
}
static void classname_no_prefix(const char *fullname, const char *package_name,
@@ -905,7 +909,8 @@ static void classname_no_prefix(const char *fullname, const char *package_name,
}
void internal_add_generated_file(const char *data, PHP_PROTO_SIZE data_len,
- InternalDescriptorPool *pool TSRMLS_DC) {
+ InternalDescriptorPool *pool,
+ bool use_nested_submsg TSRMLS_DC) {
upb_filedef **files;
size_t i;
@@ -946,16 +951,15 @@ void internal_add_generated_file(const char *data, PHP_PROTO_SIZE data_len,
const char *package = upb_filedef_package(files[0]); \
const char *php_namespace = upb_filedef_phpnamespace(files[0]); \
const char *prefix_given = upb_filedef_phpprefix(files[0]); \
- size_t classname_len = classname_len_max(fullname, package, \
- php_namespace, prefix_given); \
- char *classname = ecalloc(sizeof(char), classname_len); \
+ stringsink namesink; \
+ stringsink_init(&namesink); \
fill_qualified_classname(fullname, package, php_namespace, \
- prefix_given, classname); \
+ prefix_given, &namesink, use_nested_submsg); \
PHP_PROTO_CE_DECLARE pce; \
- if (php_proto_zend_lookup_class(classname, strlen(classname), &pce) == \
+ if (php_proto_zend_lookup_class(namesink.ptr, namesink.len, &pce) == \
FAILURE) { \
zend_error(E_ERROR, "Generated message class %s hasn't been defined", \
- classname); \
+ namesink.ptr); \
return; \
} else { \
desc->klass = PHP_PROTO_CE_UNREF(pce); \
@@ -963,7 +967,7 @@ void internal_add_generated_file(const char *data, PHP_PROTO_SIZE data_len,
add_ce_obj(desc->klass, desc_php); \
add_proto_obj(upb_##def_type_lower##_fullname(desc->def_type_lower), \
desc_php); \
- efree(classname); \
+ stringsink_uninit(&namesink); \
break; \
}
@@ -993,15 +997,18 @@ PHP_METHOD(InternalDescriptorPool, internalAddGeneratedFile) {
char *data = NULL;
PHP_PROTO_SIZE data_len;
upb_filedef **files;
+ zend_bool use_nested_submsg = false;
size_t i;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data, &data_len) ==
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b",
+ &data, &data_len, &use_nested_submsg) ==
FAILURE) {
return;
}
InternalDescriptorPool *pool = UNBOX(InternalDescriptorPool, getThis());
- internal_add_generated_file(data, data_len, pool TSRMLS_CC);
+ internal_add_generated_file(data, data_len, pool,
+ use_nested_submsg TSRMLS_CC);
}
PHP_METHOD(DescriptorPool, getDescriptorByClassName) {