/** * Convert a protobuf byte array into a Libp2pRecord * @param in the byte array * @param in_size the size of the byte array * @param out a pointer to the new Libp2pRecord * @returns true(1) on success, otherwise false(0) */ int libp2p_record_protobuf_decode(const unsigned char* in, size_t in_size, struct Libp2pRecord** out) { size_t pos = 0; int retVal = 0; if ( (*out = libp2p_record_new()) == NULL) goto exit; while(pos < in_size) { size_t bytes_read = 0; int field_no; enum WireType field_type; if (!protobuf_decode_field_and_type(&in[pos], in_size, &field_no, &field_type, &bytes_read)) { goto exit; } pos += bytes_read; switch(field_no) { case (1): // key if (!protobuf_decode_string(&in[pos], in_size - pos, (char**)&((*out)->key), &bytes_read)) goto exit; (*out)->key_size = strlen((*out)->key); pos += bytes_read; break; case (2): // value if (!protobuf_decode_length_delimited(&in[pos], in_size - pos, (char**)&((*out)->value), &((*out)->value_size), &bytes_read)) goto exit; pos += bytes_read; break; case (3): // author if (!protobuf_decode_length_delimited(&in[pos], in_size - pos, (char**)&((*out)->author), &((*out)->author_size), &bytes_read)) goto exit; pos += bytes_read; break; case (4): // signature if (!protobuf_decode_length_delimited(&in[pos], in_size - pos, (char**)&((*out)->signature), &((*out)->signature_size), &bytes_read)) goto exit; pos += bytes_read; break; case (5): // time if (!protobuf_decode_length_delimited(&in[pos], in_size - pos, (char**)&((*out)->time_received), &((*out)->time_received_size), &bytes_read)) goto exit; pos += bytes_read; break; } } retVal = 1; exit: if (retVal == 0) { free(*out); *out = NULL; } return retVal; }
int ipfs_cid_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct Cid** output) { // short cut for nulls if (buffer_length == 0) { *output = NULL; return 1; } size_t pos = 0; int version = 0; unsigned char* hash; size_t hash_length; char codec = 0; int retVal = 0; while(pos < buffer_length) { size_t bytes_read = 0; int field_no; enum WireType field_type; if (protobuf_decode_field_and_type(&buffer[pos], buffer_length, &field_no, &field_type, &bytes_read) == 0) { return 0; } pos += bytes_read; switch(field_no) { case (1): version = varint_decode(&buffer[pos], buffer_length - pos, &bytes_read); pos += bytes_read; break; case (2): codec = varint_decode(&buffer[pos], buffer_length - pos, &bytes_read); pos += bytes_read; break; case (3): retVal = protobuf_decode_length_delimited(&buffer[pos], buffer_length - pos, (char**)&hash, &hash_length, &bytes_read); if (retVal == 0) return 0; pos += bytes_read; break; } } retVal = ipfs_cid_new(version, hash, hash_length, codec, output); free(hash); return retVal; }
/*** * Decode a buffer into a struct * @param buffer the incoming buffer * @param buffer_length the length of the buffer * @param output the resultant struct * @returns true(1) on success */ int Test2_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct Test2** output) { int pos = 0; if (Test2_new(output) == 0) return 0; while (pos < buffer_length) { // loop through buffer size_t bytes_read; int field_no; enum WireType field_type; protobuf_decode_field_and_type(&buffer[pos], buffer_length - pos, &field_no, &field_type, &bytes_read); pos += bytes_read; bytes_read = 0; switch(field_no) { case 1: protobuf_decode_string(&buffer[pos], buffer_length - pos, &((*output)->a), &bytes_read); break; } pos += bytes_read; } return 1; }