From cdcfc6320697dabb396e889671751acd64a3e904 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 19 Mar 2026 01:29:33 +0000
Subject: [PATCH 1/3] Initial plan
From 7db82a503bd0481b6df283810dde8bea6698c1c5 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 19 Mar 2026 01:51:07 +0000
Subject: [PATCH 2/3] docs: fix documentation accuracy, broken imports, and API
references
Co-authored-by: rijesha <7819200+rijesha@users.noreply.github.com>
---
README.md | 42 ++++++++-------
.../docs/basic-usage/framing-details.mdx | 51 ++++++++++---------
docs/src/content/docs/basic-usage/framing.mdx | 19 ++++---
.../docs/basic-usage/language-examples.mdx | 31 +++++++----
.../content/docs/extended-features/cpp-sdk.md | 42 +++++++--------
.../extended-features/custom-features.mdx | 26 ++++++----
.../docs/extended-features/python-sdk.md | 46 +++++++++--------
.../docs/getting-started/installation.md | 2 +-
.../docs/getting-started/quick-start.md | 2 +-
docs/src/content/docs/index.mdx | 2 +-
.../content/docs/reference/cli-reference.md | 4 +-
.../src/content/docs/reference/development.md | 4 +-
docs/src/content/docs/reference/testing.md | 2 +-
13 files changed, 147 insertions(+), 126 deletions(-)
diff --git a/README.md b/README.md
index 065dc745..e4a20d49 100644
--- a/README.md
+++ b/README.md
@@ -138,9 +138,7 @@ Frame: [0x90] [0x71] [0x04] [0x2A] [0x01, 0x02, 0x03, 0x04] [0x7F] [0x8A]
| Seq | `[SEQ] [LEN] [MSG_ID] [PACKET] [CRC]` | 5 | Packet loss detection |
| MultiSystemStream | `[SEQ] [SYS] [COMP] [LEN] [MSG_ID] [PACKET] [CRC]` | 7 | Multi-vehicle streaming |
-See [Framing Documentation](docs/framing.md) for the complete frame format reference.
-
-### Parser State Machine
+See [Framing Documentation](https://struct-frame.mylonics.com/basic-usage/framing/) for the complete frame format reference.
The frame parser implements a state machine to handle partial data and synchronization recovery:
@@ -189,7 +187,7 @@ gcc examples/main.c -I generated/c -o main
#### C++
```bash
python -m struct_frame examples/myl_vehicle.proto --build_cpp
-g++ -std=c++17 examples/main.cpp -I generated/cpp -o main
+g++ -std=c++20 examples/main.cpp -I generated/cpp -o main
./main
```
@@ -203,15 +201,15 @@ python -m struct_frame examples/myl_vehicle.proto --build_gql
| Feature | C | C++ | TypeScript | Python | C# | GraphQL | Status |
|---------|---|-----|------------|--------|----|---------|--------|
-| **Core Types** | ✓ | ✓ | ✓ | ✓ | ✗ | ✓ | Stable |
-| **String** | ✓ | ✓ | ✓ | ✓ | ✗ | ✓ | Stable |
-| **Enums** | ✓ | ✓ | ✓ | ✓ | ✗ | ✓ | Stable |
-| **Enum Classes** | N/A | ✓ | N/A | N/A | ✗ | N/A | Stable |
-| **Nested Messages** | ✓ | ✓ | ✓ | ✓ | ✗ | ✓ | Stable |
-| **Message IDs** | ✓ | ✓ | ✓ | ✓ | ✗ | N/A | Stable |
-| **Message Serialization** | ✓ | ✓ | ✓ | ✓ | ✗ | N/A | Stable |
-| **Flatten** | N/A | N/A | N/A | ✓ | ✗ | ✓ | Partial |
-| **Arrays** | ✓ | ✓ | Partial | ✓ | ✗ | ✓ | Stable |
+| **Core Types** | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | Stable |
+| **String** | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | Stable |
+| **Enums** | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | Stable |
+| **Enum Classes** | N/A | ✓ | N/A | N/A | N/A | N/A | Stable |
+| **Nested Messages** | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | Stable |
+| **Message IDs** | ✓ | ✓ | ✓ | ✓ | ✓ | N/A | Stable |
+| **Message Serialization** | ✓ | ✓ | ✓ | ✓ | ✓ | N/A | Stable |
+| **Flatten** | N/A | N/A | N/A | ✓ | N/A | ✓ | Partial |
+| **Arrays** | ✓ | ✓ | Partial | ✓ | ✓ | ✓ | Stable |
**Legend:**
- **✓** - Feature works as documented
@@ -279,14 +277,14 @@ message SimpleHeartbeat {
| Feature | C | C++ | TypeScript | Python | C# | Status | Notes |
|---------|---|-----|------------|--------|----|---------|-------|
-| **Frame Encoding** | ✓ | ✓ | ✓ | ✓ | ✗ | Stable | All languages can create frames |
-| **Frame Parsing** | ✓ | ✓ | ✓ | ✓ | ✗ | Stable | State machine implementation |
-| **Checksum Validation** | ✓ | ✓ | ✓ | ✓ | ✗ | Stable | Fletcher-16 algorithm |
-| **Sync Recovery** | ✓ | ✓ | ✓ | ✓ | ✗ | Stable | Auto-recovery from corruption |
-| **Partial Frame Handling** | ✓ | ✓ | ✓ | ✓ | ✗ | Stable | Handles chunked data streams |
-| **Message ID Routing** | ✓ | ✓ | ✓ | ✓ | ✗ | Stable | Automatic message type detection |
-| **Buffer Management** | ✓ | ✓ | ✓ | ✓ | ✗ | Stable | Fixed-size buffers prevent overflow |
-| **Cross-Language Compatibility** | ✓ | ✓ | ✓ | ✓ | ✗ | Stable | Frames interoperate between languages |
+| **Frame Encoding** | ✓ | ✓ | ✓ | ✓ | ✓ | Stable | All languages can create frames |
+| **Frame Parsing** | ✓ | ✓ | ✓ | ✓ | ✓ | Stable | State machine implementation |
+| **Checksum Validation** | ✓ | ✓ | ✓ | ✓ | ✓ | Stable | Fletcher-16 algorithm |
+| **Sync Recovery** | ✓ | ✓ | ✓ | ✓ | ✓ | Stable | Auto-recovery from corruption |
+| **Partial Frame Handling** | ✓ | ✓ | ✓ | ✓ | ✓ | Stable | Handles chunked data streams |
+| **Message ID Routing** | ✓ | ✓ | ✓ | ✓ | ✓ | Stable | Automatic message type detection |
+| **Buffer Management** | ✓ | ✓ | ✓ | ✓ | ✓ | Stable | Fixed-size buffers prevent overflow |
+| **Cross-Language Compatibility** | ✓ | ✓ | ✓ | ✓ | ✓ | Stable | Frames interoperate between languages |
### Extended Frame Format Options
@@ -304,7 +302,7 @@ Struct Frame supports multiple frame types and payload types for different use c
- **SysComp**: System/Component IDs for multi-vehicle networks (MAVLink-style)
- **MultiSystemStream**: Sequence + SysComp for streaming with loss detection
-See [Framing Documentation](docs/framing.md) for the complete format reference.
+See [Framing Documentation](https://struct-frame.mylonics.com/basic-usage/framing/) for the complete format reference.
## Frame Format Examples and Usage
diff --git a/docs/src/content/docs/basic-usage/framing-details.mdx b/docs/src/content/docs/basic-usage/framing-details.mdx
index 8ff7373b..4771423f 100644
--- a/docs/src/content/docs/basic-usage/framing-details.mdx
+++ b/docs/src/content/docs/basic-usage/framing-details.mdx
@@ -107,7 +107,7 @@ For Minimal payloads, the parser requires a message length callback to determine
## Usage in C++
```cpp
-#include "FrameProfiles.hpp"
+#include "frame_profiles.hpp"
using namespace FrameParsers;
@@ -137,27 +137,31 @@ while (auto result = reader.next()) {
## Usage in Python
```python
-from struct_frame_parser import Parser, HeaderType, PayloadType
-
-# Create parser with specific frame types
-parser = Parser(
- enabled_headers=[HeaderType.BASIC, HeaderType.TINY],
- enabled_payloads=[PayloadType.DEFAULT, PayloadType.EXTENDED]
+from frame_profiles import (
+ ProfileStandardWriter,
+ ProfileStandardAccumulatingReader,
)
+from struct_frame.generated.messages import MyMessage, get_message_info
# Encode
-frame = parser.encode(
- msg_id=42,
- msg=b"payload data",
- header_type=HeaderType.BASIC,
- payload_type=PayloadType.DEFAULT
-)
-
-# Decode (byte-by-byte)
-for byte in incoming_data:
- result = parser.parse_byte(byte)
- if result.valid:
+msg = MyMessage(value=42)
+writer = ProfileStandardWriter(1024)
+writer.write(msg)
+frame = writer.data()
+
+# Decode (byte-by-byte streaming)
+reader = ProfileStandardAccumulatingReader(get_message_info=get_message_info)
+for byte in frame:
+ result = reader.push_byte(byte)
+ if result and result.valid:
handle_message(result)
+
+# Decode (buffer mode)
+reader2 = ProfileStandardAccumulatingReader(get_message_info=get_message_info)
+reader2.add_data(frame)
+result = reader2.next()
+if result and result.valid:
+ handle_message(result)
```
## Custom Profiles
@@ -182,13 +186,12 @@ Create custom frame formats by combining header and payload types:
```python
- from struct_frame_parser import create_custom_profile, HeaderType, PayloadType
+ from frame_profiles import ProfileConfig, HEADER_TINY_CONFIG, PAYLOAD_EXTENDED_CONFIG
+ from frame_profiles import BufferWriter, AccumulatingReader
- custom = create_custom_profile(
- "TinyExtended",
- HeaderType.TINY,
- PayloadType.EXTENDED
- )
+ custom_config = ProfileConfig(HEADER_TINY_CONFIG, PAYLOAD_EXTENDED_CONFIG, name="TinyExtended")
+ writer = BufferWriter(custom_config, 1024)
+ reader = AccumulatingReader(custom_config)
```
diff --git a/docs/src/content/docs/basic-usage/framing.mdx b/docs/src/content/docs/basic-usage/framing.mdx
index 6219e8a0..e8b6b241 100644
--- a/docs/src/content/docs/basic-usage/framing.mdx
+++ b/docs/src/content/docs/basic-usage/framing.mdx
@@ -61,17 +61,20 @@ The Standard profile (recommended for most uses):
```python
- from struct_frame_parser import Parser, HeaderType, PayloadType
-
- parser = Parser()
+ from frame_profiles import ProfileStandardWriter, ProfileStandardAccumulatingReader
+ from struct_frame.generated.messages import MyMessage, get_message_info
# Encode
- frame = parser.encode_basic(msg_id=42, msg=b"data")
+ msg = MyMessage(value=42)
+ writer = ProfileStandardWriter(1024)
+ writer.write(msg)
+ frame = writer.data()
# Decode
+ reader = ProfileStandardAccumulatingReader(get_message_info=get_message_info)
for byte in frame:
- result = parser.parse_byte(byte)
- if result.valid:
+ result = reader.push_byte(byte)
+ if result and result.valid:
print(f"Message {result.msg_id}: {result.msg_data}")
```
@@ -80,9 +83,9 @@ The Standard profile (recommended for most uses):
```cpp
- #include "FrameProfiles.hpp"
+ #include "frame_profiles.hpp"
- using namespace StructFrame;
+ using namespace FrameParsers;
// Encode
uint8_t buffer[1024];
diff --git a/docs/src/content/docs/basic-usage/language-examples.mdx b/docs/src/content/docs/basic-usage/language-examples.mdx
index 5c68a3f4..f3c400e7 100644
--- a/docs/src/content/docs/basic-usage/language-examples.mdx
+++ b/docs/src/content/docs/basic-usage/language-examples.mdx
@@ -33,8 +33,12 @@ Frame profiles provide complete framing and parsing functionality. This is the *
### Python with Profiles
```python
-from generated.example import ExampleStatus
-from generated.frame_profiles import (
+# Add py_path to sys.path before importing
+import sys
+sys.path.insert(0, 'generated/') # py_path
+
+from struct_frame.generated.example import ExampleStatus, get_message_info
+from frame_profiles import (
ProfileStandardWriter,
ProfileStandardAccumulatingReader
)
@@ -48,12 +52,12 @@ bytes_written = writer.write(msg)
frame_data = writer.data()
# Parse received frames
-reader = ProfileStandardAccumulatingReader()
+reader = ProfileStandardAccumulatingReader(get_message_info=get_message_info)
reader.add_data(frame_data)
# Deserialize using FrameMsgInfo
result = reader.next()
-if result:
+if result and result.valid:
decoded_msg = ExampleStatus.deserialize(result) # Pass FrameMsgInfo directly
print(f"ID: {decoded_msg.id}, Value: {decoded_msg.value}")
```
@@ -93,7 +97,7 @@ if (result) {
```cpp
#include "example.structframe.hpp"
-#include "FrameProfiles.hpp"
+#include "frame_profiles.hpp"
// Create and serialize a message
ExampleStatus msg;
@@ -183,7 +187,11 @@ For cases where you need direct access to message bytes without framing:
### Python
```python
-from generated.example import ExampleStatus
+# Add py_path to sys.path before importing
+import sys
+sys.path.insert(0, 'generated/') # py_path
+
+from struct_frame.generated.example import ExampleStatus
# Create a message
msg = ExampleStatus(id=42, value=3.14)
@@ -301,13 +309,16 @@ class Program {
### Serial Communication (Python)
```python
+import sys
import serial
-from generated.example import ExampleStatus
-from generated.frame_profiles import ProfileStandardAccumulatingReader
+sys.path.insert(0, 'generated/') # py_path
+
+from struct_frame.generated.example import ExampleStatus, get_message_info
+from frame_profiles import ProfileStandardAccumulatingReader
# Setup serial connection
ser = serial.Serial('/dev/ttyUSB0', 115200)
-reader = ProfileStandardAccumulatingReader()
+reader = ProfileStandardAccumulatingReader(get_message_info=get_message_info)
while True:
if ser.in_waiting:
@@ -330,7 +341,7 @@ while True:
```cpp
#include "example.structframe.hpp"
-#include "FrameProfiles.hpp"
+#include "frame_profiles.hpp"
// Byte-by-byte streaming parser for UART/serial
FrameParsers::ProfileStandardAccumulatingReader reader;
diff --git a/docs/src/content/docs/extended-features/cpp-sdk.md b/docs/src/content/docs/extended-features/cpp-sdk.md
index a47e3d14..06d0aefe 100644
--- a/docs/src/content/docs/extended-features/cpp-sdk.md
+++ b/docs/src/content/docs/extended-features/cpp-sdk.md
@@ -25,25 +25,29 @@ Minimal footprint for embedded systems. Serial transport only.
## Observer Pattern
-Subscribe to messages using function pointers:
+Subscribe to messages using function pointers or lambdas:
```cpp
#include "struct_frame_sdk/sdk_embedded.hpp"
-#include "messages.sf.hpp"
+#include "messages.structframe.hpp"
void handle_status(const StatusMessage& msg, uint8_t msgId) {
std::cout << "Status: " << msg.value << std::endl;
}
int main() {
- // Create SDK
- StructFrame::SDK sdk;
-
- // Subscribe to messages
- sdk.subscribe(handle_status);
-
- // Process incoming data
- sdk.process_byte(byte);
+ // Create SDK with transport and frame parser
+ StructFrame::StructFrameSdkConfig config{
+ .transport = &my_transport,
+ .frameParser = &my_frame_parser,
+ };
+ StructFrame::StructFrameSdk sdk(config);
+
+ // Subscribe to messages by message ID
+ sdk.subscribe(StatusMessage::MSG_ID, handle_status);
+
+ // Connect the transport (incoming data is handled via callbacks)
+ sdk.connect();
}
```
@@ -52,39 +56,29 @@ int main() {
### Serial
```cpp
-#include "struct_frame_sdk/transports/serial.hpp"
+#include "struct_frame_sdk/serial_transport.hpp"
StructFrame::SerialTransport serial("/dev/ttyUSB0", 115200);
serial.connect();
serial.send(message_id, data, size);
```
-### UDP
+### Network (UDP, TCP, WebSocket)
```cpp
-#include "struct_frame_sdk/transports/udp.hpp"
+#include "struct_frame_sdk/network_transports.hpp"
StructFrame::UDPTransport udp("192.168.1.100", 8080);
udp.connect();
udp.send(message_id, data, size);
```
-### TCP
-
-```cpp
-#include "struct_frame_sdk/transports/tcp.hpp"
-
-StructFrame::TCPTransport tcp("192.168.1.100", 8080);
-tcp.connect();
-tcp.send(message_id, data, size);
-```
-
## Frame Profiles
Use predefined frame profiles:
```cpp
-#include "FrameProfiles.hpp"
+#include "frame_profiles.hpp"
using namespace FrameParsers;
diff --git a/docs/src/content/docs/extended-features/custom-features.mdx b/docs/src/content/docs/extended-features/custom-features.mdx
index 39b08c21..13b6fd43 100644
--- a/docs/src/content/docs/extended-features/custom-features.mdx
+++ b/docs/src/content/docs/extended-features/custom-features.mdx
@@ -37,14 +37,18 @@ The generator creates a `get_msg_info` function automatically:
```python
- from struct_frame.frame_profiles import get_profile, Profile
- from messages import get_msg_info
-
- # Get minimal profile
- profile = get_profile(Profile.SENSOR) # TinyMinimal
-
- # Parser uses auto-generated get_msg_info
- parser = profile.create_parser(get_msg_info)
+ from frame_profiles import ProfileSensorWriter, ProfileSensorAccumulatingReader
+ from struct_frame.generated.messages import get_message_info
+
+ # Encode using sensor profile (Tiny + Minimal)
+ writer = ProfileSensorWriter(1024)
+ writer.write(msg)
+ frame = writer.data()
+
+ # Parser requires get_message_info callback for minimal profiles
+ reader = ProfileSensorAccumulatingReader(get_message_info=get_message_info)
+ reader.add_data(frame)
+ result = reader.next()
```
@@ -52,11 +56,11 @@ The generator creates a `get_msg_info` function automatically:
```cpp
- #include "FrameProfiles.hpp"
+ #include "frame_profiles.hpp"
#include "messages.structframe.hpp"
- // Use sensor profile with minimal frames
- ProfileSensorAccumulatingReader reader(get_msg_info);
+ // Use sensor profile with minimal frames (requires message info callback)
+ ProfileSensorAccumulatingReader reader(get_message_info);
```
diff --git a/docs/src/content/docs/extended-features/python-sdk.md b/docs/src/content/docs/extended-features/python-sdk.md
index c9f7ec9c..70376f47 100644
--- a/docs/src/content/docs/extended-features/python-sdk.md
+++ b/docs/src/content/docs/extended-features/python-sdk.md
@@ -16,38 +16,44 @@ python -m struct_frame messages.proto --build_py --py_path generated/ --sdk
## Parser Usage
```python
-from struct_frame_parser import Parser, HeaderType, PayloadType
-from messages_sf import Status
-
-# Create parser
-parser = Parser()
+from frame_profiles import ProfileStandardWriter, ProfileStandardAccumulatingReader
+from struct_frame.generated.messages import Status, get_message_info
# Encode
-frame = parser.encode_basic(msg_id=1, msg=Status(value=42).to_bytes())
+msg = Status(value=42)
+writer = ProfileStandardWriter(1024)
+writer.write(msg)
+frame = writer.data()
# Decode
+reader = ProfileStandardAccumulatingReader(get_message_info=get_message_info)
for byte in frame:
- result = parser.parse_byte(byte)
- if result.valid:
- msg = Status.from_bytes(result.msg_data)
- print(f"Status: {msg.value}")
+ result = reader.push_byte(byte)
+ if result and result.valid:
+ decoded = Status.deserialize(result)
+ print(f"Status: {decoded.value}")
```
## Message Router
```python
-from struct_frame_sdk import MessageRouter
-from messages_sf import Status
-
-router = MessageRouter()
-
-# Subscribe to messages
-@router.subscribe(Status)
-def handle_status(msg: Status):
+from struct_frame_sdk.struct_frame_sdk import StructFrameSdk, StructFrameSdkConfig
+from struct_frame_sdk.tcp_transport import TcpTransport
+from struct_frame.generated.messages import Status
+
+# Configure SDK with transport
+config = StructFrameSdkConfig(
+ transport=TcpTransport('192.168.1.100', 8080),
+ frame_parser=... # frame parser instance
+)
+sdk = StructFrameSdk(config)
+
+# Subscribe to messages by ID
+def handle_status(msg: Status, msg_id: int):
print(f"Status: {msg.value}")
-# Process incoming data
-router.process_byte(byte)
+sdk.subscribe(Status.msg_id, handle_status)
+sdk.connect()
```
## Transports
diff --git a/docs/src/content/docs/getting-started/installation.md b/docs/src/content/docs/getting-started/installation.md
index 15d6afe3..27805555 100644
--- a/docs/src/content/docs/getting-started/installation.md
+++ b/docs/src/content/docs/getting-started/installation.md
@@ -20,7 +20,7 @@ python -m struct_frame --help
Depending on which languages you plan to use:
- **C**: GCC or compatible C compiler
-- **C++**: G++ with C++17 support or later
+- **C++**: G++ with C++20 support or later
- **TypeScript/JavaScript**: Node.js and npm
- **Python**: Python 3.8 or later (already required for code generation)
- **C#**: .NET SDK
diff --git a/docs/src/content/docs/getting-started/quick-start.md b/docs/src/content/docs/getting-started/quick-start.md
index 91d50c6f..a0e4424c 100644
--- a/docs/src/content/docs/getting-started/quick-start.md
+++ b/docs/src/content/docs/getting-started/quick-start.md
@@ -62,7 +62,7 @@ int main() {
Compile and run:
```bash
-g++ -std=c++17 -I generated/ main.cpp -o main
+g++ -std=c++20 -I generated/ main.cpp -o main
./main
```
diff --git a/docs/src/content/docs/index.mdx b/docs/src/content/docs/index.mdx
index fc677b82..6149f226 100644
--- a/docs/src/content/docs/index.mdx
+++ b/docs/src/content/docs/index.mdx
@@ -94,7 +94,7 @@ python -m struct_frame status.proto --build_c --build_py --build_ts
msg = ExampleStatus(id=42, value=3.14)
# Serialize to bytes
- data = msg.pack()
+ data = msg.serialize()
```
diff --git a/docs/src/content/docs/reference/cli-reference.md b/docs/src/content/docs/reference/cli-reference.md
index 13f576e7..2e4a751c 100644
--- a/docs/src/content/docs/reference/cli-reference.md
+++ b/docs/src/content/docs/reference/cli-reference.md
@@ -56,6 +56,8 @@ python -m struct_frame [proto_file] [options]
| `--force` | Force regeneration even if hash matches previous generation |
| `--hash_path PATH` | Path to store the generation hash file |
| `--generate_tests` | Generate test code with dummy values for round-trip verification |
+| `--validate` | Validate the proto file without generating code |
+| `--debug` | Enable debug output during code generation |
## Examples
@@ -93,7 +95,7 @@ python -m struct_frame messages.proto --build_cpp --sdk
### TypeScript
- `.structframe.ts` - Message definitions and classes
- Frame utilities (frame-base.ts, frame-headers.ts, frame-profiles.ts, etc.)
-- `struct_frame_sdk/` - SDK files (if `--sdk` used)
+- `struct-frame-sdk/` - SDK files (if `--sdk` used)
### Python
- `struct_frame/generated/.py` - Message definitions and classes
diff --git a/docs/src/content/docs/reference/development.md b/docs/src/content/docs/reference/development.md
index 4e9fd96b..3aaf4312 100644
--- a/docs/src/content/docs/reference/development.md
+++ b/docs/src/content/docs/reference/development.md
@@ -110,10 +110,10 @@ PYTHONPATH=src python src/main.py examples/generic_robot.proto \
```bash
# Generate and check for errors
-PYTHONPATH=src python src/main.py examples/array_test.proto --build_py
+PYTHONPATH=src python src/main.py examples/array_test.proto --build_py --py_path generated/py
# Import generated code
-python -c "import sys; sys.path.insert(0, 'generated/py'); import array_test_sf"
+python -c "import sys; sys.path.insert(0, 'generated/py'); from struct_frame.generated.array_test import get_message_info"
```
## Code Style
diff --git a/docs/src/content/docs/reference/testing.md b/docs/src/content/docs/reference/testing.md
index adebfebd..438bd527 100644
--- a/docs/src/content/docs/reference/testing.md
+++ b/docs/src/content/docs/reference/testing.md
@@ -57,7 +57,7 @@ sudo apt install gcc
xcode-select --install
```
-**C++ tests**: G++ with C++14 support
+**C++ tests**: G++ with C++20 support
```bash
# Ubuntu/Debian
sudo apt install g++
From 77d26d04481bb18ac7a6a8e46e18ae87425df95e Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 19 Mar 2026 02:10:28 +0000
Subject: [PATCH 3/3] Changes before error encountered
Co-authored-by: rijesha <7819200+rijesha@users.noreply.github.com>
---
README.md | 160 +++++++++---------
.../docs/extended-features/python-sdk.md | 32 ++--
.../docs/extended-features/typescript-sdk.md | 41 +++--
docs/src/content/docs/index.mdx | 4 +-
.../docs/reference/build-integration.md | 8 +-
docs/src/content/docs/reference/testing.md | 14 +-
6 files changed, 139 insertions(+), 120 deletions(-)
diff --git a/README.md b/README.md
index e4a20d49..178921da 100644
--- a/README.md
+++ b/README.md
@@ -43,10 +43,10 @@ python test_all.py
python tests/run_tests.py --verbose
# Skip specific languages
-python tests/run_tests.py --skip-ts --skip-c --skip-cpp
+python tests/run_tests.py --skip-lang ts --skip-lang c
# Generate code only (no compilation/execution)
-python tests/run_tests.py --generate-only
+python tests/run_tests.py --only-generate
```
See `tests/README.md` for detailed test documentation.
@@ -76,7 +76,7 @@ Struct Frame provides high-level SDKs for simplified message communication:
- **C++**: Header-only with observer/subscriber pattern, ideal for embedded systems
- **C#**: Async/await-based for .NET Core, Xamarin, and MAUI applications
-See the [SDK Overview](https://struct-frame.mylonics.com/user-guide/sdk-overview/) for details.
+See the [SDK Overview](https://struct-frame.mylonics.com/extended-features/sdk-overview/) for details.
## Framing System
@@ -352,112 +352,110 @@ Result: [0x7E, 0xC9]
#### Python Frame Handling
```python
-# Import generated classes
-from myl_vehicle_sf import VehicleStatus
-from struct_frame_parser import FrameParser, BasicPacket
+import sys
+sys.path.insert(0, 'generated/py/') # py_path
+
+from struct_frame.generated.myl_vehicle import MylVehicleVehicleStatus, get_message_info
+from frame_profiles import ProfileStandardWriter, ProfileStandardAccumulatingReader
# Create message
-msg = VehicleStatus()
-msg.vehicle_id = 1234
-msg.speed = 65.5
-msg.engine_on = True
+msg = MylVehicleVehicleStatus(vehicle_id=1234, speed=65.5, engine_on=True)
# Encode to frame
-packet = BasicPacket()
-frame_bytes = packet.encode_msg(msg)
+writer = ProfileStandardWriter(1024)
+writer.write(msg)
+frame_bytes = writer.data()
print(f"Frame: {[hex(b) for b in frame_bytes]}")
-# Parse frame (simulate byte-by-byte reception)
-parser = FrameParser({0x90: BasicPacket()}, {42: VehicleStatus})
+# Parse frame (byte-by-byte)
+reader = ProfileStandardAccumulatingReader(get_message_info=get_message_info)
for byte in frame_bytes:
- result = parser.parse_char(byte)
- if result:
- print(f"Parsed: vehicle_id={result.vehicle_id}, speed={result.speed}")
+ result = reader.push_byte(byte)
+ if result and result.valid:
+ parsed = MylVehicleVehicleStatus.deserialize(result)
+ print(f"Parsed: vehicle_id={parsed.vehicle_id}, speed={parsed.speed}")
```
#### TypeScript Frame Handling
```typescript
-import * as mv from './generated/ts/myl_vehicle.sf';
-import { struct_frame_buffer, parse_char } from './generated/ts/struct_frame_parser';
+import { MylVehicleVehicleStatus } from './generated/ts/myl_vehicle.structframe';
+import { ProfileStandardWriter, ProfileStandardAccumulatingReader } from './generated/ts/frame-profiles';
// Create and encode message
-let tx_buffer = new struct_frame_buffer(256);
-let msg = new mv.VehicleStatus();
+const msg = new MylVehicleVehicleStatus();
msg.vehicle_id = 1234;
msg.speed = 65.5;
msg.engine_on = true;
-mv.VehicleStatus_encode(tx_buffer, msg);
-// Parse frame
-let rx_buffer = new struct_frame_buffer(256);
-for (let i = 0; i < tx_buffer.size; i++) {
- if (parse_char(rx_buffer, tx_buffer.data[i])) {
- let parsed = mv.VehicleStatus_decode(rx_buffer.msg_data);
+const writer = new ProfileStandardWriter(256);
+writer.write(msg);
+const frameData = writer.data();
+
+// Parse frame
+const reader = new ProfileStandardAccumulatingReader();
+reader.addData(frameData);
+const result = reader.next();
+if (result && result.valid) {
+ const parsed = MylVehicleVehicleStatus.deserialize(result);
console.log(`Parsed: vehicle_id=${parsed.vehicle_id}, speed=${parsed.speed}`);
- }
}
```
-#### C Frame Handling
+#### C Frame Handling
```c
-#include "myl_vehicle.sf.h"
-#include "struct_frame_parser.h"
+#include "myl_vehicle.structframe.h"
+#include "frame_profiles.h"
// Create message
-VehicleStatus msg = {0};
+MylVehicleVehicleStatus msg = {0};
msg.vehicle_id = 1234;
msg.speed = 65.5f;
msg.engine_on = true;
// Encode to frame
uint8_t frame_buffer[256];
-size_t frame_size = basic_frame_encode(frame_buffer, 42, (uint8_t*)&msg, sizeof(msg));
-
-// Parse frame
-packet_state_t parser = {0};
-// ... initialize parser ...
-
-for (size_t i = 0; i < frame_size; i++) {
- msg_info_t info = parse_char(&parser, frame_buffer[i]);
- if (info.valid) {
- VehicleStatus* parsed = (VehicleStatus*)info.msg_loc;
- printf("Parsed: vehicle_id=%d, speed=%.1f\n", parsed->vehicle_id, parsed->speed);
- }
+ProfileStandardWriter writer = profile_standard_writer_init(frame_buffer, sizeof(frame_buffer));
+profile_standard_writer_write(&writer, MYL_VEHICLE_VEHICLE_STATUS_MSG_ID,
+ (uint8_t*)&msg, sizeof(msg));
+
+// Parse frame byte-by-byte
+ProfileStandardAccumulatingReader reader = profile_standard_accumulating_reader_init(get_message_info);
+for (size_t i = 0; i < writer.size; i++) {
+ FrameMsgInfo info = profile_standard_accumulating_reader_push_byte(&reader, frame_buffer[i]);
+ if (info.valid) {
+ MylVehicleVehicleStatus* parsed = (MylVehicleVehicleStatus*)info.msg_data;
+ printf("Parsed: vehicle_id=%d, speed=%.1f\n", parsed->vehicle_id, parsed->speed);
+ }
}
```
#### C++ Frame Handling
```cpp
-#include "myl_vehicle.sf.hpp"
-#include "struct_frame.hpp"
+#include "myl_vehicle.structframe.hpp"
+#include "frame_profiles.hpp"
// Create message
-VehicleStatus msg{};
+MylVehicleVehicleStatus msg{};
msg.vehicle_id = 1234;
msg.speed = 65.5f;
msg.engine_on = true;
// Encode to frame
-uint8_t frame_buffer[256];
-StructFrame::BasicPacket format;
-StructFrame::EncodeBuffer encoder(frame_buffer, sizeof(frame_buffer));
-
-bool success = encoder.encode(&format, VEHICLE_STATUS_MSG_ID, &msg, sizeof(msg));
-
-// Parse frame using FrameParser
-StructFrame::FrameParser parser(&format, [](size_t msg_id, size_t* size) {
- return StructFrame::get_message_length(msg_id, size);
-});
-
-for (size_t i = 0; i < encoder.size(); i++) {
- StructFrame::MessageInfo info = parser.parse_byte(frame_buffer[i]);
- if (info.valid) {
- VehicleStatus* parsed = reinterpret_cast(info.msg_location);
- std::cout << "Parsed: vehicle_id=" << parsed->vehicle_id
- << ", speed=" << parsed->speed << std::endl;
+uint8_t buffer[256];
+FrameParsers::ProfileStandardWriter writer(buffer, sizeof(buffer));
+writer.write(msg);
+
+// Parse frame byte-by-byte
+FrameParsers::ProfileStandardAccumulatingReader reader;
+for (size_t i = 0; i < writer.size(); i++) {
+ if (auto info = reader.push_byte(buffer[i])) {
+ MylVehicleVehicleStatus parsed;
+ parsed.deserialize(info);
+ std::cout << "Parsed: vehicle_id=" << parsed.vehicle_id
+ << ", speed=" << parsed.speed << "\n";
}
}
```
@@ -466,38 +464,44 @@ for (size_t i = 0; i < encoder.size(); i++) {
#### Serial Communication
```python
+import sys
import serial
-from struct_frame_parser import FrameParser
+sys.path.insert(0, 'generated/py/')
+
+from struct_frame.generated.messages import MyMessage, get_message_info
+from frame_profiles import ProfileStandardAccumulatingReader
# Setup serial connection
ser = serial.Serial('/dev/ttyUSB0', 115200)
-parser = FrameParser(packet_formats, message_definitions)
+reader = ProfileStandardAccumulatingReader(get_message_info=get_message_info)
# Continuous parsing loop
while True:
if ser.in_waiting:
- byte = ser.read(1)[0]
- result = parser.parse_char(byte)
- if result:
+ data = ser.read(ser.in_waiting)
+ reader.add_data(data)
+ result = reader.next()
+ if result and result.valid:
handle_message(result)
```
-#### TCP Socket Communication
+#### TCP Socket Communication
```typescript
import * as net from 'net';
-import { struct_frame_buffer, parse_char } from './struct_frame_parser';
+import { ProfileStandardAccumulatingReader } from './generated/ts/frame-profiles';
+import { MyMessage } from './generated/ts/messages.structframe';
-const client = net.createConnection({port: 8080}, () => {
+const client = net.createConnection({ port: 8080 }, () => {
console.log('Connected to server');
});
-let rx_buffer = new struct_frame_buffer(1024);
+const reader = new ProfileStandardAccumulatingReader();
client.on('data', (data: Buffer) => {
- for (let byte of data) {
- if (parse_char(rx_buffer, byte)) {
- // Process complete message
- handleMessage(rx_buffer.msg_data);
- }
+ reader.addData(data);
+ let result;
+ while ((result = reader.next()) && result.valid) {
+ const msg = MyMessage.deserialize(result);
+ handleMessage(msg);
}
});
```
diff --git a/docs/src/content/docs/extended-features/python-sdk.md b/docs/src/content/docs/extended-features/python-sdk.md
index 70376f47..31e417ce 100644
--- a/docs/src/content/docs/extended-features/python-sdk.md
+++ b/docs/src/content/docs/extended-features/python-sdk.md
@@ -61,35 +61,43 @@ sdk.connect()
### Serial
```python
-import serial
-from struct_frame_sdk.transports import SerialTransport
+from struct_frame_sdk.serial_transport import SerialTransport, SerialTransportConfig
-transport = SerialTransport('/dev/ttyUSB0', 115200)
+config = SerialTransportConfig(port='/dev/ttyUSB0', baudrate=115200)
+transport = SerialTransport(config)
transport.connect()
-transport.send(msg_id, data)
```
-### Socket
+### TCP
```python
-import socket
-from struct_frame_sdk.transports import SocketTransport
+from struct_frame_sdk.tcp_transport import TcpTransport, TcpTransportConfig
-transport = SocketTransport('192.168.1.100', 8080)
+config = TcpTransportConfig(host='192.168.1.100', port=8080)
+transport = TcpTransport(config)
+transport.connect()
+```
+
+### UDP
+
+```python
+from struct_frame_sdk.udp_transport import UdpTransport, UdpTransportConfig
+
+config = UdpTransportConfig(remote_host='192.168.1.100', remote_port=8080)
+transport = UdpTransport(config)
transport.connect()
-transport.send(msg_id, data)
```
## Async Support
```python
import asyncio
-from struct_frame_sdk.async_transports import AsyncSerialTransport
+from struct_frame_sdk.async_serial_transport import AsyncSerialTransport, AsyncSerialTransportConfig
async def main():
- transport = AsyncSerialTransport('/dev/ttyUSB0', 115200)
+ config = AsyncSerialTransportConfig(port='/dev/ttyUSB0', baud_rate=115200)
+ transport = AsyncSerialTransport(config)
await transport.connect()
- await transport.send(msg_id, data)
asyncio.run(main())
```
diff --git a/docs/src/content/docs/extended-features/typescript-sdk.md b/docs/src/content/docs/extended-features/typescript-sdk.md
index 07cfbd1b..15536283 100644
--- a/docs/src/content/docs/extended-features/typescript-sdk.md
+++ b/docs/src/content/docs/extended-features/typescript-sdk.md
@@ -16,18 +16,21 @@ python -m struct_frame messages.proto --build_ts --ts_path src/generated/ --sdk
## Basic Usage
```typescript
-import { MessageRouter } from './generated/ts/struct_frame_sdk';
-import { Status } from './generated/ts/messages.sf';
+import { StructFrameSdk, StructFrameSdkConfig } from './generated/ts/struct-frame-sdk';
+import { TcpTransport } from './generated/ts/struct-frame-sdk';
+import { Status } from './generated/ts/status.structframe';
-const router = new MessageRouter();
+const sdk = new StructFrameSdk({
+ transport: new TcpTransport({ host: '192.168.1.100', port: 8080 }),
+ frameParser: ..., // frame parser instance
+});
-// Subscribe to messages
-router.subscribe(Status, (msg: Status) => {
+// Subscribe to messages by ID
+sdk.subscribe(Status.MSG_ID, (msg) => {
console.log(`Status: ${msg.value}`);
});
-// Process incoming data
-router.processByte(byte);
+sdk.connect();
```
## Transports
@@ -35,41 +38,37 @@ router.processByte(byte);
### UDP
```typescript
-import { UDPTransport } from './generated/ts/struct_frame_sdk/transports';
+import { UdpTransport } from './generated/ts/struct-frame-sdk';
-const transport = new UDPTransport('192.168.1.100', 8080);
+const transport = new UdpTransport({ remoteHost: '192.168.1.100', remotePort: 8080 });
await transport.connect();
-await transport.send(msgId, data);
```
### TCP
```typescript
-import { TCPTransport } from './generated/ts/struct_frame_sdk/transports';
+import { TcpTransport } from './generated/ts/struct-frame-sdk';
-const transport = new TCPTransport('192.168.1.100', 8080);
+const transport = new TcpTransport({ host: '192.168.1.100', port: 8080 });
await transport.connect();
-await transport.send(msgId, data);
```
### WebSocket
```typescript
-import { WebSocketTransport } from './generated/ts/struct_frame_sdk/transports';
+import { WebSocketTransport } from './generated/ts/struct-frame-sdk';
-const transport = new WebSocketTransport('ws://localhost:8080');
+const transport = new WebSocketTransport({ url: 'ws://localhost:8080' });
await transport.connect();
-await transport.send(msgId, data);
```
### Serial (Node.js only)
```typescript
-import { SerialTransport } from './generated/ts/struct_frame_sdk/transports';
+import { SerialTransport } from './generated/ts/struct-frame-sdk';
-const transport = new SerialTransport('/dev/ttyUSB0', 115200);
+const transport = new SerialTransport({ path: '/dev/ttyUSB0', baudRate: 115200 });
await transport.connect();
-await transport.send(msgId, data);
```
## Browser vs Node.js
@@ -83,10 +82,10 @@ The SDK works in both environments:
// Detect environment
if (typeof window === 'undefined') {
// Node.js
- import { SerialTransport } from './struct_frame_sdk/transports';
+ const { SerialTransport } = await import('./struct-frame-sdk');
} else {
// Browser
- import { WebSocketTransport } from './struct_frame_sdk/transports';
+ const { WebSocketTransport } = await import('./struct-frame-sdk');
}
```
diff --git a/docs/src/content/docs/index.mdx b/docs/src/content/docs/index.mdx
index 6149f226..b419f7d0 100644
--- a/docs/src/content/docs/index.mdx
+++ b/docs/src/content/docs/index.mdx
@@ -106,8 +106,8 @@ python -m struct_frame status.proto --build_c --build_py --build_ts
msg.id = 42;
msg.value = 3.14;
- // Get binary data
- const data = msg.data();
+ // Serialize to buffer
+ const data = msg.serialize();
```
diff --git a/docs/src/content/docs/reference/build-integration.md b/docs/src/content/docs/reference/build-integration.md
index e841a40a..2ec5d092 100644
--- a/docs/src/content/docs/reference/build-integration.md
+++ b/docs/src/content/docs/reference/build-integration.md
@@ -11,13 +11,13 @@ Integrate code generation into your build system so generated code automatically
PROTO_FILES := $(wildcard proto/*.proto)
GENERATED_DIR := generated
-generated/c/%.sf.h: proto/%.proto
+generated/c/%.structframe.h: proto/%.proto
python -m struct_frame $< --build_c --c_path generated/c/
-generated/py/%.sf.py: proto/%.proto
+generated/py/struct_frame/generated/%.py: proto/%.proto
python -m struct_frame $< --build_py --py_path generated/py/
-all: $(PROTO_FILES:proto/%.proto=generated/c/%.sf.h)
+all: $(PROTO_FILES:proto/%.proto=generated/c/%.structframe.h)
```
## CMake (C/C++)
@@ -31,7 +31,7 @@ set(PROTO_FILES
foreach(PROTO_FILE ${PROTO_FILES})
get_filename_component(PROTO_NAME ${PROTO_FILE} NAME_WE)
- set(GENERATED_HEADER "${CMAKE_BINARY_DIR}/generated/c/${PROTO_NAME}.sf.h")
+ set(GENERATED_HEADER "${CMAKE_BINARY_DIR}/generated/c/${PROTO_NAME}.structframe.h")
add_custom_command(
OUTPUT ${GENERATED_HEADER}
diff --git a/docs/src/content/docs/reference/testing.md b/docs/src/content/docs/reference/testing.md
index 438bd527..57a2f837 100644
--- a/docs/src/content/docs/reference/testing.md
+++ b/docs/src/content/docs/reference/testing.md
@@ -22,10 +22,15 @@ python tests/run_tests.py [options]
Options:
--verbose, -v Show detailed output
- --skip-lang LANG Skip a language (c, cpp, py, ts, js, csharp, gql)
- --only-generate Generate code only, skip tests
+ --quiet, -q Suppress failure output
+ --skip-lang LANG Skip a language (can be repeated)
+ --only-generate Generate code only, skip compile and test
+ --only-compile Stop after compilation, don't run tests
--check-tools Check tool availability only
- --clean Clean generated and compiled files
+ --no-clean Skip cleaning generated files (faster iteration)
+ --profile NAME Only test specific profile(s)
+ --no-parallel Disable parallel compilation
+ --no-color Disable colored output
```
Examples:
@@ -39,6 +44,9 @@ python tests/run_tests.py --check-tools
# Generate code without running tests
python tests/run_tests.py --only-generate
+
+# Faster iteration (skip cleaning)
+python tests/run_tests.py --no-clean
```
## Test Prerequisites