- 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;
-}
-
-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 );
-}
-
-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 );
-}
-
-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 );
-}
-
-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 );
-}
-
-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 );
-}
-
-#define vg_msg_wkvint( MSGPTR, KEY, DECL ){ \
- DECL; \
- vg__msg_wkvgen(MSGPTR, KEY, k_vg_msg_code_signed, &value, sizeof(value));\
- }
-#define vg_msg_wkvuint( MSGPTR, KEY, DECL ){ \
- DECL; \
- vg__msg_wkvgen(MSGPTR, KEY, k_vg_msg_code_unsigned, &value, sizeof(value));\
- }
-#define vg_msg_wkvfloat( MSGPTR, KEY, DECL ){ \
- DECL; \
- vg__msg_wkvgen(MSGPTR, KEY, k_vg_msg_code_float, &value, sizeof(value));\
- }
-
-static int vg_msg_next( vg_msg *msg, vg_msg_cmd *cmd ){
- vg_msg_exchbuf( msg, 0, &cmd->code, 1 );
- if( msg->error != k_vg_msg_error_OK ) return 0;
-
- if( cmd->code == k_vg_msg_code_frame ){
- cmd->key = vg_msg_rstr( msg, &cmd->key_djb2 );
- msg->depth ++;
- }
- else if( cmd->code == k_vg_msg_code_endframe ){
- if( !msg->depth ){
- msg->error = k_vg_msg_error_unbalanced;
- return 0;
- }
- msg->depth --;
- }
- else if( cmd->code >= k_vg_msg_code_kv ){
- cmd->key = vg_msg_rstr( msg, &cmd->key_djb2 );
- cmd->value_djb2 = 0;
- cmd->value._u64 = 0;
-
- if( cmd->code & (k_vg_msg_code_float|k_vg_msg_code_unsigned|
- k_vg_msg_code_signed )){
- u8 len = cmd->code & 0xf;
- vg_msg_exchbuf( msg, 0, (u8 *)(&cmd->value._u64), len );
- }
- else if( cmd->code == k_vg_msg_code_kvstring ){
- cmd->value._buf = vg_msg_rstr( msg, &cmd->value_djb2 );
- }
- else if( cmd->code == k_vg_msg_code_kvbin ){
- u32 len;
- vg_msg_exchbuf( msg, 0, (u8 *)(&len), 4 );
- if( msg->error != k_vg_msg_error_OK ) return 0;
- cmd->value._buf = &msg->buf[ msg->cur ];
- msg->cur += len;
- if( msg->cur > msg->max ){
- msg->error = k_vg_msg_error_overflow;
- }
- }
- else{
- msg->error = k_vg_msg_error_unhandled_cmd;
- }
- }
- else{
- msg->error = k_vg_msg_error_unhandled_cmd;
- }
-
- if( msg->error != k_vg_msg_error_OK ) return 0;
- else return 1;
-}
-
-static int vg_msg_skip_frame( vg_msg *msg ){
- vg_msg_cmd cmd;
-
- u32 depth = msg->depth-1;
- while( vg_msg_next( msg, &cmd ) ){
- if( msg->depth == depth ) return 1;
- }
- return 0;
-}