Skip to content

Commit

Permalink
Extend NCodec interface to include seek and tell methods.
Browse files Browse the repository at this point in the history
Directly expose ncodec_seek() and ncodec_tell() methods to wrap underlying stream methods.

Signed-off-by: Rule Timothy (VM/EMT3) <Timothy.Rule@de.bosch.com>
  • Loading branch information
timrulebosch committed Feb 26, 2024
1 parent 89e4ace commit a47887a
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 25 deletions.
68 changes: 68 additions & 0 deletions dse/ncodec/codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,74 @@ inline int ncodec_truncate(NCODEC* nc)
}


/**
ncodec_seek
===========
Parameters
----------
nc (NCODEC*)
: Network Codec object.
pos (size_t)
: Seek position relative to the seek operation.
op (int)
: Seek operation (NCodecStreamSeekOperation).
Returns
-------
+ve
: The position in the underlying stream object after the seek operation.
-ENOSTR (-60)
: The object represented by `nc` does not represent a valid stream.
-EINVAL (-22)
: Bad `msg` argument.
*/
inline long ncodec_seek(NCODEC* nc, size_t pos, int op)
{
NCodecInstance* _nc = (NCodecInstance*)nc;
if (_nc && _nc->stream && _nc->stream->seek) {
return _nc->stream->seek((NCODEC*)nc, pos, op);
} else {
return -ENOSTR;
}
}


/**
ncodec_tell
===========
Parameters
----------
nc (NCODEC*)
: Network Codec object.
Returns
-------
+ve
: The current position in the underlying stream object.
-ENOSTR (-60)
: The object represented by `nc` does not represent a valid stream.
-ENOSR (-63)
: No stream resource has been configured.
*/
inline long ncodec_tell(NCODEC* nc)
{
NCodecInstance* _nc = (NCodecInstance*)nc;
if (_nc && _nc->stream && _nc->stream->tell) {
return _nc->stream->tell((NCODEC*)nc);
} else {
return -ENOSTR;
}
}


/**
ncodec_close
============
Expand Down
7 changes: 4 additions & 3 deletions dse/ncodec/codec.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,8 @@ typedef enum NCodecStreamPosOperation {
typedef size_t (*NCodecStreamRead)(
NCODEC* nc, uint8_t** data, size_t* len, int pos_op);
typedef size_t (*NCodecStreamWrite)(NCODEC* nc, uint8_t* data, size_t len);
typedef int (*NCodecStreamSeek)(NCODEC* nc, size_t pos, int op);
typedef size_t (*NCodecStreamTell)(NCODEC* nc);
typedef long (*NCodecStreamSeek)(NCODEC* nc, size_t pos, int op);
typedef long (*NCodecStreamTell)(NCODEC* nc);
typedef int (*NCodecStreamEof)(NCODEC* nc);
typedef int (*NCodecStreamClose)(NCODEC* nc);

Expand Down Expand Up @@ -217,6 +217,7 @@ DLL_PUBLIC int ncodec_read(NCODEC* nc, NCodecMessage* msg);
DLL_PUBLIC int ncodec_flush(NCODEC* nc);
DLL_PUBLIC int ncodec_truncate(NCODEC* nc);
DLL_PUBLIC void ncodec_close(NCODEC* nc);

DLL_PUBLIC long ncodec_seek(NCODEC* nc, size_t pos, int op);
DLL_PUBLIC long ncodec_tell(NCODEC* nc);

#endif // DSE_NCODEC_CODEC_H_
5 changes: 2 additions & 3 deletions dse/ncodec/example/example.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,11 @@
#include <dse/ncodec/codec.h>


#define MIMETYPE "application/x-codec-example"
#define MIMETYPE "application/x-codec-example"
#define UNUSED(x) ((void)x)


extern NCodecStreamVTable example_stream;
extern int stream_seek(NCODEC* nc, size_t pos, int op);


static void trace_read(NCODEC* nc, NCodecMessage* m)
Expand Down Expand Up @@ -66,7 +65,7 @@ int main(int argc, char* argv[])
ncodec_flush(nc);

/* Reposition to start of stream. */
stream_seek(nc, 0, NCODEC_SEEK_SET);
ncodec_seek(nc, 0, NCODEC_SEEK_SET);

