Enhance c-capnproto to support user provided string duplication function #1

Closed
opened 2025-10-31 16:42:07 +08:00 by rshen · 3 comments
Owner

Currently, strdup() has been used to make a copy of decoded string, it seems that we need to support user provided string duplication function for possible of performance improvement

Rongsong

Currently, strdup() has been used to make a copy of decoded string, it seems that we need to support user provided string duplication function for possible of performance improvement Rongsong
Author
Owner
diff --git a/compiler/capnpc-c.c b/compiler/capnpc-c.c
index c8eb6f4..6e95212 100644
--- a/compiler/capnpc-c.c
+++ b/compiler/capnpc-c.c
@@ -903,7 +903,7 @@ static void mk_simple_list_decoder(struct str *func, const char *tab,
              "\t\t\tcapn_text text_ = capn_get_text(s->%s, i_, capn_val0);\n",
              svar);
     str_add(func, tab, -1);
-    str_addf(func, "\t\t\td->%s[i_] = strdup(text_.str);\n", dvar);
+    str_addf(func, "\t\t\td->%s[i_] = STRING_DUP(text_.str);\n", dvar);
     str_add(func, tab, -1);
     str_addf(func, "\t\t}\n");
     str_add(func, tab, -1);
@@ -1276,7 +1276,7 @@ static void decode_member(capnp_ctx_t *ctx, struct str *func, struct field *f,
     break;
   case Type_text:
     str_add(func, tab, -1);
-    str_addf(func, "d->%s = strdup(s->%s.str);\n", var2, var);
+    str_addf(func, "d->%s = STRING_DUP(s->%s.str);\n", var2, var);
     break;
   case Type__struct:
     n = find_node(ctx, f->v.t._struct.typeId);
@@ -2675,6 +2675,11 @@ int ctx_gen(capnp_ctx_t *ctx) {
     }
     str_addf(&(ctx->HDR), "\n");
 
+    str_addf(&(ctx->HDR),
+             "#ifndef STRING_DUP\n"
+             "#define STRING_DUP strdup\n"
+             "#endif\n\n");
+    
     str_addf(&(ctx->HDR), "#if CAPN_VERSION != 1\n");
     str_addf(
         &(ctx->HDR),

The generated code looks like:

.h file:

#ifndef STRING_DUP
#define STRING_DUP strdup
#endif

.h file


}

void decode_Chapter(chapter_t *d, struct Chapter *s) {
	d->caption = STRING_DUP(s->caption.str);
	d->start = s->start;
	d->end = s->end;

}
--

}

void decode_Buy(buy_t *d, struct Buy *s) {
	d->from = STRING_DUP(s->from.str);
	d->with_recipe = s->u_which;
	switch (s->u_which) {
	case Buy_u_recipeAddr:
		d->u.recipe_addr = STRING_DUP(s->u.recipeAddr.str);
		break;
	default:
		break;
	}
--

}

void decode_Book(book_t *d, struct Book *s) {
	d->title = STRING_DUP(s->title.str);
		if (1) {
		int i_, nc_;
		capn_resolve(&(s->authors));
		nc_ = s->authors.len;
--
		else {
			d->authors = (char **)calloc(nc_, sizeof(char *));
			for(i_ = 0; i_ < nc_; i_ ++) {
				capn_text text_ = capn_get_text(s->authors, i_, capn_val0);
				d->authors[i_] = STRING_DUP(text_.str);
			}
		}
	d->n_authors = nc_;
	}
--
			}
		}
	d->n_magic1 = nc_;
	}
	d->description = STRING_DUP(s->description.str);
	d->acquire_method = s->acquire_which;
	switch (s->acquire_which) {
	case Book_acquire_donation:
		d->acquire.donation = STRING_DUP(s->acquire.donation.str);
		break;
	case Book_acquire_buy:
		decode_Buy_ptr(&(d->acquire.buy), s->acquire.buy);
		break;

```diff diff --git a/compiler/capnpc-c.c b/compiler/capnpc-c.c index c8eb6f4..6e95212 100644 --- a/compiler/capnpc-c.c +++ b/compiler/capnpc-c.c @@ -903,7 +903,7 @@ static void mk_simple_list_decoder(struct str *func, const char *tab, "\t\t\tcapn_text text_ = capn_get_text(s->%s, i_, capn_val0);\n", svar); str_add(func, tab, -1); - str_addf(func, "\t\t\td->%s[i_] = strdup(text_.str);\n", dvar); + str_addf(func, "\t\t\td->%s[i_] = STRING_DUP(text_.str);\n", dvar); str_add(func, tab, -1); str_addf(func, "\t\t}\n"); str_add(func, tab, -1); @@ -1276,7 +1276,7 @@ static void decode_member(capnp_ctx_t *ctx, struct str *func, struct field *f, break; case Type_text: str_add(func, tab, -1); - str_addf(func, "d->%s = strdup(s->%s.str);\n", var2, var); + str_addf(func, "d->%s = STRING_DUP(s->%s.str);\n", var2, var); break; case Type__struct: n = find_node(ctx, f->v.t._struct.typeId); @@ -2675,6 +2675,11 @@ int ctx_gen(capnp_ctx_t *ctx) { } str_addf(&(ctx->HDR), "\n"); + str_addf(&(ctx->HDR), + "#ifndef STRING_DUP\n" + "#define STRING_DUP strdup\n" + "#endif\n\n"); + str_addf(&(ctx->HDR), "#if CAPN_VERSION != 1\n"); str_addf( &(ctx->HDR), ``` The generated code looks like: .h file: ```c #ifndef STRING_DUP #define STRING_DUP strdup #endif ``` .h file ```c } void decode_Chapter(chapter_t *d, struct Chapter *s) { d->caption = STRING_DUP(s->caption.str); d->start = s->start; d->end = s->end; } -- } void decode_Buy(buy_t *d, struct Buy *s) { d->from = STRING_DUP(s->from.str); d->with_recipe = s->u_which; switch (s->u_which) { case Buy_u_recipeAddr: d->u.recipe_addr = STRING_DUP(s->u.recipeAddr.str); break; default: break; } -- } void decode_Book(book_t *d, struct Book *s) { d->title = STRING_DUP(s->title.str); if (1) { int i_, nc_; capn_resolve(&(s->authors)); nc_ = s->authors.len; -- else { d->authors = (char **)calloc(nc_, sizeof(char *)); for(i_ = 0; i_ < nc_; i_ ++) { capn_text text_ = capn_get_text(s->authors, i_, capn_val0); d->authors[i_] = STRING_DUP(text_.str); } } d->n_authors = nc_; } -- } } d->n_magic1 = nc_; } d->description = STRING_DUP(s->description.str); d->acquire_method = s->acquire_which; switch (s->acquire_which) { case Book_acquire_donation: d->acquire.donation = STRING_DUP(s->acquire.donation.str); break; case Book_acquire_buy: decode_Buy_ptr(&(d->acquire.buy), s->acquire.buy); break; ```
rshen self-assigned this 2025-10-31 16:45:55 +08:00
Author
Owner

code merged 368511ace7

Rongsong

code merged https://gitea.shenrs.eu/rshen/c-capnproto/commit/368511ace77cc833c6b5b1f7d225a9b87e3f4687 Rongsong
rshen closed this issue 2025-10-31 16:51:58 +08:00
Author
Owner

code also updated to github:shen390s/c-capnproto.git

Rongsong

code also updated to github:shen390s/c-capnproto.git Rongsong
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: rshen/c-capnproto#1
No description provided.