bool checkreturn pb_encode_tag_for_field(pb_ostream_t *stream, const pb_field_t *field) { pb_wire_type_t wiretype; switch (PB_LTYPE(field->type)) { case PB_LTYPE_VARINT: case PB_LTYPE_UVARINT: case PB_LTYPE_SVARINT: wiretype = PB_WT_VARINT; break; case PB_LTYPE_FIXED32: wiretype = PB_WT_32BIT; break; case PB_LTYPE_FIXED64: wiretype = PB_WT_64BIT; break; case PB_LTYPE_BYTES: case PB_LTYPE_STRING: case PB_LTYPE_SUBMESSAGE: wiretype = PB_WT_STRING; break; default: PB_RETURN_ERROR(stream, "invalid field type"); } return pb_encode_tag(stream, wiretype, field->tag); }
void encode(thinger_message& message){ if(message.get_stream_id()!=0){ pb_encode_varint(thinger_message::STREAM_ID, message.get_stream_id()); } if(message.get_signal_flag()!=thinger_message::NONE){ pb_encode_varint(thinger_message::SIGNAL_FLAG, message.get_signal_flag()); } if(message.has_resource()){ pb_encode_tag(protoson::pson_type, thinger_message::RESOURCE); protoson::pson_encoder::encode(message.get_resources()); } if(message.has_data()){ pb_encode_tag(protoson::pson_type, thinger_message::PSON_PAYLOAD); protoson::pson_encoder::encode((protoson::pson&) message); } }
/* Encode field header based on LTYPE and field number defined in the field structure. * Call this from the callback before writing out field contents. */ static int pb_encode_tag_for_field(pb_ostream_t *stream, const pc_JSON *field) { /* type,tag */ int wiretype; pc_JSON *type = pc_JSON_GetObjectItem(field, "type"); pc_JSON *tag = pc_JSON_GetObjectItem(field, "tag"); wiretype = pb_get_constant_type(type->valuestring); return pb_encode_tag(stream, wiretype, (uint32_t)tag->valueint); }
/* Encode field header based on LTYPE and field number defined in the field structure. * Call this from the callback before writing out field contents. */ static int checkreturn pb_encode_tag_for_field(pb_ostream_t *stream, const json_t *field) { // type,tag int wiretype; json_t *type = json_object_get(field, "type"); json_t *tag = json_object_get(field, "tag"); wiretype = pb__get_constant_type(json_string_value(type)); return pb_encode_tag(stream, wiretype, json_number_value(tag)); }
static bool write_repeated_fixed64(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) { uint64_t dummy = 0; /* Make it a packed field */ return pb_encode_tag(stream, PB_WT_STRING, field->tag) && pb_encode_varint(stream, 5 * 8) && /* Number of bytes */ pb_encode_fixed64(stream, &dummy) && pb_encode_fixed64(stream, &dummy) && pb_encode_fixed64(stream, &dummy) && pb_encode_fixed64(stream, &dummy) && pb_encode_fixed64(stream, *arg); }
/* Encode a static array. Handles the size calculations and possible packing. */ static bool checkreturn encode_array(pb_ostream_t *stream, const pb_field_t *field, const void *pData, size_t count, pb_encoder_t func) { size_t i; const void *p; size_t size; if (count == 0) return true; if (PB_ATYPE(field->type) != PB_ATYPE_POINTER && count > field->array_size) PB_RETURN_ERROR(stream, "array max size exceeded"); /* We always pack arrays if the datatype allows it. */ if (PB_LTYPE(field->type) <= PB_LTYPE_LAST_PACKABLE) { if (!pb_encode_tag(stream, PB_WT_STRING, field->tag)) return false; /* Determine the total size of packed array. */ if (PB_LTYPE(field->type) == PB_LTYPE_FIXED32) { size = 4 * count; } else if (PB_LTYPE(field->type) == PB_LTYPE_FIXED64) { size = 8 * count; } else { pb_ostream_t sizestream = PB_OSTREAM_SIZING; p = pData; for (i = 0; i < count; i++) { if (!func(&sizestream, field, p)) return false; p = (const char*)p + field->data_size; } size = sizestream.bytes_written; } if (!pb_encode_varint(stream, (uint64_t)size)) return false; if (stream->callback == NULL) return pb_write(stream, NULL, size); /* Just sizing.. */ /* Write the data */ p = pData; for (i = 0; i < count; i++) { if (!func(stream, field, p)) return false; p = (const char*)p + field->data_size; } } else { p = pData; for (i = 0; i < count; i++) { if (!pb_encode_tag_for_field(stream, field)) return false; /* Normally the data is stored directly in the array entries, but * for pointer-type string and bytes fields, the array entries are * actually pointers themselves also. So we have to dereference once * more to get to the actual data. */ if (PB_ATYPE(field->type) == PB_ATYPE_POINTER && (PB_LTYPE(field->type) == PB_LTYPE_STRING || PB_LTYPE(field->type) == PB_LTYPE_BYTES)) { if (!func(stream, field, *(const void* const*)p)) return false; } else { if (!func(stream, field, p)) return false; } p = (const char*)p + field->data_size; } } return true; }
/* Callbacks don't need this function because they usually know the data type * without examining the field structure. * Therefore it is static for now. */ static bool checkreturn encode_array(pb_ostream_t *stream, const pb_field_t *field, const void *pData, size_t count, pb_encoder_t func) { size_t i; const void *p; size_t size; if (count == 0) return true; if (PB_LTYPE(field->type) <= PB_LTYPE_LAST_PACKABLE) { if (!pb_encode_tag(stream, PB_WT_STRING, field->tag)) return false; /* Determine the total size of packed array. */ if (PB_LTYPE(field->type) == PB_LTYPE_FIXED32) { size = 4 * count; } else if (PB_LTYPE(field->type) == PB_LTYPE_FIXED64) { size = 8 * count; } else { pb_ostream_t sizestream = {0,0,0,0}; p = pData; for (i = 0; i < count; i++) { if (!func(&sizestream, field, p)) return false; p = (const char*)p + field->data_size; } size = sizestream.bytes_written; } if (!pb_encode_varint(stream, (uint64_t)size)) return false; if (stream->callback == NULL) return pb_write(stream, NULL, size); /* Just sizing.. */ /* Write the data */ p = pData; for (i = 0; i < count; i++) { if (!func(stream, field, p)) return false; p = (const char*)p + field->data_size; } } else { p = pData; for (i = 0; i < count; i++) { if (!pb_encode_tag_for_field(stream, field)) return false; if (!func(stream, field, p)) return false; p = (const char*)p + field->data_size; } } return true; }