/* Read the response from the Network Codec. */
NCodecCanMessage msg = {};
Expand Down
4 changes: 2 additions & 2 deletions dse/ncodec/example/stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ size_t stream_write(NCODEC* nc, uint8_t* data, size_t len)
return len;
}

int stream_seek(NCODEC* nc, size_t pos, int op)
long stream_seek(NCODEC* nc, size_t pos, int op)
{
NCodecInstance* _nc = (NCodecInstance*)nc;
if (_nc && _nc->stream) {
Expand Down Expand Up @@ -88,7 +88,7 @@ int stream_seek(NCODEC* nc, size_t pos, int op)
return -ENOSTR;
}

size_t stream_tell(NCODEC* nc)
long stream_tell(NCODEC* nc)
{
NCodecInstance* _nc = (NCodecInstance*)nc;
if (_nc && _nc->stream) {
Expand Down
4 changes: 2 additions & 2 deletions dse/ncodec/libs/automotive-bus/tests/stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ size_t stream_write(NCODEC* nc, uint8_t* data, size_t len)
return len;
}

int stream_seek(NCODEC* nc, size_t pos, int op)
long stream_seek(NCODEC* nc, size_t pos, int op)
{
NCodecInstance* _nc = (NCodecInstance*)nc;
if (_nc && _nc->stream) {
Expand Down Expand Up @@ -88,7 +88,7 @@ int stream_seek(NCODEC* nc, size_t pos, int op)
return -ENOSTR;
}

size_t stream_tell(NCODEC* nc)
long stream_tell(NCODEC* nc)
{
NCodecInstance* _nc = (NCodecInstance*)nc;
if (_nc && _nc->stream) {
Expand Down
28 changes: 13 additions & 15 deletions dse/ncodec/libs/automotive-bus/tests/test_can_fbs.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ extern void codec_close(NCODEC* nc);
extern int can_write(NCODEC* nc, NCodecMessage* msg);
extern int can_read(NCODEC* nc, NCodecMessage* msg);
extern int can_flush(NCODEC* nc);
extern int stream_seek(NCODEC* nc, size_t pos, int op);
extern size_t stream_tell(NCODEC* nc);
extern int stream_read(NCODEC* nc, uint8_t** data, size_t* len,
int pos_op);

Expand Down Expand Up @@ -140,23 +138,23 @@ void test_can_fbs_truncate(void** state)
const char* greeting = "Hello World";

// Write to the stream.
stream_seek(nc, 0, NCODEC_SEEK_RESET);
ncodec_seek(nc, 0, NCODEC_SEEK_RESET);
rc = ncodec_write(nc, &(struct NCodecCanMessage){ .frame_id = 42,
.buffer = (uint8_t*)greeting,
.len = strlen(greeting) });
assert_int_equal(rc, strlen(greeting));
assert_int_equal(0x66, ncodec_flush(nc));
assert_int_equal(0x66, stream_tell(nc));
assert_int_equal(0x66, ncodec_tell(nc));

// Truncate the stream.
rc = ncodec_truncate(nc);
assert_int_equal(rc, 0);
assert_int_equal(0, stream_tell(nc));
assert_int_equal(0, ncodec_tell(nc));

// Flush the stream, and check no buffered content was retained.
rc = ncodec_flush(nc);
assert_int_equal(rc, 0);
assert_int_equal(0, stream_tell(nc));
assert_int_equal(0, ncodec_tell(nc));
}


Expand All @@ -166,7 +164,7 @@ void test_can_fbs_read_nomsg(void** state)
NCODEC* nc = mock->nc;
int rc;

stream_seek(nc, 0, NCODEC_SEEK_RESET);
ncodec_seek(nc, 0, NCODEC_SEEK_RESET);
NCodecCanMessage msg = {};
size_t len = ncodec_read(nc, &msg);
assert_int_equal(len, -ENOMSG);
Expand All @@ -191,7 +189,7 @@ void test_can_fbs_write(void** state)
assert_int_equal(len, 0x66);

// Check the result in the stream.
stream_seek(nc, 0, NCODEC_SEEK_SET);
ncodec_seek(nc, 0, NCODEC_SEEK_SET);
uint8_t* buffer;
size_t buffer_len;
stream_read(nc, &buffer, &buffer_len, NCODEC_POS_NC);
Expand All @@ -209,7 +207,7 @@ void test_can_fbs_readwrite(void** state)
const char* greeting = "Hello World";

// Write and flush a message.
stream_seek(nc, 0, NCODEC_SEEK_RESET);
ncodec_seek(nc, 0, NCODEC_SEEK_RESET);
rc = ncodec_write(nc, &(struct NCodecCanMessage){ .frame_id = 42,

.frame_type = 0,
Expand All @@ -222,7 +220,7 @@ void test_can_fbs_readwrite(void** state)


// Seek to the start, keeping the content, modify the node_id.
stream_seek(nc, 0, NCODEC_SEEK_SET);
ncodec_seek(nc, 0, NCODEC_SEEK_SET);
uint8_t* buffer;
size_t buffer_len;
stream_read(nc, &buffer, &buffer_len, NCODEC_POS_NC);
Expand Down Expand Up @@ -254,7 +252,7 @@ void test_can_fbs_readwrite_frames(void** state)
const char* greeting2 = "Foo Bar";

// Write and flush a message.
stream_seek(nc, 0, NCODEC_SEEK_RESET);
ncodec_seek(nc, 0, NCODEC_SEEK_RESET);
rc = ncodec_write(nc, &(struct NCodecCanMessage){ .frame_id = 42,
.buffer = (uint8_t*)greeting1,
.len = strlen(greeting1) });
Expand All @@ -267,7 +265,7 @@ void test_can_fbs_readwrite_frames(void** state)
assert_int_equal(len, 0x92);

// Seek to the start, keeping the content, modify the node_id.
stream_seek(nc, 0, NCODEC_SEEK_SET);
ncodec_seek(nc, 0, NCODEC_SEEK_SET);
uint8_t* buffer;
size_t buffer_len;
stream_read(nc, &buffer, &buffer_len, NCODEC_POS_NC);
Expand Down Expand Up @@ -308,7 +306,7 @@ void test_can_fbs_readwrite_messages(void** state)
const char* greeting2 = "Foo Bar";

// Write and flush a message.
stream_seek(nc, 0, NCODEC_SEEK_RESET);
ncodec_seek(nc, 0, NCODEC_SEEK_RESET);
rc = ncodec_write(nc, &(struct NCodecCanMessage){ .frame_id = 42,
.buffer = (uint8_t*)greeting1,
.len = strlen(greeting1) });
Expand All @@ -324,7 +322,7 @@ void test_can_fbs_readwrite_messages(void** state)
assert_int_equal(len, 0x62);

// Seek to the start of Reset the stream, keeping the content.
stream_seek(nc, 0, NCODEC_SEEK_SET);
ncodec_seek(nc, 0, NCODEC_SEEK_SET);
uint8_t* buffer;
size_t buffer_len;
stream_read(nc, &buffer, &buffer_len, NCODEC_POS_NC);
Expand Down Expand Up @@ -380,7 +378,7 @@ void test_can_fbs_frame_type(void** state)
len = ncodec_flush(nc);
assert_int_equal(len, tc[i].enum_value ? 0x6a : 0x66);
// Seek to the start, keeping the content, modify the node_id.
stream_seek(nc, 0, NCODEC_SEEK_SET);
ncodec_seek(nc, 0, NCODEC_SEEK_SET);
uint8_t* buffer;
size_t buffer_len;
stream_read(nc, &buffer, &buffer_len, NCODEC_POS_NC);
Expand Down
76 changes: 76 additions & 0 deletions dse/ncodec/libs/automotive-bus/tests/test_codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,19 @@ extern int can_read(NCODEC* nc, NCodecMessage* msg);
extern int can_flush(NCODEC* nc);
extern int can_truncate(NCODEC* nc);

/* Stream mock. */
extern NCodecStreamVTable mem_stream;
extern NCODEC* ncodec_open(const char* mime_type, NCodecStreamVTable* stream);


static void _adjust_node_id(NCODEC* nc, const char* node_id)
{
ncodec_config(nc, (struct NCodecConfigItem){
.name = "node_id",
.value = node_id,
});
}


typedef struct Mock {
ABCodecInstance* nc;
Expand Down Expand Up @@ -326,6 +339,68 @@ void test_ncodec_create_failon_mime(void** state)
}


void test_ncodec_call_sequence(void** state)
{
UNUSED(state);

/* Create the codec instance. */
const char* mime_type = "application/x-automotive-bus; "
"interface=stream;type=frame;bus=can;schema=fbs;"
"bus_id=1;node_id=2;interface_id=3";
NCODEC* nc = ncodec_open(mime_type, (void*)&mem_stream);
assert_non_null(nc);
NCodecInstance* _nc = (NCodecInstance*)nc;
assert_non_null(_nc);
assert_non_null(_nc->stream);
assert_non_null(_nc->stream->seek);
assert_string_equal(_nc->mime_type, mime_type);

/* Initial conditions. */
const char* greeting = "Hello World";
assert_int_equal(0, ncodec_seek(nc, 0, NCODEC_SEEK_END));
assert_int_equal(0, ncodec_tell(nc));
_adjust_node_id(nc, "42");
size_t len = ncodec_write(nc, &(struct NCodecCanMessage){ .frame_id = 42,
.buffer = (uint8_t*)greeting,
.len = strlen(greeting) });
assert_int_equal(strlen(greeting), len);
ncodec_flush(nc);
_adjust_node_id(nc, "2");
#define EXPECT_POS 0x66
assert_int_equal(EXPECT_POS, ncodec_tell(nc));

/* Read then Write. */
for (int i = 0; i < 5; i++) {
/* Seek - position to start of stream. */
assert_int_equal(EXPECT_POS, ncodec_seek(nc, 0, NCODEC_SEEK_END));
ncodec_seek(nc, 0, NCODEC_SEEK_SET);
assert_int_equal(0, ncodec_tell(nc));
/* Read - consume the stream. */
NCodecCanMessage msg = {};
size_t len = ncodec_read(nc, &msg);
assert_int_equal(strlen(greeting), len);
/* Truncate - reset the stream. */
ncodec_truncate(nc);
assert_int_equal(0, ncodec_tell(nc));
assert_int_equal(0, ncodec_seek(nc, 0, NCODEC_SEEK_END));
assert_int_equal(0, ncodec_tell(nc));
/* Write and Flush - write to stream (spoof node_id). */
_adjust_node_id(nc, "42");
len = ncodec_write(nc, &(struct NCodecCanMessage){ .frame_id = 42,
.buffer = (uint8_t*)greeting,
.len = strlen(greeting) });
assert_int_equal(strlen(greeting), len);
ncodec_flush(nc);
_adjust_node_id(nc, "2");
assert_int_equal(EXPECT_POS, ncodec_tell(nc));
assert_int_equal(EXPECT_POS, ncodec_seek(nc, 0, NCODEC_SEEK_END));
}

/* Close the codec. */
ncodec_close((void*)nc);
}


int run_codec_tests(void)
{
void* s = test_setup;
Expand All @@ -337,6 +412,7 @@ int run_codec_tests(void)
cmocka_unit_test_setup_teardown(test_codec_stat, s, t),
cmocka_unit_test_setup_teardown(test_ncodec_create_close, s, t),
cmocka_unit_test_setup_teardown(test_ncodec_create_failon_mime, s, t),
cmocka_unit_test_setup_teardown(test_ncodec_call_sequence, s, t),
};

return cmocka_run_group_tests_name("CODEC", codec_tests, NULL, NULL);
Expand Down

0 comments on commit a47887a

Please sign in to comment.