aboutsummaryrefslogtreecommitdiffstats
path: root/CAN-binder/libs/nanopb/tests/basic_stream/SConscript
blob: 7d6685623fea14e1b4cd54a666ceae112e450a70 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
# Build and run a basic round-trip test using direct stream encoding.

Import("env")

enc = env.Program(["encode_stream.c", "$COMMON/person.pb.c", "$COMMON/pb_encode.o", "$COMMON/pb_common.o"])
dec = env.Program(["decode_stream.c", "$COMMON/person.pb.c", "$COMMON/pb_decode.o", "$COMMON/pb_common.o"])

env.RunTest(enc)
env.RunTest([dec, "encode_stream.output"])
env.Decode(["encode_stream.output", "$COMMON/person.proto"], MESSAGE = "Person")
env.Compare(["decode_stream.output", "encode_stream.decoded"])
0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */ }
/* Simulate IO errors after each byte in a stream.
 * Verifies proper error propagation.
 */

#include <stdio.h>
#include <pb_decode.h>
#include <pb_encode.h>
#include "alltypes.pb.h"
#include "test_helpers.h"

typedef struct
{
    uint8_t *buffer;
    size_t fail_after;
} faulty_stream_t;

bool read_callback(pb_istream_t *stream, uint8_t *buf, size_t count)
{
    faulty_stream_t *state = stream->state;
    
    while (count--)
    {
        if (state->fail_after == 0)
            PB_RETURN_ERROR(stream, "simulated");
        state->fail_after--;
        *buf++ = *state->buffer++;
    }
    
    return true;
}
bool write_callback(pb_ostream_t *stream, const uint8_t *buf, size_t count)
{
    faulty_stream_t *state = stream->state;
    
    while (count--)
    {
        if (state->fail_after == 0)
            PB_RETURN_ERROR(stream, "simulated");
        state->fail_after--;
        *state->buffer++ = *buf++;
    }
    
    return true;
}

int main()
{
    uint8_t buffer[2048];
    size_t msglen;
    AllTypes msg = AllTypes_init_zero;
    
    /* Get some base data to run the tests with */
    SET_BINARY_MODE(stdin);
    msglen = fread(buffer, 1, sizeof(buffer), stdin);
    
    /* Test IO errors on decoding */
    {
        bool status;
        pb_istream_t stream = {&read_callback, NULL, SIZE_MAX};
        faulty_stream_t fs;
        size_t i;
        
        for (i = 0; i < msglen; i++)
        {
            stream.bytes_left = msglen;
            stream.state = &fs;
            fs.buffer = buffer;
            fs.fail_after = i;

            status = pb_decode(&stream, AllTypes_fields, &msg);
            if (status != false)
            {
                fprintf(stderr, "Unexpected success in decode\n");
                return 2;
            }
            else if (strcmp(stream.errmsg, "simulated") != 0)
            {
                fprintf(stderr, "Wrong error in decode: %s\n", stream.errmsg);
                return 3;
            }
        }
        
        stream.bytes_left = msglen;
        stream.state = &fs;
        fs.buffer = buffer;
        fs.fail_after = msglen;
        status = pb_decode(&stream, AllTypes_fields, &msg);
        
        if (!status)
        {
            fprintf(stderr, "Decoding failed: %s\n", stream.errmsg);
            return 4;
        }
    }
    
    /* Test IO errors on encoding */
    {
        bool status;
        pb_ostream_t stream = {&write_callback, NULL, SIZE_MAX, 0};
        faulty_stream_t fs;
        size_t i;
        
        for (i = 0; i < msglen; i++)
        {
            stream.max_size = msglen;
            stream.bytes_written = 0;
            stream.state = &fs;
            fs.buffer = buffer;
            fs.fail_after = i;

            status = pb_encode(&stream, AllTypes_fields, &msg);
            if (status != false)
            {
                fprintf(stderr, "Unexpected success in encode\n");
                return 5;
            }
            else if (strcmp(stream.errmsg, "simulated") != 0)
            {
                fprintf(stderr, "Wrong error in encode: %s\n", stream.errmsg);
                return 6;
            }
        }
        
        stream.max_size = msglen;
        stream.bytes_written = 0;
        stream.state = &fs;
        fs.buffer = buffer;
        fs.fail_after = msglen;
        status = pb_encode(&stream, AllTypes_fields, &msg);
        
        if (!status)
        {
            fprintf(stderr, "Encoding failed: %s\n", stream.errmsg);
            return 7;
        }
    }

    return 0;   
}