struct-frame 0.0.22__tar.gz → 0.0.24__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.

Files changed (35) hide show
  1. {struct_frame-0.0.22 → struct_frame-0.0.24}/.gitignore +2 -1
  2. {struct_frame-0.0.22 → struct_frame-0.0.24}/DEVGUIDE.md +4 -0
  3. {struct_frame-0.0.22 → struct_frame-0.0.24}/PKG-INFO +2 -1
  4. {struct_frame-0.0.22 → struct_frame-0.0.24}/index.ts +8 -5
  5. struct_frame-0.0.24/main.c +73 -0
  6. {struct_frame-0.0.22 → struct_frame-0.0.24}/myl_vehicle.proto +8 -8
  7. {struct_frame-0.0.22 → struct_frame-0.0.24}/pyproject.toml +2 -1
  8. {struct_frame-0.0.22 → struct_frame-0.0.24}/src/struct_frame/__init__.py +2 -1
  9. {struct_frame-0.0.22 → struct_frame-0.0.24}/src/struct_frame/boilerplate/c/struct_frame.h +5 -0
  10. struct_frame-0.0.24/src/struct_frame/boilerplate/c/struct_frame_cpp.h +41 -0
  11. {struct_frame-0.0.22 → struct_frame-0.0.24}/src/struct_frame/boilerplate/c/struct_frame_parser.h +3 -1
  12. {struct_frame-0.0.22 → struct_frame-0.0.24}/src/struct_frame/boilerplate/c/struct_frame_types.h +1 -2
  13. struct_frame-0.0.24/src/struct_frame/boilerplate/py/struct_frame_parser.py +118 -0
  14. struct_frame-0.0.24/src/struct_frame/boilerplate/ts/struct_frame_gen.ts +7 -0
  15. {struct_frame-0.0.22 → struct_frame-0.0.24}/src/struct_frame/generate.py +22 -2
  16. struct_frame-0.0.24/src/struct_frame/py_gen.py +160 -0
  17. {struct_frame-0.0.22 → struct_frame-0.0.24}/src/struct_frame/ts_gen.py +15 -12
  18. {struct_frame-0.0.22 → struct_frame-0.0.24}/tsconfig.json +13 -17
  19. struct_frame-0.0.22/biostream.proto +0 -41
  20. struct_frame-0.0.22/main.c +0 -80
  21. struct_frame-0.0.22/src/struct_frame/boilerplate/ts/struct_frame_gen.ts +0 -7
  22. {struct_frame-0.0.22 → struct_frame-0.0.24}/.clang-format +0 -0
  23. {struct_frame-0.0.22 → struct_frame-0.0.24}/LICENSE +0 -0
  24. {struct_frame-0.0.22 → struct_frame-0.0.24}/README.md +0 -0
  25. {struct_frame-0.0.22 → struct_frame-0.0.24}/TODO +0 -0
  26. {struct_frame-0.0.22 → struct_frame-0.0.24}/package-lock.json +0 -0
  27. {struct_frame-0.0.22 → struct_frame-0.0.24}/package.json +0 -0
  28. {struct_frame-0.0.22 → struct_frame-0.0.24}/src/main.py +0 -0
  29. {struct_frame-0.0.22 → struct_frame-0.0.24}/src/struct_frame/__main__.py +0 -0
  30. {struct_frame-0.0.22 → struct_frame-0.0.24}/src/struct_frame/base.py +0 -0
  31. {struct_frame-0.0.22 → struct_frame-0.0.24}/src/struct_frame/boilerplate/c/struct_frame_gen.h +0 -0
  32. {struct_frame-0.0.22 → struct_frame-0.0.24}/src/struct_frame/boilerplate/ts/struct_frame.ts +0 -0
  33. {struct_frame-0.0.22 → struct_frame-0.0.24}/src/struct_frame/boilerplate/ts/struct_frame_parser.ts +0 -0
  34. {struct_frame-0.0.22 → struct_frame-0.0.24}/src/struct_frame/boilerplate/ts/struct_frame_types.ts +0 -0
  35. {struct_frame-0.0.22 → struct_frame-0.0.24}/src/struct_frame/c_gen.py +0 -0
@@ -4,4 +4,5 @@ node_modules
4
4
  main.exe
5
5
  dist
6
6
  generated
7
- __pycache__/
7
+ __pycache__/
8
+ gen
@@ -13,4 +13,8 @@ Update version in pyproject.toml if needed
13
13
 
14
14
 
15
15
  ### Running Locally
16
+ Install dependancies
17
+ ```py -m pip install proto-schema-parser```
18
+
19
+ Run module
16
20
  ```py .\src\main.py ```
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: struct-frame
3
- Version: 0.0.22
3
+ Version: 0.0.24
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
@@ -11,6 +11,7 @@ Classifier: Operating System :: OS Independent
11
11
  Classifier: Programming Language :: Python :: 3
12
12
  Requires-Python: >=3.8
13
13
  Requires-Dist: proto-schema-parser>=1.4.5
14
+ Requires-Dist: structured-classes>=3.1.0
14
15
  Description-Content-Type: text/markdown
15
16
 
16
17
 
@@ -1,6 +1,6 @@
1
- import * as mv from './ts/myl_vehicle.sf';
2
- import { parse_char, parse_buffer } from './ts/struct_frame_parser';
3
- import { struct_frame_buffer, buffer_parser_result_t, } from './ts/struct_frame_types';
1
+ import * as mv from './gen/ts/myl_vehicle.sf';
2
+ import { parse_char, parse_buffer } from './gen/ts/struct_frame_parser';
3
+ import { struct_frame_buffer, buffer_parser_result_t, } from './gen/ts/struct_frame_types';
4
4
  import { type ExtractType } from 'typed-struct';
5
5
 
6
6
  let tx_buffer = new struct_frame_buffer(256)
@@ -15,7 +15,7 @@ mv.myl_vehicle_pose_encode(tx_buffer, msg);
15
15
  let hb = new mv.myl_vehicle_heartbeat();
16
16
 
17
17
  hb.id = 23;
18
- hb.type = mv.myl_vehicle_VehicleType.myl_vehicle_VEHICLE_TYPE_FW;
18
+ hb.type = mv.myl_vehicletype.FW;
19
19
  mv.myl_vehicle_heartbeat_encode(tx_buffer, hb);
20
20
 
21
21
 
@@ -61,6 +61,9 @@ while (parse_buffer(tx_buffer.data, tx_buffer.max_size, result)) {
61
61
  }
62
62
 
63
63
  if (hb && hb3 && hb5) {
64
- console.log("%d %d %d %d", hb.id, hb.type, hb3.id, hb3.type, hb5.id, hb5.type);
64
+ //console.log("%d %d %d %d", hb.id, hb.type, hb3.id, hb3.type, hb5.id, hb5.type);
65
+ console.log(hb)
66
+ console.log(hb3)
67
+ console.log(hb5)
65
68
  }
66
69
 
@@ -0,0 +1,73 @@
1
+ #include <stdio.h>
2
+
3
+ #include "c/struct_frame_gen.h"
4
+ #include "c/struct_frame_parser.h"
5
+
6
+ // CREATE_DEFAULT_STRUCT_BUFFER(tx_buffer, 256);
7
+ uint8_t tx_buffer_buffer[256];
8
+ struct_buffer tx_buffer = {default_parser, tx_buffer_buffer, 256, 0, 0, false, 0, 0, 0};
9
+
10
+ // CREATE_DEFAULT_STRUCT_BUFFER(rx_buffer, 256);
11
+ uint8_t rx_buffer_buffer[256];
12
+ struct_buffer rx_buffer = {default_parser, rx_buffer_buffer, 256, 0, 0, false, 0, 0, 0};
13
+
14
+ int main() {
15
+ MylVehiclePose msg;
16
+ msg.pitch = 100;
17
+ msg.yaw_rate = -1.45;
18
+ msg.test = 4883;
19
+ myl_vehicle_pose_encode(&tx_buffer, &msg);
20
+
21
+ MylVehicleHeartbeat *hb;
22
+ if (myl_vehicle_heartbeat_reserve(&tx_buffer, &hb)) {
23
+ hb->id = 23;
24
+ hb->type = VEHICLE_TYPE_VEHICLE_TYPE_FW;
25
+ myl_vehicle_heartbeat_finish(&tx_buffer);
26
+ }
27
+
28
+ MylVehiclePose msg2;
29
+ MylVehicleHeartbeat *hb2;
30
+ MylVehicleHeartbeat hb3;
31
+ for (int i = 0; i < tx_buffer.size; i++) {
32
+ if (parse_char(&rx_buffer, tx_buffer.data[i])) {
33
+ switch (rx_buffer.msg_id_len.msg_id) {
34
+ case MYL_VEHICLE_HEARTBEAT_MSG_ID:
35
+ printf("got hb msg with id %d\n", rx_buffer.msg_id_len.msg_id);
36
+ hb2 = myl_vehicle_heartbeat_get_ref(&rx_buffer);
37
+ hb3 = myl_vehicle_heartbeat_get(&rx_buffer);
38
+ break;
39
+ case MYL_VEHICLE_POSE_MSG_ID:
40
+ printf("got pose msg with id %d\n", rx_buffer.msg_id_len.msg_id);
41
+ msg2 = myl_vehicle_pose_get(&rx_buffer);
42
+ break;
43
+
44
+ default:
45
+ break;
46
+ }
47
+ }
48
+ }
49
+
50
+ MylVehiclePose msg3;
51
+ MylVehicleHeartbeat *hb4;
52
+ MylVehicleHeartbeat hb5;
53
+ buffer_parser_result_t result = zero_initialized_parser_result;
54
+ while (parse_buffer(tx_buffer_buffer, 256, &result)) {
55
+ switch (result.msg_id_len.msg_id) {
56
+ case MYL_VEHICLE_HEARTBEAT_MSG_ID:
57
+ printf("got hb msg with id %d\n", result.msg_id_len.msg_id);
58
+ hb4 = myl_vehicle_heartbeat_get_ref_from_buffer_result(result);
59
+ hb5 = myl_vehicle_heartbeat_get_from_buffer_result(result);
60
+ break;
61
+ case MYL_VEHICLE_POSE_MSG_ID:
62
+ printf("got pose msg with id %d\n", result.msg_id_len.msg_id);
63
+ msg3 = myl_vehicle_pose_get_from_buffer_result(result);
64
+ break;
65
+
66
+ default:
67
+ break;
68
+ }
69
+ }
70
+ printf("%d %d %d %d", hb->id, hb->type, hb2->id, hb2->type);
71
+
72
+ return 0;
73
+ }
@@ -2,13 +2,13 @@ syntax = "proto3";
2
2
  import "nanopb.proto";
3
3
  package myl_vehicle;
4
4
 
5
- enum VehicleType {
6
- VEHICLE_TYPE_UNSPECIFIED = 0;
7
- VEHICLE_TYPE_ROVER = 1;
8
- VEHICLE_TYPE_BOAT = 2;
9
- VEHICLE_TYPE_FW = 3;
10
- VEHICLE_TYPE_MR = 4;
11
- VEHICLE_TYPE_CAR = 5;
5
+ enum Type {
6
+ UNSPECIFIED = 0;
7
+ ROVER = 1;
8
+ BOAT = 2;
9
+ FW = 3;
10
+ MR = 4;
11
+ CAR = 5;
12
12
  }
13
13
 
14
14
  message position {
@@ -35,7 +35,7 @@ message pose {
35
35
 
36
36
  message heartbeat {
37
37
  option msgid = 3;
38
- VehicleType type = 1;
38
+ Type type = 1;
39
39
  int32 id = 2;
40
40
  }
41
41
 
@@ -4,11 +4,12 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "struct-frame"
7
- version = "0.0.22"
7
+ version = "0.0.24"
8
8
  authors = [
9
9
  { name="Rijesh Augustine", email="rijesh@mylonics.com" },
10
10
  ]
11
11
  dependencies = [
12
+ "structured-classes>=3.1.0",
12
13
  "proto-schema-parser>=1.4.5",
13
14
  ]
14
15
  description = "A framework for serializing data with headers"
@@ -2,8 +2,9 @@ from .base import version, NamingStyleC, CamelToSnakeCase, pascalCase
2
2
 
3
3
  from .c_gen import FileCGen
4
4
  from .ts_gen import FileTsGen
5
+ from .py_gen import FilePyGen
5
6
 
6
7
  from .generate import main
7
8
 
8
- __all__ = ["main", "FileCGen", "FileTsGen", "version",
9
+ __all__ = ["main", "FileCGen", "FileTsGen", "FilePyGen", "version",
9
10
  "NamingStyleC", "CamelToSnakeCase", "pascalCase"]
@@ -88,11 +88,16 @@ static inline bool msg_finish(struct_buffer *buffer) {
88
88
  name msg = *(name *)(buffer->data); \
89
89
  return msg; \
90
90
  } \
91
+ static inline name funcname##_get(uint8_t *buffer) { \
92
+ name msg = *(name *)(buffer); \
93
+ return msg; \
94
+ } \
91
95
  static inline name funcname##_get_from_buffer_result(buffer_parser_result_t result) { \
92
96
  name msg = *(name *)(result.msg_loc); \
93
97
  return msg; \
94
98
  } \
95
99
  static inline name *funcname##_get_ref(struct_buffer *buffer) { return (name *)(buffer->data); } \
100
+ static inline name *funcname##_get_ref(uint8_t *buffer) { return (name *)(buffer); } \
96
101
  static inline name *funcname##_get_ref_from_buffer_result(buffer_parser_result_t result) { \
97
102
  return (name *)(result.msg_loc); \
98
103
  }
@@ -0,0 +1,41 @@
1
+ #pragma once
2
+
3
+ #include "struct_frame_parser.h"
4
+ #include "struct_frame_types.h"
5
+
6
+ class StructFrameDevice : public struct_buffer {
7
+ public:
8
+ StructFrameDevice(struct_frame_config config)
9
+ : struct_buffer{config, nullptr, 0, 0, false, 0, LOOKING_FOR_START_BYTE, 0, {false, 0, 0}},
10
+ parser_result_{config, false, 0, 0, false, {0, 0}} {}
11
+
12
+ void RunRx() {
13
+ uint8_t *buffer;
14
+ size_t buffer_size;
15
+ GetArray(buffer, buffer_size);
16
+ if (buffer && buffer_size) {
17
+ while (!parser_result_.finished) {
18
+ if (parse_buffer(buffer, buffer_size, &parser_result_)) {
19
+ if (parser_result_.valid) {
20
+ HandleResult();
21
+ }
22
+ }
23
+ }
24
+ }
25
+ }
26
+
27
+ void RunTx() { PutArray(struct_buffer::data, struct_buffer::max_size, struct_buffer::size); }
28
+
29
+ protected:
30
+ void Init() { PutArray(struct_buffer::data, struct_buffer::max_size, 0); }
31
+
32
+ // Put Array must accept the full buffer of data and returns a pointer to either a new buffer or the same buffer
33
+ // that is free
34
+ virtual void PutArray(uint8_t *&buffer, size_t &max_length, size_t length) = 0;
35
+
36
+ // Get array, a pointer to an array and refernce to the array length is pased and mutated by this function
37
+ virtual void GetArray(uint8_t *&buffer, size_t &length) = 0;
38
+
39
+ virtual void HandleResult() = 0;
40
+ buffer_parser_result_t parser_result_;
41
+ };
@@ -63,6 +63,7 @@ static inline bool parse_char(struct_buffer *pb, uint8_t c) {
63
63
  static inline bool parse_buffer(uint8_t *buffer, size_t size, buffer_parser_result_t *parser_result) {
64
64
  enum ParserState state = LOOKING_FOR_START_BYTE;
65
65
  parser_functions_t *parse_func_ptr;
66
+ parser_result->finished = false;
66
67
  for (size_t i = parser_result->r_loc; i < size; i++) {
67
68
  switch (state) {
68
69
  case LOOKING_FOR_START_BYTE:
@@ -81,7 +82,6 @@ static inline bool parse_buffer(uint8_t *buffer, size_t size, buffer_parser_resu
81
82
  case GETTING_PAYLOAD:
82
83
  parser_result->msg_loc = buffer + i;
83
84
  parser_result->r_loc = i + parser_result->msg_id_len.len;
84
- parser_result->found = true;
85
85
  if (parse_func_ptr->validate_packet(parser_result->msg_loc, &parser_result->msg_id_len)) {
86
86
  parser_result->valid = true;
87
87
  return true;
@@ -95,5 +95,7 @@ static inline bool parse_buffer(uint8_t *buffer, size_t size, buffer_parser_resu
95
95
  break;
96
96
  }
97
97
  }
98
+ parser_result->finished = true;
99
+ parser_result->r_loc = 0;
98
100
  return false;
99
101
  }
@@ -43,7 +43,6 @@ typedef struct _struct_frame_buffer {
43
43
 
44
44
  typedef struct _buffer_parser_result_t {
45
45
  struct_frame_config config;
46
- bool found;
47
46
  bool valid;
48
47
  uint8_t *msg_loc;
49
48
  size_t r_loc;
@@ -56,7 +55,7 @@ typedef struct _buffer_parser_result_t {
56
55
 
57
56
  #define default_parser {0, 0, 0x90}
58
57
 
59
- #define zero_initialized_parser_result {default_parser, false, false, 0, 0, false, {0, 0}};
58
+ #define zero_initialized_parser_result {default_parser, false, 0, 0, false, {0, 0}}
60
59
 
61
60
  #define CREATE_DEFAULT_STRUCT_BUFFER(name, size) \
62
61
  uint8_t name##_buffer[size]; \
@@ -0,0 +1,118 @@
1
+
2
+ from enum import Enum
3
+
4
+
5
+ def fletcher_checksum_calculation(buffer, start=0, end=None):
6
+ if end == None:
7
+ end = buffer.length
8
+
9
+ byte1 = 0
10
+ byte2 = 2
11
+
12
+ for x in range(start, end):
13
+ byte1 += buffer[x]
14
+ byte2 += byte1
15
+
16
+ return [byte1, byte2]
17
+
18
+
19
+ class BasicPacket:
20
+ start_byte = None
21
+ header_length = 0
22
+ footer_length = 0
23
+
24
+ desired_packet_length = 0
25
+ packet = []
26
+
27
+ def __init__(self, start_byte, header_length, footer_length):
28
+ self.start_byte = start_byte
29
+ self.header_length = header_length
30
+ self.footer_length = footer_length
31
+
32
+ def add_header_byte(self, byte, clear):
33
+ if clear:
34
+ self.packet.clear()
35
+ self.packet.push(byte)
36
+ return len(self.packet) == self.header_length
37
+
38
+ def add_packet_byte(self, byte):
39
+ self.packet.push(byte)
40
+ return len(self.packet) == self.desired_packet_length
41
+
42
+ def get_msg_id(self):
43
+ return self.packet[1]
44
+
45
+ def get_full_packet_length(self, msg_length):
46
+ self.desired_packet_length = self.header_length + self.footer_length + msg_length
47
+ return self.desired_packet_length
48
+
49
+ def validate_packet(self):
50
+ checksum = fletcher_checksum_calculation(
51
+ self.packet, self.header_length, self.desired_packet_length - self.footer_length)
52
+ return checksum[0] == self.packet[-2] and checksum[1] == self.packet[-1]
53
+
54
+ def get_msg_buffer(self):
55
+ return self.packet[self.header_length:self.desired_packet_length - self.footer_length]
56
+
57
+ def encode(self, data, msg_id):
58
+ output = []
59
+ output.push(self.start_byte)
60
+ output.push(msg_id)
61
+ output.push(data)
62
+ checksum = fletcher_checksum_calculation(data)
63
+
64
+ output.push(checksum[0])
65
+ output.push(checksum[1])
66
+ return output
67
+
68
+
69
+ class ParserState(Enum):
70
+ LOOKING_FOR_START_BYTE = 0
71
+ GETTING_HEADER = 1
72
+ GETTING_PACKET = 2
73
+
74
+
75
+ class FrameParser:
76
+ state = ParserState.LOOKING_FOR_START_BYTE
77
+ buffer = []
78
+ parser = None
79
+ msg_definitions = None
80
+ msg_id_loc = None
81
+ msg_type = None
82
+
83
+ def __init__(self, parsers, msg_definitions):
84
+ self.parsers = parsers
85
+ self.msg_definitions = msg_definitions
86
+
87
+ def parse_char(self, c):
88
+ if state == ParserState.LOOKING_FOR_START_BYTE:
89
+ self.parser = self.parsers[c]
90
+ if self.parser:
91
+ if self.parser.add_header_byte(c, True):
92
+ state = ParserState.GETTING_PACKET
93
+ else:
94
+ state = ParserState.GETTING_HEADER
95
+
96
+ elif state == ParserState.GETTING_HEADER:
97
+ if self.parser.add_header_byte(c):
98
+ msg_id = self.parser.get_msg_id()
99
+ self.msg_type = self.msg_definitions[msg_id]
100
+ if self.msg_type:
101
+ self.parser.get_full_packet_length(self.msg_type.msg_size)
102
+ state = ParserState.GETTING_PACKET
103
+ else:
104
+ state = ParserState.LOOKING_FOR_START_BYTE
105
+
106
+ elif state == ParserState.GETTING_PACKET:
107
+ if self.parser.add_packet_byte(c):
108
+ state = ParserState.LOOKING_FOR_START_BYTE
109
+ if self.parser.validatePackage:
110
+ return self.msg_type.create_unpack(self.parser.get_msg_buffer())
111
+
112
+ return False
113
+
114
+
115
+ def TestFunction():
116
+ parsers = {BasicPacket.start_byte, BasicPacket()}
117
+ frameParser = FrameParser(parsers)
118
+ frameParser.parse_char
@@ -0,0 +1,7 @@
1
+
2
+ import * as myl from './myl_vehicle.sf';
3
+
4
+ export function get_message_length(msg_id: number) {
5
+ console.log(msg_id)
6
+ return myl.get_message_length(msg_id);
7
+ }
@@ -6,6 +6,7 @@ import os
6
6
  import shutil
7
7
  from struct_frame import FileCGen
8
8
  from struct_frame import FileTsGen
9
+ from struct_frame import FilePyGen
9
10
  from proto_schema_parser.parser import Parser
10
11
  from proto_schema_parser import ast
11
12
 
@@ -258,8 +259,10 @@ parser.add_argument('filename')
258
259
  parser.add_argument('--debug', action='store_true')
259
260
  parser.add_argument('--build_c', action='store_true')
260
261
  parser.add_argument('--build_ts', action='store_true')
262
+ parser.add_argument('--build_py', action='store_true')
261
263
  parser.add_argument('--c_path', nargs=1, type=str, default=['c/'])
262
264
  parser.add_argument('--ts_path', nargs=1, type=str, default=['ts/'])
265
+ parser.add_argument('--py_path', nargs=1, type=str, default=['py/'])
263
266
 
264
267
 
265
268
  def parseFile(filename):
@@ -334,11 +337,20 @@ def generateTsFileStrings(path):
334
337
  return out
335
338
 
336
339
 
340
+ def generatePyFileStrings(path):
341
+ out = {}
342
+ for key, value in packages.items():
343
+ name = os.path.join(path, value.name + ".sf.py")
344
+ data = ''.join(FilePyGen.generate(value))
345
+ out[name] = data
346
+ return out
347
+
348
+
337
349
  def main():
338
350
  args = parser.parse_args()
339
351
  parseFile(args.filename)
340
352
 
341
- if (not args.build_c and not args.build_ts):
353
+ if (not args.build_c and not args.build_ts and not args.build_py):
342
354
  print("Select at least one build argument")
343
355
  return
344
356
 
@@ -348,12 +360,16 @@ def main():
348
360
  print(
349
361
  f'Recursion Error. Messages most likely have a cyclical dependancy. Check Message: {recErrCurrentMessage} and Field: {recErrCurrentField}')
350
362
 
363
+ files = {}
351
364
  if (args.build_c):
352
- files = generateCFileStrings(args.c_path[0])
365
+ files.update(generateCFileStrings(args.c_path[0]))
353
366
 
354
367
  if (args.build_ts):
355
368
  files.update(generateTsFileStrings(args.ts_path[0]))
356
369
 
370
+ if (args.build_py):
371
+ files.update(generatePyFileStrings(args.py_path[0]))
372
+
357
373
  for filename, filedata in files.items():
358
374
  dirname = os.path.dirname(filename)
359
375
  if dirname and not os.path.exists(dirname):
@@ -372,6 +388,10 @@ def main():
372
388
  shutil.copytree(os.path.join(dir_path, "boilerplate/ts"),
373
389
  args.ts_path[0], dirs_exist_ok=True)
374
390
 
391
+ if (args.build_py):
392
+ shutil.copytree(os.path.join(dir_path, "boilerplate/py"),
393
+ args.py_path[0], dirs_exist_ok=True)
394
+
375
395
  if args.debug:
376
396
  printPackages()
377
397
  print("Struct Frame successfully completed")
@@ -0,0 +1,160 @@
1
+ #!/usr/bin/env python3
2
+ # kate: replace-tabs on; indent-width 4;
3
+
4
+ from struct_frame import version, NamingStyleC, CamelToSnakeCase, pascalCase
5
+ import time
6
+
7
+ StyleC = NamingStyleC()
8
+
9
+ py_types = {"uint8": "uint8",
10
+ "int8": "int8",
11
+ "uint16": "uint16",
12
+ "int16": "int16",
13
+ "uint32": "uint32",
14
+ "int32": "int32",
15
+ "bool": "bool8",
16
+ "float": "float32",
17
+ "double": "float64",
18
+ "uint64": 'uint64',
19
+ "int64": 'int64',
20
+ }
21
+
22
+
23
+ class EnumPyGen():
24
+ @staticmethod
25
+ def generate(field):
26
+ leading_comment = field.comments
27
+
28
+ result = ''
29
+ if leading_comment:
30
+ for c in leading_comment:
31
+ result = '#%s\n' % c
32
+
33
+ enumName = '%s%s' % (pascalCase(field.package), field.name)
34
+ result += 'class %s(Enum):\n' % (enumName)
35
+
36
+ enum_length = len(field.data)
37
+ enum_values = []
38
+ for index, (d) in enumerate(field.data):
39
+ leading_comment = field.data[d][1]
40
+
41
+ if leading_comment:
42
+ for c in leading_comment:
43
+ enum_values.append("#" + c)
44
+
45
+ enum_value = " %s_%s = %d" % (CamelToSnakeCase(
46
+ field.name).upper(), StyleC.enum_entry(d), field.data[d][0])
47
+
48
+ enum_values.append(enum_value)
49
+
50
+ result += '\n'.join(enum_values)
51
+ return result
52
+
53
+
54
+ class FieldPyGen():
55
+ @staticmethod
56
+ def generate(field):
57
+ result = ''
58
+
59
+ var_name = field.name
60
+ type_name = field.fieldType
61
+ if type_name in py_types:
62
+ type_name = py_types[type_name]
63
+ else:
64
+ type_name = '%s%s' % (pascalCase(field.package), type_name)
65
+ if field.isEnum:
66
+ type_name = 'uint8 #%s' % type_name
67
+
68
+ result += ' %s: %s' % (var_name, type_name)
69
+
70
+ leading_comment = field.comments
71
+ if leading_comment:
72
+ for c in leading_comment:
73
+ result = "#" + c + "\n" + result
74
+
75
+ return result
76
+
77
+
78
+ class MessagePyGen():
79
+ @staticmethod
80
+ def generate(msg):
81
+ leading_comment = msg.comments
82
+
83
+ result = ''
84
+ if leading_comment:
85
+ for c in msg.comments:
86
+ result = '#%s\n' % c
87
+
88
+ structName = '%s%s' % (pascalCase(msg.package), msg.name)
89
+ result += 'class %s(Structured):\n' % structName
90
+ result += ' msg_size = %s\n' % msg.size
91
+ if msg.id:
92
+ result += ' msg_id = %s\n' % msg.id
93
+
94
+ size = 1
95
+ if not msg.fields:
96
+ # Empty structs are not allowed in C standard.
97
+ # Therefore add a dummy field if an empty message occurs.
98
+ result += ' dummy_field: pad'
99
+ else:
100
+ size = msg.size
101
+
102
+ result += '\n'.join([FieldPyGen.generate(f)
103
+ for key, f in msg.fields.items()])
104
+
105
+ # defineName = '%s_%s' % (CamelToSnakeCase(
106
+ # msg.package).upper(), CamelToSnakeCase(msg.name).upper())
107
+ # result += '#define %s_MAX_SIZE %d\n' % (defineName, size)
108
+ #
109
+ # if msg.id:
110
+ # result += '#define %s_MSG_ID %d\n' % (defineName, msg.id)
111
+ #
112
+ # funcName = defineName.lower()
113
+ # if msg.id:
114
+ # result += 'MESSAGE_HELPER(%s, %s, %d, %d);\n\n' % (funcName, structName,
115
+ # size, msg.id)
116
+ #
117
+ return result + '\n'
118
+
119
+ @staticmethod
120
+ def get_initializer(msg, null_init):
121
+ if not msg.fields:
122
+ return '{0}'
123
+
124
+ parts = []
125
+ for field in msg.fields:
126
+ parts.append(field.get_initializer(null_init))
127
+ return '{' + ', '.join(parts) + '}'
128
+
129
+
130
+ class FilePyGen():
131
+ @staticmethod
132
+ def generate(package):
133
+ yield '# Automatically generated struct frame header \n'
134
+ yield '# Generated by %s at %s. \n\n' % (version, time.asctime())
135
+
136
+ yield 'from structured import *\n'
137
+ yield 'from enum import Enum\n\n'
138
+
139
+ if package.enums:
140
+ yield '# Enum definitions\n'
141
+ for key, enum in package.enums.items():
142
+ yield EnumPyGen.generate(enum) + '\n\n'
143
+
144
+ if package.messages:
145
+ yield '# Struct definitions \n'
146
+ # Need to sort messages to make sure dependecies are properly met
147
+
148
+ for key, msg in package.sortedMessages().items():
149
+ yield MessagePyGen.generate(msg) + '\n'
150
+ yield '\n'
151
+
152
+ if package.messages:
153
+
154
+ yield '%s_definitions = {\n' % package.name
155
+ for key, msg in package.sortedMessages().items():
156
+ if msg.id:
157
+ structName = '%s%s' % (pascalCase(msg.package), msg.name)
158
+ yield ' %s: %s,\n' % (msg.id, structName)
159
+
160
+ yield '}\n'
@@ -101,9 +101,10 @@ class MessageTsGen():
101
101
  for c in msg.comments:
102
102
  result = '%s\n' % c
103
103
 
104
- struct_name = '%s_%s' % (packageName, StyleC.type_name(msg.name))
104
+ package_msg_name = '%s_%s' % (packageName, msg.name)
105
+
105
106
  result += 'export const %s = new typed_struct.Struct(\'%s\') ' % (
106
- struct_name, struct_name)
107
+ package_msg_name, package_msg_name)
107
108
 
108
109
  result += '\n'
109
110
 
@@ -119,25 +120,26 @@ class MessageTsGen():
119
120
  for key, f in msg.fields.items()])
120
121
  result += '\n .compile();\n\n'
121
122
 
122
- result += 'export const %s_max_size = %d;\n' % (struct_name, size)
123
+ result += 'export const %s_max_size = %d;\n' % (package_msg_name, size)
123
124
 
124
125
  if msg.id:
125
- result += 'export const %s_msgid = %d\n' % (msg.name, msg.id)
126
+ result += 'export const %s_msgid = %d\n' % (
127
+ package_msg_name, msg.id)
126
128
 
127
129
  result += 'export function %s_encode(buffer: struct_frame_buffer, msg: any) {\n' % (
128
- msg.name)
129
- result += ' msg_encode(buffer, msg, %s_msgid)\n}\n' % (msg.name)
130
+ package_msg_name)
131
+ result += ' msg_encode(buffer, msg, %s_msgid)\n}\n' % (package_msg_name)
130
132
 
131
133
  result += 'export function %s_reserve(buffer: struct_frame_buffer) {\n' % (
132
- msg.name)
134
+ package_msg_name)
133
135
  result += ' const msg_buffer = msg_reserve(buffer, %s_msgid, %s_max_size);\n' % (
134
- msg.name, msg.name)
136
+ package_msg_name, package_msg_name)
135
137
  result += ' if (msg_buffer){\n'
136
138
  result += ' return new %s(msg_buffer)\n }\n return;\n}\n' % (
137
- msg.name)
139
+ package_msg_name)
138
140
 
139
141
  result += 'export function %s_finish(buffer: struct_frame_buffer) {\n' % (
140
- msg.name)
142
+ package_msg_name)
141
143
  result += ' msg_finish(buffer);\n}\n'
