static bool write_repeated_varint(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
{
    return pb_encode_tag_for_field(stream, field) &&
           pb_encode_varint(stream, 0) &&
           pb_encode_tag_for_field(stream, field) &&
           pb_encode_varint(stream, 0) &&
           pb_encode_tag_for_field(stream, field) &&
           pb_encode_varint(stream, 0) &&
           pb_encode_tag_for_field(stream, field) &&
           pb_encode_varint(stream, 0) &&
           pb_encode_tag_for_field(stream, field) &&
           pb_encode_varint(stream, (long)*arg);
}
示例#2
0
static int checkreturn pb_encode_array(pb_ostream_t *stream, const json_t *gprotos, const json_t *protos,
                                       const json_t *proto, json_t *array) {
    json_t *type = json_object_get(proto, "type");
    const char *type_text = json_string_value(type);
    size_t len = json_array_size(array);
    size_t i;
    // simple msg
    if (pb__get_type(type_text) && pb__get_type(type_text) != PB_string) {
        if (!pb_encode_tag_for_field(stream, proto)) {
            return 0;
        }

        if (!pb_encode_varint(stream, len)) {
            return 0;
        }
        for (i = 0; i < len; i++) {
            if (!pb_encode_proto(stream, gprotos, protos, proto,
                                 json_array_get(array, i))) {
                return 0;
            }
        }
    } else {
        for (i = 0; i < len; i++) {
            if (!pb_encode_tag_for_field(stream, proto)) {
                return 0;
            }
            if (!pb_encode_proto(stream, gprotos, protos, proto,
                                 json_array_get(array, i))) {
                return 0;
            }
        }
    }
    return 1;
}
示例#3
0
/* Encode a string or bytes type field. For strings, pass strlen(s) as size. */
static int  pb_encode_string(pb_ostream_t *stream, const uint8_t *buffer,
        size_t size) {
    if (!pb_encode_varint(stream, (uint64_t) size))
        return 0;

    return pb_write(stream, buffer, size);
}
示例#4
0
static int  pb_encode_array(pb_ostream_t *stream, const pc_JSON *gprotos, const pc_JSON *protos,
        const pc_JSON *proto, pc_JSON *array) {
    pc_JSON *type = pc_JSON_GetObjectItem(proto, "type");
    const char *type_text = type->valuestring;
    size_t len = pc_JSON_GetArraySize(array);
    size_t i;
    /* simple msg */
    if (pb_get_type(type_text) && pb_get_type(type_text) != PB_string) {
        if (!pb_encode_tag_for_field(stream, proto)) {
            return 0;
        }

        if (!pb_encode_varint(stream, len)) {
            return 0;
        }
        for (i = 0; i < len; i++) {
            if (!pb_encode_proto(stream, gprotos, protos, proto,
                        pc_JSON_GetArrayItem(array, i))) {
                return 0;
            }
        }
    } else {
        for (i = 0; i < len; i++) {
            if (!pb_encode_tag_for_field(stream, proto)) {
                return 0;
            }
            if (!pb_encode_proto(stream, gprotos, protos, proto,
                        pc_JSON_GetArrayItem(array, i))) {
                return 0;
            }
        }
    }
    return 1;
}
示例#5
0
bool checkreturn pb_encode_string(pb_ostream_t *stream, const uint8_t *buffer, size_t size)
{
    if (!pb_encode_varint(stream, (uint64_t)size))
        return false;
    
    return pb_write(stream, buffer, size);
}
 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);
     }
 }
示例#7
0
/* Encode an integer in the zig-zagged svarint format.
 * This works for sint32 and sint64. */
