Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights reserved. 2 // See the file tools.license for terms. 3 4 #ifndef toolx_hdf5_pages 5 #define toolx_hdf5_pages 6 7 #include "T_tools" 8 #include "tools" 9 10 #include <tools/S_STRING> 11 12 #ifdef TOOLS_MEM 13 #include <tools/mem> 14 #endif 15 16 #include <ostream> 17 18 namespace toolx { 19 namespace hdf5 { 20 21 TOOLS_GLOBAL_STRING(pages) 22 TOOLS_GLOBAL_STRING(entries) 23 TOOLS_GLOBAL_STRING(columns) 24 TOOLS_GLOBAL_STRING(names) 25 TOOLS_GLOBAL_STRING(forms) 26 27 class pages { 28 TOOLS_SCLASS(toolx::hdf5::pages) 29 public: 30 pages(std::ostream& a_out, 31 hid_t a_group,const std::string& a_name,const std::string& a_form, 32 bool a_write,unsigned int a_compress) 33 :m_out(a_out),m_name(a_name),m_form(a_form) 34 //,m_type(0),m_size(0) 35 ,m_group(-1),m_dataset(-1),m_write(a_write),m_compress(a_compress),m_entries(0),m_pos(0){ 36 #ifdef TOOLS_MEM 37 tools::mem::increment(s_class().c_str()); 38 #endif 39 if(m_write) { 40 m_group = toolx_H5Gcreate(a_group,m_name.c_str(),0); 41 if(m_group<0) { 42 m_out << "pages::pages : can't create group for column " << m_name << "." << std::endl; 43 m_group = -1; 44 return; 45 } 46 if(!write_atb(m_group,"class",s_class())) { 47 m_out << "pages::pages : write_atb(class) failed." << std::endl; 48 ::H5Gclose(m_group); 49 m_group = -1; 50 return; 51 } 52 int v = 1; 53 if (!write_scalar_atb<int>(m_group,"version",v)) { 54 m_out << "pages::pages : write_scalar_atb(version) failed." << std::endl; 55 ::H5Gclose(m_group); 56 m_group = -1; 57 return; 58 } 59 } else { 60 m_group = toolx_H5Gopen(a_group,m_name.c_str()); 61 if(m_group<0) { 62 m_out << "pages::pages : can't open group for column " << m_name << "." << std::endl; 63 m_group = -1; 64 return; 65 } 66 if(!read_scalar<tools::uint64>(m_group,s_entries(),m_entries)) { 67 m_out << "pages::pages : read_scalar(entries) failed." << std::endl; 68 ::H5Gclose(m_group); 69 m_group = -1; 70 return; 71 } 72 } 73 } 74 virtual ~pages(){ 75 if(m_write) { 76 if(!write_scalar<tools::uint64>(m_group,s_entries(),m_entries)) { 77 m_out << "pages::~pages : write_scalar(entries) failed." << std::endl; 78 } 79 if(m_dataset>=0) ::H5Dclose(m_dataset); 80 } 81 ::H5Gclose(m_group); 82 #ifdef TOOLS_MEM 83 tools::mem::decrement(s_class().c_str()); 84 #endif 85 } 86 protected: 87 pages(const pages& a_from):m_out(a_from.m_out){ 88 #ifdef TOOLS_MEM 89 tools::mem::increment(s_class().c_str()); 90 #endif 91 } 92 pages& operator=(const pages&){return *this;} 93 public: 94 bool is_valid() const {return m_group<0?false:true;} 95 96 const std::string& name() const {return m_name;} 97 const std::string& form() const {return m_form;} 98 //int type() const {return m_type;} 99 //unsigned int size() const {return m_size;} 100 tools::uint64 entries() const {return m_entries;} 101 tools::uint64 pos() const {return m_pos;} 102 void reset_pos() {m_pos = 0;} 103 104 template <class TYPE> 105 bool write_page(size_t a_size,const TYPE* a_array) { 106 if(!m_pos) { 107 if(!write_array<TYPE>(m_group,s_pages(),a_size,a_array,a_size?a_size:32,m_compress)) { 108 m_out << "pages::write_page : write_array<TYPE>() failed. Pos " << m_pos << std::endl; 109 return false; 110 } 111 m_dataset = toolx_H5Dopen(m_group,s_pages().c_str()); 112 if(m_dataset<0) { 113 m_out << "pages::write_page : H5Dopen failed. Pos " << m_pos << std::endl; 114 return false; 115 } 116 } else { 117 if(!write_append_array_dataset<TYPE>(m_dataset,a_size,a_array)) { 118 m_out << "pages::write_page : write_append_array_dataset<TYPE>() failed. Pos " << m_pos << std::endl; 119 return false; 120 } 121 } 122 m_pos += a_size; 123 m_entries = m_pos; 124 return true; 125 } 126 127 template <class TYPE> 128 bool read_page(size_t a_size,TYPE* a_array) { 129 //it is assumed that a_array can contain a_size*sizeof(TYPE) bytes. 130 unsigned int _size = a_size; 131 unsigned int n = 0; 132 TYPE* array = 0; 133 if(!read_sub_array<TYPE>(m_group,s_pages(),(unsigned int)m_pos,(unsigned int)_size,n,array)) { 134 m_out << "pages::read_page : read_sub_array<TYPE>() failed." << std::endl; 135 return false; 136 } 137 if(n!=_size) { 138 m_out << "pages::read_page : size mismatch. Requested " << _size << ", got "<< n << "." << std::endl; 139 delete [] array; 140 return false; 141 } 142 143 {TYPE* rpos = (TYPE*)array; 144 TYPE* wpos = (TYPE*)a_array; 145 for(size_t i=0;i<n;i++,rpos++,wpos++) *wpos = *rpos; 146 for(size_t i=n;i<_size;i++,rpos++,wpos++) *wpos = TYPE();} 147 148 delete [] array; 149 150 m_pos += n; 151 return true; 152 } 153 154 template <class TYPE> 155 bool write_vlen(size_t a_size,const TYPE* a_array) { 156 if(!m_pos) { 157 if(!hdf5::write_vlen<TYPE>(m_group,s_pages(),a_size,a_array,a_size?a_size:32,m_compress)) { 158 m_out << "pages::write_vlen : write_vlen<TYPE>() failed. Pos " << m_pos << std::endl; 159 return false; 160 } 161 m_dataset = toolx_H5Dopen(m_group,s_pages().c_str()); 162 if(m_dataset<0) { 163 m_out << "pages::write_vlen : H5Dopen failed. Pos " << m_pos << std::endl; 164 return false; 165 } 166 } else { 167 if(!write_append_vlen_dataset<TYPE>(m_dataset,a_size,a_array)) { 168 m_out << "pages::write_vlen : write_append_vlen_dataset<TYPE>() failed. Pos " << m_pos << std::endl; 169 return false; 170 } 171 } 172 m_pos++; 173 m_entries++; 174 return true; 175 } 176 177 template <class TYPE> 178 bool read_vlen(size_t& a_size,TYPE*& a_array) { 179 //it is assumed that a_array can contain a_size*sizeof(TYPE) bytes. 180 unsigned int sz; 181 if(!read_sub_vlen<TYPE>(m_group,s_pages(),(unsigned int)m_pos,sz,a_array)) { 182 m_out << "pages::read_vlen : read_sub_vlen<TYPE>() failed." << std::endl; 183 a_size = 0; 184 a_array = 0; 185 return false; 186 } 187 a_size = sz; 188 m_pos++; 189 m_entries++; 190 return true; 191 } 192 193 bool write_string(const std::string& a_string) { 194 if(!m_pos) { 195 if(!hdf5::write_string_dataset(m_group,s_pages(),a_string,128,m_compress)) { //32=>enforce extendable. 196 m_out << "pages::write_string : hdf5::write_string() failed. Pos " << m_pos << std::endl; 197 return false; 198 } 199 m_dataset = toolx_H5Dopen(m_group,s_pages().c_str()); 200 if(m_dataset<0) { 201 m_out << "pages::write_string : H5Dopen failed. Pos " << m_pos << std::endl; 202 return false; 203 } 204 } else { 205 if(!write_append_string_dataset(m_dataset,a_string)) { 206 m_out << "pages::write_string : write_append_string_dataset() failed. Pos " << m_pos << std::endl; 207 return false; 208 } 209 } 210 m_pos++; 211 m_entries++; 212 return true; 213 } 214 215 bool read_string(std::string& a_string) { 216 if(!read_sub_string(m_group,s_pages(),(unsigned int)m_pos,a_string)) { 217 m_out << "pages::read_string : read_sub_string() failed." << std::endl; 218 a_string.clear(); 219 return false; 220 } 221 m_pos++; 222 m_entries++; 223 return true; 224 } 225 226 /* 227 bool write_string(const std::string& a_string) {return write_vlen<char>(a_string.size(),a_string.c_str());} 228 229 bool read_string(std::string& a_string) { 230 size_t sz;char* _data; 231 if(!read_vlen<char>(sz,_data)) {a_string.clear();return false;} 232 a_string.resize(sz); 233 for(size_t index=0;index<sz;index++) a_string[index] = _data[index]; 234 delete [] _data; 235 return true; 236 } 237 */ 238 239 /* 240 bool write_strings(size_t a_number,void* a_array) { 241 size_t sz = m_size*a_number; 242 char* buffer = new char[sz]; 243 {char* pos = buffer; 244 for(size_t index=0;index<sz;index++,pos++) *pos = ' ';} 245 246 {char** strings = (char**)a_array; 247 char* pos = buffer; 248 size_t ls; 249 for(size_t index=0;index<a_number;index++) { 250 char* ss = strings[index]; 251 ls = ::strlen(ss); 252 ::memcpy(pos,ss,ls); //do not copy the ending 0. 253 *(pos+m_size-1) = 0; 254 pos += m_size; 255 }} 256 257 if(!m_pos) { 258 unsigned int chunked = 32*m_size; //<size>A strings. 259 if(!write_array<char>(m_group,s_pages(),sz,buffer,chunked,m_compress)) { 260 m_out << "pages::write_strings : write_strings() failed. Pos " << m_pos << std::endl; 261 return false; 262 } 263 m_dataset = toolx_H5Dopen(m_group,s_pages().c_str()); 264 if(m_dataset<0) { 265 m_out << "pages::write_strings : H5Dopen failed. Pos " << m_pos << std::endl; 266 return false; 267 } 268 } else { 269 if(!write_append_array_dataset<char>(m_dataset,sz,buffer)) { 270 m_out << "pages::write_strings : write_append_strings() failed. Pos " << m_pos << std::endl; 271 return false; 272 } 273 } 274 m_pos += a_number; 275 m_entries = m_pos; 276 return true; 277 } 278 279 bool read_strings(size_t a_size,char* a_array) { 280 unsigned int _size = a_size*m_size; 281 unsigned int n = 0; 282 char* array = 0; 283 if(!read_sub_array<char>(m_group,s_pages(),m_pos,_size,n,array)) { 284 m_out << "pages::read_strings : read_sub_array<char>() failed." << std::endl; 285 return false; 286 } 287 if(n!=_size) { 288 m_out << "pages::read_strings : size mismatch. Requested " << _size << ", got "<< n << "." << std::endl; 289 delete [] array; 290 return false; 291 } 292 char* pos = array; 293 {char** strings = (char**)a_array; 294 for(size_t index=0;index<a_size;index++) { 295 ::memcpy(strings[index],pos,m_size*sizeof(char)); 296 pos += m_size; 297 }} 298 delete [] array; 299 m_pos += n; 300 return true; 301 } 302 */ 303 protected: 304 std::ostream& m_out; 305 std::string m_name; 306 std::string m_form; 307 //int m_type; 308 //unsigned int m_size; 309 hid_t m_group; 310 hid_t m_dataset; 311 bool m_write; 312 unsigned int m_compress; //if write. 313 tools::uint64 m_entries; 314 tools::uint64 m_pos; 315 }; 316 317 }} 318 319 #endif