Esempio n. 1
0
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] );
}
Esempio n. 2
0
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;
	}
}
Esempio n. 3
0
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) );
}
Esempio n. 4
0
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) );
}
Esempio n. 5
0
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] );
}
Esempio n. 6
0
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 );
	}
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
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, '}' );
}
Esempio n. 9
0
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, '\"' );
}
Esempio n. 10
0
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;
}
Esempio n. 11
0
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 );
}
Esempio n. 12
0
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 );
}
Esempio n. 13
0
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;
}
Esempio n. 14
0
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;
}
Esempio n. 15
0
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 );
}
Esempio n. 16
0
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, ']' );
}
Esempio n. 17
0
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 );
	}
}