142
144
  return result + '\n'
143
145
 
@@ -182,8 +184,9 @@ class FileTsGen():
182
184
  if package.messages:
183
185
  yield 'export function get_message_length(msg_id : number){\n switch (msg_id)\n {\n'
184
186
  for key, msg in package.sortedMessages().items():
185
- name = StyleC.type_name(msg.name)
186
- yield ' case %s_msgid: return %s_max_size;\n' % (name, name)
187
+
188
+ package_msg_name = '%s_%s' % (package.name, msg.name)
189
+ yield ' case %s_msgid: return %s_max_size;\n' % (package_msg_name, package_msg_name)
187
190
 
188
191
  yield ' default: break;\n } return 0;\n}'
189
192
  yield '\n'
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "compilerOptions": {
3
3
  /* Visit https://aka.ms/tsconfig to read more about this file */
4
-
5
4
  /* Projects */
6
5
  // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
7
6
  // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
@@ -9,9 +8,8 @@
9
8
  // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
10
9
  // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
11
10
  // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
12
-
13
11
  /* Language and Environment */
14
- "target": "ES6", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
12
+ "target": "ES6", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
15
13
  // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
16
14
  // "jsx": "preserve", /* Specify what JSX code is generated. */
17
15
  // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
@@ -23,9 +21,8 @@
23
21
  // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
24
22
  // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
25
23
  // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
26
-
27
24
  /* Modules */
28
- "module": "commonjs", /* Specify what module code is generated. */
25
+ "module": "commonjs", /* Specify what module code is generated. */
29
26
  // "rootDir": "./", /* Specify the root folder within your source files. */
30
27
  // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */
31
28
  // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
@@ -44,12 +41,10 @@
44
41
  // "resolveJsonModule": true, /* Enable importing .json files. */
45
42
  // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
46
43
  // "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
47
-
48
44
  /* JavaScript Support */
49
45
  // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
50
46
  // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
51
47
  // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
52
-
53
48
  /* Emit */
54
49
  // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
55
50
  // "declarationMap": true, /* Create sourcemaps for d.ts files. */
@@ -58,7 +53,7 @@
58
53
  // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
59
54
  // "noEmit": true, /* Disable emitting files from a compilation. */
60
55
  // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
61
- "outDir": "./ts_out", /* Specify an output folder for all emitted files. */
56
+ "outDir": "./ts_out", /* Specify an output folder for all emitted files. */
62
57
  // "removeComments": true, /* Disable emitting comments. */
63
58
  // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
64
59
  // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
@@ -72,18 +67,16 @@
72
67
  // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
73
68
  // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
74
69
  // "declarationDir": "./", /* Specify the output directory for generated declaration files. */
75
-
76
70
  /* Interop Constraints */
77
71
  // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
78
72
  // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
79
73
  // "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */
80
74
  // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
81
- "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
75
+ "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
82
76
  // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
83
- "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
84
-
77
+ "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
85
78
  /* Type Checking */
86
- "strict": true, /* Enable all strict type-checking options. */
79
+ "strict": true, /* Enable all strict type-checking options. */
87
80
  // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
88
81
  // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
89
82
  // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
@@ -103,9 +96,12 @@
103
96
  // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
104
97
  // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
105
98
  // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
106
-
107
99
  /* Completeness */
108
100
  // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
109
- "skipLibCheck": true /* Skip type checking all .d.ts files. */
110
- }
111
- }
101
+ "skipLibCheck": true /* Skip type checking all .d.ts files. */
102
+ },
103
+ "exclude": [
104
+ "node_modules",
105
+ "src",
106
+ ]
107
+ }
@@ -1,41 +0,0 @@
1
- package biostream;
2
-
3
- enum AdcSamplingFrequency {
4
- FREQ_1000 = 0;
5
- FREQ_2000 = 1;
6
- FREQ_4000 = 2;
7
- FREQ_8000 = 3;
8
- FREQ_16000 = 4;
9
- }
10
-
11
- //enum before comment
12
- enum TransImpedanceGain {
13
- R_10 = 0;
14
- R_100 = 1;
15
- R_1k = 2;
16
- //Enum inside comment
17
- R_10k = 3;
18
- }
19
-
20
-
21
- message RawData {
22
- option msgid = 1;
23
- float refV = 1;
24
- float drnC = 2;
25
- float srcV = 3;
26
- float drnV = 4;
27
- float gteV = 5;
28
- float phsV = 6;
29
- float gteC = 7;
30
- float temp = 8;
31
- float time = 9;
32
- }
33
-
34
- message AdcCommand {
35
- option msgid = 112;
36
- bool enable = 1;
37
- AdcSamplingFrequency sampligFreq= 2;
38
- uint8 overSamplingRate = 3;
39
- TransImpedanceGain drainRes = 4;
40
- TransImpedanceGain gateRes = 5;
41
- }
@@ -1,80 +0,0 @@
1
- #include <stdio.h>
2
- #include "c/struct_frame_gen.h"
3
-
4
- #include "c/struct_frame_parser.h"
5
-
6
- // CREATE_DEFAULT_STRUCT_BUFFER(tx_buffer, 256);
7
- uint8_t tx_buffer_buffer[256];
8
- struct_buffer tx_buffer = {default_parser, tx_buffer_buffer, 256, 0, 0, false, 0, 0, 0};
9
-
10
- // CREATE_DEFAULT_STRUCT_BUFFER(rx_buffer, 256);
11
- uint8_t rx_buffer_buffer[256];
12
- struct_buffer rx_buffer = {default_parser, rx_buffer_buffer, 256, 0, 0, false, 0, 0, 0};
13
-
14
- int main()
15
- {
16
- MylVehiclePose msg;
17
- msg.pitch = 100;
18
- msg.yaw_rate = -1.45;
19
- msg.test = 4883;
20
- myl_vehicle_pose_encode(&tx_buffer, &msg);
21
-
22
- MylVehicleHeartbeat *hb;
23
- if (myl_vehicle_heartbeat_reserve(&tx_buffer, &hb))
24
- {
25
- hb->id = 23;
26
- hb->type = VEHICLE_TYPE_VEHICLE_TYPE_FW;
27
- myl_vehicle_heartbeat_finish(&tx_buffer);
28
- }
29
-
30
- MylVehiclePose msg2;
31
- MylVehicleHeartbeat *hb2;
32
- MylVehicleHeartbeat hb3;
33
- for (int i = 0; i < tx_buffer.size; i++)
34
- {
35
- if (parse_char(&rx_buffer, tx_buffer.data[i]))
36
- {
37
- switch (rx_buffer.msg_id_len.msg_id)
38
- {
39
- case MYL_VEHICLE_HEARTBEAT_MSG_ID:
40
- printf("got hb msg with id %d\n", rx_buffer.msg_id_len.msg_id);
41
- hb2 = myl_vehicle_heartbeat_get_ref(&rx_buffer);
42
- hb3 = myl_vehicle_heartbeat_get(&rx_buffer);
43
- break;
44
- case MYL_VEHICLE_POSE_MSG_ID:
45
- printf("got pose msg with id %d\n", rx_buffer.msg_id_len.msg_id);
46
- msg2 = myl_vehicle_pose_get(&rx_buffer);
47
- break;
48
-
49
- default:
50
- break;
51
- }
52
- }
53
- }
54
-
55
- MylVehiclePose msg3;
56
- MylVehicleHeartbeat *hb4;
57
- MylVehicleHeartbeat hb5;
58
- buffer_parser_result_t result = zero_initialized_parser_result;
59
- while (parse_buffer(tx_buffer_buffer, 256, &result))
60
- {
61
- switch (result.msg_id_len.msg_id)
62
- {
63
- case MYL_VEHICLE_HEARTBEAT_MSG_ID:
64
- printf("got hb msg with id %d\n", result.msg_id_len.msg_id);
65
- hb4 = myl_vehicle_heartbeat_get_ref_from_buffer_result(result);
66
- hb5 = myl_vehicle_heartbeat_get_from_buffer_result(result);
67
- break;
68
- case MYL_VEHICLE_POSE_MSG_ID:
69
- printf("got pose msg with id %d\n", result.msg_id_len.msg_id);
70
- msg3 = myl_vehicle_pose_get_from_buffer_result(result);
71
- break;
72
-
73
- default:
74
- break;
75
- }
76
- }
77
- printf("%d %d %d %d", hb->id, hb->type, hb2->id,hb2->type);
78
-
79
- return 0;
80
- }
@@ -1,7 +0,0 @@
1
-
2
- import * as bs from './biostream.sf';
3
-
4
- export function get_message_length(msg_id: number) {
5
- console.log(msg_id)
6
- return bs.get_message_length(msg_id);
7
- }
File without changes
File without changes
File without changes
File without changes