-};
-
-/* generic stream reset */
-static void vg_msg_init( vg_msg *msg, u8 *buf, u32 max ){
- msg->cur = 0;
- msg->max = max;
- msg->buf = buf;
- msg->depth = 0;
- msg->error = k_vg_msg_error_OK;
- msg->rframe_depth = 0;
- msg->rframe_cur = 0;
-}
-
-/* write or read a buffer from msg, rang checked. */
-static void vg_msg_exchbuf( vg_msg *msg, int write, u8 *buf, u32 len ){
- if( msg->error != k_vg_msg_error_OK ) return;
- if( msg->cur+len > msg->max ){
- msg->error = k_vg_msg_error_overflow;
- return;
- }
- for( u32 i=0; i<len; i++ ){
- if( write ) msg->buf[ msg->cur ++ ] = buf[i];
- else buf[i] = msg->buf[ msg->cur ++ ];
- }
-}
-
-/* write null terminated string to stream */
-static void vg_msg_wstr( vg_msg *msg, const char *str ){
- if( msg->error != k_vg_msg_error_OK ) return;
- for( u32 i=0;; i++ ){
- vg_msg_exchbuf( msg, 1, (u8[]){ str[i] }, 1 );
- if( !str[i] ) break;
- }
-}
-
-/* read null terminated string, range check and generate hash (djb2) */
-static const char *vg_msg_rstr( vg_msg *msg, u32 *djb2 ){
- if( msg->error != k_vg_msg_error_OK ) return 0;
-
- u32 hash = 5381, c;
- const char *str = (void *)(&msg->buf[ msg->cur ]);
-
- while( (c = msg->buf[ msg->cur ++ ]) ){
- if( msg->cur >= msg->max ){
- msg->error = k_vg_msg_error_overflow;
- return 0;
- }
- hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
- }
-
- *djb2 = hash;
- return str;
-}
-
-/* begin a new frame in message stream */
-static void vg_msg_frame( vg_msg *msg, const char *name ){
- if( msg->error != k_vg_msg_error_OK ) return;
-
- msg->depth ++;
- vg_msg_exchbuf( msg, 1, (u8[]){ k_vg_msg_code_frame }, 1 );
- vg_msg_wstr( msg, name );
-}
-
-/* end frame in message stream */
-static void vg_msg_end_frame( vg_msg *msg ){
- if( msg->error != k_vg_msg_error_OK ) return;
- if( !msg->depth ){
- msg->error = k_vg_msg_error_unbalanced;
- return;
- }
- msg->depth --;
- vg_msg_exchbuf( msg, 1, (u8[]){ k_vg_msg_code_endframe }, 1 );
-}
-
-/* write a KV string to stream */
-static void vg_msg_wkvstr( vg_msg *msg, const char *key, const char *value ){
- vg_msg_exchbuf( msg, 1, (u8[]){ k_vg_msg_code_kvstring }, 1 );
- vg_msg_wstr( msg, key );
- vg_msg_wstr( msg, value );
-}
-
-/* write a binary block to stream */
-static void vg_msg_wkvbin( vg_msg *msg, const char *key, u8 *bin, u32 len ){
- vg_msg_exchbuf( msg, 1, (u8[]){ k_vg_msg_code_kvbin }, 1 );
- vg_msg_wstr( msg, key );
- vg_msg_exchbuf( msg, 1, (u8 *)(&len), 4 );
- vg_msg_exchbuf( msg, 1, bin, len );
-}
-
-/* write a generic sized kv */
-static void vg__msg_wkvgen( vg_msg *msg, const char *key,
- u8 basecode, void *value, u32 size ){
- u8 code = basecode | size;
- vg_msg_exchbuf( msg, 1, &code, 1 );
- vg_msg_wstr( msg, key );
- vg_msg_exchbuf( msg, 1, value, size );
-}