235 lines
6.7 KiB
Plaintext
235 lines
6.7 KiB
Plaintext
// 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 <tools/S_STRING>
|
|
|
|
#ifdef TOOLS_MEM
|
|
#include <tools/mem>
|
|
#endif
|
|
|
|
#include <ostream>
|
|
|
|
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<int>(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<tools::uint64>(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<tools::uint64>(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 <class TYPE>
|
|
bool write_page(size_t a_size,void* a_array) {
|
|
if(!m_pos) {
|
|
if(!write_array<TYPE>(m_group,s_pages(),a_size,(TYPE*)a_array,a_size,m_compress)) {
|
|
m_out << "pages::write_page : write_array<TYPE>() 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<TYPE>(m_dataset,a_size,(TYPE*)a_array)) {
|
|
m_out << "pages::write_page : write_append_array<TYPE>() failed. Pos " << m_pos << std::endl;
|
|
return false;
|
|
}
|
|
}
|
|
m_pos += a_size;
|
|
m_entries = m_pos;
|
|
return true;
|
|
}
|
|
|
|
template <class TYPE>
|
|
bool read_page(size_t a_size,void* 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<TYPE>(m_group,s_pages(),(unsigned int)m_pos,(unsigned int)_size,n,array)) {
|
|
m_out << "pages::read_page : read_sub_array<TYPE>() 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<n;i++,rpos++,wpos++) *wpos = *rpos;
|
|
for(size_t i=n;i<_size;i++,rpos++,wpos++) *wpos = TYPE();}
|
|
|
|
delete [] array;
|
|
|
|
m_pos += n;
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
bool write_strings(size_t a_number,void* a_array) {
|
|
size_t sz = m_size*a_number;
|
|
char* buffer = new char[sz];
|
|
{char* pos = buffer;
|
|
for(size_t index=0;index<sz;index++,pos++) *pos = ' ';}
|
|
|
|
{char** strings = (char**)a_array;
|
|
char* pos = buffer;
|
|
size_t ls;
|
|
for(size_t index=0;index<a_number;index++) {
|
|
char* ss = strings[index];
|
|
ls = ::strlen(ss);
|
|
::memcpy(pos,ss,ls); //do not copy the ending 0.
|
|
*(pos+m_size-1) = 0;
|
|
pos += m_size;
|
|
}}
|
|
|
|
if(!m_pos) {
|
|
unsigned int chunked = 32*m_size; //<size>A strings.
|
|
if(!write_array<char>(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<char>(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,void* a_array) {
|
|
unsigned int _size = a_size*m_size;
|
|
unsigned int n = 0;
|
|
char* array = 0;
|
|
if(!read_sub_array<char>(m_group,s_pages(),m_pos,_size,n,array)) {
|
|
m_out << "pages::read_strings : read_sub_array<char>() 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<a_size;index++) {
|
|
::memcpy(strings[index],pos,m_size*sizeof(char));
|
|
pos += m_size;
|
|
}}
|
|
delete [] array;
|
|
m_pos += n;
|
|
return true;
|
|
}
|
|
*/
|
|
protected:
|
|
std::ostream& m_out;
|
|
std::string m_name;
|
|
std::string m_form;
|
|
//int m_type;
|
|
//unsigned int m_size;
|
|
hid_t m_group;
|
|
hid_t m_dataset;
|
|
bool m_write;
|
|
unsigned int m_compress; //if write.
|
|
tools::uint64 m_entries;
|
|
tools::uint64 m_pos;
|
|
};
|
|
|
|
}}
|
|
|
|
#endif
|