Forráskód Böngészése

exception mechanism

Patrik Kovacs 6 éve
szülő
commit
6d3ca943df

+ 4 - 1
CMakeLists.txt

@@ -13,7 +13,10 @@ find_package(HDF4)
 add_library(hdf4cpp
         lib/HdfFile.cpp
         lib/HdfItem.cpp
-        lib/HdfAttribute.cpp)
+        lib/HdfAttribute.cpp
+        lib/HdfException.cpp
+        include/hdf4cpp/HdfObject.h
+        )
 
 target_include_directories(hdf4cpp
         PUBLIC

+ 23 - 33
include/hdf4cpp/HdfAttribute.h

@@ -4,7 +4,8 @@
 
 #ifndef HDF4CPP_HDFATTRIBUTE_H
 #define HDF4CPP_HDFATTRIBUTE_H
-
+#include <hdf4cpp/HdfException.h>
+#include <hdf4cpp/HdfObject.h>
 #include <hdf/hdf.h>
 #include <hdf/mfhdf.h>
 #include <string>
@@ -14,30 +15,28 @@
 
 namespace hdf4cpp {
 
-class HdfAttributeBase {
+class HdfAttributeBase : public HdfObject {
 public:
-    HdfAttributeBase(int32 id, int32 index) : id(id), index(index) {}
+    HdfAttributeBase(int32 id, int32 index, Type type) : HdfObject(type, ATTRIBUTE), id(id), index(index) {
+        if(id == FAIL || index == FAIL) {
+            raiseException(INVALID_ID);
+        }
+    }
     virtual ~HdfAttributeBase() {}
-    virtual bool isValid() const { return index != FAIL; }
-    virtual Type getType() const = 0;
 
     virtual intn size() const = 0;
 
-    template <class T> bool get(std::vector<T> &dest) {
+    template <class T> void get(std::vector<T> &dest) {
         intn length = size();
-        if(length != FAIL) {
-            auto it = typeSizeMap.find(getDataType());
-            if(it != typeSizeMap.end()) {
-                if(it->second != sizeof(T)) {
-                    throw std::runtime_error("HDF4CPP: type size missmatch");
-                }
-            } else {
-                throw std::runtime_error("HDF4CPP: hdf data set type not supported");
+        auto it = typeSizeMap.find(getDataType());
+        if (it != typeSizeMap.end()) {
+            if ((size_t) it->second != sizeof(T)) {
+                raiseException(BUFFER_SIZE_NOT_ENOUGH);
             }
             dest.resize(length);
-            return get(dest.data());
+            get(dest.data());
         } else {
-            return false;
+            raiseException(INVALID_DATA_TYPE);
         }
     }
 
@@ -45,14 +44,13 @@ protected:
     int32 id;
     int32 index;
 
-    virtual bool get(void *dest) = 0;
+    virtual void get(void *dest) = 0;
     virtual int32 getDataType() const = 0;
 };
 
 class HdfDatasetAttribute : public HdfAttributeBase {
 public:
     HdfDatasetAttribute(int32 id, const std::string& name);
-    Type getType() const;
 
     intn size() const;
 
@@ -60,14 +58,13 @@ private:
     intn _size;
     int32 dataType;
 
-    bool get(void *dest);
+    void get(void *dest);
     int32 getDataType() const;
 };
 
 class HdfGroupAttribute : public HdfAttributeBase {
 public:
     HdfGroupAttribute(int32 id, const std::string& name);
-    Type getType() const;
 
     intn size() const;
 
@@ -75,43 +72,36 @@ private:
     intn _size;
     int32 dataType;
 
-    bool get(void *dest);
+    void get(void *dest);
     int32 getDataType() const;
 };
 
 class HdfDataAttribute : public HdfAttributeBase {
 public:
     HdfDataAttribute(int32 id, const std::string& name);
-    Type getType() const;
 
     intn size() const;
 
 private:
     intn _size;
     int32 dataType;
-    bool get(void *dest);
+    void get(void *dest);
     int32 getDataType() const;
 };
 
-class HdfAttribute {
+class HdfAttribute : public HdfObject {
 public:
-    HdfAttribute(HdfAttributeBase *attribute) : attribute(attribute) {}
+    HdfAttribute(HdfAttributeBase *attribute) : HdfObject(attribute->getType(), attribute->getClassType()), attribute(attribute) {}
     HdfAttribute(const HdfAttribute&) = delete;
     HdfAttribute(HdfAttribute&& attr);
     HdfAttribute& operator=(const HdfAttribute& attribute) = delete;
     HdfAttribute& operator=(HdfAttribute&& attribute);
 
-    bool isValid() const;
-    explicit operator bool() const { return isValid(); }
     Type getType() const;
 
     intn size() const;
-    template <class T> bool get(std::vector<T> &dest) {
-        if(isValid()) {
-            return attribute->get(dest);
-        } else {
-            return false;
-        }
+    template <class T> void get(std::vector<T> &dest) {
+        attribute->get(dest);
     }
 
 private:

+ 17 - 1
include/hdf4cpp/HdfDefines.h

@@ -13,7 +13,23 @@
 
 namespace hdf4cpp {
 
-enum Type {SDATA, VGROUP, VDATA, NONE};
+enum Type {HFILE, SDATA, VGROUP, VDATA};
+
+enum ClassType {FILE, ITEM, ATTRIBUTE, ITERATOR};
+
+
+enum ExceptionType {
+    INVALID_ID,
+    INVALID_OPERATION,
+    INVALID_NAME,
+    OUT_OF_RANGE,
+    BUFFER_SIZE_NOT_ENOUGH,
+    BUFFER_SIZE_NOT_DIVISIBLE,
+    INVALID_RANGES,
+    STATUS_RETURN_FAIL,
+    INVALID_DATA_TYPE,
+    OTHER
+};
 
 const std::multimap<int32, int32> typeSizeMap = {
         {DFNT_CHAR, SIZE_CHAR},

+ 58 - 0
include/hdf4cpp/HdfException.h

@@ -0,0 +1,58 @@
+//
+// Created by patrik on 22.08.17.
+//
+
+#ifndef HDF4CPP_HDFEXCEPTION_H
+#define HDF4CPP_HDFEXCEPTION_H
+
+#include <hdf4cpp/HdfDefines.h>
+
+namespace hdf4cpp {
+
+
+const std::string exceptionMessagePrefix = "HDF4CPP: ";
+
+const std::map<ExceptionType, std::string> exceptionTypeMap = {
+    {INVALID_ID, "cannot construct object, the id is invalid"},
+    {INVALID_OPERATION, "operation not supported for this type"},
+    {INVALID_NAME, "invalid item name"},
+    {OUT_OF_RANGE, "out of range, cannot access element (usually thrown when an iterator points to an inaccessible address)"},
+    {BUFFER_SIZE_NOT_ENOUGH, "not enough buffer size (usually thrown when the type of the vector in which we read the data is too small)"},
+    {BUFFER_SIZE_NOT_DIVISIBLE, "buffer cannot be splited up (usually thrown when the size of the readable data is not divisible by the type size of the vector"},
+    {INVALID_RANGES, "the given ranges are invalids (usually thrown when the ranges is negative or it is bigger than the dimension of tha data)"},
+    {STATUS_RETURN_FAIL, "hdf routine failed"},
+    {INVALID_DATA_TYPE, "the type of the data in the hdf item is not supported"},
+    {OTHER, "exception thrown"},
+};
+
+class HdfException : public std::exception {
+  public:
+    HdfException(const Type& type, const ClassType& classType, const std::string& message) : type(type),
+                                                                                             classType(classType),
+                                                                                             exceptionType(OTHER),
+                                                                                             message(exceptionMessagePrefix + message) {}
+    HdfException(const Type& type, const ClassType& classType, const ExceptionType& exceptionType) : type(type),
+                                                                                                     classType(classType),
+                                                                                                     exceptionType(exceptionType),
+                                                                                                     message(exceptionMessagePrefix + exceptionTypeMap.at(exceptionType)) {}
+    Type getType() const noexcept;
+    ClassType getClassType() const noexcept;
+    ExceptionType getExceptionType() const noexcept;
+    std::string getMessage() const noexcept;
+
+    const char *what() const noexcept {
+        return message.data();
+    }
+
+  private:
+    Type type;
+    ClassType classType;
+    ExceptionType exceptionType;
+    std::string message;
+};
+
+
+}
+
+
+#endif //HDF4CPP_HDFEXCEPTION_H

+ 11 - 8
include/hdf4cpp/HdfFile.h

@@ -8,12 +8,13 @@
 #include <string>
 #include <vector>
 
+#include <hdf4cpp/HdfObject.h>
 #include <hdf4cpp/HdfItem.h>
 #include <hdf4cpp/HdfAttribute.h>
 
 namespace hdf4cpp {
 
-class HdfFile {
+class HdfFile : public HdfObject {
   public:
     HdfFile(const std::string& path);
     HdfFile(const HdfFile& file) = delete;
@@ -21,9 +22,9 @@ class HdfFile {
     HdfFile& operator=(const HdfFile& file) = delete;
     HdfFile& operator=(HdfFile&& file);
     ~HdfFile();
-    bool isValid() const;
 
-    explicit operator bool() const { return isValid(); }
+    int32 getSId() const;
+    int32 getVId() const;
 
     HdfItem get(const std::string& name) const;
     std::vector<HdfItem> getAll(const std::string& name) const;
@@ -52,9 +53,11 @@ class HdfFile {
     std::vector<std::pair<int32, Type> > loneRefs;
 };
 
-class HdfFile::Iterator : public std::iterator<std::bidirectional_iterator_tag, HdfItem> {
+class HdfFile::Iterator : public HdfObject, public std::iterator<std::bidirectional_iterator_tag, HdfItem> {
 public:
-    Iterator(const HdfFile* file, int32 index) : file(file), index(index) {}
+    Iterator(const HdfFile* file, int32 index) : HdfObject(HFILE, ITERATOR),
+                                                                                 file(file),
+                                                                                 index(index) {}
 
     bool operator!=(const Iterator& it) { return index != it.index; }
     bool operator==(const Iterator& it) { return index == it.index; }
@@ -80,20 +83,20 @@ public:
 
     HdfItem operator*() {
         if(index < 0 || index >= (int) file->loneRefs.size()) {
-            throw std::runtime_error("HDF4CPP: cannot access invalid item");
+            raiseException(OUT_OF_RANGE);
         }
         int32 ref = file->loneRefs[index].first;
         switch(file->loneRefs[index].second) {
             case VGROUP: {
                 int32 id = Vattach(file->vId, ref, "r");
-                return HdfItem(new HdfGroupItem(id), file->sId, file->vId);
             }
+                return HdfItem(new HdfGroupItem(id), file->sId, file->vId);
             case VDATA: {
                 int32 id = VSattach(file->vId, ref, "r");
                 return HdfItem(new HdfDataItem(id), file->sId, file->vId);
             }
             default: {
-                return HdfItem(nullptr, file->sId, file->vId);
+                raiseException(OUT_OF_RANGE);
             }
         }
     }

+ 60 - 126
include/hdf4cpp/HdfItem.h

@@ -7,6 +7,7 @@
 
 #include <hdf4cpp/HdfDefines.h>
 #include <hdf4cpp/HdfAttribute.h>
+#include <hdf4cpp/HdfException.h>
 #include <iostream>
 #include <algorithm>
 #include <map>
@@ -45,60 +46,21 @@ struct Range {
     }
 };
 
-class HdfItemBase {
+class HdfItemBase : public HdfObject {
 public:
 
-    HdfItemBase(int32 id) : id(id) {}
+    HdfItemBase(int32 id, const Type& type) : HdfObject(type, ITEM), id(id) {
+        if(id == FAIL) {
+            raiseException(INVALID_ID);
+        }
+    }
     virtual ~HdfItemBase() {}
-    virtual bool isValid() const { return id != FAIL; }
-
 
-    virtual Type getType() const = 0;
     virtual int32 getId() const = 0;
     virtual std::string getName() const = 0;
     virtual std::vector<int32> getDims() = 0;
     virtual intn size() const = 0;
 
-    template <class T> bool read(std::vector<T> &dest, const std::vector<Range>& ranges) {
-        if(size() == FAIL) {
-            return false;
-        }
-        std::vector<int32> dims = getDims();
-        if(ranges.size() != dims.size()) {
-            throw std::runtime_error("HDF4CPP: incorrect number of ranges");
-        }
-        intn length = 1;
-        for(size_t i = 0; i < dims.size(); ++i) {
-            if(ranges[i].begin < 0 || ranges[i].begin >= dims[i] || ranges[i].quantity < 0 || ranges[i].begin + ranges[i].quantity > dims[i] || ranges[i].stride <= 0) {
-                throw std::runtime_error("HDF4CPP: incorrect range");
-            }
-            length *= ranges[i].size();
-        }
-        if(length > 0) {
-            auto it = typeSizeMap.find(getDataType());
-            if(it != typeSizeMap.end()) {
-                if(it->second != sizeof(T)) {
-                    throw std::runtime_error("HDF4CPP: type size missmatch");
-                }
-            } else {
-                throw std::runtime_error("HDF4CPP: hdf data set type not supported");
-            }
-            dest.resize(length);
-            return read(dest, ranges);
-        } else {
-            return false;
-        }
-    }
-
-    template <class T> bool read(std::vector<T> &dest) {
-        std::vector<int32> dims = getDims();
-        std::vector<Range> ranges(dims.size());
-        std::transform(dims.begin(), dims.end(), ranges.begin(), [](const int32& t) {
-            return Range(0, t);
-        });
-        return read(dest, ranges);
-    }
-
     virtual HdfAttribute getAttribute(const std::string& name) const = 0;
 
 protected:
@@ -112,66 +74,57 @@ public:
     HdfDatasetItem(int32 id);
     ~HdfDatasetItem();
 
-    Type getType() const;
     int32 getId() const;
     std::string getName() const;
     std::vector<int32> getDims();
     intn size() const;
     HdfAttribute getAttribute(const std::string& name) const;
 
-    template <class T> bool read(std::vector<T>& dest, std::vector<Range>& ranges) {
-        if(_size == FAIL) {
-            return false;
-        }
-        if(!isValid()) {
-            return false;
-        }
+    template <class T> void read(std::vector<T>& dest, std::vector<Range>& ranges) {
         std::vector<int32> dims = getDims();
         Range::fill(ranges, dims);
         intn length = 1;
         for(size_t i = 0; i < ranges.size(); ++i) {
             if(!ranges[i].check(dims[i])) {
-                return false;
-                // TODO or throw exception (ask Moritz)
+                raiseException(INVALID_RANGES);
             }
             length *= ranges[i].size();
         }
-        if(length > 0) {
-            // TODO try with the new size getter hdf function
-            auto it = typeSizeMap.find(getDataType());
-            if(it != typeSizeMap.end()) {
-                if(it->second != sizeof(T)) {
-                    throw std::runtime_error("HDF4CPP: type size missmatch");
-                }
-            } else {
-                throw std::runtime_error("HDF4CPP: hdf data type not supported");
+        auto it = typeSizeMap.find(getDataType());
+        if(it != typeSizeMap.end()) {
+            if((size_t) it->second != sizeof(T)) {
+                raiseException(BUFFER_SIZE_NOT_ENOUGH);
             }
-            dest.resize(length);
-            std::vector<int32> start, quantity, stride;
-            for(const auto& range : ranges) {
-                start.push_back(range.begin);
-                quantity.push_back(range.quantity);
-                stride.push_back(range.stride);
-            }
-            return SDreaddata(id, start.data(), stride.data(), quantity.data(), dest.data()) != FAIL;
         } else {
-            return false;
+            raiseException(INVALID_DATA_TYPE);
+        }
+        dest.resize(length);
+        std::vector<int32> start, quantity, stride;
+        for(const auto& range : ranges) {
+            start.push_back(range.begin);
+            quantity.push_back(range.quantity);
+            stride.push_back(range.stride);
+        }
+
+        if(SDreaddata(id, start.data(), stride.data(), quantity.data(), dest.data()) == FAIL) {
+            raiseException(STATUS_RETURN_FAIL);
         }
     }
 
-    template <class T> bool read(std::vector<T>& dest) {
+    template <class T> void read(std::vector<T>& dest) {
         std::vector<int32> dims = getDims();
         std::vector<Range> ranges;
         for(const auto& dim : dims) {
             ranges.push_back(Range(0, dim));
         }
-        return read(dest, ranges);
+        read(dest, ranges);
     }
 
 private:
     intn _size;
     int32 dataType;
     std::string name;
+    std::vector<int32> dims;
 
     int32 getDataType() const;
 };
@@ -181,7 +134,6 @@ public:
     HdfGroupItem(int32 id);
     ~HdfGroupItem();
 
-    Type getType() const;
     int32 getId() const;
     std::string getName() const;
     std::vector<int32> getDims();
@@ -201,8 +153,6 @@ public:
 
     ~HdfDataItem();
 
-    Type getType() const;
-
     int32 getId() const;
 
     std::string getName() const;
@@ -214,55 +164,53 @@ public:
     HdfAttribute getAttribute(const std::string &name) const;
 
     template<class T>
-    bool read(std::vector<T> &dest, const std::string &field, int32 records) {
+    void read(std::vector<T> &dest, const std::string &field, int32 records) {
         if (!records) {
             records = nrRecords;
         }
 
         if (VSsetfields(id, field.c_str()) == FAIL) {
-            return false;
+            raiseException(STATUS_RETURN_FAIL);
         }
 
         int32 fieldSize = VSsizeof(id, (char *) field.c_str());
         if (sizeof(T) < fieldSize) {
-            throw std::runtime_error(
-                    "HDF4CPP: the size of the destination type is less than the size of the field type");
+            raiseException(BUFFER_SIZE_NOT_ENOUGH);
         }
 
         size_t size = records * fieldSize;
         std::vector<uint8> buff(size);
         if (VSread(id, buff.data(), records, interlace) == FAIL) {
-            return false;
+            raiseException(STATUS_RETURN_FAIL);
         }
 
         dest.resize(records);
         VOIDP buffptrs[1];
         buffptrs[0] = dest.data();
         if (VSfpack(id, _HDF_VSUNPACK, field.c_str(), buff.data(), size, records, field.c_str(), buffptrs) == FAIL) {
-            return false;
+            raiseException(STATUS_RETURN_FAIL);
         }
-        return true;
     }
 
 
-    template <class T> bool read(std::vector<std::vector<T> >& dest, const std::string& field, int32 records) {
+    template <class T> void read(std::vector<std::vector<T> >& dest, const std::string& field, int32 records) {
         if(!records) {
             records = nrRecords;
         }
 
         if(VSsetfields(id, field.c_str()) == FAIL) {
-            return false;
+            raiseException(STATUS_RETURN_FAIL);
         }
 
         int32 fieldSize = VSsizeof(id, (char *) field.c_str());
         if(fieldSize % sizeof(T) != 0) {
-            throw std::runtime_error("HDF4CPP: the size of the destination type is less than the size of the field type");
+            raiseException(BUFFER_SIZE_NOT_DIVISIBLE);
         }
 
         size_t size = records * fieldSize;
         std::vector<uint8> buff(size);
         if(VSread(id, buff.data(), records, interlace) == FAIL) {
-            return false;
+            raiseException(STATUS_RETURN_FAIL);
         }
 
         int32 divided = fieldSize / sizeof(T);
@@ -281,7 +229,6 @@ public:
             }
             ++i;
         }
-        return true;
     }
 
 private:
@@ -296,15 +243,14 @@ private:
     int32 getDataType() const;
 };
 
-class HdfItem {
+
+class HdfItem : public HdfObject {
 public:
-    HdfItem(HdfItemBase *item, int32 sId, int32 vId) : item(item), sId(sId), vId(vId) {}
+    HdfItem(HdfItemBase *item, int32 sId, int32 vId);
     HdfItem(const HdfItem& item) = delete;
     HdfItem(HdfItem&& item);
     HdfItem& operator=(const HdfItem& item) = delete;
     HdfItem& operator=(HdfItem&& it);
-    bool isValid() const;
-    explicit operator bool() const { return isValid(); }
 
     Type getType() const;
     std::string getName() const;
@@ -312,52 +258,39 @@ public:
     intn size() const;
     HdfAttribute getAttribute(const std::string& name) const;
 
-    template <class T> bool read(std::vector<T>& dest) {
-        if(!isValid()) {
-            return false;
-        }
-
+    template <class T> void read(std::vector<T>& dest) {
         switch(item->getType()) {
             case SDATA: {
                 HdfDatasetItem *dItem = dynamic_cast<HdfDatasetItem *>(item.get());
-                return dItem->read(dest);
-            }
-            case VGROUP: {
-                HdfGroupItem *gItem = dynamic_cast<HdfGroupItem *>(item.get());
-                return gItem->read(dest);
+                dItem->read(dest);
+                break;
             }
             default:
-                return false;
+                raiseException(INVALID_OPERATION);
         }
     }
 
-    template <class T> bool read(std::vector<T>& dest, std::vector<Range> ranges) {
-        if(!isValid()) {
-            return false;
-        }
-
+    template <class T> void read(std::vector<T>& dest, std::vector<Range> ranges) {
         switch(item->getType()) {
             case SDATA: {
                 HdfDatasetItem *dItem = dynamic_cast<HdfDatasetItem *>(item.get());
-                return dItem->read(dest, ranges);
+                dItem->read(dest, ranges);
+                break;
             }
             default:
-                return false;
+                raiseException(INVALID_OPERATION);
         }
     }
 
-    template <class T> bool read(std::vector<T>& dest, const std::string& field, int32 records = 0) {
-        if(!isValid()) {
-            return false;
-        }
-
+    template <class T> void read(std::vector<T>& dest, const std::string& field, int32 records = 0) {
         switch(item->getType()) {
             case VDATA: {
                 HdfDataItem *vItem = dynamic_cast<HdfDataItem*>(item.get());
-                return vItem->read(dest, field, records);
+                vItem->read(dest, field, records);
+                break;
             }
             default:
-                return false;
+                raiseException(INVALID_OPERATION);
         }
     }
 
@@ -372,16 +305,17 @@ private:
     int32 vId;
 };
 
-class HdfItem::Iterator : public std::iterator<std::bidirectional_iterator_tag, HdfItem> {
+class HdfItem::Iterator : public HdfObject, public std::iterator<std::bidirectional_iterator_tag, HdfItem> {
 public:
-    Iterator(int32 sId, int32 vId, int32 key, int32 index) : sId(sId), vId(vId), key(key), index(index) {}
+    Iterator(int32 sId, int32 vId, int32 key, int32 index, Type type) :
+                                                                        HdfObject(type, ITERATOR),
+                                                                        sId(sId),
+                                                                        vId(vId),
+                                                                        key(key),
+                                                                        index(index) {}
 
     bool operator!=(const Iterator& it) { return index != it.index; }
     bool operator==(const Iterator& it) { return index == it.index; }
-//    bool operator<(const Iterator& it) { return index < it.index; }
-//    bool operator>(const Iterator& it) { return index > it.index; }
-//    bool operator>=(const Iterator& it) { return index >= it.index; }
-//    bool operator<=(const Iterator& it) { return index <= it.index; }
 
     Iterator& operator++() {
         ++index;
@@ -405,7 +339,7 @@ public:
     HdfItem operator*() {
         int32 tag, ref;
         if(Vgettagref(key, index, &tag, &ref) == FAIL) {
-            throw std::runtime_error("HDF4CPP: cannot access invalid item");
+            raiseException(OUT_OF_RANGE);
         }
         if(Visvs(key, ref)) {
             int32 id = VSattach(vId, ref, "r");

+ 42 - 0
include/hdf4cpp/HdfObject.h

@@ -0,0 +1,42 @@
+//
+// Created by patrik on 23.08.17.
+//
+
+#ifndef GRASP_SEGMENTER_HDFOBJECT_H
+#define GRASP_SEGMENTER_HDFOBJECT_H
+
+#include <hdf4cpp/HdfDefines.h>
+#include <hdf4cpp/HdfException.h>
+
+namespace hdf4cpp {
+
+class HdfObject {
+  public:
+    virtual Type getType() const { return type; }
+    virtual ClassType getClassType() const { return classType; }
+
+  protected:
+    HdfObject(const Type& type, const ClassType& classType) : type(type),
+                                                              classType(classType) {}
+    HdfObject(const HdfObject *object) : type(object->getType()), classType(object->getClassType()) {}
+
+    virtual void setType(const Type& type) { this->type = type; }
+    virtual void setClassType(const ClassType& classType) { this->classType = classType; }
+
+    virtual void raiseException(const ExceptionType& exceptionType) const {
+        throw HdfException(type, classType, exceptionType);
+    }
+
+    virtual void raiseException(const std::string& message) const {
+        throw HdfException(type, classType, message);
+    }
+
+  private:
+    Type type;
+    ClassType classType;
+};
+}
+
+
+
+#endif //GRASP_SEGMENTER_HDFOBJECT_H

+ 29 - 53
lib/HdfAttribute.cpp

@@ -6,40 +6,31 @@
 #include <hdf4cpp/HdfAttribute.h>
 #include <stdexcept>
 
-hdf4cpp::HdfDatasetAttribute::HdfDatasetAttribute(int32 id, const std::string& name) : HdfAttributeBase(id, SDfindattr(id, name.c_str())) {
-    if(index != FAIL) {
-        int32 nrValues;
-        char nameRet[MAX_NAME_LENGTH];
-        SDattrinfo(id, index, nameRet, &dataType, &_size);
-    } else {
-        dataType = 0;
-        _size = FAIL;
+hdf4cpp::HdfDatasetAttribute::HdfDatasetAttribute(int32 id, const std::string& name) : HdfAttributeBase(id, SDfindattr(id, name.c_str()), SDATA) {
+    char waste[MAX_NAME_LENGTH];
+    if(SDattrinfo(id, index, waste, &dataType, &_size) == FAIL) {
+        raiseException(STATUS_RETURN_FAIL);
     }
 }
-hdf4cpp::Type hdf4cpp::HdfDatasetAttribute::getType() const {
-    return VDATA;
-}
 intn hdf4cpp::HdfDatasetAttribute::size() const {
     return _size;
 }
 int32 hdf4cpp::HdfDatasetAttribute::getDataType() const {
     return dataType;
 }
-bool hdf4cpp::HdfDatasetAttribute::get(void *dest) {
-    if(!isValid()) {
-        return false;
-    }
-
+void hdf4cpp::HdfDatasetAttribute::get(void *dest) {
     int32 nrValues;
     char nameRet[MAX_NAME_LENGTH];
     int32 status = SDattrinfo(id, index, nameRet, &dataType, &nrValues);
     if(status == FAIL) {
-        return false;
+        raiseException(STATUS_RETURN_FAIL);
     }
 
-    return SDreadattr(id, index, dest) != FAIL;
+    if(SDreadattr(id, index, dest) == FAIL) {
+        raiseException(STATUS_RETURN_FAIL);
+    }
 }
-hdf4cpp::HdfGroupAttribute::HdfGroupAttribute(int32 id, const std::string& name) : HdfAttributeBase(id, -1), _size(FAIL) {
+hdf4cpp::HdfGroupAttribute::HdfGroupAttribute(int32 id, const std::string& name) : HdfAttributeBase(id, 0, VGROUP) {
     int32 nrAtts = Vnattrs2(id);
     for(intn i = 0; i < nrAtts; ++i) {
         char names[MAX_NAME_LENGTH];
@@ -50,12 +41,10 @@ hdf4cpp::HdfGroupAttribute::HdfGroupAttribute(int32 id, const std::string& name)
             index = i;
             _size = count;
             dataType = type;
-            break;
+            return;
         }
     }
-}
-hdf4cpp::Type hdf4cpp::HdfGroupAttribute::getType() const {
-    return VGROUP;
+    raiseException(INVALID_NAME);
 }
 intn hdf4cpp::HdfGroupAttribute::size() const {
     return _size;
@@ -63,51 +52,38 @@ intn hdf4cpp::HdfGroupAttribute::size() const {
 int32 hdf4cpp::HdfGroupAttribute::getDataType() const {
     return dataType;
 }
-bool hdf4cpp::HdfGroupAttribute::get(void *dest) {
-    return Vgetattr2(id, index, dest) != FAIL;
-}
-hdf4cpp::HdfDataAttribute::HdfDataAttribute(int32 id, const std::string &name) : HdfAttributeBase(id, VSfindattr(id, _HDF_VDATA, name.c_str())) {
-    if(index != FAIL) {
-        int32 nrBytes;
-        char _name[MAX_NAME_LENGTH];
-        VSattrinfo(id, _HDF_VDATA, index, _name, &dataType, &_size, &nrBytes);
-    } else {
-        dataType = 0;
-        _size = FAIL;
+void hdf4cpp::HdfGroupAttribute::get(void *dest) {
+    if(Vgetattr2(id, index, dest) == FAIL) {
+        raiseException(STATUS_RETURN_FAIL);
     }
 }
-hdf4cpp::Type hdf4cpp::HdfDataAttribute::getType() const {
-    return VDATA;
+hdf4cpp::HdfDataAttribute::HdfDataAttribute(int32 id, const std::string &name) : HdfAttributeBase(id, VSfindattr(id, _HDF_VDATA, name.c_str()), VDATA) {
+    if(VSattrinfo(id, _HDF_VDATA, index, nullptr, &dataType, &_size, nullptr) == FAIL) {
+        raiseException(STATUS_RETURN_FAIL);
+    }
 }
 intn hdf4cpp::HdfDataAttribute::size() const {
     return _size;
 }
-bool hdf4cpp::HdfDataAttribute::get(void *dest) {
-    return VSgetattr(id, _HDF_VDATA, index, dest) != FAIL;
+void hdf4cpp::HdfDataAttribute::get(void *dest) {
+    if(VSgetattr(id, _HDF_VDATA, index, dest) == FAIL) {
+        raiseException(STATUS_RETURN_FAIL);
+    }
 }
 int32 hdf4cpp::HdfDataAttribute::getDataType() const {
     return dataType;
 }
-hdf4cpp::HdfAttribute::HdfAttribute(HdfAttribute &&other) : attribute(std::move(other.attribute)) {
+hdf4cpp::HdfAttribute::HdfAttribute(HdfAttribute &&other) : HdfObject(other.getType(), other.getClassType()), attribute(std::move(other.attribute)) {
 }
 hdf4cpp::HdfAttribute& hdf4cpp::HdfAttribute::operator=(HdfAttribute&& attr) {
-    attribute = std::move(attr.attribute);\
+    attribute = std::move(attr.attribute);
+    setType(attribute->getType());
+    setClassType(attribute->getClassType());
     return *this;
 }
-bool hdf4cpp::HdfAttribute::isValid() const {
-    return attribute && attribute->isValid();
-}
 hdf4cpp::Type hdf4cpp::HdfAttribute::getType() const {
-    if(isValid()) {
-        return attribute->getType();
-    } else {
-        return NONE;
-    }
+    return attribute->getType();
 }
 intn hdf4cpp::HdfAttribute::size() const {
-    if(isValid()) {
-        return attribute->size();
-    } else {
-        return FAIL;
-    }
+    return attribute->size();
 }

+ 21 - 0
lib/HdfException.cpp

@@ -0,0 +1,21 @@
+//
+// Created by patrik on 22.08.17.
+//
+
+#include <hdf4cpp/HdfException.h>
+
+hdf4cpp::Type hdf4cpp::HdfException::getType() const noexcept {
+    return type;
+}
+
+hdf4cpp::ClassType hdf4cpp::HdfException::getClassType() const noexcept {
+    return classType;
+}
+
+hdf4cpp::ExceptionType hdf4cpp::HdfException::getExceptionType() const noexcept {
+    return exceptionType;
+}
+
+std::string hdf4cpp::HdfException::getMessage() const noexcept {
+    return message;
+}

+ 22 - 13
lib/HdfFile.cpp

@@ -7,12 +7,17 @@
 
 #include <hdf4cpp/HdfDefines.h>
 #include <hdf4cpp/HdfFile.h>
+#include <hdf4cpp/HdfException.h>
 
 
-
-hdf4cpp::HdfFile::HdfFile(const std::string& path) {
+hdf4cpp::HdfFile::HdfFile(const std::string& path) : HdfObject(HFILE, FILE) {
     sId = SDstart(path.c_str(), DFACC_READ);
     vId = Hopen(path.c_str(), DFACC_READ, 0);
+
+    if(sId == FAIL || vId == FAIL) {
+        throw HdfException(getType(), getClassType(), INVALID_ID);
+    }
+
     Vstart(vId);
 
     int32 loneSize = Vlone(vId, nullptr, 0);
@@ -29,7 +34,7 @@ hdf4cpp::HdfFile::HdfFile(const std::string& path) {
         loneRefs.push_back(std::pair<int32, Type>(ref, VDATA));
     }
 }
-hdf4cpp::HdfFile::HdfFile(HdfFile&& file) {
+hdf4cpp::HdfFile::HdfFile(HdfFile&& file) : HdfObject(file.getType(), file.getClassType()) {
     sId = file.sId;
     vId = file.vId;
     loneRefs = file.loneRefs;
@@ -38,11 +43,13 @@ hdf4cpp::HdfFile::HdfFile(HdfFile&& file) {
 }
 hdf4cpp::HdfFile& hdf4cpp::HdfFile::operator=(HdfFile&& file) {
     destroy();
+    setType(file.getType());
+    setClassType(file.getClassType());
     sId = file.sId;
     vId = file.vId;
     loneRefs = file.loneRefs;
     file.sId = file.vId = FAIL;
-    loneRefs.clear();
+    file.loneRefs.clear();
     return *this;
 }
 void hdf4cpp::HdfFile::destroy() {
@@ -53,6 +60,12 @@ void hdf4cpp::HdfFile::destroy() {
 hdf4cpp::HdfFile::~HdfFile() {
     destroy();
 }
+int32 hdf4cpp::HdfFile::getSId() const {
+    return sId;
+}
+int32 hdf4cpp::HdfFile::getVId() const {
+    return vId;
+}
 int32 hdf4cpp::HdfFile::getDatasetId(const std::string &name) const {
     int32 index = SDnametoindex(sId, name.c_str());
     return (index == FAIL) ? (FAIL) : (SDselect(sId, index));
@@ -72,7 +85,7 @@ hdf4cpp::HdfItem hdf4cpp::HdfFile::get(const std::string& name) const {
         if(id == FAIL) {
             id = getDataId(name);
             if(id == FAIL) {
-                return HdfItem(nullptr, sId, vId);
+                raiseException(INVALID_ID);
             }
             return HdfItem(new HdfDataItem(id), sId, vId);
         }
@@ -83,13 +96,12 @@ hdf4cpp::HdfItem hdf4cpp::HdfFile::get(const std::string& name) const {
 std::vector<int32> hdf4cpp::HdfFile::getDatasetIds(const std::string &name) const {
     std::vector<int32> ids;
     char nameDataset[MAX_NAME_LENGTH];
-    int32 datasets, attrs;
-    SDfileinfo(sId, &datasets, &attrs);
+    int32 datasets, waste;
+    SDfileinfo(sId, &datasets, &waste);
     for(int32 i = 0; i < datasets; ++i) {
         int32 id = SDselect(sId, i);
-        int32 rank, dimSize, nt, nAttr;
-        SDgetinfo(id, nameDataset, &rank, &dimSize, &nt, &nAttr);
-        if(name == std::string(nameDataset)) {
+        SDgetinfo(id, nameDataset, nullptr, nullptr, nullptr, nullptr);
+        if(id != FAIL && name == std::string(nameDataset)) {
             ids.push_back(id);
         } else {
             SDendaccess(id);
@@ -129,9 +141,6 @@ std::vector<hdf4cpp::HdfItem> hdf4cpp::HdfFile::getAll(const std::string& name)
 hdf4cpp::HdfAttribute hdf4cpp::HdfFile::getAttribute(const std::string &name) {
     return HdfAttribute(new HdfDatasetAttribute(sId, name));
 }
-bool hdf4cpp::HdfFile::isValid() const {
-    return sId != FAIL || vId != FAIL;
-}
 hdf4cpp::HdfFile::Iterator hdf4cpp::HdfFile::begin() const {
     return Iterator(this, 0);
 }

+ 42 - 74
lib/HdfItem.cpp

@@ -2,39 +2,29 @@
 // Created by patrik on 11.08.17.
 //
 
+#include <hdf4cpp/HdfFile.h>
 #include <hdf4cpp/HdfItem.h>
 #include <hdf/mfhdf.h>
 #include <sstream>
 
-hdf4cpp::HdfDatasetItem::HdfDatasetItem(int32 id) : HdfItemBase(id) {
-    if(id == FAIL) {
-        _size = FAIL;
-    } else {
-        std::vector<int32> dims = getDims();
-        _size = 1;
-        std::for_each(dims.begin(), dims.end(), [this](const int32 &t) {
-            _size *= t;
-        });
-        int32 dim[MAX_DIMENSION];
-        int32 size, nrAtt;
-        char _name[MAX_NAME_LENGTH];
-        SDgetinfo(id, _name, &size, dim, &dataType, &nrAtt);
-        name = std::string(_name);
-    }
+hdf4cpp::HdfDatasetItem::HdfDatasetItem(int32 id) : HdfItemBase(id, SDATA) {
+    _size = 1;
+    std::for_each(dims.begin(), dims.end(), [this](const int32 &t) {
+        _size *= t;
+    });
+    int32 dim[MAX_DIMENSION];
+    int32 size;
+    char _name[MAX_NAME_LENGTH];
+    SDgetinfo(id, _name, &size, dim, &dataType, nullptr);
+    dims = std::vector<int32>(dim, dim + size);
+    name = std::string(_name);
 }
 std::vector<int32> hdf4cpp::HdfDatasetItem::getDims() {
-    int32 dims[MAX_DIMENSION];
-    int32 size, dataType, nrAtt;
-    char name[MAX_NAME_LENGTH];
-    SDgetinfo(id, name, &size, dims, &dataType, &nrAtt);
-    return std::vector<int32>(dims, dims + size);
+    return dims;
 }
 hdf4cpp::HdfAttribute hdf4cpp::HdfDatasetItem::getAttribute(const std::string &name) const {
     return HdfAttribute(new HdfDatasetAttribute(id, name));
 }
-hdf4cpp::Type hdf4cpp::HdfDatasetItem::getType() const {
-    return SDATA;
-}
 std::string hdf4cpp::HdfDatasetItem::getName() const {
     return name;
 }
@@ -45,27 +35,22 @@ int32 hdf4cpp::HdfDatasetItem::getDataType() const {
     return dataType;
 }
 hdf4cpp::HdfDatasetItem::~HdfDatasetItem() {
-    if(isValid()) {
-        SDendaccess(id);
-    }
+    SDendaccess(id);
 }
 intn hdf4cpp::HdfDatasetItem::size() const {
     return _size;
 }
-hdf4cpp::HdfGroupItem::HdfGroupItem(int32 id) : HdfItemBase(id) {
+hdf4cpp::HdfGroupItem::HdfGroupItem(int32 id) : HdfItemBase(id, VGROUP) {
     char _name[MAX_NAME_LENGTH];
     Vgetname(id, _name);
     name = std::string(_name);
 }
 std::vector<int32> hdf4cpp::HdfGroupItem::getDims() {
-    throw std::runtime_error("HDF4CPP: getDims not defined for HdfGroupItem");
+    raiseException(INVALID_OPERATION);
 }
 hdf4cpp::HdfAttribute hdf4cpp::HdfGroupItem::getAttribute(const std::string &name) const {
     return HdfAttribute(new HdfGroupAttribute(id, name));
 }
-hdf4cpp::Type hdf4cpp::HdfGroupItem::getType() const {
-    return VGROUP;
-}
 std::string hdf4cpp::HdfGroupItem::getName() const {
     return name;
 }
@@ -73,17 +58,15 @@ int32 hdf4cpp::HdfGroupItem::getId() const {
     return id;
 }
 hdf4cpp::HdfGroupItem::~HdfGroupItem() {
-    if(isValid()) {
-        Vdetach(id);
-    }
+    Vdetach(id);
 }
 intn hdf4cpp::HdfGroupItem::size() const {
-    throw std::runtime_error("HdfFile: read not defined for HdfGroupItem");
+    raiseException(INVALID_OPERATION);
 }
 int32 hdf4cpp::HdfGroupItem::getDataType() const {
-    throw std::runtime_error("HDF4CPP: no data type for HdfGroup");
+    raiseException(INVALID_OPERATION);
 }
-hdf4cpp::HdfDataItem::HdfDataItem(int32 id) : HdfItemBase(id) {
+hdf4cpp::HdfDataItem::HdfDataItem(int32 id) : HdfItemBase(id, VDATA) {
     char fieldNameList[MAX_NAME_LENGTH];
     char _name[MAX_NAME_LENGTH];
     VSinquire(id, &nrRecords, &interlace, fieldNameList, &recordSize, _name);
@@ -95,16 +78,11 @@ hdf4cpp::HdfDataItem::HdfDataItem(int32 id) : HdfItemBase(id) {
     }
 }
 hdf4cpp::HdfDataItem::~HdfDataItem() {
-    if(isValid()) {
-        VSdetach(id);
-    }
+    VSdetach(id);
 }
 hdf4cpp::HdfAttribute hdf4cpp::HdfDataItem::getAttribute(const std::string &name) const {
     return HdfAttribute(new HdfDataAttribute(id, name));
 }
-hdf4cpp::Type hdf4cpp::HdfDataItem::getType() const {
-    return VDATA;
-}
 int32 hdf4cpp::HdfDataItem::getId() const {
     return id;
 }
@@ -123,54 +101,44 @@ intn hdf4cpp::HdfDataItem::size() const {
 int32 hdf4cpp::HdfDataItem::getDataType() const {
     return 0;
 }
-hdf4cpp::HdfItem::HdfItem(HdfItem&& other) : item(std::move(other.item)), sId(other.sId), vId(other.vId) {
-}
+hdf4cpp::HdfItem::HdfItem(HdfItemBase *item, int32 sId, int32 vId) : HdfObject(item),
+                                                                    item(item),
+                                                                    sId(sId),
+                                                                    vId(vId) {}
+hdf4cpp::HdfItem::HdfItem(HdfItem&& other) : HdfObject(other.getType(), other.getClassType()),
+                                             item(std::move(other.item)),
+                                             sId(other.sId),
+                                             vId(other.vId) {}
 hdf4cpp::HdfItem& hdf4cpp::HdfItem::operator=(HdfItem&& it) {
     item = std::move(it.item);
     return *this;
 }
 std::vector<int32> hdf4cpp::HdfItem::getDims() {
-    if(isValid()) {
-        return item->getDims();
-    } else {
-        return std::vector<int32>();
-    }
+    return item->getDims();
 }
 hdf4cpp::HdfAttribute hdf4cpp::HdfItem::getAttribute(const std::string &name) const {
     return item->getAttribute(name);
 }
 hdf4cpp::Type hdf4cpp::HdfItem::getType() const {
-    if(isValid()) {
-        return item->getType();
-    } else {
-        return NONE;
-    }
+    return item->getType();
 }
 std::string hdf4cpp::HdfItem::getName() const {
-    if(isValid()) {
-        return item->getName();
-    } else {
-        return std::string();
-    }
-}
-bool hdf4cpp::HdfItem::isValid() const {
-    return item && item->isValid();
+    return item->getName();
 }
 intn hdf4cpp::HdfItem::size() const {
-    if(isValid()) {
-        return item->size();
-    } else {
-        return FAIL;
-    }
+    return item->size();
 }
 hdf4cpp::HdfItem::Iterator hdf4cpp::HdfItem::begin() const {
-    return Iterator(sId, vId, item->getId(), 0);
+    return Iterator(sId, vId, item->getId(), 0, getType());
 }
 hdf4cpp::HdfItem::Iterator hdf4cpp::HdfItem::end() const {
-    int32 size = Vntagrefs(item->getId());
-    if(size == FAIL) {
-        return Iterator(sId, vId, item->getId(), 0);
-    } else {
-        return Iterator(sId, vId, item->getId(), size);
+    switch(item->getType()) {
+        case VGROUP: {
+            int32 size = Vntagrefs(item->getId());
+            return Iterator(sId, vId, item->getId(), size, getType());
+        }
+        default: {
+            return Iterator(sId, vId, item->getId(), 0, getType());
+        }
     }
 }

+ 26 - 72
tests/HdfFileTest.cpp

@@ -8,53 +8,35 @@
 using namespace hdf4cpp;
 
 class HdfFileTest : public ::testing::Test {
-protected:
+  protected:
     HdfFileTest() : file(std::string(TEST_DATA_PATH) + "small_test.hdf") {}
 
-    void writeOut(const HdfItem& item, std::ostream& out, const std::string& tab = std::string()) {
-        if(!item.isValid()) return;
-        out << tab << item.getName() << '\n';
-        for(const auto& it : item) {
-            writeOut(it, out, tab + "\t");
-        }
-    }
-
-    void writeOut(const HdfFile& file, std::ostream& out) {
-        for(const auto& it : file) {
-            writeOut(it, out);
-        }
-    }
-
     HdfFile file;
 };
 
-TEST_F(HdfFileTest, FileValidity) {
-    ASSERT_TRUE(file.isValid());
-}
-
 TEST_F(HdfFileTest, DatasetValidity) {
-    ASSERT_TRUE(file.get("Data").isValid());
+    ASSERT_NO_THROW(file.get("Data"));
 }
 
 TEST_F(HdfFileTest, GroupValidity) {
-    ASSERT_TRUE(file.get("Group").isValid());
+    ASSERT_NO_THROW(file.get("Group"));
 }
 
 TEST_F(HdfFileTest, InvalidItem) {
-    ASSERT_FALSE(file.get("InvalidKey").isValid());
+    ASSERT_THROW(file.get("InvalidKey"), HdfException);
 }
 
 TEST_F(HdfFileTest, ReadData1) {
     HdfItem item = file.get("Data");
     std::vector<int32> vec;
-    ASSERT_TRUE(item.read(vec));
+    item.read(vec);
     ASSERT_EQ(vec, std::vector<int32>({1, 2, 3, 4, 5, 6, 7, 8, 9}));
 }
 
 TEST_F(HdfFileTest, ReadData2) {
     HdfItem item = file.get("DataWithAttributes");
     std::vector<float32> vec;
-    ASSERT_TRUE(item.read(vec));
+    item.read(vec);
     ASSERT_EQ(vec, std::vector<float32>({0.0, 0.1, 0.2, 1.0, 1.1, 1.2, 2.0, 2.1, 2.2}));
 }
 
@@ -63,12 +45,12 @@ TEST_F(HdfFileTest, ReadDatasetAttributes) {
 
     HdfAttribute attribute1 = item.getAttribute("Integer");
     std::vector<int32> integer;
-    ASSERT_TRUE(attribute1.get(integer));
+    attribute1.get(integer);
     ASSERT_EQ(integer, std::vector<int32>({12345}));
 
     HdfAttribute attribute2 = item.getAttribute("Integers");
     std::vector<int32> integers;
-    ASSERT_TRUE(attribute2.get(integers));
+    attribute2.get(integers);
     ASSERT_EQ(integers, std::vector<int32>({1, 12, 123, 1234, 12345}));
 }
 
@@ -78,110 +60,88 @@ TEST_F(HdfFileTest, ReadGroupAttributes) {
     {
         HdfAttribute attribute = item.getAttribute("Egy");
         std::vector<int8> egy;
-        ASSERT_TRUE(attribute.get(egy));
+        attribute.get(egy);
         ASSERT_EQ(egy, std::vector<int8>({1}));
     }
 
     {
         HdfAttribute attribute = item.getAttribute("One");
         std::vector<int16> one;
-        ASSERT_TRUE(attribute.get(one));
+        attribute.get(one);
         ASSERT_EQ(one, std::vector<int16>({1}));
     }
 
     {
         HdfAttribute attribute = item.getAttribute("Ein");
         std::vector<int32> ein;
-        ASSERT_TRUE(attribute.get(ein));
+        attribute.get(ein);
         ASSERT_EQ(ein, std::vector<int32>({1}));
     }
 }
 
 TEST_F(HdfFileTest, ReadInvalidData) {
-    HdfItem item = file.get("InvalidKey");
-    std::vector<int32> vec;
-    ASSERT_FALSE(item.read(vec));
+    ASSERT_THROW(file.get("InvalidKey"), HdfException);
 }
 
 TEST_F(HdfFileTest, ReadDataInRange) {
     {
         HdfItem item = file.get("Data");
-        ASSERT_TRUE(item.isValid());
         std::vector<int32> vec;
-        ASSERT_TRUE(item.read(vec, std::vector<Range>({Range(0, 2), Range(1, 2)})));
+        item.read(vec, std::vector<Range>({Range(0, 2), Range(1, 2)}));
         ASSERT_EQ(vec, std::vector<int32>({2, 3, 5, 6}));
     }
     {
         HdfItem item = file.get("DataWithAttributes");
-        ASSERT_TRUE(item.isValid());
         std::vector<float32> vec;
-        ASSERT_TRUE(item.read(vec, std::vector<Range>({Range(2, 1), Range(0, 2)})));
+        item.read(vec, std::vector<Range>({Range(2, 1), Range(0, 2)}));
         ASSERT_EQ(vec, std::vector<float32>({2.0, 2.1}));
     }
 }
 
 TEST_F(HdfFileTest, ReadInvalidDatasetAttribute) {
     HdfItem item = file.get("Data");
-    ASSERT_TRUE(item.isValid());
-    HdfAttribute attribute = item.getAttribute("Attribute");
-    ASSERT_FALSE(attribute.isValid());
-    std::vector<int32> vec;
-    ASSERT_FALSE(attribute.get(vec));
+    ASSERT_THROW(HdfAttribute attribute = item.getAttribute("Attribute"), HdfException);
 }
 
 TEST_F(HdfFileTest, ReadInvalidGroupAttribute) {
     HdfItem item = file.get("Group");
-    ASSERT_TRUE(item.isValid());
-    HdfAttribute attribute = item.getAttribute("Attribute");
-    ASSERT_FALSE(attribute.isValid());
-    std::vector<int32> vec;
-    ASSERT_FALSE(attribute.get(vec));
-}
-
-TEST_F(HdfFileTest, MovingItems) {
-    HdfItem item1 = file.get("Data");
-    HdfItem item2 = std::move(item1);
-    ASSERT_FALSE(item1.isValid());
-    std::vector<int32> vec;
-    ASSERT_TRUE(item2.read(vec));
-    ASSERT_EQ(vec, std::vector<int32>({1, 2, 3, 4, 5, 6, 7, 8, 9}));
+    ASSERT_THROW(HdfAttribute attribute = item.getAttribute("Attribute"), HdfException);
 }
 
 TEST_F(HdfFileTest, GetAllDatsetsWithTheSameName) {
     std::vector<HdfItem> items = file.getAll("DoubleDataset");
     ASSERT_EQ(items.size(), 2);
     std::vector<int32> vec;
-    ASSERT_TRUE(items[0].read(vec));
+    items[0].read(vec);
     ASSERT_EQ(vec, std::vector<int32>({0}));
-    ASSERT_TRUE(items[1].read(vec));
+    items[1].read(vec);
     ASSERT_EQ(vec, std::vector<int32>({0, 1}));
 }
 
 TEST_F(HdfFileTest, DatasetTypeIncompatibility) {
     std::vector<std::string> vec;
     HdfItem item = file.get("Data");
-    ASSERT_ANY_THROW(item.read(vec));
+    ASSERT_THROW(item.read(vec), HdfException);
 }
 
 TEST_F(HdfFileTest, DatasetAttributeTypeIncompatibility) {
     std::vector<std::string> vec;
     HdfItem item = file.get("DataWithAttributes");
     HdfAttribute attribute = item.getAttribute("Integer");
-    ASSERT_ANY_THROW(attribute.get(vec));
+    ASSERT_THROW(attribute.get(vec), HdfException);
 }
 
 TEST_F(HdfFileTest, GroupAttributeTypeIncompatibility) {
     std::vector<std::string> vec;
     HdfItem item = file.get("GroupWithOnlyAttribute");
     HdfAttribute attribute = item.getAttribute("Egy");
-    ASSERT_ANY_THROW(attribute.get(vec));
+    ASSERT_THROW(attribute.get(vec), HdfException);
 }
 
 TEST_F(HdfFileTest, GlobalAttribute) {
     std::vector<int8> vec;
     HdfAttribute attribute = file.getAttribute("GlobalAttribute");
-    ASSERT_TRUE(attribute.isValid());
-    ASSERT_TRUE(attribute.get(vec));
+    attribute.get(vec);
     ASSERT_EQ(vec, std::vector<int8>({11, 22}));
 }
 
@@ -195,7 +155,6 @@ TEST_F(HdfFileTest, FileIterator) {
 
 TEST_F(HdfFileTest, GroupIterator) {
     HdfItem item = file.get("Group");
-    ASSERT_TRUE(item.isValid());
     std::ostringstream out;
     for(auto it : item) {
         out << it.getName() << '*';
@@ -223,25 +182,22 @@ TEST_F(HdfFileTest, ItemIterator3) {
 }
 
 TEST_F(HdfFileTest, HiddenGroup) {
-    HdfItem item = file.get("RIG0.0");
-    ASSERT_TRUE(item.isValid());
+    ASSERT_NO_THROW(file.get("RIG0.0"));
 }
 
 TEST_F(HdfFileTest, VDataRead1) {
     HdfItem item = file.get("Vdata");
-    ASSERT_TRUE(item.isValid());
     ASSERT_EQ(item.getName(), "Vdata");
     std::vector<int32> vec;
-    ASSERT_TRUE(item.read(vec, "age"));
+    item.read(vec, "age");
     ASSERT_EQ(vec, std::vector<int32>({39, 19, 55}));
 }
 
 TEST_F(HdfFileTest, VDataRead2) {
     HdfItem item = file.get("Vdata");
-    ASSERT_TRUE(item.isValid());
     ASSERT_EQ(item.getName(), "Vdata");
     std::vector<std::vector<char> > vec;
-    ASSERT_TRUE(item.read(vec, "name"));
+    item.read(vec, "name");
     std::vector<std::string> exp = {"Patrick Jane", "Barry Allen", "Angus MacGyver"};
     ASSERT_EQ(vec.size(), 3);
     for(int i = 0; i < 3; ++i) {
@@ -251,11 +207,9 @@ TEST_F(HdfFileTest, VDataRead2) {
 
 TEST_F(HdfFileTest, VDataAttributes) {
     HdfItem item = file.get("Vdata");
-    ASSERT_TRUE(item.isValid());
     ASSERT_EQ(item.getName(), "Vdata");
     HdfAttribute attribute = item.getAttribute("attribute");
-    ASSERT_TRUE(attribute.isValid());
     std::vector<int32> vec;
-    ASSERT_TRUE(attribute.get(vec));
+    attribute.get(vec);
     ASSERT_EQ(vec, std::vector<int32>({1, 2, 3, 3, 2, 1}));
 }