static int  pb_encode_svarint(pb_ostream_t *stream, int64_t value) {
    uint64_t zigzagged;
    if (value < 0)
        zigzagged = (uint64_t)(~(value << 1));
    else
        zigzagged = (uint64_t)(value << 1);

    return pb_encode_varint(stream, zigzagged);
}
示例#8
0
bool checkreturn pb_encode_svarint(pb_ostream_t *stream, int64_t value)
{
    uint64_t zigzagged;
    if (value < 0)
        zigzagged = ~((uint64_t)value << 1);
    else
        zigzagged = (uint64_t)value << 1;
    
    return pb_encode_varint(stream, zigzagged);
}
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);
}
示例#10
0
static bool checkreturn pb_enc_uvarint(pb_ostream_t *stream, const pb_field_t *field, const void *src)
{
    uint64_t value = 0;
    
    switch (field->data_size)
    {
        case 4: value = *(const uint32_t*)src; break;
        case 8: value = *(const uint64_t*)src; break;
        default: PB_RETURN_ERROR(stream, "invalid data_size");
    }
    
    return pb_encode_varint(stream, value);
}
示例#11
0
bool checkreturn pb_encode_submessage(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct)
{
    /* First calculate the message size using a non-writing substream. */
    pb_ostream_t substream = PB_OSTREAM_SIZING;
    size_t size;
    bool status;
    
    if (!pb_encode(&substream, fields, src_struct))
    {
#ifndef PB_NO_ERRMSG
        stream->errmsg = substream.errmsg;
#endif
        return false;
    }
    
    size = substream.bytes_written;
    
    if (!pb_encode_varint(stream, (uint64_t)size))
        return false;
    
    if (stream->callback == NULL)
        return pb_write(stream, NULL, size); /* Just sizing */
    
    if (stream->bytes_written + size > stream->max_size)
        PB_RETURN_ERROR(stream, "stream full");
        
    /* Use a substream to verify that a callback doesn't write more than
     * what it did the first time. */
    substream.callback = stream->callback;
    substream.state = stream->state;
    substream.max_size = size;
    substream.bytes_written = 0;
#ifndef PB_NO_ERRMSG
    substream.errmsg = NULL;
#endif
    
    status = pb_encode(&substream, fields, src_struct);
    
    stream->bytes_written += substream.bytes_written;
    stream->state = substream.state;
#ifndef PB_NO_ERRMSG
    stream->errmsg = substream.errmsg;
#endif
    
    if (substream.bytes_written != size)
        PB_RETURN_ERROR(stream, "submsg size changed");
    
    return status;
}
示例#12
0
bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_t *field, const void *src)
{
    uint64_t value = 0;
    
    switch (field->data_size)
    {
        case 1: value = *(const uint8_t*)src; break;
        case 2: value = *(const uint16_t*)src; break;
        case 4: value = *(const uint32_t*)src; break;
        case 8: value = *(const uint64_t*)src; break;
        default: return false;
    }
    
    return pb_encode_varint(stream, value);
}
示例#13
0
bool checkreturn pb_enc_svarint(pb_ostream_t *stream, const pb_field_t *field, const void *src)
{
    uint64_t value = 0;
    uint64_t zigzagged;
    uint64_t signbitmask, xormask;
    endian_copy(&value, src, sizeof(value), field->data_size);
    
    signbitmask = (uint64_t)0x80 << (field->data_size * 8 - 8);
    xormask = ((uint64_t)-1) >> (64 - field->data_size * 8);
    if (value & signbitmask)
        zigzagged = ((value ^ xormask) << 1) | 1;
    else
        zigzagged = value << 1;
    
    return pb_encode_varint(stream, zigzagged);
}
示例#14
0
static bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_t *field, const void *src)
{
    int64_t value = 0;
    
    /* Cases 1 and 2 are for compilers that have smaller types for bool
     * or enums, and for int_size option. */
    switch (field->data_size)
    {
        case 1: value = *(const int8_t*)src; break;
        case 2: value = *(const int16_t*)src; break;
        case 4: value = *(const int32_t*)src; break;
        case 8: value = *(const int64_t*)src; break;
        default: PB_RETURN_ERROR(stream, "invalid data_size");
    }
    
    return pb_encode_varint(stream, (uint64_t)value);
}
示例#15
0
static bool checkreturn pb_enc_uvarint(pb_ostream_t *stream, const pb_field_t *field, const void *src)
{
	uint64_t value = 0;

	if (field->data_size == sizeof(uint_least8_t))
		value = *(const uint_least8_t*)src;
	else if (field->data_size == sizeof(uint_least16_t))
		value = *(const uint_least16_t*)src;
	else if (field->data_size == sizeof(uint32_t))
		value = *(const uint32_t*)src;
	else if (field->data_size == sizeof(uint64_t))
		value = *(const uint64_t*)src;
	else
		PB_RETURN_ERROR(stream, "invalid data_size");

	return pb_encode_varint(stream, value);
}
示例#16
0
/* Eecode submessage in __messages protos */
static int pb_encode_submessage(pb_ostream_t *stream, const pc_JSON *gprotos, const pc_JSON *protos, pc_JSON *value) {
    /* First calculate the message size using a non-writing substream. */
    pb_ostream_t substream = { 0, 0, 0, 0 };
    size_t size;
    int status;

    if (!pb_encode(&substream, gprotos, protos, value)) {
        return 0;
    }

    size = substream.bytes_written;

    if (!pb_encode_varint(stream, (uint64_t) size)) {
        return 0;
    }

    if (stream->callback == NULL )
        return pb_write(stream, NULL, size); /* Just sizing */

    if (stream->bytes_written + size > stream->max_size)
        return 0;

    /* Use a substream to verify that a callback doesn't write more than
     * what it did the first time. */
    substream.callback = stream->callback;
    substream.state = stream->state;
    substream.max_size = size;
    substream.bytes_written = 0;

    status = pb_encode(&substream, gprotos, protos, value);

    stream->bytes_written += substream.bytes_written;
    stream->state = substream.state;

    if (substream.bytes_written != size) {
        return 0;
    }

    return status;
}
示例#17
0
bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_t *field, const void *src)
{
    pb_ostream_t substream = {0};
    size_t size;
    bool status;
    
    if (field->ptr == NULL)
        return false;
    
    if (!pb_encode(&substream, (pb_field_t*)field->ptr, src))
        return false;
    
    size = substream.bytes_written;
    
    if (!pb_encode_varint(stream, size))
        return false;
    
    if (stream->callback == NULL)
        return pb_write(stream, NULL, size); /* Just sizing */
    
    if (stream->bytes_written + size > stream->max_size)
        return false;
        
    /* Use a substream to verify that a callback doesn't write more than
     * what it did the first time. */
    substream.callback = stream->callback;
    substream.state = stream->state;
    substream.max_size = size;
    substream.bytes_written = 0;
    
    status = pb_encode(&substream, (pb_field_t*)field->ptr, src);
    
    stream->bytes_written += substream.bytes_written;
    
    if (substream.bytes_written != size)
        return false;
    
    return status;
}
示例#18
0
bool checkreturn pb_encode_submessage(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct)
{
    /* First calculate the message size using a non-writing substream. */
    pb_ostream_t substream = {0,0,0,0};
    size_t size;
    bool status;
    
    if (!pb_encode(&substream, fields, src_struct))
        return false;
    
    size = substream.bytes_written;
    
    if (!pb_encode_varint(stream, (uint64_t)size))
        return false;
    
    if (stream->callback == NULL)
        return pb_write(stream, NULL, size); /* Just sizing */
    
    if (stream->bytes_written + size > stream->max_size)
        return false;
        
    /* Use a substream to verify that a callback doesn't write more than
     * what it did the first time. */
    substream.callback = stream->callback;
    substream.state = stream->state;
    substream.max_size = size;
    substream.bytes_written = 0;
    
    status = pb_encode(&substream, fields, src_struct);
    
    stream->bytes_written += substream.bytes_written;
    stream->state = substream.state;
    
    if (substream.bytes_written != size)
        return false;
    
    return status;
}
示例#19
0
/* 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;
}
示例#20
0
static int checkreturn pb_encode_proto(pb_ostream_t *stream, const json_t *gprotos, const json_t *protos,
                                       const json_t *proto, json_t *value) {
    json_t *_messages;
    json_t *_type = json_object_get(proto, "type");
    json_t *sub_msg;
    const char *type = json_string_value(_type);
    const char *str;
    json_int_t int_val;
    float float_val;
    double double_val;
    int length;

    _messages = json_object_get(protos, "__messages");
    switch (pb__get_type(type)) {
    case PB_uInt32:
        int_val = json_number_value(value);
        if (!pb_encode_varint(stream, int_val)) {
            return 0;
        }
        break;
    case PB_int32:
    case PB_sInt32:
        int_val = json_number_value(value);
        if (!pb_encode_svarint(stream, int_val)) {
            return 0;
        }
        break;
    case PB_float:
        float_val = json_number_value(value);
        if (!pb_encode_fixed32(stream, &float_val)) {
            return 0;
        }
        break;
    case PB_double:
        double_val = json_number_value(value);
        if (!pb_encode_fixed64(stream, &double_val)) {
            return 0;
        }
        break;
    case PB_string:
        str = json_string_value(value);
        length = strlen(str);
        if (!pb_encode_string(stream, (const uint8_t *)str, length)) {
            return 0;
        }
        break;
    default:
        if (_messages) {
            sub_msg = json_object_get(_messages, type);
            if (!sub_msg) {
                // check root msg in gprotos
                const char *head = "message ";
                char *head_text = (char *)pc_jsonp_malloc(strlen(head) + strlen(type) + 1);
                memset(head_text, 0, sizeof(head_text));
                strcpy(head_text, head);
                strcat(head_text, type);
                sub_msg = json_object_get(gprotos, head_text);
                pc_jsonp_free(head_text);
            }
            if (sub_msg) {
                if (!pb_encode_submessage(stream, gprotos, sub_msg, value)) {
                    return 0;
                }
            } else {
                return 0;
            }
        }

    }
    return 1;
}
示例#21
0
/* Encode field header by manually specifing wire type. You need to use this if
 * you want to write out packed arrays from a callback field. */
