Created
August 22, 2019 09:57
-
-
Save vpetrigo/df85bbb8197e3be76f644bb8290444c4 to your computer and use it in GitHub Desktop.
Pack repeated fields with Nanopb library
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <pb_decode.h> | |
#include <pb_encode.h> | |
#include <stdbool.h> | |
#include <stddef.h> | |
#include <stdio.h> | |
#include "Test.pb.h" | |
bool str_encode(pb_ostream_t *stream, const pb_field_t *field, | |
void *const *arg) { | |
const char *str = *arg; | |
if (!pb_encode_tag_for_field(stream, field)) { | |
return false; | |
} | |
return pb_encode_string(stream, (unsigned char *)str, strlen(str)); | |
} | |
struct repeated { | |
void **repeated_f; | |
int index; | |
size_t max_size; | |
}; | |
bool req_encode(pb_ostream_t *stream, const pb_field_t *field, | |
void *const *arg) { | |
struct repeated *req = *arg; | |
while (req->index < req->max_size) { | |
SearchRequest *sreq = ((SearchRequest **)req->repeated_f)[req->index]; | |
printf("%s: Try to encode: %s\n", __func__, sreq->query.arg); | |
++req->index; | |
if (!pb_encode_tag(stream, PB_WT_STRING, field->tag)) { | |
return false; | |
} | |
if (!pb_encode_submessage(stream, SearchRequest_fields, sreq)) { | |
return false; | |
} | |
} | |
return true; | |
} | |
int main(void) { | |
const char *str1 = "Hello"; | |
const char *str2 = "World"; | |
unsigned char buffer[128]; | |
size_t message_length; | |
bool status; | |
Result result_msg = Result_init_default; | |
pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof buffer); | |
SearchRequest first = { | |
.query = {.funcs = {.encode = str_encode}, .arg = str1}}; | |
SearchRequest second = { | |
.query = {.funcs = {.encode = str_encode}, .arg = str2}}; | |
SearchRequest *requests[] = {&first, &second}; | |
struct repeated r1 = {.repeated_f = requests, .index = 0, .max_size = 2}; | |
result_msg.requests.funcs.encode = req_encode; | |
result_msg.requests.arg = &r1; | |
status = pb_encode(&stream, Result_fields, &result_msg); | |
message_length = stream.bytes_written; | |
if (!status) { | |
printf("Encoding failed: %s\n", PB_GET_ERROR(&stream)); | |
return -1; | |
} | |
printf("Success: %zu written\n", message_length); | |
for (size_t i = 0; i < message_length; ++i) { | |
printf("%02hhx", buffer[i]); | |
} | |
puts(""); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
syntax = "proto3"; | |
message SearchRequest { | |
string query = 1; | |
} | |
message Result { | |
repeated SearchRequest requests = 1; | |
} |
@vpetrigo Hello. I can tell, the snippet above was very helpful for me.
due to your example I was able to pack and unpack something more complex. Thanks!
Thanks a lot for the snippet!!! it was very helpful for me.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@ssevans87 would you tell whether snippet above was helpful?