-};
-
-/* write a buffer from msg, rang checked. */
-static void vg_msg_wbuf( vg_msg *msg, 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++ ){
- msg->buf[ msg->cur ++ ] = buf[i];
- msg->len ++;
- }
-}
-
-/* read a buffer from msg, rang checked. */
-static void vg_msg_rbuf( vg_msg *msg, u8 *buf, u32 len ){
- if( msg->error != k_vg_msg_error_OK ) return;
- if( msg->cur+len > msg->len ){
- msg->error = k_vg_msg_error_overflow;
- return;
- }
-
- for( u32 i=0; i<len; i++ ){
- 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_wbuf( msg, (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_wbuf( msg, (u8[]){ k_vg_msg_frame }, 1 );
- vg_msg_wstr( msg, name );
-}
-
-/* shift right side of cursor by len */
-static void vg_msg_makeroom( vg_msg *msg, u32 len ){
- if( msg->error != k_vg_msg_error_OK ) return;
- if( msg->len + len > msg->max ){
- msg->error = k_vg_msg_error_overflow;
- return;
- }
- u32 i = msg->len-msg->cur;
- while( i --> 0 ){
- msg->buf[ msg->cur+len+i ] = msg->buf[ msg->cur+i ];
- }
- msg->len += len;
-}
-
-/* paste data into msg, at the cursor location */
-static void vg_msg_insert( vg_msg *msg, vg_msg *data ){
- vg_msg_makeroom( msg, data->len );
- vg_msg_wbuf( msg, data->buf, data->len );
- msg->depth += data->depth;
-}
-
-/* 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_wbuf( msg, (u8[]){ k_vg_msg_endframe }, 1 );
-}
-
-/* write a KV string to stream */
-static void vg_msg_wkvstr( vg_msg *msg, const char *key, const char *value ){
- vg_msg_wbuf( msg, (u8[]){ k_vg_msg_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_wbuf( msg, (u8[]){ k_vg_msg_kvbin }, 1 );
- vg_msg_wstr( msg, key );
- vg_msg_wbuf( msg, (u8 *)(&len), 4 );
- vg_msg_wbuf( msg, bin, len );
-}
-
-/* get the byte count of a sized code */
-static u32 vg_msg_sized_bytecount( u8 code ){
- u32 size = 0x1 << (code & k_vg_msg_size_bits),
- count = ((code & k_vg_msg_array_count_bits)>>2) + 1;
- return size * count;
-}
-
-/* write a sized type */
-static void vg_msg_wkvnum( vg_msg *msg, const char *key,
- u8 type, u8 count, void *data ){
- u8 code = type | ((count-1)<<2);
-
- vg_msg_wbuf( msg, &code, 1 );
- vg_msg_wstr( msg, key );
- vg_msg_wbuf( msg, data, vg_msg_sized_bytecount(code) );
-}