struct-frame 0.0.14__tar.gz → 0.0.16__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of struct-frame might be problematic. Click here for more details.
- {struct_frame-0.0.14 → struct_frame-0.0.16}/PKG-INFO +1 -1
- {struct_frame-0.0.14 → struct_frame-0.0.16}/pyproject.toml +1 -1
- {struct_frame-0.0.14 → struct_frame-0.0.16}/src/struct_frame/generate.py +20 -15
- {struct_frame-0.0.14/c → struct_frame-0.0.16/tester}/biostream.sf.h +1 -1
- struct_frame-0.0.16/tester/struct_frame.h +103 -0
- struct_frame-0.0.16/tester/struct_frame_gen.h +2 -0
- struct_frame-0.0.16/tester/struct_frame_parser.h +101 -0
- struct_frame-0.0.16/tester/struct_frame_types.h +69 -0
- {struct_frame-0.0.14/ts → struct_frame-0.0.16/testerts}/biostream.sf.ts +1 -1
- struct_frame-0.0.16/testerts/struct_frame.ts +65 -0
- struct_frame-0.0.16/testerts/struct_frame_gen.ts +7 -0
- struct_frame-0.0.16/testerts/struct_frame_parser.ts +98 -0
- struct_frame-0.0.16/testerts/struct_frame_types.ts +80 -0
- {struct_frame-0.0.14 → struct_frame-0.0.16}/.gitignore +0 -0
- {struct_frame-0.0.14 → struct_frame-0.0.16}/LICENSE +0 -0
- {struct_frame-0.0.14 → struct_frame-0.0.16}/README.md +0 -0
- {struct_frame-0.0.14 → struct_frame-0.0.16}/biostream.proto +0 -0
- {struct_frame-0.0.14 → struct_frame-0.0.16}/index.ts +0 -0
- {struct_frame-0.0.14 → struct_frame-0.0.16}/main.c +0 -0
- {struct_frame-0.0.14 → struct_frame-0.0.16}/myl_vehicle.proto +0 -0
- {struct_frame-0.0.14 → struct_frame-0.0.16}/package-lock.json +0 -0
- {struct_frame-0.0.14 → struct_frame-0.0.16}/package.json +0 -0
- {struct_frame-0.0.14 → struct_frame-0.0.16}/src/main.py +0 -0
- {struct_frame-0.0.14 → struct_frame-0.0.16}/src/struct_frame/__init__.py +0 -0
- {struct_frame-0.0.14 → struct_frame-0.0.16}/src/struct_frame/__main__.py +0 -0
- {struct_frame-0.0.14 → struct_frame-0.0.16}/src/struct_frame/base.py +0 -0
- {struct_frame-0.0.14 → struct_frame-0.0.16}/src/struct_frame/boilerplate/c/struct_frame.h +0 -0
- {struct_frame-0.0.14 → struct_frame-0.0.16}/src/struct_frame/boilerplate/c/struct_frame_gen.h +0 -0
- {struct_frame-0.0.14 → struct_frame-0.0.16}/src/struct_frame/boilerplate/c/struct_frame_parser.h +0 -0
- {struct_frame-0.0.14 → struct_frame-0.0.16}/src/struct_frame/boilerplate/c/struct_frame_types.h +0 -0
- {struct_frame-0.0.14 → struct_frame-0.0.16}/src/struct_frame/boilerplate/ts/struct_frame.ts +0 -0
- {struct_frame-0.0.14 → struct_frame-0.0.16}/src/struct_frame/boilerplate/ts/struct_frame_gen.ts +0 -0
- {struct_frame-0.0.14 → struct_frame-0.0.16}/src/struct_frame/boilerplate/ts/struct_frame_parser.ts +0 -0
- {struct_frame-0.0.14 → struct_frame-0.0.16}/src/struct_frame/boilerplate/ts/struct_frame_types.ts +0 -0
- {struct_frame-0.0.14 → struct_frame-0.0.16}/src/struct_frame/c_gen.py +0 -0
- {struct_frame-0.0.14 → struct_frame-0.0.16}/src/struct_frame/ts_gen.py +0 -0
- {struct_frame-0.0.14 → struct_frame-0.0.16}/tsconfig.json +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: struct-frame
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.16
|
|
4
4
|
Summary: A framework for serializing data with headers
|
|
5
5
|
Project-URL: Homepage, https://github.com/mylonics/struct-frame
|
|
6
6
|
Project-URL: Issues, https://github.com/mylonics/struct-frame/issues
|
|
@@ -246,11 +246,13 @@ processed_file = []
|
|
|
246
246
|
required_file = []
|
|
247
247
|
|
|
248
248
|
parser = argparse.ArgumentParser(
|
|
249
|
-
prog='
|
|
250
|
-
description='
|
|
251
|
-
epilog='Text at the bottom of help')
|
|
249
|
+
prog='struct_frame',
|
|
250
|
+
description='Message serialization and header generation program')
|
|
252
251
|
|
|
253
|
-
parser.add_argument('filename')
|
|
252
|
+
parser.add_argument('filename')
|
|
253
|
+
parser.add_argument('--debug', action='store_true')
|
|
254
|
+
parser.add_argument('--c_path', nargs=1, type=str, default=['c/'])
|
|
255
|
+
parser.add_argument('--ts_path', nargs=1, type=str, default=['ts/'])
|
|
254
256
|
|
|
255
257
|
|
|
256
258
|
def parseFile(filename):
|
|
@@ -305,11 +307,13 @@ def printPackages():
|
|
|
305
307
|
for key, value in packages.items():
|
|
306
308
|
print(value)
|
|
307
309
|
|
|
310
|
+
import os
|
|
311
|
+
import shutil
|
|
308
312
|
|
|
309
313
|
def generateCFileStrings(path):
|
|
310
314
|
out = {}
|
|
311
315
|
for key, value in packages.items():
|
|
312
|
-
name = path
|
|
316
|
+
name = os.path.join(path, value.name + ".sf.h")
|
|
313
317
|
data = ''.join(FileCGen.generate(value))
|
|
314
318
|
out[name] = data
|
|
315
319
|
|
|
@@ -318,15 +322,12 @@ def generateCFileStrings(path):
|
|
|
318
322
|
def generateTsFileStrings(path):
|
|
319
323
|
out = {}
|
|
320
324
|
for key, value in packages.items():
|
|
321
|
-
name = path
|
|
325
|
+
name = os.path.join(path, value.name + ".sf.ts")
|
|
322
326
|
data = ''.join(FileTsGen.generate(value))
|
|
323
327
|
out[name] = data
|
|
324
|
-
|
|
325
328
|
return out
|
|
326
329
|
|
|
327
330
|
|
|
328
|
-
import os
|
|
329
|
-
|
|
330
331
|
def main():
|
|
331
332
|
args = parser.parse_args()
|
|
332
333
|
parseFile(args.filename)
|
|
@@ -337,11 +338,10 @@ def main():
|
|
|
337
338
|
print(
|
|
338
339
|
f'Recursion Error. Messages most likely have a cyclical dependancy. Check Message: {recErrCurrentMessage} and Field: {recErrCurrentField}')
|
|
339
340
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
files.update(generateTsFileStrings(tspath))
|
|
341
|
+
print(args.c_path)
|
|
342
|
+
print(args.ts_path)
|
|
343
|
+
files = generateCFileStrings(args.c_path[0])
|
|
344
|
+
files.update(generateTsFileStrings(args.ts_path[0]))
|
|
345
345
|
|
|
346
346
|
for filename, filedata in files.items():
|
|
347
347
|
dirname = os.path.dirname(filename)
|
|
@@ -351,7 +351,12 @@ def main():
|
|
|
351
351
|
with open(filename , 'w', encoding='utf-8') as f:
|
|
352
352
|
f.write(filedata)
|
|
353
353
|
|
|
354
|
-
|
|
354
|
+
dir_path = os.path.dirname(os.path.realpath(__file__))
|
|
355
|
+
shutil.copytree(os.path.join(dir_path,"boilerplate/c"), args.c_path[0], dirs_exist_ok=True)
|
|
356
|
+
shutil.copytree(os.path.join(dir_path,"boilerplate/ts"), args.ts_path[0], dirs_exist_ok=True)
|
|
357
|
+
|
|
358
|
+
if args.debug:
|
|
359
|
+
printPackages()
|
|
355
360
|
|
|
356
361
|
|
|
357
362
|
if __name__ == '__main__':
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
#include "stdbool.h"
|
|
3
|
+
#include "stdint.h"
|
|
4
|
+
#include "string.h"
|
|
5
|
+
#include "struct_frame_types.h"
|
|
6
|
+
|
|
7
|
+
static inline struct checksum_t fletcher_checksum_calculation(uint8_t *buffer, uint8_t data_length)
|
|
8
|
+
{
|
|
9
|
+
checksum_t checksum;
|
|
10
|
+
|
|
11
|
+
for (int i = 0; i < data_length; i++)
|
|
12
|
+
{
|
|
13
|
+
checksum.byte1 += buffer[i];
|
|
14
|
+
checksum.byte2 += checksum.byte1;
|
|
15
|
+
}
|
|
16
|
+
return checksum;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
static inline void msg_encode(struct_buffer *buffer, void *msg_buffer, uint8_t msg_id, uint8_t size)
|
|
20
|
+
{
|
|
21
|
+
buffer->data[buffer->size++] = buffer->config.start_byte;
|
|
22
|
+
buffer->crc_start_loc = buffer->size;
|
|
23
|
+
buffer->data[buffer->size++] = msg_id;
|
|
24
|
+
|
|
25
|
+
if (buffer->config.has_len)
|
|
26
|
+
{
|
|
27
|
+
buffer->data[buffer->size++] = size;
|
|
28
|
+
}
|
|
29
|
+
memcpy(buffer->data + buffer->size, (uint8_t *)msg_buffer, size);
|
|
30
|
+
buffer->size += size;
|
|
31
|
+
if (buffer->config.has_crc)
|
|
32
|
+
{
|
|
33
|
+
checksum_t crc = fletcher_checksum_calculation(buffer->data + buffer->crc_start_loc,
|
|
34
|
+
buffer->crc_start_loc - buffer->size);
|
|
35
|
+
buffer->data[buffer->size++] = crc.byte1;
|
|
36
|
+
buffer->data[buffer->size++] = crc.byte2;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
static inline void *msg_reserve(struct_buffer *buffer, uint8_t msg_id, uint8_t size)
|
|
41
|
+
{
|
|
42
|
+
if (buffer->in_progress)
|
|
43
|
+
{
|
|
44
|
+
return 0;
|
|
45
|
+
}
|
|
46
|
+
buffer->in_progress = true;
|
|
47
|
+
buffer->data[buffer->size++] = buffer->config.start_byte;
|
|
48
|
+
|
|
49
|
+
buffer->data[buffer->size++] = msg_id;
|
|
50
|
+
if (buffer->config.has_len)
|
|
51
|
+
{
|
|
52
|
+
buffer->data[buffer->size++] = size;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
void *out = &buffer->data[buffer->size];
|
|
56
|
+
buffer->size += size;
|
|
57
|
+
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
static inline void msg_finish(struct_buffer *buffer)
|
|
62
|
+
{
|
|
63
|
+
if (buffer->config.has_crc)
|
|
64
|
+
{
|
|
65
|
+
checksum_t crc = fletcher_checksum_calculation(buffer->data + buffer->crc_start_loc,
|
|
66
|
+
buffer->crc_start_loc - buffer->size);
|
|
67
|
+
buffer->data[buffer->size++] = crc.byte1;
|
|
68
|
+
buffer->data[buffer->size++] = crc.byte2;
|
|
69
|
+
}
|
|
70
|
+
buffer->in_progress = false;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
#define MESSAGE_HELPER(funcname, name, msg_size, msg_id) \
|
|
74
|
+
static inline void funcname##_encode(struct_buffer *buffer, name *name##_obj) \
|
|
75
|
+
{ \
|
|
76
|
+
msg_encode(buffer, name##_obj, msg_id, msg_size); \
|
|
77
|
+
} \
|
|
78
|
+
static inline bool funcname##_reserve(struct_buffer *buffer, name **msg) \
|
|
79
|
+
{ \
|
|
80
|
+
void *ptr = msg_reserve(buffer, msg_id, msg_size); \
|
|
81
|
+
if (ptr) \
|
|
82
|
+
{ \
|
|
83
|
+
*msg = (name *)ptr; \
|
|
84
|
+
return true; \
|
|
85
|
+
} \
|
|
86
|
+
return false; \
|
|
87
|
+
} \
|
|
88
|
+
static inline void funcname##_finish(struct_buffer *buffer) { msg_finish(buffer); } \
|
|
89
|
+
static inline name funcname##_get(struct_buffer *buffer) \
|
|
90
|
+
{ \
|
|
91
|
+
name msg = *(name *)(buffer->data); \
|
|
92
|
+
return msg; \
|
|
93
|
+
} \
|
|
94
|
+
static inline name funcname##_get_from_buffer_result(buffer_parser_result_t result) \
|
|
95
|
+
{ \
|
|
96
|
+
name msg = *(name *)(result.msg_loc); \
|
|
97
|
+
return msg; \
|
|
98
|
+
} \
|
|
99
|
+
static inline name *funcname##_get_ref(struct_buffer *buffer) { return (name *)(buffer->data); } \
|
|
100
|
+
static inline name *funcname##_get_ref_from_buffer_result(buffer_parser_result_t result) \
|
|
101
|
+
{ \
|
|
102
|
+
return (name *)(result.msg_loc); \
|
|
103
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
#include "stdint.h"
|
|
3
|
+
#include "struct_frame_gen.h"
|
|
4
|
+
#include "struct_frame_types.h"
|
|
5
|
+
|
|
6
|
+
// https://github.com/serge-sans-paille/frozen
|
|
7
|
+
|
|
8
|
+
static inline bool parse_default_format_validate(uint8_t *data, msg_id_len_t *msg_id_len) {
|
|
9
|
+
(void)data;
|
|
10
|
+
(void)msg_id_len;
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
static inline bool parse_default_format_char_for_len_id(msg_id_len_t *msg_id_len, const uint8_t c) {
|
|
15
|
+
msg_id_len->msg_id = c;
|
|
16
|
+
msg_id_len->len = get_message_length(c);
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
parser_functions_t default_parser_functions = {parse_default_format_char_for_len_id,
|
|
21
|
+
parse_default_format_validate};
|
|
22
|
+
|
|
23
|
+
static inline parser_functions_t *parse_char_for_start_byte(const struct_frame_config config,
|
|
24
|
+
const uint8_t c) {
|
|
25
|
+
if (config.start_byte == c) {
|
|
26
|
+
return &default_parser_functions;
|
|
27
|
+
}
|
|
28
|
+
return NULL;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
static inline bool parse_char(struct_buffer *pb, uint8_t c) {
|
|
32
|
+
parser_functions_t *parse_func_ptr = NULL;
|
|
33
|
+
switch (pb->state) {
|
|
34
|
+
case LOOKING_FOR_START_BYTE:
|
|
35
|
+
parse_func_ptr = parse_char_for_start_byte(pb->config, c);
|
|
36
|
+
if (parse_func_ptr) {
|
|
37
|
+
pb->config.parser_funcs = parse_func_ptr;
|
|
38
|
+
pb->state = GETTING_LENGTH_MSG_AND_ID;
|
|
39
|
+
}
|
|
40
|
+
break;
|
|
41
|
+
|
|
42
|
+
case GETTING_LENGTH_MSG_AND_ID:
|
|
43
|
+
if (pb->config.parser_funcs->get_msg_id_len(&pb->msg_id_len, c)) {
|
|
44
|
+
pb->state = GETTING_PAYLOAD;
|
|
45
|
+
pb->size = 0;
|
|
46
|
+
}
|
|
47
|
+
break;
|
|
48
|
+
|
|
49
|
+
case GETTING_PAYLOAD:
|
|
50
|
+
pb->data[pb->size++] = c;
|
|
51
|
+
if (pb->size >= pb->msg_id_len.len) {
|
|
52
|
+
pb->state = LOOKING_FOR_START_BYTE;
|
|
53
|
+
return pb->config.parser_funcs->validate_packet(pb->data, &pb->msg_id_len);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
break;
|
|
57
|
+
|
|
58
|
+
default:
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
static inline bool parse_buffer(uint8_t *buffer, size_t size, buffer_parser_result_t *parser_result) {
|
|
66
|
+
enum ParserState state = LOOKING_FOR_START_BYTE;
|
|
67
|
+
parser_functions_t *parse_func_ptr;
|
|
68
|
+
for (size_t i = parser_result->r_loc; i < size; i++) {
|
|
69
|
+
switch (state) {
|
|
70
|
+
case LOOKING_FOR_START_BYTE:
|
|
71
|
+
parse_func_ptr = parse_char_for_start_byte(parser_result->config, buffer[i]);
|
|
72
|
+
if (parse_func_ptr) {
|
|
73
|
+
state = GETTING_LENGTH_MSG_AND_ID;
|
|
74
|
+
}
|
|
75
|
+
break;
|
|
76
|
+
|
|
77
|
+
case GETTING_LENGTH_MSG_AND_ID:
|
|
78
|
+
if (parse_func_ptr->get_msg_id_len(&parser_result->msg_id_len, buffer[i])) {
|
|
79
|
+
state = GETTING_PAYLOAD;
|
|
80
|
+
}
|
|
81
|
+
break;
|
|
82
|
+
|
|
83
|
+
case GETTING_PAYLOAD:
|
|
84
|
+
parser_result->msg_loc = buffer + i;
|
|
85
|
+
parser_result->r_loc = i + parser_result->msg_id_len.len;
|
|
86
|
+
parser_result->found = true;
|
|
87
|
+
if (parse_func_ptr->validate_packet(parser_result->msg_loc, &parser_result->msg_id_len)) {
|
|
88
|
+
parser_result->valid = true;
|
|
89
|
+
return true;
|
|
90
|
+
} else {
|
|
91
|
+
parser_result->valid = false;
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
break;
|
|
95
|
+
|
|
96
|
+
default:
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "stdbool.h"
|
|
4
|
+
#include "stdint.h"
|
|
5
|
+
|
|
6
|
+
typedef struct _msg_id_len_t {
|
|
7
|
+
bool valid;
|
|
8
|
+
uint8_t len;
|
|
9
|
+
uint8_t msg_id;
|
|
10
|
+
} msg_id_len_t;
|
|
11
|
+
|
|
12
|
+
typedef struct _parser_functions_t {
|
|
13
|
+
bool (*get_msg_id_len)(msg_id_len_t *, uint8_t);
|
|
14
|
+
bool (*validate_packet)(uint8_t *, msg_id_len_t *);
|
|
15
|
+
} parser_functions_t;
|
|
16
|
+
|
|
17
|
+
typedef struct _struct_frame_config {
|
|
18
|
+
uint8_t has_crc;
|
|
19
|
+
uint8_t has_len;
|
|
20
|
+
uint8_t start_byte;
|
|
21
|
+
parser_functions_t *parser_funcs;
|
|
22
|
+
} struct_frame_config;
|
|
23
|
+
|
|
24
|
+
enum ParserState { LOOKING_FOR_START_BYTE = 0, GETTING_LENGTH_MSG_AND_ID = 1, GETTING_PAYLOAD = 2 };
|
|
25
|
+
|
|
26
|
+
typedef struct _struct_frame_buffer {
|
|
27
|
+
// Used for framing and parsing
|
|
28
|
+
struct_frame_config config;
|
|
29
|
+
uint8_t *data;
|
|
30
|
+
size_t max_size;
|
|
31
|
+
size_t size;
|
|
32
|
+
bool in_progress;
|
|
33
|
+
|
|
34
|
+
// Used for framing
|
|
35
|
+
size_t crc_start_loc;
|
|
36
|
+
|
|
37
|
+
// Used for parsing
|
|
38
|
+
enum ParserState state;
|
|
39
|
+
size_t payload_len;
|
|
40
|
+
msg_id_len_t msg_id_len;
|
|
41
|
+
|
|
42
|
+
} struct_buffer;
|
|
43
|
+
|
|
44
|
+
typedef struct _buffer_parser_result_t {
|
|
45
|
+
struct_frame_config config;
|
|
46
|
+
bool found;
|
|
47
|
+
bool valid;
|
|
48
|
+
uint8_t *msg_loc;
|
|
49
|
+
size_t r_loc;
|
|
50
|
+
bool finished;
|
|
51
|
+
msg_id_len_t msg_id_len;
|
|
52
|
+
} buffer_parser_result_t;
|
|
53
|
+
|
|
54
|
+
// https://github.com/serge-sans-paille/frozen
|
|
55
|
+
// https://www.npmjs.com/package/typed-struct
|
|
56
|
+
|
|
57
|
+
#define default_parser {0, 0, 0x90}
|
|
58
|
+
|
|
59
|
+
#define zero_initialized_parser_result {default_parser, false, false, 0, 0, false, {0, 0}};
|
|
60
|
+
|
|
61
|
+
#define CREATE_DEFAULT_STRUCT_BUFFER(name, size) \
|
|
62
|
+
uint8_t name##_buffer[size]; \
|
|
63
|
+
struct_buffer name = { \
|
|
64
|
+
default_parser, name##_buffer, size, 0, false, 0, LOOKING_FOR_START_BYTE, 0, {false, 0, 0}}
|
|
65
|
+
|
|
66
|
+
typedef struct checksum_t {
|
|
67
|
+
uint8_t byte1;
|
|
68
|
+
uint8_t byte2;
|
|
69
|
+
} checksum_t;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Struct } from 'typed-struct';
|
|
2
|
+
import * as sf_types from './struct_frame_types';
|
|
3
|
+
|
|
4
|
+
function fletcher_checksum_calculation(buffer: Uint8Array, data_length: number): sf_types.checksum_t {
|
|
5
|
+
const checksum: sf_types.checksum_t = { byte1: 0, byte2: 0 };
|
|
6
|
+
|
|
7
|
+
for (let i = 0; i < data_length; i++) {
|
|
8
|
+
checksum.byte1 += buffer[i];
|
|
9
|
+
checksum.byte2 += checksum.byte1;
|
|
10
|
+
}
|
|
11
|
+
return checksum;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function msg_encode(buffer: sf_types.struct_frame_buffer, msg: any, msgid: number) {
|
|
15
|
+
buffer.data[buffer.size++] = buffer.config.start_byte;
|
|
16
|
+
buffer.crc_start_loc = buffer.size;
|
|
17
|
+
buffer.data[buffer.size++] = msgid;
|
|
18
|
+
|
|
19
|
+
if (buffer.config.has_len) {
|
|
20
|
+
buffer.data[buffer.size++] = msg.getSize();
|
|
21
|
+
}
|
|
22
|
+
const rawData = Struct.raw(msg);
|
|
23
|
+
for (let i = 0; i < rawData.length; i++) {
|
|
24
|
+
buffer.data[buffer.size++] = rawData[i]
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (buffer.config.has_crc) {
|
|
28
|
+
const crc = fletcher_checksum_calculation(buffer.data.slice(buffer.crc_start_loc), buffer.crc_start_loc + rawData.length);
|
|
29
|
+
buffer.data[buffer.size++] = crc.byte1;
|
|
30
|
+
buffer.data[buffer.size++] = crc.byte2;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function msg_reserve(buffer: sf_types.struct_frame_buffer, msg_id: number, msg_size: number) {
|
|
35
|
+
throw new Error('Function Unimplemented');
|
|
36
|
+
|
|
37
|
+
if (buffer.in_progress) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
buffer.in_progress = true;
|
|
41
|
+
buffer.data[buffer.size++] = buffer.config.start_byte;
|
|
42
|
+
|
|
43
|
+
buffer.data[buffer.size++] = msg_id;
|
|
44
|
+
if (buffer.config.has_len) {
|
|
45
|
+
buffer.data[buffer.size++] = msg_size;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const ret = Buffer.from(buffer.data, buffer.size, msg_size);
|
|
49
|
+
buffer.size += msg_size;
|
|
50
|
+
return ret;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
export function msg_finish(buffer: sf_types.struct_frame_buffer) {
|
|
56
|
+
throw new Error('Function Unimplemented');
|
|
57
|
+
|
|
58
|
+
if (buffer.config.has_crc) {
|
|
59
|
+
const crc = fletcher_checksum_calculation(buffer.data.slice(buffer.crc_start_loc), buffer.crc_start_loc - buffer.size);
|
|
60
|
+
buffer.data[buffer.size++] = crc.byte1;
|
|
61
|
+
buffer.data[buffer.size++] = crc.byte2;
|
|
62
|
+
buffer.size += 2
|
|
63
|
+
}
|
|
64
|
+
buffer.in_progress = false;
|
|
65
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { get_message_length } from './struct_frame_gen';
|
|
2
|
+
import * as sf_types from './struct_frame_types';
|
|
3
|
+
|
|
4
|
+
function parse_default_format_validate(buffer: Uint8Array, msg_id_len: sf_types.msg_id_len_t): boolean {
|
|
5
|
+
return true;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function parse_default_format_char_for_len_id(c: number, msg_id_len: sf_types.msg_id_len_t): boolean {
|
|
9
|
+
msg_id_len.msg_id = c;
|
|
10
|
+
msg_id_len.len = get_message_length(c);
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const default_parser_functions: sf_types.parser_functions_t = { get_msg_id_len: parse_default_format_char_for_len_id, validate_packet: parse_default_format_validate };
|
|
15
|
+
|
|
16
|
+
function parse_char_for_start_byte(config: sf_types.struct_frame_config, c: number): sf_types.parser_functions_t | undefined {
|
|
17
|
+
if (config.start_byte == c) {
|
|
18
|
+
return default_parser_functions;
|
|
19
|
+
}
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function parse_char(pb: sf_types.struct_frame_buffer, c: number): boolean {
|
|
24
|
+
let parse_func_ptr: sf_types.parser_functions_t | undefined = undefined;
|
|
25
|
+
switch (pb.state) {
|
|
26
|
+
case sf_types.ParserState.LOOKING_FOR_START_BYTE:
|
|
27
|
+
parse_func_ptr = parse_char_for_start_byte(pb.config, c);
|
|
28
|
+
if (parse_func_ptr) {
|
|
29
|
+
pb.config.parser_funcs = parse_func_ptr;
|
|
30
|
+
pb.state = sf_types.ParserState.GETTING_LENGTH_MSG_AND_ID;
|
|
31
|
+
}
|
|
32
|
+
break;
|
|
33
|
+
|
|
34
|
+
case sf_types.ParserState.GETTING_LENGTH_MSG_AND_ID:
|
|
35
|
+
if (pb.config.parser_funcs && pb.config.parser_funcs.get_msg_id_len(c, pb.msg_id_len)) {
|
|
36
|
+
pb.state = sf_types.ParserState.GETTING_PAYLOAD;
|
|
37
|
+
pb.size = 0;
|
|
38
|
+
}
|
|
39
|
+
break;
|
|
40
|
+
|
|
41
|
+
case sf_types.ParserState.GETTING_PAYLOAD:
|
|
42
|
+
pb.data[pb.size] = c;
|
|
43
|
+
pb.size++;
|
|
44
|
+
if (pb.size >= pb.msg_id_len.len) {
|
|
45
|
+
pb.msg_data = Buffer.from(pb.data, 0, pb.size)
|
|
46
|
+
pb.state = sf_types.ParserState.LOOKING_FOR_START_BYTE;
|
|
47
|
+
if (pb.config.parser_funcs) {
|
|
48
|
+
return pb.config.parser_funcs.validate_packet(pb.data, pb.msg_id_len);
|
|
49
|
+
}
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
break;
|
|
53
|
+
|
|
54
|
+
default:
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function parse_buffer(buffer: Uint8Array, size: number, parser_result: sf_types.buffer_parser_result_t): boolean {
|
|
62
|
+
let state: sf_types.ParserState = sf_types.ParserState.LOOKING_FOR_START_BYTE;
|
|
63
|
+
let parse_func_ptr: sf_types.parser_functions_t | undefined;
|
|
64
|
+
for (let i = parser_result.r_loc; i < size; i++) {
|
|
65
|
+
switch (state) {
|
|
66
|
+
case sf_types.ParserState.LOOKING_FOR_START_BYTE:
|
|
67
|
+
parse_func_ptr = parse_char_for_start_byte(parser_result.config, buffer[i]);
|
|
68
|
+
if (parse_func_ptr) {
|
|
69
|
+
state = sf_types.ParserState.GETTING_LENGTH_MSG_AND_ID;
|
|
70
|
+
}
|
|
71
|
+
break;
|
|
72
|
+
|
|
73
|
+
case sf_types.ParserState.GETTING_LENGTH_MSG_AND_ID:
|
|
74
|
+
if (parse_func_ptr && parse_func_ptr.get_msg_id_len(buffer[i], parser_result.msg_id_len)) {
|
|
75
|
+
state = sf_types.ParserState.GETTING_PAYLOAD;
|
|
76
|
+
}
|
|
77
|
+
break;
|
|
78
|
+
|
|
79
|
+
case sf_types.ParserState.GETTING_PAYLOAD:
|
|
80
|
+
parser_result.msg_data = Buffer.from(buffer, i, (i + parser_result.msg_id_len.len));
|
|
81
|
+
parser_result.r_loc = i + parser_result.msg_id_len.len;
|
|
82
|
+
parser_result.found = true;
|
|
83
|
+
if (parse_func_ptr && parse_func_ptr.validate_packet(parser_result.msg_data, parser_result.msg_id_len)) {
|
|
84
|
+
parser_result.valid = true;
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
parser_result.valid = false;
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
break;
|
|
92
|
+
|
|
93
|
+
default:
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
|
|
2
|
+
export class msg_id_len_t {
|
|
3
|
+
valid = false;
|
|
4
|
+
len = 0;
|
|
5
|
+
msg_id = 0;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export type GetMsgIdLenType = (c: number, msg_id_len: msg_id_len_t) => boolean;
|
|
9
|
+
export type ValidatePacketType = (buffer: Uint8Array, msg_id_len: msg_id_len_t) => boolean;
|
|
10
|
+
|
|
11
|
+
export interface parser_functions_t {
|
|
12
|
+
get_msg_id_len: GetMsgIdLenType;
|
|
13
|
+
validate_packet: ValidatePacketType;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface struct_frame_config {
|
|
17
|
+
has_crc: number;
|
|
18
|
+
has_len: number;
|
|
19
|
+
start_byte: number;
|
|
20
|
+
parser_funcs?: parser_functions_t;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export enum ParserState {
|
|
24
|
+
LOOKING_FOR_START_BYTE = 0,
|
|
25
|
+
GETTING_LENGTH_MSG_AND_ID = 1,
|
|
26
|
+
GETTING_PAYLOAD = 2
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const basic_frame_config: struct_frame_config = { has_crc: 0, has_len: 0, start_byte: 0x90 };
|
|
30
|
+
|
|
31
|
+
export class struct_frame_buffer {
|
|
32
|
+
// Used for framing and parsing
|
|
33
|
+
config: struct_frame_config = basic_frame_config;
|
|
34
|
+
data: Uint8Array;
|
|
35
|
+
size = 0;
|
|
36
|
+
in_progress = false;
|
|
37
|
+
|
|
38
|
+
// Used for framing
|
|
39
|
+
crc_start_loc = 0;
|
|
40
|
+
|
|
41
|
+
// Used for parsing
|
|
42
|
+
state: ParserState = ParserState.LOOKING_FOR_START_BYTE;
|
|
43
|
+
payload_len = 0;
|
|
44
|
+
msg_id_len: msg_id_len_t = new msg_id_len_t();
|
|
45
|
+
msg_data: Buffer = Buffer.allocUnsafe(0);
|
|
46
|
+
|
|
47
|
+
constructor(public max_size: number, buffer?: Uint8Array) {
|
|
48
|
+
if (buffer) {
|
|
49
|
+
this.data = buffer;
|
|
50
|
+
} else {
|
|
51
|
+
this.data = new Uint8Array(max_size);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export class buffer_parser_result_t {
|
|
57
|
+
config: struct_frame_config = basic_frame_config;
|
|
58
|
+
found = false;
|
|
59
|
+
valid = false;
|
|
60
|
+
msg_data: Buffer = Buffer.allocUnsafe(0);
|
|
61
|
+
r_loc = 0;
|
|
62
|
+
finished = false;
|
|
63
|
+
msg_id_len: msg_id_len_t = new msg_id_len_t();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// https://github.com/serge-sans-paille/frozen
|
|
67
|
+
// https://www.npmjs.com/package/typed-struct
|
|
68
|
+
|
|
69
|
+
//#define default_parser { 0, 0, 0x90 }
|
|
70
|
+
//
|
|
71
|
+
//#define zero_initialized_parser_result { default_parser, false, false, 0, 0, false, { 0, 0} };
|
|
72
|
+
//
|
|
73
|
+
//#define CREATE_DEFAULT_STRUCT_BUFFER(name, size) \
|
|
74
|
+
// uint8_t name##_buffer[size]; \
|
|
75
|
+
// struct_buffer name = { default_parser, name##_buffer, size, 0, 0, false, 0, 0, 0, 0, NULL }
|
|
76
|
+
|
|
77
|
+
export interface checksum_t {
|
|
78
|
+
byte1: number;
|
|
79
|
+
byte2: number;
|
|
80
|
+
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{struct_frame-0.0.14 → struct_frame-0.0.16}/src/struct_frame/boilerplate/c/struct_frame_gen.h
RENAMED
|
File without changes
|
{struct_frame-0.0.14 → struct_frame-0.0.16}/src/struct_frame/boilerplate/c/struct_frame_parser.h
RENAMED
|
File without changes
|
{struct_frame-0.0.14 → struct_frame-0.0.16}/src/struct_frame/boilerplate/c/struct_frame_types.h
RENAMED
|
File without changes
|
|
File without changes
|
{struct_frame-0.0.14 → struct_frame-0.0.16}/src/struct_frame/boilerplate/ts/struct_frame_gen.ts
RENAMED
|
File without changes
|
{struct_frame-0.0.14 → struct_frame-0.0.16}/src/struct_frame/boilerplate/ts/struct_frame_parser.ts
RENAMED
|
File without changes
|
{struct_frame-0.0.14 → struct_frame-0.0.16}/src/struct_frame/boilerplate/ts/struct_frame_types.ts
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|