static int  pb_encode_tag(pb_ostream_t *stream, int wiretype,
        uint32_t field_number) {
    uint64_t tag = wiretype | (field_number << 3);
    return pb_encode_varint(stream, tag);
}
示例#22
0
bool micropb_encode<int64_t, nullptr>(pb_ostream_t *stream, int64_t* arg) {
  // Yes, this looks dodgy, and yes, this is what the docs say to do:
  // https://jpa.kapsi.fi/nanopb/docs/reference.html#pb-encode-varint
  return pb_encode_varint(stream, *reinterpret_cast<uint64_t*>(arg));
}
示例#23
0
static int  pb_encode_proto(pb_ostream_t *stream, const pc_JSON *gprotos, const pc_JSON *protos,
        const pc_JSON *proto, pc_JSON *value) {
    pc_JSON *_messages;
    pc_JSON *_type = pc_JSON_GetObjectItem(proto, "type");
    pc_JSON *sub_msg;
    const char *type = _type->valuestring;
    const char *str;
    int int_val;
    float float_val;
    double double_val;
    int length;

    _messages = pc_JSON_GetObjectItem(protos, "__messages");
    switch (pb_get_type(type)) {
        case PB_uInt32:
            int_val = value->valueint;
            if (!pb_encode_varint(stream, int_val)) {
                return 0;
            }
            break;
        case PB_int32:
        case PB_sInt32:
            int_val = value->valueint;
            if (!pb_encode_svarint(stream, int_val)) {
                return 0;
            }
            break;
        case PB_float:
            float_val = (float)value->valuedouble;
            if (!pb_encode_fixed32(stream, &float_val)) {
                return 0;
            }
            break;
        case PB_double:
            double_val = value->valuedouble;
            if (!pb_encode_fixed64(stream, &double_val)) {
                return 0;
            }
            break;
        case PB_string:
            str = value->valuestring;
            length = strlen(str);
            if (!pb_encode_string(stream, (const uint8_t *)str, length)) {
                return 0;
            }
            break;
        default:
            if (_messages) {
                sub_msg = pc_JSON_GetObjectItem(_messages, type);
                if (!sub_msg) {
                    /* check root msg in gprotos */
                    const char *head = "message ";
                    size_t len = strlen(head) + strlen(type) + 1;
                    char *head_text = (char *)malloc(len);
                    memset(head_text, 0, len);
                    strcpy(head_text, head);
                    strcat(head_text, type);
                    sub_msg = pc_JSON_GetObjectItem(gprotos, head_text);
                    free(head_text);
                }
                if (sub_msg) {
                    if (!pb_encode_submessage(stream, gprotos, sub_msg, value)) {
                        return 0;
                    }
                } else {
                    return 0;
                }
            }

    }
    return 1;
}
示例#24
0
bool checkreturn pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, int field_number)
{
    int tag = wiretype | (field_number << 3);
    return pb_encode_varint(stream, tag);
}
示例#25
0
bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_t *field, const void *src)
{
    uint64_t value = 0;
    endian_copy(&value, src, sizeof(value), field->data_size);
    return pb_encode_varint(stream, value);
}
示例#26
0
/* 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;
}
示例#27
0
bool checkreturn pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, uint32_t field_number)
{
    uint64_t tag = ((uint64_t)field_number << 3) | wiretype;
    return pb_encode_varint(stream, tag);
}