#include #include #include #include #include #include "cgbio.hpp" using std::fill_n; namespace cgc { namespace bio { bin_io* bin_io::instance_ = 0; bin_io::bin_io() { } bin_io::bin_io( const bin_io& ) { } const bin_io* bin_io::instance() { if ( 0 == instance_ ) { instance_ = new bin_io; } return instance_; } void bin_io::delete_instance() { if ( 0 != instance_ ) { delete instance_; instance_ = 0; } } CGBIO_ERROR bin_io::new_elf_reader( elf_reader** obj ) const { CGBIO_ERROR ret = CGBIO_ERROR_NO_ERROR; *obj = new elf_reader_impl; if ( 0 == *obj ) ret = CGBIO_ERROR_MEMORY; return ret; } const char* bin_io::error_string( CGBIO_ERROR error ) const { switch ( error ) { case CGBIO_ERROR_NO_ERROR: return "No error"; case CGBIO_ERROR_LOADED: return "Binary file has been loaded earlier"; case CGBIO_ERROR_FILEIO: return "File input output error"; case CGBIO_ERROR_FORMAT: return "File format error"; case CGBIO_ERROR_INDEX: return "Index is out of range"; case CGBIO_ERROR_MEMORY: return "Can't allocate memory"; case CGBIO_ERROR_RELOC: return "Relocation error"; case CGBIO_ERROR_SYMBOL: return "Symbol error"; case CGBIO_ERROR_UNKNOWN_TYPE: return "Uknown type"; default: return "Unknown error"; } return "Unknown error"; } CGBIO_ERROR bin_io::new_nvb_reader( nvb_reader** obj ) const { CGBIO_ERROR ret = CGBIO_ERROR_NO_ERROR; *obj = new nvb_reader_impl; if ( *obj == 0 ) ret = CGBIO_ERROR_MEMORY; return ret; } nvb_reader_impl::nvb_reader_impl() { ref_count_ = 1; offset_ = 0; image_ = 0; owner_ = false; loaded_ = false; endianness_ = host_endianness(); std::fill_n( reinterpret_cast( &header_ ), sizeof( header_ ), '\0' ); } nvb_reader_impl::~nvb_reader_impl() { if ( image_ != 0 ) delete [] image_; } ptrdiff_t nvb_reader_impl::reference() const { return ++ref_count_; } ptrdiff_t nvb_reader_impl::release() const { ptrdiff_t ret = --ref_count_; if ( ref_count_ == 0 ) delete this; return ret; } CGBIO_ERROR nvb_reader_impl::loadFromString( const char* source, size_t length) { if ( loaded_ ) { return CGBIO_ERROR_LOADED; } CGBIO_ERROR ret = CGBIO_ERROR_NO_ERROR; while (1) { if (length < sizeof( header_ )) { ret = CGBIO_ERROR_FORMAT; break; } memcpy(&header_ ,source,sizeof( header_ )); if ( CG_BINARY_FORMAT_REVISION != header_.binaryFormatRevision ) { endianness_ = ( CGBIODATALSB == endianness_ ) ? CGBIODATAMSB : CGBIODATALSB; int binaryRevision = convert_endianness( header_.binaryFormatRevision, endianness_ ); if ( CG_BINARY_FORMAT_REVISION != binaryRevision ) { ret = CGBIO_ERROR_FORMAT; break; } } size_t sz = length; image_ = new char[sz]; memcpy(image_,source,sz); loaded_ = true; ret = CGBIO_ERROR_NO_ERROR; break; } return ret; } bool nvb_reader_impl::is_loaded() const { return loaded_; } unsigned char nvb_reader_impl::endianness() const { return endianness_; } CGprofile nvb_reader_impl::profile() const { return (CGprofile) convert_endianness( (unsigned int) header_.profile, endianness() ); } unsigned int nvb_reader_impl::revision() const { return convert_endianness( header_.binaryFormatRevision, endianness() ); } unsigned int nvb_reader_impl::size() const { return convert_endianness( header_.totalSize, endianness() ); } unsigned int nvb_reader_impl::number_of_params() const { return convert_endianness( header_.parameterCount, endianness() ); } unsigned int nvb_reader_impl::ucode_size() const { return convert_endianness( header_.ucodeSize, endianness() ); } const char* nvb_reader_impl::ucode() const { if ( 0 == image_ || 0 == ucode_size() ) return 0; return ( image_ + convert_endianness( header_.ucode, endianness() ) ); } const CgBinaryFragmentProgram* nvb_reader_impl::fragment_program() const { if ( 0 == image_ ) return 0; return reinterpret_cast( &image_[convert_endianness( header_.program, endianness_ )] ); } const CgBinaryVertexProgram* nvb_reader_impl::vertex_program() const { if ( 0 == image_ ) return 0; return reinterpret_cast( &image_[convert_endianness( header_.program, endianness_ )] ); } CGBIO_ERROR nvb_reader_impl::get_param_name( unsigned int index, const char **name, bool& is_referenced ) const { if ( index >= number_of_params() ) return CGBIO_ERROR_INDEX; if ( 0 == image_ ) return CGBIO_ERROR_NO_ERROR; const CgBinaryParameter* params = reinterpret_cast( &image_[convert_endianness( header_.parameterArray, endianness_ )] ); const CgBinaryParameter& pp = params[index]; is_referenced = convert_endianness( pp.isReferenced, endianness() ) != 0; CgBinaryStringOffset nm_offset = convert_endianness( pp.name,endianness() ); if ( nm_offset != 0 ) *name = &image_[nm_offset]; else *name = ""; return CGBIO_ERROR_NO_ERROR; } CGBIO_ERROR nvb_reader_impl::get_param( unsigned int index, CGtype& type, CGresource& resource, CGenum& variability, int& resource_index, const char ** name, std::vector& default_value, std::vector& embedded_constants, const char ** semantic, int& paramno, bool& is_referenced, bool& is_shared ) const { if ( index >= number_of_params() ) return CGBIO_ERROR_INDEX; if ( 0 == image_ ) return CGBIO_ERROR_NO_ERROR; const CgBinaryParameter* params = reinterpret_cast( &image_[convert_endianness( header_.parameterArray, endianness_ )] ); const CgBinaryParameter& pp = params[index]; type = static_cast(convert_endianness( static_cast( pp.type ), endianness() ) ); resource = static_cast(convert_endianness( static_cast( pp.res ), endianness() ) ); variability = static_cast(convert_endianness( static_cast( pp.var ),endianness() ) ); resource_index = convert_endianness( pp.resIndex,endianness() ); paramno = convert_endianness( pp.paramno, endianness() ); is_referenced = convert_endianness( pp.isReferenced,endianness() ) != 0; is_shared = convert_endianness( pp.isShared,endianness() ) != 0; CgBinaryStringOffset nm_offset = convert_endianness( pp.name,endianness() ); CgBinaryFloatOffset dv_offset = convert_endianness( pp.defaultValue,endianness() ); CgBinaryEmbeddedConstantOffset ec_offset = convert_endianness( pp.embeddedConst,endianness() ); CgBinaryStringOffset sm_offset = convert_endianness( pp.semantic,endianness() ); if ( 0 != nm_offset ) { *name = &image_[nm_offset]; } else *name = ""; if ( 0 != sm_offset ) { *semantic = &image_[sm_offset]; } else *semantic = ""; if ( 0 != dv_offset ) { char *vp = &image_[dv_offset]; for (int ii = 0; ii < 4; ++ii) { int tmp; memcpy(&tmp,vp+4*ii,4); tmp = convert_endianness(tmp,endianness()); float tmp2; memcpy(&tmp2,&tmp,4); default_value.push_back( tmp2 ); } } if ( 0 != ec_offset ) { void *vp = &image_[ec_offset]; CgBinaryEmbeddedConstant& ec = *(static_cast( vp )); for (unsigned int ii = 0; ii < convert_endianness( ec.ucodeCount, endianness() ); ++ii) { unsigned int offset = convert_endianness( ec.ucodeOffset[ii], endianness() ); embedded_constants.push_back( offset ); } } return CGBIO_ERROR_NO_ERROR; } elf_reader_impl::elf_reader_impl() { ref_count_ = 1; initialized_ = false; fill_n( reinterpret_cast( &header_ ), sizeof( header_ ), '\0' ); } elf_reader_impl::~elf_reader_impl() { } CGBIO_ERROR elf_reader_impl::load( const char* filename ) { return CGBIO_ERROR_NO_ERROR; } CGBIO_ERROR elf_reader_impl::load( std::istream* stream, int start ) { return CGBIO_ERROR_NO_ERROR; } bool elf_reader_impl::is_initialized() const { return initialized_; } ptrdiff_t elf_reader_impl::reference() const { return ++ref_count_; } ptrdiff_t elf_reader_impl::release() const { ptrdiff_t ret = --ref_count_; if ( 0 == ref_count_ ) { delete this; } return ret; } } }