{
vg_kv *kv = &kvs->kvs[ kv_id ];
*out_length = (kv->key_info >> 20) & 0x3FF;
- return kvs->source_buffer + kv->key_offset;
+ return (*out_length)? kvs->source_buffer + kv->key_offset: NULL;
}
const char *vg_kv_value( vg_kvs *kvs, u32 kv_id, u32 *out_length )
return 0;
}
+typedef struct vg_kv_write vg_kv_write;
+struct vg_kv_write
+{
+ FILE *fp;
+ u32 depth;
+};
+
+void vg_kv_write_indent( vg_kv_write *w )
+{
+ for( u32 i=0; i<w->depth; i ++ )
+ fputc( ' ', w->fp );
+}
+
+void vg_kv_write_string( vg_kv_write *w, const char *string, u32 length )
+{
+ if( length == 0 )
+ length = 0xffffffff;
+
+ u32 i=0;
+ char delim=0;
+ for( ;i<length; i ++ )
+ {
+ char c = string[i];
+ if( c == '\0' )
+ break;
+
+ char new_delim = 0;
+ if( c == '"' )
+ new_delim = '\'';
+ else if( c == '\'' || c == ' ' || c == '\t' || c == '\n' )
+ new_delim = '"';
+
+ if( new_delim )
+ {
+ if( delim && (new_delim != delim) )
+ {
+ vg_kv_write_string( w, "VG_KV_UNWRITABLE_STRING", 0 );
+ return;
+ }
+ else delim = new_delim;
+ }
+ }
+
+ if( delim ) fputc( delim, w->fp );
+ for( u32 j=0; j<i; j ++ ) fputc( string[j], w->fp );
+ if( delim ) fputc( delim, w->fp );
+}
+
+void vg_kv_write_block( vg_kv_write *w, const char *name, u32 name_length )
+{
+ vg_kv_write_indent( w );
+ if( name )
+ {
+ vg_kv_write_string( w, name, name_length );
+ fputc( '\n', w->fp );
+ vg_kv_write_indent( w );
+ }
+
+ fputc( '{', w->fp );
+ fputc( '\n', w->fp );
+ w->depth ++;
+}
+
+void vg_kv_end_block( vg_kv_write *w )
+{
+ w->depth --;
+ vg_kv_write_indent( w );
+ fputc( '}', w->fp );
+ fputc( '\n', w->fp );
+}
+
+void vg_kv_write_kv( vg_kv_write *w, const char *key, u32 key_len, const char *value, u32 value_len )
+{
+ vg_kv_write_indent( w );
+ vg_kv_write_string( w, key, key_len );
+ fputc( ' ', w->fp );
+ vg_kv_write_string( w, value, value_len );
+ fputc( '\n', w->fp );
+}
+
+#if 0
void vg_kv_print_info( vg_kvs *kvs )
{
vg_low( "Compression ratio: %.2f%%\n", ((f32)(kvs->kv_count * sizeof(vg_kv)) / (f32)kvs->source_length )*100.0f );
}
-void vg_kv_print_tree( vg_kvs *kvs, u32 root_id, u32 depth )
+void vg_kv_print_tree( vg_kv_write *w, vg_kvs *kvs, u32 root_id )
{
VG_ASSERT( vg_kv_type( kvs, root_id ) == 0x0 );
- const char *k_whitespace = " ";
-
u32 root_len;
const char *root_str = vg_kv_key( kvs, root_id, &root_len );
- vg_info( "%.*s\"%.*s\"\n", depth*2, k_whitespace, root_len, root_str );
- vg_info( "%.*s{\n", depth*2, k_whitespace );
- depth ++;
+ vg_kv_write_block( w, root_str, root_len );
u32 child_id = vg_kv_child( kvs, root_id, 0 );
while( child_id )
{
if( vg_kv_type( kvs, child_id ) == 0x0 )
- vg_kv_print_tree( kvs, child_id, depth );
+ vg_kv_print_tree( w, kvs, child_id );
else
{
u32 key_len;
const char *value_str = vg_kv_value( kvs, child_id, &value_len );
if( key_str && value_str )
- vg_info( "%.*s\"%.*s\" \"%.*s\"\n", depth*2, k_whitespace, key_len, key_str, value_len, value_str );
- else
- vg_error( "%.*s<KV ERROR>\n", depth*2, k_whitespace );
+ vg_kv_write_kv( w, key_str, key_len, value_str, value_len );
}
child_id = vg_kv_next( kvs, child_id );
}
- depth --;
+ vg_kv_end_block( w );
+#if 0
vg_info( "%.*s}\n", depth*2, k_whitespace );
+#endif
}
+#endif