// Copyright (C) 2010, Guy Barrand. All rights reserved. // See the file tools.license for terms. #ifndef tools_hdf5_pages #define tools_hdf5_pages #include "T_tools" #include "tools" #include #ifdef TOOLS_MEM #include #endif #include namespace tools { namespace hdf5 { TOOLS_GLOBAL_STRING(pages) TOOLS_GLOBAL_STRING(entries) TOOLS_GLOBAL_STRING(columns) TOOLS_GLOBAL_STRING(names) TOOLS_GLOBAL_STRING(forms) class pages { TOOLS_SCLASS(tools::hdf5::pages) public: pages(std::ostream& a_out, hid_t a_group,const std::string& a_name,const std::string& a_form, bool a_write,unsigned int a_compress) :m_out(a_out),m_name(a_name),m_form(a_form) //,m_type(0),m_size(0) ,m_group(-1),m_dataset(-1),m_write(a_write),m_compress(a_compress),m_entries(0),m_pos(0){ #ifdef TOOLS_MEM tools::mem::increment(s_class().c_str()); #endif if(m_write) { m_group = tools_H5Gcreate(a_group,m_name.c_str(),0); if(m_group<0) { m_out << "pages::pages : can't create group for column " << m_name << "." << std::endl; m_group = -1; return; } if(!write_atb(m_group,"class",s_class())) { m_out << "pages::pages : write_atb(class) failed." << std::endl; ::H5Gclose(m_group); m_group = -1; return; } int v = 1; if (!write_scalar_atb(m_group,"version",v)) { m_out << "pages::pages : write_scalar_atb(version) failed." << std::endl; ::H5Gclose(m_group); m_group = -1; return; } } else { m_group = tools_H5Gopen(a_group,m_name.c_str()); if(m_group<0) { m_out << "pages::pages : can't open group for column " << m_name << "." << std::endl; m_group = -1; return; } if(!read_scalar(m_group,s_entries(),m_entries)) { m_out << "pages::pages : read_scalar(entries) failed." << std::endl; ::H5Gclose(m_group); m_group = -1; return; } } } virtual ~pages(){ if(m_write) { if(!write_scalar(m_group,s_entries(),m_entries)) { m_out << "pages::~pages : write_scalar(entries) failed." << std::endl; } if(m_dataset>=0) ::H5Dclose(m_dataset); } ::H5Gclose(m_group); #ifdef TOOLS_MEM tools::mem::decrement(s_class().c_str()); #endif } protected: pages(const pages& a_from):m_out(a_from.m_out){ #ifdef TOOLS_MEM tools::mem::increment(s_class().c_str()); #endif } pages& operator=(const pages&){return *this;} public: bool is_valid() const {return m_group<0?false:true;} const std::string& name() const {return m_name;} const std::string& form() const {return m_form;} //int type() const {return m_type;} //unsigned int size() const {return m_size;} tools::uint64 entries() const {return m_entries;} tools::uint64 pos() const {return m_pos;} void reset_pos() {m_pos = 0;} template bool write_page(size_t a_size,const TYPE* a_array) { if(!m_pos) { if(!write_array(m_group,s_pages(),a_size,a_array,a_size?a_size:32,m_compress)) { m_out << "pages::write_page : write_array() failed. Pos " << m_pos << std::endl; return false; } m_dataset = tools_H5Dopen(m_group,s_pages().c_str()); if(m_dataset<0) { m_out << "pages::write_page : H5Dopen failed. Pos " << m_pos << std::endl; return false; } } else { if(!write_append_array_dataset(m_dataset,a_size,a_array)) { m_out << "pages::write_page : write_append_array_dataset() failed. Pos " << m_pos << std::endl; return false; } } m_pos += a_size; m_entries = m_pos; return true; } template bool read_page(size_t a_size,TYPE* a_array) { //it is assumed that a_array can contain a_size*sizeof(TYPE) bytes. unsigned int _size = a_size; unsigned int n = 0; TYPE* array = 0; if(!read_sub_array(m_group,s_pages(),(unsigned int)m_pos,(unsigned int)_size,n,array)) { m_out << "pages::read_page : read_sub_array() failed." << std::endl; return false; } if(n!=_size) { m_out << "pages::read_page : size mismatch. Requested " << _size << ", got "<< n << "." << std::endl; delete [] array; return false; } {TYPE* rpos = (TYPE*)array; TYPE* wpos = (TYPE*)a_array; for(size_t i=0;i bool write_vlen(size_t a_size,const TYPE* a_array) { if(!m_pos) { if(!hdf5::write_vlen(m_group,s_pages(),a_size,a_array,a_size?a_size:32,m_compress)) { m_out << "pages::write_vlen : write_vlen() failed. Pos " << m_pos << std::endl; return false; } m_dataset = tools_H5Dopen(m_group,s_pages().c_str()); if(m_dataset<0) { m_out << "pages::write_vlen : H5Dopen failed. Pos " << m_pos << std::endl; return false; } } else { if(!write_append_vlen_dataset(m_dataset,a_size,a_array)) { m_out << "pages::write_vlen : write_append_vlen_dataset() failed. Pos " << m_pos << std::endl; return false; } } m_pos++; m_entries++; return true; } template bool read_vlen(size_t& a_size,TYPE*& a_array) { //it is assumed that a_array can contain a_size*sizeof(TYPE) bytes. unsigned int sz; if(!read_sub_vlen(m_group,s_pages(),(unsigned int)m_pos,sz,a_array)) { m_out << "pages::read_vlen : read_sub_vlen() failed." << std::endl; a_size = 0; a_array = 0; return false; } a_size = sz; m_pos++; m_entries++; return true; } bool write_string(const std::string& a_string) { if(!m_pos) { if(!hdf5::write_string_dataset(m_group,s_pages(),a_string,128,m_compress)) { //32=>enforce extendable. m_out << "pages::write_string : hdf5::write_string() failed. Pos " << m_pos << std::endl; return false; } m_dataset = tools_H5Dopen(m_group,s_pages().c_str()); if(m_dataset<0) { m_out << "pages::write_string : H5Dopen failed. Pos " << m_pos << std::endl; return false; } } else { if(!write_append_string_dataset(m_dataset,a_string)) { m_out << "pages::write_string : write_append_string_dataset() failed. Pos " << m_pos << std::endl; return false; } } m_pos++; m_entries++; return true; } bool read_string(std::string& a_string) { if(!read_sub_string(m_group,s_pages(),(unsigned int)m_pos,a_string)) { m_out << "pages::read_string : read_sub_string() failed." << std::endl; a_string.clear(); return false; } m_pos++; m_entries++; return true; } /* bool write_string(const std::string& a_string) {return write_vlen(a_string.size(),a_string.c_str());} bool read_string(std::string& a_string) { size_t sz;char* _data; if(!read_vlen(sz,_data)) {a_string.clear();return false;} a_string.resize(sz); for(size_t index=0;indexA strings. if(!write_array(m_group,s_pages(),sz,buffer,chunked,m_compress)) { m_out << "pages::write_strings : write_strings() failed. Pos " << m_pos << std::endl; return false; } m_dataset = tools_H5Dopen(m_group,s_pages().c_str()); if(m_dataset<0) { m_out << "pages::write_strings : H5Dopen failed. Pos " << m_pos << std::endl; return false; } } else { if(!write_append_array_dataset(m_dataset,sz,buffer)) { m_out << "pages::write_strings : write_append_strings() failed. Pos " << m_pos << std::endl; return false; } } m_pos += a_number; m_entries = m_pos; return true; } bool read_strings(size_t a_size,char* a_array) { unsigned int _size = a_size*m_size; unsigned int n = 0; char* array = 0; if(!read_sub_array(m_group,s_pages(),m_pos,_size,n,array)) { m_out << "pages::read_strings : read_sub_array() failed." << std::endl; return false; } if(n!=_size) { m_out << "pages::read_strings : size mismatch. Requested " << _size << ", got "<< n << "." << std::endl; delete [] array; return false; } char* pos = array; {char** strings = (char**)a_array; for(size_t index=0;index