#include #include #include #include #include #include #include "napiconfig.h" #include "binary/BinaryRetriever.hpp" #include "string_util.h" using std::invalid_argument; using std::runtime_error; using std::string; using std::vector; using std::cout; using std::endl; static const string myINT8("INT8"); static const string myINT16("INT16"); static const string myINT32("INT32"); static const string myUINT8("UINT8"); static const string myUINT16("UINT16"); static const string myUINT32("UINT32"); static const string myFLOAT32("FLOAT32"); static const string myFLOAT64("FLOAT64"); static const string myBYTE("BYTE"); static const int NX_DEFAULT_TYPE=NX_UINT32; /** * \file NXtranslate/binary/BinaryRetriever.cpp */ /** * All nodes returned by BinaryRetriever::getData will have this name. */ static const string NAME("binary"); /** * This is the constructor for the object. No resources are allocated. * * \param str The source string is ignored, but necessary to implement * the interface. */ BinaryRetriever::BinaryRetriever(const string &source_file): filename(source_file) { // there is nothing additional to allocate } /** * Since no resources were allocated, the destructor does nothing */ BinaryRetriever::~BinaryRetriever() { // there is nothing to deallocate } static size_t calculate_position(const vector &file_size, const vector &pos) { size_t rank=file_size.size(); size_t result=0; for( size_t i=0 ; i(file_size[i]*result+pos[i]); } return result; } static bool increment_position(const vector &offset, const vector &size, vector &pos) { int index=size.size()-2; while(index>=0){ if(pos[index]+1 &tr) { // check that the argument is not an empty string if(location.size()<=0) { throw invalid_argument("cannot parse empty string"); } // break the location string into a type and sizing information int type; string sizing; { vector temp=string_util::split(location,":"); if(temp.size()==1){ type=getDataType(""); sizing=location; }else if(temp.size()==2){ type=getDataType(temp[0]); sizing=temp[1]; }else{ throw invalid_argument("can only specify one type in location string"); } } // break the location string into three parts: file_size,data_start,data_size string file_size_str; string start_str; string size_str; { vector temp=string_util::split(sizing,"]["); if(temp.size()!=3) { throw invalid_argument("wrong number of groups in location string"); } file_size_str=temp[0].substr(1); start_str=temp[1]; size_str=temp[2].substr(0,temp[2].size()-1); } // convert the parts into vector vector file_size=string_util::str_to_intVec(file_size_str); vector start=string_util::str_to_intVec(start_str); vector size=string_util::str_to_intVec(size_str); // check for the same dimension int rank=file_size.size(); if(start.size()!=rank || size.size()!=rank) { throw invalid_argument("All parts of the location string must be the same rank"); } // confirm that the size doesn't have a zero component for( size_t i=0 ; i::iterator it=file_size.begin() ; it!=file_size.end() ; ++it) { tot_file_size*=(*it); } // set up the starting position vector pos; for( size_t i=0 ; i dims(size.size()); for( size_t i=0 ; i data_buffer(buffer_size); // push through the file grabbing the proper bits scalar_position=data_size*calculate_position(file_size,pos); data_file.seekg(scalar_position,std::ios::beg); data_file.read(&(data_buffer[0]),buffer_size); // copy into final array memcpy((static_cast(data))+data_index*data_size,&(data_buffer[0]),buffer_size); data_index+=num_items; while(increment_position(start,size,pos)) { // calculate where to go and read in a block of data scalar_position=data_size*calculate_position(file_size,pos); data_file.seekg(scalar_position,std::ios::beg); data_file.read(&(data_buffer[0]),buffer_size); // copy into final array memcpy((static_cast(data))+data_index*data_size,&(data_buffer[0]),buffer_size); data_index+=num_items; } // close the file data_file.close(); // create the node - this copies the data Node node=Node(NAME,data,rank,&(dims[0]),type); // insert the data into the tree tr.insert(tr.begin(),node); // delete the data if(NXfree(&data)!=NX_OK) { throw runtime_error("NXfree failed"); } } /** * The MIME_TYPE is necessary so the retriever can be selected by the * factory. */ const string BinaryRetriever::MIME_TYPE("binary"); /** * This function returns a string representation of the retriever for * debugging. Since no resources are allocated the string is always * identical. * * \return The string returned is always "[loopy]". */ string BinaryRetriever::toString() const { return "["+MIME_TYPE+"]:"+filename; }