#include "vg_msg.h"
#include "vg_platform.h"
#include "vg_string.h"
+#include "vg_kv.h"
#include <string.h>
#include <stdio.h>
{
if( src_base == k_vg_msg_float )
{
- retrun (u64)vg_msg_cast_to_f64( src, src_base, src_size );
+ return (u64)vg_msg_cast_to_f64( src, src_base, src_size );
}
else
{
{
if( src_base == k_vg_msg_float )
{
- retrun (i64)vg_msg_cast_to_f64( src, src_base, src_size );
+ return (i64)vg_msg_cast_to_f64( src, src_base, src_size );
}
else
{
{
f32 a = 0;
memcpy( &a, src, sizeof(a) );
- return (f64);
+ return (f64)a;
}
else if( src_size == 8 )
{
}
}
}
+
+void vg_kvs_append_from_legacy_msg2( vg_kvs *kvs, u32 root, void *buffer, u32 len, vg_stack_allocator *stack )
+{
+ vg_msg b;
+ vg_msg_init( &b, buffer, len );
+
+ u32 frame_stack[ 16 ];
+ u32 frame_depth = 0;
+ frame_stack[0] = root;
+
+ vg_msg_cmd cmd;
+ while( vg_msg_next( &b, &cmd ) )
+ {
+ if( cmd.code == k_vg_msg_frame )
+ {
+ VG_ASSERT( frame_depth < VG_ARRAY_LEN(frame_stack) );
+ u32 next = vg_kv_append( kvs, frame_stack[frame_depth++], cmd.key, NULL );
+ }
+ else
+ {
+ if( cmd.code == k_vg_msg_endframe )
+ {
+ VG_ASSERT( frame_depth );
+ frame_depth --;
+ }
+ else if( cmd.code == k_vg_msg_kvstring )
+ {
+ vg_kv_append( kvs, frame_stack[frame_depth], cmd.key, cmd.value );
+ }
+ else if( cmd.code == k_vg_msg_kvbin )
+ {
+ vg_warn( "Unsupported legacy kv code: binary blob.\n" );
+ }
+ else
+ {
+ u32 base = cmd.code & k_vg_msg_type_base_bits,
+ count = vg_msg_cmd_array_count( cmd.code ),
+ size = vg_msg_cmd_type_size( cmd.code );
+ c8 formatted[ 1024 ];
+ formatted[0] = '\0';
+ for( u32 i=0; i<count; i++ )
+ {
+ const c8 *end = (i+1==count)?"":" ";
+ const void *p = cmd.value + size*i;
+ if( base == k_vg_msg_unsigned )
+ {
+ snprintf( formatted, 1024, "%s"
+#ifdef _WIN32
+ "%llu%s"
+#else
+ "%lu%s"
+#endif
+ , formatted, vg_msg_cast_to_u64( p, base, size ), end );
+ }
+ else if( base == k_vg_msg_signed )
+ {
+ snprintf( formatted, 1024, "%s"
+#ifdef _WIN32
+ "%lld%s"
+#else
+ "%ld%s"
+#endif
+ , formatted, vg_msg_cast_to_i64( p, base, size ), end );
+ }
+ else
+ snprintf( formatted, 1024, "%s%f%s", formatted, vg_msg_cast_to_f64( p, base, size ), end );
+ }
+ vg_kv_append( kvs, frame_stack[frame_depth], cmd.key, formatted );
+ }
+ }
+ }
+}
int vg_msg_getkvvecf( vg_msg *msg, const char *key, u8 type,
void *v, void *default_value );
void vg_msg_print( vg_msg *msg, u32 len );
+
+#include "vg_kv.h"
+void vg_kvs_append_from_legacy_msg2( vg_kvs *kvs, u32 root, void *buffer, u32 len, vg_stack_allocator *stack );
va_end( args );
}
-u32 vg_strdjb2( const char *str )
+u32 vg_strdjb2( const c8 *str )
{
u32 hash = 5381, c;
-
if( str )
while( (c = *str++) )
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
-
return hash;
}
-int vg_strdjb2_eq( const char *s1, u32 h1, const char *s2, u32 h2 )
+bool vg_strdjb2_eq( const char *s1, u32 h1, const char *s2, u32 h2 )
{
if( h1 == h2 )
{
buf[j] = 0x00;
return j;
}
+
+
+
+
+
+
+const c8 *vg_strp_info_str[] =
+{
+ [k_vg_strp_ok] = "ok",
+ [k_vg_strp_eof] = "eof",
+ [k_vg_strp_error] = "error",
+ [k_vg_strp_whitespace] = "whitespace"
+};
+
+static vg_strp_info vg_strp_char( vg_strp *p, c8 *c )
+{
+ *c = 0;
+ if( p->buffer == NULL )
+ return k_vg_strp_eof;
+
+ *c = *p->buffer;
+ if( *c == '\0' )
+ {
+ p->buffer = NULL;
+ return k_vg_strp_eof;
+ }
+ p->buffer ++;
+
+ if( *c == '\t' || *c == '\n' || *c == ' ' || *c == '\r' )
+ return k_vg_strp_whitespace;
+ else
+ return k_vg_strp_ok;
+}
+
+vg_strp_info vg_strp_u64( vg_strp *p, u64 *value )
+{
+ c8 c;
+ vg_strp_info info = k_vg_strp_whitespace;
+ while( info == k_vg_strp_whitespace )
+ info = vg_strp_char( p, &c );
+
+ u64 result = 0;
+ bool got = 0;
+ while( info == k_vg_strp_ok )
+ {
+ if( c >= '0' && c <= '9' )
+ {
+ result = result*10 + ((u64)c - (u64)'0');
+ got = 1;
+ }
+ else
+ goto err;
+ info = vg_strp_char( p, &c );
+ }
+ info = k_vg_strp_ok;
+ goto ok;
+
+ err: while( info == k_vg_strp_ok )
+ info = vg_strp_char( p, &c );
+ info = k_vg_strp_error;
+
+ ok: *value = result;
+ return got? info: k_vg_strp_eof;
+}
+
+vg_strp_info vg_strp_i64( vg_strp *p, i64 *value )
+{
+ c8 c;
+ vg_strp_info info = k_vg_strp_whitespace;
+ while( info == k_vg_strp_whitespace )
+ info = vg_strp_char( p, &c );
+
+ i64 result = 0,
+ sign = 1;
+
+ if( c == '+' || c == '-' )
+ {
+ if( c == '-' )
+ sign = -1;
+ info = vg_strp_char( p, &c );
+ }
+
+ bool got = 0;
+ while( info == k_vg_strp_ok )
+ {
+ if( c >= '0' && c <= '9' )
+ {
+ result = result*10 + ((i64)c - (i64)'0');
+ got = 1;
+ }
+ else
+ goto err;
+
+ info = vg_strp_char( p, &c );
+ }
+ info = k_vg_strp_ok;
+ goto ok;
+
+ err: while( info == k_vg_strp_ok )
+ info = vg_strp_char( p, &c );
+ info = k_vg_strp_error;
+
+ ok: *value = result*sign;
+ return got? info: k_vg_strp_eof;
+}
+
+vg_strp_info vg_strp_f64( vg_strp *p, f64 *value )
+{
+ c8 c;
+ vg_strp_info info = k_vg_strp_whitespace;
+ while( info == k_vg_strp_whitespace )
+ info = vg_strp_char( p, &c );
+
+ i64 result = 0,
+ resultm= 0;
+ u32 dp = 0;
+ f64 sign = 1.0;
+
+ if( c == '+' || c == '-' )
+ {
+ if( c == '-' )
+ sign = -1.0;
+ info = vg_strp_char( p, &c );
+ }
+
+ bool got = 0, got_decimal = 0;
+ while( info == k_vg_strp_ok )
+ {
+ if( c == '.' )
+ {
+ if( got_decimal )
+ goto err;
+ resultm = result;
+ result = 0;
+ got_decimal = 1;
+ dp = 0;
+ }
+ else if( c >= '0' && c <= '9' )
+ {
+ result = result*10 + ((i64)c - (i64)'0');
+ got = 1;
+ dp ++;
+ }
+ else
+ goto err;
+ info = vg_strp_char( p, &c );
+ }
+
+ info = k_vg_strp_ok;
+ goto ok;
+
+ err: while( info == k_vg_strp_ok )
+ info = vg_strp_char( p, &c );
+ info = k_vg_strp_error;
+
+ ok:;
+ f64 int_part = 0.0, decimal_part = 0.0;
+
+ if( got_decimal )
+ {
+ decimal_part = (f64)result;
+ for( u32 i=0; i<dp; i ++ )
+ decimal_part /= 10.0;
+ int_part = resultm;
+ }
+ else int_part = result;
+
+ *value = (f64)sign * (int_part + decimal_part);
+ return (got||got_decimal)? info: k_vg_strp_eof;
+}
u32 vg_strncpy( const char *src, char *dst, u32 len, enum strncpy_behaviour behaviour );
u32 vg_strdjb2( const char *str );
-int vg_strdjb2_eq( const char *s1, u32 h1, const char *s2, u32 h2 );
+bool vg_strdjb2_eq( const char *s1, u32 h1, const char *s2, u32 h2 );
#define VG_STRDJB2_EQ( CS1, S2, H2 ) \
vg_strdjb2_eq( CS1, vg_strdjb2(CS1), S2, H2 )
bool vg_str_flushfd( vg_str *str, int fd );
u32 str_utf8_collapse( const char *str, char *buf, u32 length );
+
+typedef struct vg_strp vg_strp;
+struct vg_strp
+{
+ const c8 *buffer;
+};
+
+typedef enum vg_strp_info vg_strp_info;
+enum vg_strp_info
+{
+ k_vg_strp_ok,
+ k_vg_strp_eof,
+ k_vg_strp_error,
+ k_vg_strp_whitespace
+};
+
+vg_strp_info vg_strp_i64( vg_strp *p, i64 *value );
+vg_strp_info vg_strp_u64( vg_strp *p, u64 *value );
+vg_strp_info vg_strp_f64( vg_strp *p, f64 *value );
+extern const c8 *vg_strp_info_str[];
+
+void vg_strcatf64( vg_str *str, f64 value, u32 decimals );