-static u64 vg_msg_read_as_u64( vg_msg_cmd *cmd ){
- u8 sized_type = cmd->code & k_vg_msg_sized_type_bits;
-
- u64 result = 0x00;
- u8 *dst = (void *)(&result);
- const u8 *src = cmd->value;
-
- if( (sized_type == k_vg_msg_unsigned) || (sized_type == k_vg_msg_signed) ){
- u32 bytes = vg_msg_sized_bytecount( cmd->code );
- if( bytes > 8 ) bytes = 8;
- for( u32 i=0; i<bytes; i ++ ) dst[i] = src[i];
+/*
+ * Convert any full integral type code to another
+ * Passing in non-integral codes is undefined
+ */
+static void vg_msg_cast( const void *src, u8 src_code, void *dst, u8 dst_code ){
+ if( src_code == dst_code ){
+ memcpy( dst, src, vg_msg_cmd_bytecount( src_code ) );
+ }
+ else {
+ u32 src_n = vg_msg_cmd_array_count( src_code ),
+ dst_n = vg_msg_cmd_array_count( dst_code ),
+ src_s = vg_msg_cmd_type_size( src_code ),
+ dst_s = vg_msg_cmd_type_size( dst_code ),
+ src_b = src_code & k_vg_msg_type_base_bits,
+ dst_b = dst_code & k_vg_msg_type_base_bits;
+
+ memset( dst, 0, dst_s * dst_n );
+
+ for( u32 i=0; i<VG_MIN(src_n,dst_n); i ++ ){
+ const void *ptr_s = src + i*src_s;
+ void *ptr_d = dst + i*dst_s;
+
+ if( dst_b == k_vg_msg_unsigned ){
+ u64 a = vg_msg_cast_to_u64( ptr_s, src_b, src_s );
+ if ( dst_s == 1 ) *((u8 *)ptr_d) = (u8 )a;
+ else if( dst_s == 2 ) *((u16*)ptr_d) = (u16)a;
+ else if( dst_s == 4 ) *((u32*)ptr_d) = (u32)a;
+ else if( dst_s == 8 ) *((u64*)ptr_d) = a;
+ }
+ else if( dst_b == k_vg_msg_signed ){
+ i64 a = vg_msg_cast_to_i64( ptr_s, src_b, src_s );
+ if ( dst_s == 1 ) *((i8 *)ptr_d) = (i8 )a;
+ else if( dst_s == 2 ) *((i16*)ptr_d) = (i16)a;
+ else if( dst_s == 4 ) *((i32*)ptr_d) = (i32)a;
+ else if( dst_s == 8 ) *((i64*)ptr_d) = a;
+ }
+ else {
+ f64 a = vg_msg_cast_to_f64( ptr_s, src_b, src_s );
+ if ( dst_s == 4 ) *((f32*)ptr_d) = (f32)a;
+ else if( dst_s == 8 ) *((f64*)ptr_d) = a;
+ }
+ }