static void dl_txt_unpack_write_subdata_ptr( dl_ctx_t dl_ctx, dl_txt_unpack_ctx* unpack_ctx, dl_binary_writer* writer, const uint8_t* ptrptr, const dl_type_desc* sub_type ) { uintptr_t offset = *(uintptr_t*)( ptrptr ); if( offset == (uintptr_t)-1 ) return; if( offset == 0 ) return; for( int i = 0; i < unpack_ctx->ptrs_count; ++i ) if( unpack_ctx->ptrs[i].offset == offset ) return; // TODO: overflow! unpack_ctx->ptrs[unpack_ctx->ptrs_count++].offset = offset; dl_txt_unpack_write_indent( writer, unpack_ctx ); dl_txt_unpack_ptr( writer, offset ); dl_binary_writer_write( writer, " : ", 3 ); dl_txt_unpack_struct( dl_ctx, unpack_ctx, writer, sub_type, &unpack_ctx->packed_instance[offset] ); // TODO: extra , at last elem =/ dl_binary_writer_write( writer, ",\n", 2 ); dl_txt_unpack_write_subdata( dl_ctx, unpack_ctx, writer, sub_type, &unpack_ctx->packed_instance[offset] ); }
static void dl_internal_store_array( dl_ctx_t dl_ctx, dl_type_t storage_type, const dl_type_desc* sub_type, uint8_t* instance, uint32_t count, uintptr_t size, CDLBinStoreContext* store_ctx ) { switch( storage_type ) { case DL_TYPE_STORAGE_STRUCT: { uintptr_t size_ = sub_type->size[DL_PTR_SIZE_HOST]; if( sub_type->flags & DL_TYPE_FLAG_HAS_SUBDATA ) { for (uint32_t elem = 0; elem < count; ++elem) dl_internal_instance_store(dl_ctx, sub_type, instance + (elem * size_), store_ctx); } else dl_binary_writer_write( &store_ctx->writer, instance, count * size_ ); } break; case DL_TYPE_STORAGE_STR: for( uint32_t elem = 0; elem < count; ++elem ) dl_internal_store_string( instance + (elem * sizeof(char*)), store_ctx ); break; default: // default is a standard pod-type dl_binary_writer_write( &store_ctx->writer, instance, count * size ); break; } }
static void dl_internal_store_string( const uint8* instance, CDLBinStoreContext* store_ctx ) { char* str = *(char**)instance; pint pos = dl_binary_writer_tell( &store_ctx->writer ); dl_binary_writer_seek_end( &store_ctx->writer ); pint offset = dl_binary_writer_tell( &store_ctx->writer ); dl_binary_writer_write( &store_ctx->writer, str, strlen(str) + 1 ); dl_binary_writer_seek_set( &store_ctx->writer, pos ); dl_binary_writer_write( &store_ctx->writer, &offset, sizeof(pint) ); }
static void dl_internal_store_string( const uint8_t* instance, CDLBinStoreContext* store_ctx ) { char* str = *(char**)instance; if( str == 0x0 ) { dl_binary_writer_write( &store_ctx->writer, &DL_NULL_PTR_OFFSET[ DL_PTR_SIZE_HOST ], sizeof(uintptr_t) ); return; } uintptr_t pos = dl_binary_writer_tell( &store_ctx->writer ); dl_binary_writer_seek_end( &store_ctx->writer ); uintptr_t offset = dl_binary_writer_tell( &store_ctx->writer ); dl_binary_writer_write( &store_ctx->writer, str, strlen(str) + 1 ); dl_binary_writer_seek_set( &store_ctx->writer, pos ); dl_binary_writer_write( &store_ctx->writer, &offset, sizeof(uintptr_t) ); }
static void dl_txt_unpack_write_string_or_null( dl_binary_writer* writer, dl_txt_unpack_ctx* unpack_ctx, uintptr_t offset ) { if( offset == (uintptr_t)-1 ) dl_binary_writer_write( writer, "null", 4 ); else dl_txt_unpack_write_string( writer, (const char*)&unpack_ctx->packed_instance[offset] ); }
static void dl_txt_unpack_ptr( dl_binary_writer* writer, uintptr_t offset ) { if( offset == (uintptr_t)-1 ) { dl_binary_writer_write( writer, "null", 4 ); } else if( offset == 0 ) { dl_binary_writer_write( writer, "\"__root\"", 8 ); } else { char buffer[256]; dl_internal_str_format( buffer, sizeof(buffer), "ptr_" DL_UINT64_FMT_STR, (uint64_t)offset ); dl_txt_unpack_write_string( writer, buffer ); } }
static dl_error_t dl_txt_unpack_root( dl_ctx_t dl_ctx, dl_txt_unpack_ctx* unpack_ctx, dl_binary_writer* writer, dl_typeid_t root_type ) { dl_binary_writer_write_uint8( writer, '{' ); dl_binary_writer_write_uint8( writer, '\n' ); const dl_type_desc* type = dl_internal_find_type(dl_ctx, root_type); if( type == 0x0 ) return DL_ERROR_TYPE_NOT_FOUND; // could not find root-type! unpack_ctx->indent += 2; dl_txt_unpack_write_indent( writer, unpack_ctx ); dl_txt_unpack_write_string( writer, dl_internal_type_name( dl_ctx, type ) ); dl_binary_writer_write( writer, " : ", 3 ); dl_txt_unpack_struct( dl_ctx, unpack_ctx, writer, type, unpack_ctx->packed_instance ); unpack_ctx->indent -= 2; dl_binary_writer_write( writer, "\n}\0", 3 ); return DL_ERROR_OK; }
static void dl_txt_unpack_struct( dl_ctx_t dl_ctx, dl_txt_unpack_ctx* unpack_ctx, dl_binary_writer* writer, const dl_type_desc* type, const uint8_t* struct_data ) { dl_binary_writer_write( writer, "{\n", 2 ); unpack_ctx->indent += 2; if( type->flags & DL_TYPE_FLAG_IS_UNION ) { // TODO: check if type is not set at all ... size_t type_offset = dl_internal_union_type_offset( dl_ctx, type, DL_PTR_SIZE_HOST ); // find member index from union type ... uint32_t union_type = *((uint32_t*)(struct_data + type_offset)); const dl_member_desc* member = dl_internal_find_member_desc_by_name_hash( dl_ctx, type, union_type ); dl_txt_unpack_member( dl_ctx, unpack_ctx, writer, member, struct_data + member->offset[DL_PTR_SIZE_HOST] ); dl_binary_writer_write( writer, "\n", 1 ); } else { for( uint32_t member_index = 0; member_index < type->member_count; ++member_index ) { const dl_member_desc* member = dl_get_type_member( dl_ctx, type, member_index ); dl_txt_unpack_member( dl_ctx, unpack_ctx, writer, member, struct_data + member->offset[DL_PTR_SIZE_HOST] ); if( member_index < type->member_count - 1 ) dl_binary_writer_write( writer, ",\n", 2 ); else dl_binary_writer_write( writer, "\n", 1 ); } } if( struct_data == unpack_ctx->packed_instance ) { if( unpack_ctx->has_ptrs ) { unpack_ctx->indent += 2; dl_txt_unpack_write_indent( writer, unpack_ctx ); dl_binary_writer_write( writer, ", \"__subdata\" : {\n", 18 ); unpack_ctx->indent += 2; dl_txt_unpack_write_subdata( dl_ctx, unpack_ctx, writer, type, struct_data ); unpack_ctx->indent -= 2; dl_txt_unpack_write_indent( writer, unpack_ctx ); dl_binary_writer_write( writer, "}\n", 2 ); unpack_ctx->indent -= 2; } } unpack_ctx->indent -= 2; dl_txt_unpack_write_indent( writer, unpack_ctx ); dl_binary_writer_write_uint8( writer, '}' ); }
static void dl_txt_unpack_write_string( dl_binary_writer* writer, const char* str ) { dl_binary_writer_write_uint8( writer, '\"' ); while( *str ) { switch( *str ) { case '\'': dl_binary_writer_write( writer, "\\\'", 2 ); break; case '\"': dl_binary_writer_write( writer, "\\\"", 2 ); break; case '\\': dl_binary_writer_write( writer, "\\\\", 2 ); break; case '\n': dl_binary_writer_write( writer, "\\n", 2 ); break; case '\r': dl_binary_writer_write( writer, "\\r", 2 ); break; case '\t': dl_binary_writer_write( writer, "\\t", 2 ); break; case '\b': dl_binary_writer_write( writer, "\\b", 2 ); break; case '\f': dl_binary_writer_write( writer, "\\f", 2 ); break; break; default: dl_binary_writer_write_uint8( writer, (uint8_t)*str ); } ++str; } dl_binary_writer_write_uint8( writer, '\"' ); }
static dl_error_t dl_internal_convert_write_struct( dl_ctx_t dl_ctx, const uint8* data, const SDLType* type, SConvertContext& conv_ctx, dl_binary_writer* writer ) { dl_binary_writer_align( writer, type->alignment[conv_ctx.m_TargetPtrSize] ); pint Pos = dl_binary_writer_tell( writer ); dl_binary_writer_reserve( writer, type->size[conv_ctx.m_TargetPtrSize] ); for(uint32 iMember = 0; iMember < type->member_count; ++iMember) { const SDLMember& Member = type->members[iMember]; const uint8* pMemberData = data + Member.offset[conv_ctx.m_SourcePtrSize]; dl_binary_writer_align( writer, Member.alignment[conv_ctx.m_TargetPtrSize] ); dl_type_t AtomType = Member.AtomType(); dl_type_t StorageType = Member.StorageType(); switch(AtomType) { case DL_TYPE_ATOM_POD: { switch (StorageType) { case DL_TYPE_STORAGE_STRUCT: { const SDLType* pSubType = dl_internal_find_type(dl_ctx, Member.type_id); if(pSubType == 0x0) return DL_ERROR_TYPE_NOT_FOUND; dl_internal_convert_write_struct( dl_ctx, pMemberData, pSubType, conv_ctx, writer ); } break; case DL_TYPE_STORAGE_STR: { pint Offset = DLInternalReadPtrData(pMemberData, conv_ctx.m_SourceEndian, conv_ctx.m_SourcePtrSize); conv_ctx.m_lPatchOffset.Add( SConvertContext::PatchPos( dl_binary_writer_tell( writer ), Offset ) ); dl_binary_writer_write_ptr( writer, 0x0 ); } break; case DL_TYPE_STORAGE_PTR: { pint Offset = DLInternalReadPtrData(pMemberData, conv_ctx.m_SourceEndian, conv_ctx.m_SourcePtrSize); if (Offset != DL_NULL_PTR_OFFSET[conv_ctx.m_SourcePtrSize]) conv_ctx.m_lPatchOffset.Add(SConvertContext::PatchPos( dl_binary_writer_tell( writer ), Offset ) ); dl_binary_writer_write_ptr( writer, pint(-1) ); } break; default: DL_ASSERT(Member.IsSimplePod() || StorageType == DL_TYPE_STORAGE_ENUM); dl_binary_writer_write_swap( writer, pMemberData, Member.size[conv_ctx.m_SourcePtrSize] ); break; } } break; case DL_TYPE_ATOM_INLINE_ARRAY: { switch(StorageType) { case DL_TYPE_STORAGE_STRUCT: { const SDLType* pSubType = dl_internal_find_type(dl_ctx, Member.type_id); if(pSubType == 0x0) return DL_ERROR_TYPE_NOT_FOUND; pint MemberSize = Member.size[conv_ctx.m_SourcePtrSize]; pint SubtypeSize = pSubType->size[conv_ctx.m_SourcePtrSize]; for (pint ElemOffset = 0; ElemOffset < MemberSize; ElemOffset += SubtypeSize) dl_internal_convert_write_struct( dl_ctx, pMemberData + ElemOffset, pSubType, conv_ctx, writer ); } break; case DL_TYPE_STORAGE_STR: { pint PtrSizeSource = dl_internal_ptr_size(conv_ctx.m_SourcePtrSize); pint PtrSizeTarget = dl_internal_ptr_size(conv_ctx.m_TargetPtrSize); uint32 Count = Member.size[conv_ctx.m_SourcePtrSize] / (uint32)PtrSizeSource; pint Pos = dl_binary_writer_tell( writer ); for (pint iElem = 0; iElem < Count; ++iElem) { pint OldOffset = DLInternalReadPtrData(pMemberData + (iElem * PtrSizeSource), conv_ctx.m_SourceEndian, conv_ctx.m_SourcePtrSize); conv_ctx.m_lPatchOffset.Add(SConvertContext::PatchPos(Pos + (iElem * PtrSizeTarget), OldOffset)); } dl_binary_writer_write_zero( writer, Member.size[conv_ctx.m_TargetPtrSize] ); } break; default: { DL_ASSERT(Member.IsSimplePod() || StorageType == DL_TYPE_STORAGE_ENUM); pint PodSize = DLPodSize(Member.type); uint32 ArraySize = Member.size[conv_ctx.m_SourcePtrSize]; switch(PodSize) { case 1: dl_binary_writer_write_array( writer, pMemberData, ArraySize / sizeof( uint8), sizeof( uint8) ); break; case 2: dl_binary_writer_write_array( writer, pMemberData, ArraySize / sizeof(uint16), sizeof(uint16) ); break; case 4: dl_binary_writer_write_array( writer, pMemberData, ArraySize / sizeof(uint32), sizeof(uint32) ); break; case 8: dl_binary_writer_write_array( writer, pMemberData, ArraySize / sizeof(uint64), sizeof(uint64) ); break; default: DL_ASSERT(false && "Not supported pod-size!"); } } break; } } break; case DL_TYPE_ATOM_ARRAY: { pint Offset = 0; uint32 Count = 0; dl_internal_read_array_data( pMemberData, &Offset, &Count, conv_ctx.m_SourceEndian, conv_ctx.m_SourcePtrSize ); if(Offset != DL_NULL_PTR_OFFSET[conv_ctx.m_SourcePtrSize]) conv_ctx.m_lPatchOffset.Add(SConvertContext::PatchPos( dl_binary_writer_tell( writer ), Offset) ); else Offset = DL_NULL_PTR_OFFSET[conv_ctx.m_TargetPtrSize]; dl_binary_writer_write_ptr( writer, Offset ); dl_binary_writer_write_4byte( writer, pMemberData + dl_internal_ptr_size( conv_ctx.m_SourcePtrSize ) ); if( conv_ctx.m_TargetPtrSize == DL_PTR_SIZE_64BIT ) dl_binary_writer_write_zero( writer, 4 ); } break; case DL_TYPE_ATOM_BITFIELD: { uint32 j = iMember; do { j++; } while(j < type->member_count && type->members[j].AtomType() == DL_TYPE_ATOM_BITFIELD); if(conv_ctx.m_SourceEndian != conv_ctx.m_TargetEndian) { uint32 nBFMembers = j - iMember; switch(Member.size[conv_ctx.m_SourcePtrSize]) { case 1: { uint8 val = dl_convert_bit_field_format_uint8( *(uint8*)pMemberData, &Member, nBFMembers, &conv_ctx ); dl_binary_writer_write_1byte( writer, &val ); } break; case 2: { uint16 val = dl_convert_bit_field_format_uint16( *(uint16*)pMemberData, &Member, nBFMembers, &conv_ctx ); dl_binary_writer_write_2byte( writer, &val ); } break; case 4: { uint32 val = dl_convert_bit_field_format_uint32( *(uint32*)pMemberData, &Member, nBFMembers, &conv_ctx ); dl_binary_writer_write_4byte( writer, &val ); } break; case 8: { uint64 val = dl_convert_bit_field_format_uint64( *(uint64*)pMemberData, &Member, nBFMembers, &conv_ctx ); dl_binary_writer_write_8byte( writer, &val ); } break; default: DL_ASSERT(false && "Not supported pod-size or bitfield-size!"); } } else dl_binary_writer_write( writer, pMemberData, Member.size[conv_ctx.m_SourcePtrSize] ); iMember = j - 1; } break; default: DL_ASSERT(false && "Invalid ATOM-type!"); } } // we need to write our entire size with zeroes. Our entire size might be less than the sum of teh members. pint PosDiff = dl_binary_writer_tell( writer ) - Pos; if(PosDiff < type->size[conv_ctx.m_TargetPtrSize]) dl_binary_writer_write_zero( writer, type->size[conv_ctx.m_TargetPtrSize] - PosDiff ); DL_ASSERT( dl_binary_writer_tell( writer ) - Pos == type->size[conv_ctx.m_TargetPtrSize] ); return DL_ERROR_OK; }
static void dl_txt_unpack_int64( dl_binary_writer* writer, int64_t data ) { char buffer[256]; int len = dl_internal_str_format( buffer, sizeof(buffer), DL_INT64_FMT_STR, data ); dl_binary_writer_write( writer, buffer, (size_t)len ); }
static void dl_txt_unpack_uint16( dl_binary_writer* writer, uint16_t data ) { char buffer[256]; int len = dl_internal_str_format( buffer, sizeof(buffer), "%u", data ); dl_binary_writer_write( writer, buffer, (size_t)len ); }
static dl_error_t dl_internal_store_member( dl_ctx_t dl_ctx, const dl_member_desc* member, uint8_t* instance, CDLBinStoreContext* store_ctx ) { dl_type_t atom_type = dl_type_t(member->type & DL_TYPE_ATOM_MASK); dl_type_t storage_type = dl_type_t(member->type & DL_TYPE_STORAGE_MASK); switch ( atom_type ) { case DL_TYPE_ATOM_POD: { switch( storage_type ) { case DL_TYPE_STORAGE_STRUCT: { const dl_type_desc* sub_type = dl_internal_find_type( dl_ctx, member->type_id ); if( sub_type == 0x0 ) { dl_log_error( dl_ctx, "Could not find subtype for member %s", dl_internal_member_name( dl_ctx, member ) ); return DL_ERROR_TYPE_NOT_FOUND; } dl_internal_instance_store( dl_ctx, sub_type, instance, store_ctx ); } break; case DL_TYPE_STORAGE_STR: dl_internal_store_string( instance, store_ctx ); break; case DL_TYPE_STORAGE_PTR: { uint8_t* data = *(uint8_t**)instance; uintptr_t offset = store_ctx->FindWrittenPtr( data ); if( data == 0x0 ) // Null-pointer, store pint(-1) to signal to patching! { DL_ASSERT(offset == (uintptr_t)-1 && "This pointer should not have been found among the written ptrs!"); // keep the -1 in Offset and store it to ptr. } else if( offset == (uintptr_t)-1 ) // has not been written yet! { uintptr_t pos = dl_binary_writer_tell( &store_ctx->writer ); dl_binary_writer_seek_end( &store_ctx->writer ); const dl_type_desc* sub_type = dl_internal_find_type( dl_ctx, member->type_id ); uintptr_t size = dl_internal_align_up( sub_type->size[DL_PTR_SIZE_HOST], sub_type->alignment[DL_PTR_SIZE_HOST] ); dl_binary_writer_align( &store_ctx->writer, sub_type->alignment[DL_PTR_SIZE_HOST] ); offset = dl_binary_writer_tell( &store_ctx->writer ); // write data! dl_binary_writer_reserve( &store_ctx->writer, size ); // reserve space for ptr so subdata is placed correctly store_ctx->AddWrittenPtr(data, offset); dl_internal_instance_store(dl_ctx, sub_type, data, store_ctx); dl_binary_writer_seek_set( &store_ctx->writer, pos ); } dl_binary_writer_write( &store_ctx->writer, &offset, sizeof(uintptr_t) ); } break; default: // default is a standard pod-type DL_ASSERT( member->IsSimplePod() || storage_type == DL_TYPE_STORAGE_ENUM ); dl_binary_writer_write( &store_ctx->writer, instance, member->size[DL_PTR_SIZE_HOST] ); break; } } return DL_ERROR_OK; case DL_TYPE_ATOM_INLINE_ARRAY: { const dl_type_desc* sub_type = 0x0; uint32_t count = member->inline_array_cnt(); if( storage_type == DL_TYPE_STORAGE_STRUCT ) { sub_type = dl_internal_find_type(dl_ctx, member->type_id); if (sub_type == 0x0) { dl_log_error(dl_ctx, "Could not find subtype for member %s", dl_internal_member_name(dl_ctx, member)); return DL_ERROR_TYPE_NOT_FOUND; } } else if( storage_type != DL_TYPE_STORAGE_STR ) count = member->size[DL_PTR_SIZE_HOST]; dl_internal_store_array( dl_ctx, storage_type, sub_type, instance, count, 1, store_ctx ); } return DL_ERROR_OK; case DL_TYPE_ATOM_ARRAY: { uintptr_t size = 0; const dl_type_desc* sub_type = 0x0; uint8_t* data_ptr = instance; uint32_t count = *(uint32_t*)( data_ptr + sizeof(void*) ); uintptr_t offset = 0; if( count == 0 ) offset = DL_NULL_PTR_OFFSET[ DL_PTR_SIZE_HOST ]; else { uintptr_t pos = dl_binary_writer_tell( &store_ctx->writer ); dl_binary_writer_seek_end( &store_ctx->writer ); switch(storage_type) { case DL_TYPE_STORAGE_STRUCT: sub_type = dl_internal_find_type( dl_ctx, member->type_id ); size = dl_internal_align_up( sub_type->size[DL_PTR_SIZE_HOST], sub_type->alignment[DL_PTR_SIZE_HOST] ); dl_binary_writer_align( &store_ctx->writer, sub_type->alignment[DL_PTR_SIZE_HOST] ); break; case DL_TYPE_STORAGE_STR: size = sizeof(void*); dl_binary_writer_align( &store_ctx->writer, size ); break; default: size = dl_pod_size( member->type ); dl_binary_writer_align( &store_ctx->writer, size ); } offset = dl_binary_writer_tell( &store_ctx->writer ); // write data! dl_binary_writer_reserve( &store_ctx->writer, count * size ); // reserve space for array so subdata is placed correctly uint8_t* data = *(uint8_t**)data_ptr; dl_internal_store_array( dl_ctx, storage_type, sub_type, data, count, size, store_ctx ); dl_binary_writer_seek_set( &store_ctx->writer, pos ); } // make room for ptr dl_binary_writer_write( &store_ctx->writer, &offset, sizeof(uintptr_t) ); // write count dl_binary_writer_write( &store_ctx->writer, &count, sizeof(uint32_t) ); } return DL_ERROR_OK; case DL_TYPE_ATOM_BITFIELD: dl_binary_writer_write( &store_ctx->writer, instance, member->size[DL_PTR_SIZE_HOST] ); break; default: DL_ASSERT(false && "Invalid ATOM-type!"); break; } return DL_ERROR_OK; }
static dl_error_t dl_internal_store_member( dl_ctx_t dl_ctx, const SDLMember* member, uint8* instance, CDLBinStoreContext* store_ctx ) { dl_type_t atom_type = dl_type_t(member->type & DL_TYPE_ATOM_MASK); dl_type_t storage_type = dl_type_t(member->type & DL_TYPE_STORAGE_MASK); switch ( atom_type ) { case DL_TYPE_ATOM_POD: { switch( storage_type ) { case DL_TYPE_STORAGE_STRUCT: { const SDLType* sub_type = dl_internal_find_type( dl_ctx, member->type_id ); if( sub_type == 0x0 ) { dl_log_error( dl_ctx, "Could not find subtype for member %s", member->name ); return DL_ERROR_TYPE_NOT_FOUND; } dl_internal_instance_store( dl_ctx, sub_type, instance, store_ctx ); } break; case DL_TYPE_STORAGE_STR: dl_internal_store_string( instance, store_ctx ); break; case DL_TYPE_STORAGE_PTR: { uint8* data = *(uint8**)instance; pint offset = store_ctx->FindWrittenPtr( data ); if( data == 0x0 ) // Null-pointer, store pint(-1) to signal to patching! { DL_ASSERT(offset == pint(-1) && "This pointer should not have been found among the written ptrs!"); // keep the -1 in Offset and store it to ptr. } else if( offset == pint(-1) ) // has not been written yet! { pint pos = dl_binary_writer_tell( &store_ctx->writer ); dl_binary_writer_seek_end( &store_ctx->writer ); const SDLType* sub_type = dl_internal_find_type( dl_ctx, member->type_id ); pint size = dl_internal_align_up( sub_type->size[DL_PTR_SIZE_HOST], sub_type->alignment[DL_PTR_SIZE_HOST] ); dl_binary_writer_align( &store_ctx->writer, sub_type->alignment[DL_PTR_SIZE_HOST] ); offset = dl_binary_writer_tell( &store_ctx->writer ); // write data! dl_binary_writer_reserve( &store_ctx->writer, size ); // reserve space for ptr so subdata is placed correctly store_ctx->AddWrittenPtr(data, offset); dl_internal_instance_store(dl_ctx, sub_type, data, store_ctx); dl_binary_writer_seek_set( &store_ctx->writer, pos ); } dl_binary_writer_write( &store_ctx->writer, &offset, sizeof(pint) ); } break; default: // default is a standard pod-type DL_ASSERT( member->IsSimplePod() || storage_type == DL_TYPE_STORAGE_ENUM ); dl_binary_writer_write( &store_ctx->writer, instance, member->size[DL_PTR_SIZE_HOST] ); break; } } return DL_ERROR_OK; case DL_TYPE_ATOM_INLINE_ARRAY: { switch( storage_type ) { case DL_TYPE_STORAGE_STRUCT: dl_binary_writer_write( &store_ctx->writer, instance, member->size[DL_PTR_SIZE_HOST] ); // TODO: I Guess that this is a bug! Will it fix ptrs well? break; case DL_TYPE_STORAGE_STR: { uint32 count = member->size[DL_PTR_SIZE_HOST] / sizeof(char*); for( uint32 elem = 0; elem < count; ++elem ) dl_internal_store_string( instance + (elem * sizeof(char*)), store_ctx ); } break; default: // default is a standard pod-type DL_ASSERT( member->IsSimplePod() || storage_type == DL_TYPE_STORAGE_ENUM ); dl_binary_writer_write( &store_ctx->writer, instance, member->size[DL_PTR_SIZE_HOST] ); break; } } return DL_ERROR_OK; case DL_TYPE_ATOM_ARRAY: { pint size = 0; const SDLType* sub_type = 0x0; uint8* data_ptr = instance; uint32 count = *(uint32*)( data_ptr + sizeof(void*) ); pint offset = 0; if( count == 0 ) offset = DL_NULL_PTR_OFFSET[ DL_PTR_SIZE_HOST ]; else { pint pos = dl_binary_writer_tell( &store_ctx->writer ); dl_binary_writer_seek_end( &store_ctx->writer ); switch(storage_type) { case DL_TYPE_STORAGE_STRUCT: sub_type = dl_internal_find_type( dl_ctx, member->type_id ); size = dl_internal_align_up( sub_type->size[DL_PTR_SIZE_HOST], sub_type->alignment[DL_PTR_SIZE_HOST] ); dl_binary_writer_align( &store_ctx->writer, sub_type->alignment[DL_PTR_SIZE_HOST] ); break; case DL_TYPE_STORAGE_STR: size = sizeof(void*); dl_binary_writer_align( &store_ctx->writer, size ); break; default: size = DLPodSize( member->type ); dl_binary_writer_align( &store_ctx->writer, size ); } offset = dl_binary_writer_tell( &store_ctx->writer ); // write data! dl_binary_writer_reserve( &store_ctx->writer, count * size ); // reserve space for array so subdata is placed correctly uint8* data = *(uint8**)data_ptr; switch(storage_type) { case DL_TYPE_STORAGE_STRUCT: for ( unsigned int elem = 0; elem < count; ++elem ) dl_internal_instance_store( dl_ctx, sub_type, data + (elem * size), store_ctx ); break; case DL_TYPE_STORAGE_STR: for ( unsigned int elem = 0; elem < count; ++elem ) dl_internal_store_string( data + (elem * size), store_ctx ); break; default: for ( unsigned int elem = 0; elem < count; ++elem ) dl_binary_writer_write( &store_ctx->writer, data + (elem * size), size ); break; } dl_binary_writer_seek_set( &store_ctx->writer, pos ); } // make room for ptr dl_binary_writer_write( &store_ctx->writer, &offset, sizeof(pint) ); // write count dl_binary_writer_write( &store_ctx->writer, &count, sizeof(uint32) ); } return DL_ERROR_OK; case DL_TYPE_ATOM_BITFIELD: dl_binary_writer_write( &store_ctx->writer, instance, member->size[DL_PTR_SIZE_HOST] ); break; default: DL_ASSERT(false && "Invalid ATOM-type!"); break; } return DL_ERROR_OK; }
static void dl_txt_unpack_fp64( dl_binary_writer* writer, double data ) { char buffer[256]; int len = dl_internal_str_format( buffer, sizeof(buffer), "%.17g", data ); dl_binary_writer_write( writer, buffer, (size_t)len ); }
static void dl_txt_unpack_array( dl_ctx_t dl_ctx, dl_txt_unpack_ctx* unpack_ctx, dl_binary_writer* writer, dl_type_storage_t storage, const uint8_t* array_data, uint32_t array_count, dl_typeid_t tid ) { dl_binary_writer_write_uint8( writer, '[' ); switch( storage ) { case DL_TYPE_STORAGE_INT8: { int8_t* mem = (int8_t*)array_data; for( uint32_t i = 0; i < array_count - 1; ++i ) { dl_txt_unpack_int8( writer, mem[i] ); dl_binary_writer_write( writer, ", ", 2 ); } dl_txt_unpack_int8( writer, mem[array_count - 1] ); } break; case DL_TYPE_STORAGE_INT16: { int16_t* mem = (int16_t*)array_data; for( uint32_t i = 0; i < array_count - 1; ++i ) { dl_txt_unpack_int16( writer, mem[i] ); dl_binary_writer_write( writer, ", ", 2 ); } dl_txt_unpack_int16( writer, mem[array_count - 1] ); } break; case DL_TYPE_STORAGE_INT32: { int32_t* mem = (int32_t*)array_data; for( uint32_t i = 0; i < array_count - 1; ++i ) { dl_txt_unpack_int32( writer, mem[i] ); dl_binary_writer_write( writer, ", ", 2 ); } dl_txt_unpack_int32( writer, mem[array_count - 1] ); } break; case DL_TYPE_STORAGE_INT64: { int64_t* mem = (int64_t*)array_data; for( uint32_t i = 0; i < array_count - 1; ++i ) { dl_txt_unpack_int64( writer, mem[i] ); dl_binary_writer_write( writer, ", ", 2 ); } dl_txt_unpack_int64( writer, mem[array_count - 1] ); } break; case DL_TYPE_STORAGE_UINT8: { uint8_t* mem = (uint8_t*)array_data; for( uint32_t i = 0; i < array_count - 1; ++i ) { dl_txt_unpack_uint8( writer, mem[i] ); dl_binary_writer_write( writer, ", ", 2 ); } dl_txt_unpack_uint8( writer, mem[array_count - 1] ); } break; case DL_TYPE_STORAGE_UINT16: { uint16_t* mem = (uint16_t*)array_data; for( uint32_t i = 0; i < array_count - 1; ++i ) { dl_txt_unpack_uint16( writer, mem[i] ); dl_binary_writer_write( writer, ", ", 2 ); } dl_txt_unpack_uint16( writer, mem[array_count - 1] ); } break; case DL_TYPE_STORAGE_UINT32: { uint32_t* mem = (uint32_t*)array_data; for( uint32_t i = 0; i < array_count - 1; ++i ) { dl_txt_unpack_uint32( writer, mem[i] ); dl_binary_writer_write( writer, ", ", 2 ); } dl_txt_unpack_uint32( writer, mem[array_count - 1] ); } break; case DL_TYPE_STORAGE_UINT64: { uint64_t* mem = (uint64_t*)array_data; for( uint32_t i = 0; i < array_count - 1; ++i ) { dl_txt_unpack_uint64( writer, mem[i] ); dl_binary_writer_write( writer, ", ", 2 ); } dl_txt_unpack_uint64( writer, mem[array_count - 1] ); } break; case DL_TYPE_STORAGE_FP32: { float* mem = (float*)array_data; for( uint32_t i = 0; i < array_count - 1; ++i ) { dl_txt_unpack_fp32( writer, mem[i] ); dl_binary_writer_write( writer, ", ", 2 ); } dl_txt_unpack_fp32( writer, mem[array_count - 1] ); } break; case DL_TYPE_STORAGE_FP64: { double* mem = (double*)array_data; for( uint32_t i = 0; i < array_count - 1; ++i ) { dl_txt_unpack_fp64( writer, mem[i] ); dl_binary_writer_write( writer, ", ", 2 ); } dl_txt_unpack_fp64( writer, mem[array_count - 1] ); } break; case DL_TYPE_STORAGE_STR: { uintptr_t* mem = (uintptr_t*)array_data; for( uint32_t i = 0; i < array_count - 1; ++i ) { dl_txt_unpack_write_string_or_null( writer, unpack_ctx, mem[i] ); dl_binary_writer_write( writer, ", ", 2 ); } dl_txt_unpack_write_string_or_null( writer, unpack_ctx, mem[array_count - 1] ); } break; case DL_TYPE_STORAGE_PTR: { uintptr_t* mem = (uintptr_t*)array_data; for( uint32_t i = 0; i < array_count - 1; ++i ) { dl_txt_unpack_ptr( writer, mem[i] ); dl_binary_writer_write( writer, ", ", 2 ); } dl_txt_unpack_ptr( writer, mem[array_count - 1] ); unpack_ctx->has_ptrs = true; break; } case DL_TYPE_STORAGE_STRUCT: { const dl_type_desc* type = dl_internal_find_type( dl_ctx, tid ); for( uint32_t i = 0; i < array_count - 1; ++i ) { dl_txt_unpack_struct( dl_ctx, unpack_ctx, writer, type, array_data + i * type->size[DL_PTR_SIZE_HOST] ); dl_binary_writer_write( writer, ", ", 2 ); } dl_txt_unpack_struct( dl_ctx, unpack_ctx, writer, type, array_data + (array_count - 1) * type->size[DL_PTR_SIZE_HOST] ); break; } case DL_TYPE_STORAGE_ENUM_INT8: { const dl_enum_desc* e = dl_internal_find_enum( dl_ctx, tid ); DL_ASSERT( e != 0x0, "handle this error!"); int8_t* mem = (int8_t*)array_data; for( uint32_t i = 0; i < array_count - 1; ++i ) { dl_txt_unpack_enum( dl_ctx, writer, e, (uint64_t)mem[i] ); dl_binary_writer_write( writer, ", ", 2 ); } dl_txt_unpack_enum( dl_ctx, writer, e, (uint64_t)mem[array_count - 1] ); } break; case DL_TYPE_STORAGE_ENUM_UINT8: { const dl_enum_desc* e = dl_internal_find_enum( dl_ctx, tid ); DL_ASSERT( e != 0x0, "handle this error!"); uint8_t* mem = (uint8_t*)array_data; for( uint32_t i = 0; i < array_count - 1; ++i ) { dl_txt_unpack_enum( dl_ctx, writer, e, (uint64_t)mem[i] ); dl_binary_writer_write( writer, ", ", 2 ); } dl_txt_unpack_enum( dl_ctx, writer, e, (uint64_t)mem[array_count - 1] ); } break; case DL_TYPE_STORAGE_ENUM_INT16: { const dl_enum_desc* e = dl_internal_find_enum( dl_ctx, tid ); DL_ASSERT( e != 0x0, "handle this error!"); int16_t* mem = (int16_t*)array_data; for( uint32_t i = 0; i < array_count - 1; ++i ) { dl_txt_unpack_enum( dl_ctx, writer, e, (uint64_t)mem[i] ); dl_binary_writer_write( writer, ", ", 2 ); } dl_txt_unpack_enum( dl_ctx, writer, e, (uint64_t)mem[array_count - 1] ); } break; case DL_TYPE_STORAGE_ENUM_UINT16: { const dl_enum_desc* e = dl_internal_find_enum( dl_ctx, tid ); DL_ASSERT( e != 0x0, "handle this error!"); uint16_t* mem = (uint16_t*)array_data; for( uint32_t i = 0; i < array_count - 1; ++i ) { dl_txt_unpack_enum( dl_ctx, writer, e, (uint64_t)mem[i] ); dl_binary_writer_write( writer, ", ", 2 ); } dl_txt_unpack_enum( dl_ctx, writer, e, (uint64_t)mem[array_count - 1] ); } break; case DL_TYPE_STORAGE_ENUM_INT32: { const dl_enum_desc* e = dl_internal_find_enum( dl_ctx, tid ); DL_ASSERT( e != 0x0, "handle this error!"); int32_t* mem = (int32_t*)array_data; for( uint32_t i = 0; i < array_count - 1; ++i ) { dl_txt_unpack_enum( dl_ctx, writer, e, (uint64_t)mem[i] ); dl_binary_writer_write( writer, ", ", 2 ); } dl_txt_unpack_enum( dl_ctx, writer, e, (uint64_t)mem[array_count - 1] ); } break; case DL_TYPE_STORAGE_ENUM_UINT32: { const dl_enum_desc* e = dl_internal_find_enum( dl_ctx, tid ); DL_ASSERT( e != 0x0, "handle this error!"); uint32_t* mem = (uint32_t*)array_data; for( uint32_t i = 0; i < array_count - 1; ++i ) { dl_txt_unpack_enum( dl_ctx, writer, e, (uint64_t)mem[i] ); dl_binary_writer_write( writer, ", ", 2 ); } dl_txt_unpack_enum( dl_ctx, writer, e, (uint64_t)mem[array_count - 1] ); } break; case DL_TYPE_STORAGE_ENUM_INT64: { const dl_enum_desc* e = dl_internal_find_enum( dl_ctx, tid ); DL_ASSERT( e != 0x0, "handle this error!"); int64_t* mem = (int64_t*)array_data; for( uint32_t i = 0; i < array_count - 1; ++i ) { dl_txt_unpack_enum( dl_ctx, writer, e, (uint64_t)mem[i] ); dl_binary_writer_write( writer, ", ", 2 ); } dl_txt_unpack_enum( dl_ctx, writer, e, (uint64_t)mem[array_count - 1] ); } break; case DL_TYPE_STORAGE_ENUM_UINT64: { const dl_enum_desc* e = dl_internal_find_enum( dl_ctx, tid ); DL_ASSERT( e != 0x0, "handle this error!"); uint64_t* mem = (uint64_t*)array_data; for( uint32_t i = 0; i < array_count - 1; ++i ) { dl_txt_unpack_enum( dl_ctx, writer, e, (uint64_t)mem[i] ); dl_binary_writer_write( writer, ", ", 2 ); } dl_txt_unpack_enum( dl_ctx, writer, e, (uint64_t)mem[array_count - 1] ); } break; default: DL_ASSERT( false ); } dl_binary_writer_write_uint8( writer, ']' ); }
static void dl_txt_unpack_member( dl_ctx_t dl_ctx, dl_txt_unpack_ctx* unpack_ctx, dl_binary_writer* writer, const dl_member_desc* member, const uint8_t* member_data ) { dl_txt_unpack_write_indent( writer, unpack_ctx ); dl_txt_unpack_write_string( writer, dl_internal_member_name( dl_ctx, member ) ); dl_binary_writer_write( writer, " : ", 3 ); switch( member->AtomType() ) { case DL_TYPE_ATOM_POD: { switch( member->StorageType() ) { case DL_TYPE_STORAGE_INT8: dl_txt_unpack_int8 ( writer, *(int8_t* )member_data ); break; case DL_TYPE_STORAGE_INT16: dl_txt_unpack_int16 ( writer, *(int16_t*)member_data ); break; case DL_TYPE_STORAGE_INT32: dl_txt_unpack_int32 ( writer, *(int32_t*)member_data ); break; case DL_TYPE_STORAGE_INT64: dl_txt_unpack_int64 ( writer, *(int64_t*)member_data ); break; case DL_TYPE_STORAGE_UINT8: dl_txt_unpack_uint8 ( writer, *(uint8_t* )member_data ); break; case DL_TYPE_STORAGE_UINT16: dl_txt_unpack_uint16( writer, *(uint16_t*)member_data ); break; case DL_TYPE_STORAGE_UINT32: dl_txt_unpack_uint32( writer, *(uint32_t*)member_data ); break; case DL_TYPE_STORAGE_UINT64: dl_txt_unpack_uint64( writer, *(uint64_t*)member_data ); break; case DL_TYPE_STORAGE_FP32: dl_txt_unpack_fp32 ( writer, *(float*)member_data ); break; case DL_TYPE_STORAGE_FP64: dl_txt_unpack_fp64 ( writer, *(double*)member_data ); break; case DL_TYPE_STORAGE_ENUM_INT8: dl_txt_unpack_enum ( dl_ctx, writer, dl_internal_find_enum( dl_ctx, member->type_id ), (uint64_t)*( int8_t*) member_data ); break; case DL_TYPE_STORAGE_ENUM_UINT8: dl_txt_unpack_enum ( dl_ctx, writer, dl_internal_find_enum( dl_ctx, member->type_id ), (uint64_t)*(uint8_t*) member_data ); break; case DL_TYPE_STORAGE_ENUM_INT16: dl_txt_unpack_enum ( dl_ctx, writer, dl_internal_find_enum( dl_ctx, member->type_id ), (uint64_t)*( int16_t*) member_data ); break; case DL_TYPE_STORAGE_ENUM_UINT16: dl_txt_unpack_enum ( dl_ctx, writer, dl_internal_find_enum( dl_ctx, member->type_id ), (uint64_t)*(uint16_t*) member_data ); break; case DL_TYPE_STORAGE_ENUM_INT32: dl_txt_unpack_enum ( dl_ctx, writer, dl_internal_find_enum( dl_ctx, member->type_id ), (uint64_t)*( int32_t*) member_data ); break; case DL_TYPE_STORAGE_ENUM_UINT32: dl_txt_unpack_enum ( dl_ctx, writer, dl_internal_find_enum( dl_ctx, member->type_id ), (uint64_t)*(uint32_t*) member_data ); break; case DL_TYPE_STORAGE_ENUM_INT64: dl_txt_unpack_enum ( dl_ctx, writer, dl_internal_find_enum( dl_ctx, member->type_id ), (uint64_t)*( int64_t*) member_data ); break; case DL_TYPE_STORAGE_ENUM_UINT64: dl_txt_unpack_enum ( dl_ctx, writer, dl_internal_find_enum( dl_ctx, member->type_id ), (uint64_t)*(uint64_t*) member_data ); break; case DL_TYPE_STORAGE_STR: dl_txt_unpack_write_string_or_null( writer, unpack_ctx, *(uintptr_t*)member_data ); break; case DL_TYPE_STORAGE_PTR: { dl_txt_unpack_ptr( writer, *(uintptr_t*)member_data ); unpack_ctx->has_ptrs = true; } break; case DL_TYPE_STORAGE_STRUCT: dl_txt_unpack_struct( dl_ctx, unpack_ctx, writer, dl_internal_find_type( dl_ctx, member->type_id ), member_data ); break; default: DL_ASSERT(false); } } break; case DL_TYPE_ATOM_ARRAY: { uintptr_t offset = *(uintptr_t*)member_data; uint32_t count = *(uint32_t*)(member_data + sizeof(uintptr_t)); if( offset == (uintptr_t)-1 ) dl_binary_writer_write( writer, "[]", 2 ); else dl_txt_unpack_array( dl_ctx, unpack_ctx, writer, member->StorageType(), &unpack_ctx->packed_instance[offset], count, member->type_id ); } break; case DL_TYPE_ATOM_INLINE_ARRAY: dl_txt_unpack_array( dl_ctx, unpack_ctx, writer, member->StorageType(), member_data, member->inline_array_cnt(), member->type_id ); break; case DL_TYPE_ATOM_BITFIELD: { uint64_t write_me = 0; uint32_t bf_bits = member->bitfield_bits(); uint32_t bf_offset = dl_bf_offset( DL_ENDIAN_HOST, member->size[DL_PTR_SIZE_HOST], member->bitfield_offset(), bf_bits ); switch( member->size[DL_PTR_SIZE_HOST] ) { case 1: write_me = DL_EXTRACT_BITS( uint64_t( *(uint8_t*)member_data), uint64_t(bf_offset), uint64_t(bf_bits) ); break; case 2: write_me = DL_EXTRACT_BITS( uint64_t(*(uint16_t*)member_data), uint64_t(bf_offset), uint64_t(bf_bits) ); break; case 4: write_me = DL_EXTRACT_BITS( uint64_t(*(uint32_t*)member_data), uint64_t(bf_offset), uint64_t(bf_bits) ); break; case 8: write_me = DL_EXTRACT_BITS( uint64_t(*(uint64_t*)member_data), uint64_t(bf_offset), uint64_t(bf_bits) ); break; default: DL_ASSERT(false && "This should not happen!"); break; } dl_txt_unpack_uint64( writer, write_me ); } break; default: DL_ASSERT( false ); } }