Last active
December 11, 2018 20:58
-
-
Save wc-duck/ae50cdebf1fa0a7c20abbc8c2cd1233a to your computer and use it in GitHub Desktop.
wc_engine dl utils.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <wcdl/wcdl.h> | |
#include <dbgtools/assert.h> | |
#include <debug/log.h> | |
#include <memory/memory_file.h> | |
#include <dl/dl_txt.h> | |
#include <dl/dl_reflect.h> | |
#include <stdlib.h> | |
static log_domain DL_LOG_DOMAIN( "dl" ); | |
static void wcdl_log_error( const char* msg, void* userdata ) | |
{ | |
LOG_DOMAIN_ERROR( &DL_LOG_DOMAIN, "%s", msg ); | |
} | |
static void* wcdl_alloc ( size_t size, void* alloc_ctx ) { return memory_alloc ( (memory_allocator_t)alloc_ctx, size ); } | |
static void* wcdl_realloc( void* ptr, size_t size, size_t /*old_size*/, void* alloc_ctx ) { return memory_realloc( (memory_allocator_t)alloc_ctx, ptr, size ); } | |
static void wcdl_free ( void* ptr, void* alloc_ctx ) { return memory_free ( (memory_allocator_t)alloc_ctx, ptr ); } | |
static const char* wcdl_get_type_name( dl_ctx_t ctx, dl_typeid_t type ) | |
{ | |
dl_type_info_t info; | |
dl_error_t err = dl_reflect_get_type_info( ctx, type, &info ); | |
if(err == DL_ERROR_OK) | |
return info.name; | |
return "<unknown_type>"; | |
} | |
dl_ctx_t wcdl_create_ctx( memory_allocator_t alloc ) | |
{ | |
dl_create_params_t create_params; | |
DL_CREATE_PARAMS_SET_DEFAULT( create_params ); | |
if( alloc != nullptr ) | |
{ | |
create_params.alloc_func = wcdl_alloc; | |
create_params.realloc_func = wcdl_realloc; | |
create_params.free_func = wcdl_free; | |
create_params.alloc_ctx = alloc; | |
} | |
create_params.error_msg_func = wcdl_log_error; | |
dl_ctx_t ctx = 0x0; | |
dl_error_t err = dl_context_create( &ctx, &create_params ); | |
ASSERT( err == DL_ERROR_OK ); | |
return ctx; | |
} | |
dl_ctx_t wcdl_create_ctx( memory_allocator_t alloc, const wcdl_tld* libs, size_t libcnt ) | |
{ | |
dl_ctx_t ctx = wcdl_create_ctx( alloc ); | |
if( ctx == 0x0 ) | |
return 0x0; | |
for( size_t i = 0; i < libcnt; ++i ) | |
{ | |
dl_error_t err = dl_context_load_type_library( ctx, libs[i].lib, libs[i].size ); | |
ASSERT( err == DL_ERROR_OK, "%s", dl_error_to_string( err ) ); | |
} | |
return ctx; | |
} | |
dl_ctx_t wcdl_create_ctx( memory_allocator_t alloc, const uint8_t* typelib, size_t typelibsize ) | |
{ | |
wcdl_tld t = { typelib, typelibsize }; | |
return wcdl_create_ctx( alloc, &t, 1 ); | |
} | |
static void* wcdl_alloc( memory_allocator_t alloc, size_t bytes ) | |
{ | |
if( alloc ) | |
return memory_alloc( alloc, bytes ); | |
return malloc( bytes ); | |
} | |
static void wcdl_free( memory_allocator_t alloc, void* ptr ) | |
{ | |
if( alloc ) | |
memory_free( alloc, ptr ); | |
else | |
free( ptr ); | |
} | |
void* wcdl_load_from_buffer( dl_ctx_t dl_ctx, dl_typeid_t tid, memory_allocator_t alloc, const uint8_t* data, size_t data_size ) | |
{ | |
dl_error_t dlerr; | |
dl_instance_info_t info; | |
dlerr = dl_instance_get_info( data, data_size, &info ); | |
if( dlerr != DL_ERROR_OK ) | |
{ | |
LOG_ERROR( "Failed to fetch instance info with error %s", dl_error_to_string( dlerr ) ); | |
return nullptr; | |
} | |
void* loaded = wcdl_alloc( alloc, info.load_size ); | |
dlerr = dl_instance_load( dl_ctx, tid, loaded, info.load_size, data, data_size, nullptr ); | |
if( dlerr != DL_ERROR_OK ) | |
{ | |
LOG_ERROR( "Failed to load instance with error %s", dl_error_to_string( dlerr ) ); | |
wcdl_free( alloc, loaded ); | |
return nullptr; | |
} | |
return loaded; | |
} | |
void* wcdl_load_from_buffer_inplace( dl_ctx_t dl_ctx, dl_typeid_t tid, uint8_t* data, size_t data_size ) | |
{ | |
void* loaded; | |
dl_error_t dlerr = dl_instance_load_inplace( dl_ctx, tid, data, data_size, (void**)&loaded, 0x0 ); | |
if( dlerr != DL_ERROR_OK ) | |
{ | |
LOG_ERROR( "Failed to load instance inplace with error %s", dl_error_to_string( dlerr ) ); | |
return nullptr; | |
} | |
return loaded; | |
} | |
uint8_t* wcdl_pack_to_buffer( dl_ctx_t dl_ctx, dl_typeid_t tid, memory_allocator_t alloc, const void* instance, size_t* pack_size ) | |
{ | |
dl_error_t dlerr; | |
dlerr = dl_instance_store( dl_ctx, tid, instance, 0x0, 0, pack_size ); | |
if( dlerr != DL_ERROR_OK ) | |
{ | |
LOG_ERROR( "Failed to calculate instance size with error %s", dl_error_to_string( dlerr ) ); | |
return 0x0; | |
} | |
uint8_t* res = (uint8_t*)wcdl_alloc( alloc, *pack_size ); | |
dlerr = dl_instance_store( dl_ctx, tid, instance, res, *pack_size, 0x0 ); | |
if( dlerr != DL_ERROR_OK ) | |
{ | |
wcdl_free( alloc, res ); | |
LOG_ERROR( "Failed to calculate instance size with error %s", dl_error_to_string( dlerr ) ); | |
return 0x0; | |
} | |
return res; | |
} | |
void* wcdl_load_from_txt( dl_ctx_t ctx, memory_allocator_t alloc, const char* txt, dl_typeid_t type ) | |
{ | |
dl_error_t error; | |
size_t packsize; | |
error = dl_txt_pack( ctx, txt, 0x0, 0, &packsize ); | |
if( error != DL_ERROR_OK ) | |
{ | |
LOG_DOMAIN_ERROR( &DL_LOG_DOMAIN, "failed to load %s-instance from txt, error: %s", wcdl_get_type_name(ctx, type), dl_error_to_string( error ) ); | |
return nullptr; | |
} | |
unsigned char* packbuffer = (unsigned char*)wcdl_alloc( alloc, packsize ); | |
error = dl_txt_pack( ctx, txt, packbuffer, packsize, 0x0 ); | |
if( error != DL_ERROR_OK ) | |
{ | |
wcdl_free( alloc, packbuffer ); | |
LOG_DOMAIN_ERROR( &DL_LOG_DOMAIN, "failed to load %s-instance from txt, error: %s", wcdl_get_type_name(ctx, type), dl_error_to_string( error ) ); | |
return nullptr; | |
} | |
dl_instance_info_t out_info; | |
error = dl_instance_get_info( packbuffer, packsize, &out_info ); | |
if( error != DL_ERROR_OK ) | |
{ | |
wcdl_free( alloc, packbuffer ); | |
LOG_DOMAIN_ERROR( &DL_LOG_DOMAIN, "failed to load %s-instance from txt, error: %s", wcdl_get_type_name(ctx, type), dl_error_to_string( error ) ); | |
return nullptr; | |
} | |
void* instance = wcdl_alloc( alloc, out_info.load_size ); | |
error = dl_instance_load( ctx, type, instance, out_info.load_size, packbuffer, packsize, 0x0 ); | |
wcdl_free( alloc, packbuffer ); | |
if( error != DL_ERROR_OK ) | |
{ | |
wcdl_free( alloc, instance ); | |
LOG_DOMAIN_ERROR( &DL_LOG_DOMAIN, "failed to load %s-instance from txt, error: %s", wcdl_get_type_name(ctx, type), dl_error_to_string( error ) ); | |
return nullptr; | |
} | |
return instance; | |
} | |
void* wcdl_load_txt_from_file( dl_ctx_t dlctx, memory_allocator_t inst_alloc, memory_allocator_t tmp_alloc, const char* path, dl_typeid_t type ) | |
{ | |
const uint8_t* filedata = nullptr; | |
if(tmp_alloc) | |
filedata = memory_fileslurp( tmp_alloc, path, nullptr ); | |
else | |
filedata = fileslurp(path, nullptr); | |
if(filedata == nullptr) | |
{ | |
LOG_DOMAIN_ERROR( &DL_LOG_DOMAIN, "failed to open file %s", path ); | |
return nullptr; | |
} | |
void* instance = wcdl_load_from_txt( dlctx, inst_alloc, (const char*)filedata, type ); | |
if(instance == nullptr) | |
LOG_DOMAIN_ERROR( &DL_LOG_DOMAIN, "failed to open file %s", path ); | |
wcdl_free(tmp_alloc, (void*)filedata); | |
return instance; | |
} | |
char* wcdl_pack_to_txt( dl_ctx_t ctx, dl_typeid_t tid, memory_allocator_t alloc, memory_allocator_t temp_alloc, const void* instance ) | |
{ | |
size_t packed_size; | |
uint8_t* packed = wcdl_pack_to_buffer( ctx, tid, temp_alloc, instance, &packed_size ); | |
if( packed == nullptr ) | |
return nullptr; | |
size_t out_txt_size = 0; | |
dl_error_t error; | |
error = dl_txt_unpack( ctx, tid, packed, packed_size, nullptr, 0, &out_txt_size ); | |
if( error != DL_ERROR_OK ) | |
{ | |
memory_free( temp_alloc, (void*)packed ); | |
LOG_DOMAIN_ERROR( &DL_LOG_DOMAIN, "failed to unpack %s-instance to txt, error: %s", wcdl_get_type_name(ctx, tid), dl_error_to_string( error ) ); | |
return nullptr; | |
} | |
char* packed_txt = (char*)memory_alloc( alloc, out_txt_size ); | |
error = dl_txt_unpack( ctx, tid, packed, packed_size, packed_txt, out_txt_size, nullptr ); | |
if( error != DL_ERROR_OK ) | |
{ | |
memory_free( temp_alloc, (void*)packed ); | |
LOG_DOMAIN_ERROR( &DL_LOG_DOMAIN, "failed to unpack %s-instance to txt, error: %s", wcdl_get_type_name(ctx, tid), dl_error_to_string( error ) ); | |
return nullptr; | |
} | |
memory_free( temp_alloc, (void*)packed ); | |
packed = (uint8_t*)packed_txt; | |
return packed_txt; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef WCDL_WCDL_H_INCLUDED | |
#define WCDL_WCDL_H_INCLUDED | |
#include <dl/dl.h> | |
#include <platform/fileutil.h> | |
#include <memory/memory.h> | |
#include <stdlib.h> | |
/** | |
* | |
*/ | |
struct wcdl_tld | |
{ | |
const uint8_t* lib; | |
size_t size; | |
}; | |
/** | |
* Create a dl_ctx_t and hook up wc-engine specific functionality. | |
* | |
* @param alloc allocator to use in created ctx. | |
*/ | |
dl_ctx_t wcdl_create_ctx( memory_allocator_t alloc ); | |
/** | |
* Create a dl_ctx_t and hook up wc-engine specific functionality and load a typelibrary into ctx. | |
* | |
* @param alloc allocator to use in created ctx. | |
* @param typelib libdata to load. | |
* @param typelibsize number of bytes pointed to by typelib. | |
*/ | |
dl_ctx_t wcdl_create_ctx( memory_allocator_t alloc, const wcdl_tld* libs, size_t libcnt ); | |
/** | |
* Create a dl_ctx_t and hook up wc-engine specific functionality and load a typelibrary into ctx. | |
* | |
* @param alloc allocator to use in created ctx. | |
* @param typelib libdata to load. | |
* @param typelibsize number of bytes pointed to by typelib. | |
*/ | |
dl_ctx_t wcdl_create_ctx( memory_allocator_t alloc, const uint8_t* typelib, size_t typelibsize ); | |
/** | |
* | |
*/ | |
void* wcdl_load_from_buffer( dl_ctx_t dl_ctx, dl_typeid_t tid, memory_allocator_t alloc, const uint8_t* data, size_t data_size ); | |
template <typename T> | |
T* wcdl_load_from_buffer( dl_ctx_t dl_ctx, memory_allocator_t alloc, const uint8_t* data, size_t data_size ) | |
{ | |
return (T*)wcdl_load_from_buffer( dl_ctx, T::TYPE_ID, alloc, data, data_size ); | |
} | |
/** | |
* | |
*/ | |
void* wcdl_load_from_buffer_inplace( dl_ctx_t dl_ctx, dl_typeid_t tid, uint8_t* data, size_t data_size ); | |
template <typename T> | |
T* wcdl_load_from_buffer_inplace( dl_ctx_t dl_ctx, uint8_t* data, size_t data_size ) | |
{ | |
return (T*)wcdl_load_from_buffer_inplace( dl_ctx, T::TYPE_ID, data, data_size ); | |
} | |
/** | |
* Store dl instance to binary buffer. | |
* | |
* @param dl_ctx dl-context to use when packing. | |
* @param tid type id of instance. | |
* @param alloc allocator to use when allocating result. | |
* @param instance to store | |
* @param pack_size [out] number of bytes in returned buffer. | |
* | |
* @return buffer containing the packed dl-instance | |
*/ | |
uint8_t* wcdl_pack_to_buffer( dl_ctx_t dl_ctx, dl_typeid_t tid, memory_allocator_t alloc, const void* instance, size_t* pack_size ); | |
/** | |
* | |
*/ | |
template <typename T> | |
uint8_t* wcdl_pack_to_buffer( dl_ctx_t dl_ctx, memory_allocator_t alloc, const T* instance, size_t* pack_size ) | |
{ | |
return wcdl_pack_to_buffer( dl_ctx, T::TYPE_ID, alloc, instance, pack_size ); | |
} | |
/** | |
* | |
*/ | |
template <typename T> | |
bool wcdl_pack_to_file( dl_ctx_t dl_ctx, const char* path, memory_allocator_t temp_alloc, const T* instance ) | |
{ | |
size_t pack_size; | |
uint8_t* packed = wcdl_pack_to_buffer( dl_ctx, T::TYPE_ID, temp_alloc, instance, &pack_size ); | |
if( !packed ) | |
return false; | |
bool res = filedump( path, packed, pack_size ); | |
if( temp_alloc ) | |
memory_free( temp_alloc, packed ); | |
else | |
free( packed ); | |
return res; | |
} | |
/** | |
* | |
*/ | |
template <typename T> | |
bool wcdl_pack_to_file( dl_ctx_t dl_ctx, const char* path, const T* instance ) | |
{ | |
return wcdl_pack_to_file<T>(dl_ctx, path, nullptr, instance); | |
} | |
/** | |
* Load instance from text data into instance where all memory is allocated by specified allocator. | |
*/ | |
void* wcdl_load_from_txt( dl_ctx_t ctx, memory_allocator_t alloc, const char* txt, dl_typeid_t type ); | |
/** | |
* Load instance from file into instance where all memory is allocated by specified allocator. | |
* @param dlcxt ctx with loaded typelib for type | |
* @param inst_alloc allocator to allocate the returned type with. | |
* @param tmp_alloc allocator to use for temporary allocations, if null malloc/free will be used. | |
* @param path to file to load. | |
* @param type typeid of type expected to be loaded from txt. | |
* | |
* @return loaded type or nullptr on failure. | |
*/ | |
void* wcdl_load_txt_from_file( dl_ctx_t dlctx, | |
memory_allocator_t inst_alloc, | |
memory_allocator_t tmp_alloc, | |
const char* path, | |
dl_typeid_t type ); | |
template <typename T> | |
T* wcdl_load_from_txt( dl_ctx_t ctx, memory_allocator_t alloc, const char* txt ) | |
{ | |
return (T*)wcdl_load_from_txt( ctx, alloc, txt, T::TYPE_ID ); | |
} | |
/** | |
* Helper-function for compilers only to load dl-instance from file. | |
*/ | |
template <typename T> | |
T* wcdl_load_txt_from_file( dl_ctx_t dlctx, memory_allocator_t inst_alloc, memory_allocator_t tmp_alloc, const char* path ) | |
{ | |
return (T*)wcdl_load_txt_from_file( dlctx, inst_alloc, tmp_alloc, path, T::TYPE_ID ); | |
} | |
template <typename T> | |
T* wcdl_load_txt_from_file( dl_ctx_t dlctx, memory_allocator_t alloc, const char* path ) | |
{ | |
return wcdl_load_txt_from_file<T>(dlctx, alloc, alloc, path); | |
} | |
/** | |
* Helper-function for compilers only to load dl-instance from file. | |
*/ | |
template <typename T> | |
T* wcdl_load_txt_from_file( dl_ctx_t dlctx, const char* path ) | |
{ | |
return wcdl_load_txt_from_file<T>( dlctx, nullptr, nullptr, path ); | |
} | |
/** | |
* | |
*/ | |
char* wcdl_pack_to_txt( dl_ctx_t dl_ctx, dl_typeid_t tid, memory_allocator_t alloc, memory_allocator_t temp_alloc, const void* instance ); | |
/** | |
* | |
*/ | |
template <typename T> | |
char* wcdl_pack_to_txt( dl_ctx_t dl_ctx, memory_allocator_t alloc, memory_allocator_t temp_alloc, const T* instance ) | |
{ | |
return wcdl_pack_to_txt( dl_ctx, T::TYPE_ID, alloc, temp_alloc, instance ); | |
} | |
#endif // WCDL_WCDL_H_INCLUDED |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment