7 k_vg_msg_code_frame
= 1,
8 k_vg_msg_code_endframe
= 2,
10 k_vg_msg_code_kvstring
= 11,
11 k_vg_msg_code_kvbin
= 12,
12 k_vg_msg_code_signed
= 0x80, /* byte sizes stored in lower 4 bits */
13 k_vg_msg_code_unsigned
= 0x40,
14 k_vg_msg_code_float
= 0x20
17 typedef struct vg_msg vg_msg
;
18 typedef struct vg_msg_cmd vg_msg_cmd
;
26 k_vg_msg_error_unbalanced
,
27 k_vg_msg_error_overflow
,
28 k_vg_msg_error_unhandled_cmd
39 union{ const void *_buf
;
42 u32 _u32
; i32 _i32
; f32 _f32
;
43 u64 _u64
; i64 _i64
; f64 _f64
;
48 static void vg_msg_init( vg_msg
*msg
, u8
*buf
, u32 max
){
53 msg
->error
= k_vg_msg_error_OK
;
56 static void vg_msg_exchbuf( vg_msg
*msg
, int write
, u8
*buf
, u32 len
){
57 if( msg
->error
!= k_vg_msg_error_OK
) return;
58 if( msg
->cur
+len
> msg
->max
){
59 msg
->error
= k_vg_msg_error_overflow
;
62 for( u32 i
=0; i
<len
; i
++ ){
63 if( write
) msg
->buf
[ msg
->cur
++ ] = buf
[i
];
64 else buf
[i
] = msg
->buf
[ msg
->cur
++ ];
68 static void vg_msg_wstr( vg_msg
*msg
, const char *str
){
69 if( msg
->error
!= k_vg_msg_error_OK
) return;
71 vg_msg_exchbuf( msg
, 1, (u8
[]){ str
[i
] }, 1 );
76 static const char *vg_msg_rstr( vg_msg
*msg
, u32
*djb2
){
77 if( msg
->error
!= k_vg_msg_error_OK
) return 0;
80 const char *str
= (void *)(&msg
->buf
[ msg
->cur
]);
82 while( (c
= msg
->buf
[ msg
->cur
++ ]) ){
83 if( msg
->cur
>= msg
->max
){
84 msg
->error
= k_vg_msg_error_overflow
;
87 hash
= ((hash
<< 5) + hash
) + c
; /* hash * 33 + c */
94 static void vg_msg_frame( vg_msg
*msg
, const char *name
){
95 if( msg
->error
!= k_vg_msg_error_OK
) return;
98 vg_msg_exchbuf( msg
, 1, (u8
[]){ k_vg_msg_code_frame
}, 1 );
99 vg_msg_wstr( msg
, name
);
102 static void vg_msg_end_frame( vg_msg
*msg
){
103 if( msg
->error
!= k_vg_msg_error_OK
) return;
105 msg
->error
= k_vg_msg_error_unbalanced
;
109 vg_msg_exchbuf( msg
, 1, (u8
[]){ k_vg_msg_code_endframe
}, 1 );
112 static void vg_msg_wkvstr( vg_msg
*msg
, const char *key
, const char *value
){
113 vg_msg_exchbuf( msg
, 1, (u8
[]){ k_vg_msg_code_kvstring
}, 1 );
114 vg_msg_wstr( msg
, key
);
115 vg_msg_wstr( msg
, value
);
118 static void vg_msg_wkvbin( vg_msg
*msg
, const char *key
, u8
*bin
, u32 len
){
119 vg_msg_exchbuf( msg
, 1, (u8
[]){ k_vg_msg_code_kvbin
}, 1 );
120 vg_msg_wstr( msg
, key
);
121 vg_msg_exchbuf( msg
, 1, (u8
*)(&len
), 4 );
122 vg_msg_exchbuf( msg
, 1, bin
, len
);
125 static void vg__msg_wkvgen( vg_msg
*msg
, const char *key
,
126 u8 basecode
, void *value
, u32 size
){
127 u8 code
= basecode
| size
;
128 vg_msg_exchbuf( msg
, 1, &code
, 1 );
129 vg_msg_wstr( msg
, key
);
130 vg_msg_exchbuf( msg
, 1, value
, size
);
133 #define vg_msg_wkvint( MSGPTR, KEY, DECL ){ \
135 vg__msg_wkvgen(MSGPTR, KEY, k_vg_msg_code_signed, &value, sizeof(value));\
137 #define vg_msg_wkvuint( MSGPTR, KEY, DECL ){ \
139 vg__msg_wkvgen(MSGPTR, KEY, k_vg_msg_code_unsigned, &value, sizeof(value));\
141 #define vg_msg_wkvfloat( MSGPTR, KEY, DECL ){ \
143 vg__msg_wkvgen(MSGPTR, KEY, k_vg_msg_code_float, &value, sizeof(value));\
146 static int vg_msg_next( vg_msg
*msg
, vg_msg_cmd
*cmd
){
147 vg_msg_exchbuf( msg
, 0, &cmd
->code
, 1 );
148 if( msg
->error
!= k_vg_msg_error_OK
) return 0;
150 if( cmd
->code
== k_vg_msg_code_frame
){
151 cmd
->key
= vg_msg_rstr( msg
, &cmd
->key_djb2
);
154 else if( cmd
->code
== k_vg_msg_code_endframe
){
156 msg
->error
= k_vg_msg_error_unbalanced
;
161 else if( cmd
->code
>= k_vg_msg_code_kv
){
162 cmd
->key
= vg_msg_rstr( msg
, &cmd
->key_djb2
);
166 if( cmd
->code
& (k_vg_msg_code_float
|k_vg_msg_code_unsigned
|
167 k_vg_msg_code_signed
)){
168 u8 len
= cmd
->code
& 0xf;
169 vg_msg_exchbuf( msg
, 0, (u8
*)(&cmd
->value
._u64
), len
);
171 else if( cmd
->code
== k_vg_msg_code_kvstring
){
172 cmd
->value
._buf
= vg_msg_rstr( msg
, &cmd
->value_djb2
);
174 else if( cmd
->code
== k_vg_msg_code_kvbin
){
176 vg_msg_exchbuf( msg
, 0, (u8
*)(&len
), 4 );
177 if( msg
->error
!= k_vg_msg_error_OK
) return 0;
178 cmd
->value
._buf
= &msg
->buf
[ msg
->cur
];
180 if( msg
->cur
> msg
->max
){
181 msg
->error
= k_vg_msg_error_overflow
;
185 msg
->error
= k_vg_msg_error_unhandled_cmd
;
189 msg
->error
= k_vg_msg_error_unhandled_cmd
;
192 if( msg
->error
!= k_vg_msg_error_OK
) return 0;
196 static int vg_msg_skip_frame( vg_msg
*msg
){
199 u32 depth
= msg
->depth
-1;
200 while( vg_msg_next( msg
, &cmd
) ){
201 if( msg
->depth
== depth
) return 1;
206 #endif /* VG_MSG_H */