asrt
Automated System Runtime Testing library
Loading...
Searching...
No Matches
collect_proto.h
1
11#ifndef ASRT_COLLECT_PROTO_H
12#define ASRT_COLLECT_PROTO_H
13
14#ifdef __cplusplus
15extern "C" {
16#endif
17
18#include "./chann.h"
19#include "./flat_tree.h"
20
22enum asrt_collect_message_id_e
23{
24 ASRT_COLLECT_MSG_READY = 0x01, // controller -> reactor
25 ASRT_COLLECT_MSG_READY_ACK = 0x02, // reactor -> controller
26 ASRT_COLLECT_MSG_APPEND = 0x03, // reactor -> controller
27 ASRT_COLLECT_MSG_ERROR = 0x04, // controller -> reactor
28};
29typedef uint8_t asrt_collect_message_id;
30
31// node_id=0 is the reserved NONE sentinel.
32#define ASRT_COLLECT_NONE_ID ( (asrt_flat_id) 0 )
33
34enum asrt_collect_err_e
35{
36 ASRT_COLLECT_ERR_NONE = 0x00,
37 ASRT_COLLECT_ERR_APPEND_FAILED = 0x01,
38};
39
40typedef enum asrt_status ( *asrt_collect_msg_callback )( void* ptr, struct asrt_span* buff );
41
42static inline struct asrt_send_req* asrt_msg_ctor_collect_ready(
43 struct asrt_u8d9msg* ready_msg,
44 asrt_flat_id root_id,
45 asrt_flat_id next_node_id )
46{
47 uint8_t* p = ready_msg->buff;
48 *p++ = ASRT_COLLECT_MSG_READY;
49 asrt_add_u32( &p, root_id );
50 asrt_add_u32( &p, next_node_id );
51 ready_msg->req.buff = ( struct asrt_span_span ){
52 .b = ready_msg->buff,
53 .e = ready_msg->buff + sizeof ready_msg->buff,
54 .rest = NULL,
55 .rest_count = 0,
56 };
57 return &ready_msg->req;
58}
59
60static inline struct asrt_send_req* asrt_msg_rtoc_collect_ready_ack(
61 struct asrt_u8d1msg* ready_ack_msg )
62{
63 ready_ack_msg->buff[0] = ASRT_COLLECT_MSG_READY_ACK;
64 ready_ack_msg->req.buff = ( struct asrt_span_span ){
65 .b = ready_ack_msg->buff,
66 .e = ready_ack_msg->buff + 1,
67 .rest = NULL,
68 .rest_count = 0,
69 };
70 return &ready_ack_msg->req;
71}
72
74{
75 uint8_t val_buff[9];
76 struct asrt_span span[3];
77 uint8_t hdr[9];
78 struct asrt_send_req req;
79};
80
81static inline struct asrt_send_req* asrt_msg_rtoc_collect_append(
82 struct asrt_collect_append_msg* msg,
83 asrt_flat_id parent_id,
84 asrt_flat_id node_id,
85 char const* key,
86 struct asrt_flat_value const* value )
87{
88 // tail: type byte + encoded value (strings chain to their pointer)
89 // OBJECT/ARRAY carry no value payload in the collect protocol — the
90 // first/last child ids are managed by the receiving tree.
91 uint8_t val_buf[9]; // type(1) + max non-string payload(8)
92 uint8_t* vp = val_buf;
93 *vp++ = (uint8_t) value->type;
94
95 struct asrt_span* key_span = &msg->span[0];
96 struct asrt_span* val_span = &msg->span[1];
97
98 uint32_t rest_count;
99 if ( value->type == ASRT_FLAT_STYPE_STR ) {
100 // span[1] = type byte, span[2] = string bytes (including NUL)
101 size_t slen = strlen( value->data.s.str_val );
102 memcpy( msg->val_buff, val_buf, (size_t) ( vp - val_buf ) );
103 *val_span = ( struct asrt_span ){
104 .b = msg->val_buff, .e = msg->val_buff + (size_t) ( vp - val_buf ) };
105 msg->span[2] = ( struct asrt_span ){
106 .b = (uint8_t*) value->data.s.str_val,
107 .e = (uint8_t*) value->data.s.str_val + slen + 1 };
108 rest_count = 3;
109 } else if ( value->type == ASRT_FLAT_CTYPE_OBJECT || value->type == ASRT_FLAT_CTYPE_ARRAY ) {
110 memcpy( msg->val_buff, val_buf, (size_t) ( vp - val_buf ) );
111 *val_span = ( struct asrt_span ){
112 .b = msg->val_buff, .e = msg->val_buff + (size_t) ( vp - val_buf ) };
113 rest_count = 2;
114 } else {
115 asrt_flat_value_write( &vp, *value );
116 memcpy( msg->val_buff, val_buf, (size_t) ( vp - val_buf ) );
117 *val_span = ( struct asrt_span ){
118 .b = msg->val_buff, .e = msg->val_buff + (size_t) ( vp - val_buf ) };
119 rest_count = 2;
120 }
121
122 // key: borrow caller's string (including NUL) or point at a static NUL byte
123 if ( key ) {
124 size_t klen = strlen( key );
125 *key_span =
126 ( struct asrt_span ){ .b = (uint8_t*) key, .e = (uint8_t*) key + klen + 1 };
127 } else {
128 static uint8_t const nul = '\0';
129 *key_span = ( struct asrt_span ){ .b = (uint8_t*) &nul, .e = (uint8_t*) &nul + 1 };
130 }
131
132 // header: msg_id + parent_id + node_id
133 uint8_t* h = msg->hdr;
134 *h++ = ASRT_COLLECT_MSG_APPEND;
135 asrt_add_u32( &h, parent_id );
136 asrt_add_u32( &h, node_id );
137 msg->req.buff = ( struct asrt_span_span ){
138 .b = msg->hdr,
139 .e = msg->hdr + sizeof msg->hdr,
140 .rest = msg->span,
141 .rest_count = rest_count,
142 };
143 return &msg->req;
144}
145
146
147static inline struct asrt_send_req* asrt_msg_ctor_collect_error(
148 struct asrt_u8d2msg* err_msg,
149 enum asrt_collect_err_e error_code )
150{
151 err_msg->buff[0] = ASRT_COLLECT_MSG_ERROR;
152 err_msg->buff[1] = (uint8_t) error_code;
153 err_msg->req.buff = ( struct asrt_span_span ){
154 .b = err_msg->buff,
155 .e = err_msg->buff + sizeof err_msg->buff,
156 .rest = NULL,
157 .rest_count = 0,
158 };
159 return &err_msg->req;
160}
161
162#ifdef __cplusplus
163}
164#endif
165
166#endif // ASRT_COLLECT_PROTO_H
Definition: collect_proto.h:74
Definition: flat_tree.h:90
An outgoing message request placed in a module's send queue.
Definition: chann.h:64
struct asrt_span_span buff
Message payload (scatter-gather).
Definition: chann.h:65
Scatter-gather buffer: a primary byte range [b, e) followed by rest_count additional spans.
Definition: span.h:37
uint32_t rest_count
Number of entries in rest.
Definition: span.h:41
uint8_t * b
Primary buffer start.
Definition: span.h:38
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee ...
Definition: span.h:23
uint8_t * b
Pointer to the first byte.
Definition: span.h:24
uint8_t * e
One-past-the-end pointer.
Definition: span.h:25
Definition: chann.h:191
Definition: chann.h:196
Definition: chann.h:221