Prechádzať zdrojové kódy

setting up destroyers

Patrik Kovacs 6 rokov pred
rodič
commit
d53bef71d8

+ 1 - 0
CMakeLists.txt

@@ -16,6 +16,7 @@ add_library(hdf4cpp
         lib/HdfAttribute.cpp
         lib/HdfException.cpp
         include/hdf4cpp/HdfObject.h
+        include/hdf4cpp/HdfDestroyer.h
         )
 
 target_include_directories(hdf4cpp

+ 7 - 5
include/hdf4cpp/HdfAttribute.h

@@ -6,6 +6,8 @@
 #define HDF4CPP_HDFATTRIBUTE_H
 #include <hdf4cpp/HdfException.h>
 #include <hdf4cpp/HdfObject.h>
+#include <hdf4cpp/HdfDestroyer.h>
+#include <iostream>
 #include <hdf/hdf.h>
 #include <hdf/mfhdf.h>
 #include <string>
@@ -17,7 +19,7 @@ namespace hdf4cpp {
 
 class HdfAttributeBase : public HdfObject {
 public:
-    HdfAttributeBase(int32 id, int32 index, Type type) : HdfObject(type, ATTRIBUTE), id(id), index(index) {
+    HdfAttributeBase(int32 id, int32 index, Type type, const HdfDestroyerChain& chain) : HdfObject(type, ATTRIBUTE, chain), id(id), index(index) {
         if(id == FAIL || index == FAIL) {
             raiseException(INVALID_ID);
         }
@@ -50,7 +52,7 @@ protected:
 
 class HdfDatasetAttribute : public HdfAttributeBase {
 public:
-    HdfDatasetAttribute(int32 id, const std::string& name);
+    HdfDatasetAttribute(int32 id, const std::string& name, const HdfDestroyerChain& chain);
 
     intn size() const;
 
@@ -64,7 +66,7 @@ private:
 
 class HdfGroupAttribute : public HdfAttributeBase {
 public:
-    HdfGroupAttribute(int32 id, const std::string& name);
+    HdfGroupAttribute(int32 id, const std::string& name, const HdfDestroyerChain& chain);
 
     intn size() const;
 
@@ -78,7 +80,7 @@ private:
 
 class HdfDataAttribute : public HdfAttributeBase {
 public:
-    HdfDataAttribute(int32 id, const std::string& name);
+    HdfDataAttribute(int32 id, const std::string& name, const HdfDestroyerChain& chain);
 
     intn size() const;
 
@@ -91,7 +93,7 @@ private:
 
 class HdfAttribute : public HdfObject {
 public:
-    HdfAttribute(HdfAttributeBase *attribute) : HdfObject(attribute->getType(), attribute->getClassType()), attribute(attribute) {}
+    HdfAttribute(HdfAttributeBase *attribute) : HdfObject(attribute), attribute(attribute) {}
     HdfAttribute(const HdfAttribute&) = delete;
     HdfAttribute(HdfAttribute&& attr);
     HdfAttribute& operator=(const HdfAttribute& attribute) = delete;

+ 85 - 0
include/hdf4cpp/HdfDestroyer.h

@@ -0,0 +1,85 @@
+//
+// Created by patrik on 23.08.17.
+//
+
+#ifndef GRASP_SEGMENTER_HDFDESTROYER_H
+#define GRASP_SEGMENTER_HDFDESTROYER_H
+
+#include <iostream>
+
+#include <boost/shared_ptr.hpp>
+#include <hdf/hdf.h>
+#include <hdf/mfhdf.h>
+#include <vector>
+
+namespace hdf4cpp {
+
+
+class HdfDestroyerBase {
+  public:
+    virtual ~HdfDestroyerBase() {}
+  protected:
+    HdfDestroyerBase() {}
+};
+
+class HdfFileDestroyer : public HdfDestroyerBase {
+  public:
+    HdfFileDestroyer(int32 sId, int32 vId) : sId(sId), vId(vId) {}
+    ~HdfFileDestroyer() {
+        SDend(sId);
+        Vend(vId);
+        Hclose(vId);
+    }
+
+  private:
+    int32 sId;
+    int32 vId;
+};
+
+class HdfDatasetItemDestroyer : public HdfDestroyerBase {
+  public:
+    HdfDatasetItemDestroyer(int32 id) : id(id) {}
+    ~HdfDatasetItemDestroyer() {
+        SDendaccess(id);
+    }
+
+  private:
+    int32 id;
+};
+
+class HdfGroupItemDestroyer : public HdfDestroyerBase {
+  public:
+    HdfGroupItemDestroyer(int32 id) : id(id) {}
+    ~HdfGroupItemDestroyer() {
+        Vdetach(id);
+    }
+
+  private:
+    int32 id;
+};
+
+class HdfDataItemDestroyer : public HdfDestroyerBase {
+  public:
+    HdfDataItemDestroyer(int32 id) : id(id) {}
+    ~HdfDataItemDestroyer() {
+        VSdetach(id);
+    }
+
+  private:
+    int32 id;
+};
+
+class HdfDestroyer {
+  public:
+    HdfDestroyer(HdfDestroyerBase *destroyerBase) : destroyer(destroyerBase) {}
+    HdfDestroyer(const HdfDestroyer& destroyerObject) : destroyer(destroyerObject.destroyer) {}
+
+  private:
+    std::shared_ptr<HdfDestroyerBase> destroyer;
+};
+
+typedef std::vector<HdfDestroyer> HdfDestroyerChain;
+
+}
+
+#endif //GRASP_SEGMENTER_HDFDESTROYER_H

+ 4 - 4
include/hdf4cpp/HdfFile.h

@@ -11,6 +11,7 @@
 #include <hdf4cpp/HdfObject.h>
 #include <hdf4cpp/HdfItem.h>
 #include <hdf4cpp/HdfAttribute.h>
+#include <hdf4cpp/HdfDestroyer.h>
 
 namespace hdf4cpp {
 
@@ -37,7 +38,6 @@ class HdfFile : public HdfObject {
     Iterator end() const;
 
   private:
-    void destroy();
 
     int32 getDatasetId(const std::string& name) const;
     int32 getGroupId(const std::string& name) const;
@@ -55,7 +55,7 @@ class HdfFile : public HdfObject {
 
 class HdfFile::Iterator : public HdfObject, public std::iterator<std::bidirectional_iterator_tag, HdfItem> {
 public:
-    Iterator(const HdfFile* file, int32 index) : HdfObject(HFILE, ITERATOR),
+    Iterator(const HdfFile* file, int32 index, const HdfDestroyerChain& chain) : HdfObject(HFILE, ITERATOR, chain),
                                                                                  file(file),
                                                                                  index(index) {}
 
@@ -89,11 +89,11 @@ public:
         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, chain), file->sId, file->vId);
             }
             case VDATA: {
                 int32 id = VSattach(file->vId, ref, "r");
-                return HdfItem(new HdfDataItem(id), file->sId, file->vId);
+                return HdfItem(new HdfDataItem(id, chain), file->sId, file->vId);
             }
             default: {
                 raiseException(OUT_OF_RANGE);

+ 10 - 9
include/hdf4cpp/HdfItem.h

@@ -8,6 +8,7 @@
 #include <hdf4cpp/HdfDefines.h>
 #include <hdf4cpp/HdfAttribute.h>
 #include <hdf4cpp/HdfException.h>
+#include <hdf4cpp/HdfDestroyer.h>
 #include <iostream>
 #include <algorithm>
 #include <map>
@@ -49,7 +50,7 @@ struct Range {
 class HdfItemBase : public HdfObject {
 public:
 
-    HdfItemBase(int32 id, const Type& type) : HdfObject(type, ITEM), id(id) {
+    HdfItemBase(int32 id, const Type& type, const HdfDestroyerChain& chain) : HdfObject(type, ITEM, chain), id(id) {
         if(id == FAIL) {
             raiseException(INVALID_ID);
         }
@@ -71,7 +72,7 @@ protected:
 
 class HdfDatasetItem : public HdfItemBase {
 public:
-    HdfDatasetItem(int32 id);
+    HdfDatasetItem(int32 id, const HdfDestroyerChain& chain);
     ~HdfDatasetItem();
 
     int32 getId() const;
@@ -131,7 +132,7 @@ private:
 
 class HdfGroupItem : public HdfItemBase {
 public:
-    HdfGroupItem(int32 id);
+    HdfGroupItem(int32 id, const HdfDestroyerChain& chain);
     ~HdfGroupItem();
 
     int32 getId() const;
@@ -149,7 +150,7 @@ private:
 
 class HdfDataItem : public HdfItemBase {
 public:
-    HdfDataItem(int32 id);
+    HdfDataItem(int32 id, const HdfDestroyerChain& chain);
 
     ~HdfDataItem();
 
@@ -307,8 +308,8 @@ private:
 
 class HdfItem::Iterator : public HdfObject, public std::iterator<std::bidirectional_iterator_tag, HdfItem> {
 public:
-    Iterator(int32 sId, int32 vId, int32 key, int32 index, Type type) :
-                                                                        HdfObject(type, ITERATOR),
+    Iterator(int32 sId, int32 vId, int32 key, int32 index, Type type, const HdfDestroyerChain& chain) :
+                                                                        HdfObject(type, ITERATOR, chain),
                                                                         sId(sId),
                                                                         vId(vId),
                                                                         key(key),
@@ -343,13 +344,13 @@ public:
         }
         if(Visvs(key, ref)) {
             int32 id = VSattach(vId, ref, "r");
-            return HdfItem(new HdfDataItem(id), sId, vId);
+            return HdfItem(new HdfDataItem(id, chain), sId, vId);
         } else if(Visvg(key, ref)) {
             int32 id = Vattach(vId, ref, "r");
-            return HdfItem(new HdfGroupItem(id), sId, vId);
+            return HdfItem(new HdfGroupItem(id, chain), sId, vId);
         } else {
             int32 id = SDselect(sId, SDreftoindex(sId, ref));
-            return HdfItem(new HdfDatasetItem(id), sId, vId);
+            return HdfItem(new HdfDatasetItem(id, chain), sId, vId);
         }
     }
 

+ 8 - 3
include/hdf4cpp/HdfObject.h

@@ -7,6 +7,7 @@
 
 #include <hdf4cpp/HdfDefines.h>
 #include <hdf4cpp/HdfException.h>
+#include <hdf4cpp/HdfDestroyer.h>
 
 namespace hdf4cpp {
 
@@ -16,9 +17,10 @@ class HdfObject {
     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()) {}
+    HdfObject(const Type& type, const ClassType& classType, const HdfDestroyerChain& chain = HdfDestroyerChain()) : type(type),
+                                                                                                                    classType(classType),
+                                                                                                                    chain(chain) {}
+    HdfObject(const HdfObject *object) : type(object->getType()), classType(object->getClassType()), chain(object->chain) {}
 
     virtual void setType(const Type& type) { this->type = type; }
     virtual void setClassType(const ClassType& classType) { this->classType = classType; }
@@ -34,6 +36,9 @@ class HdfObject {
   private:
     Type type;
     ClassType classType;
+
+  protected:
+    HdfDestroyerChain chain;
 };
 }
 

+ 3 - 3
lib/HdfAttribute.cpp

@@ -6,7 +6,7 @@
 #include <hdf4cpp/HdfAttribute.h>
 #include <stdexcept>
 
-hdf4cpp::HdfDatasetAttribute::HdfDatasetAttribute(int32 id, const std::string& name) : HdfAttributeBase(id, SDfindattr(id, name.c_str()), SDATA) {
+hdf4cpp::HdfDatasetAttribute::HdfDatasetAttribute(int32 id, const std::string& name, const HdfDestroyerChain& chain) : HdfAttributeBase(id, SDfindattr(id, name.c_str()), SDATA, chain) {
     char waste[MAX_NAME_LENGTH];
     if(SDattrinfo(id, index, waste, &dataType, &_size) == FAIL) {
         raiseException(STATUS_RETURN_FAIL);
@@ -30,7 +30,7 @@ void hdf4cpp::HdfDatasetAttribute::get(void *dest) {
         raiseException(STATUS_RETURN_FAIL);
     }
 }
-hdf4cpp::HdfGroupAttribute::HdfGroupAttribute(int32 id, const std::string& name) : HdfAttributeBase(id, 0, VGROUP) {
+hdf4cpp::HdfGroupAttribute::HdfGroupAttribute(int32 id, const std::string& name, const HdfDestroyerChain& chain) : HdfAttributeBase(id, 0, VGROUP, chain) {
     int32 nrAtts = Vnattrs2(id);
     for(intn i = 0; i < nrAtts; ++i) {
         char names[MAX_NAME_LENGTH];
@@ -57,7 +57,7 @@ void hdf4cpp::HdfGroupAttribute::get(void *dest) {
         raiseException(STATUS_RETURN_FAIL);
     }
 }
-hdf4cpp::HdfDataAttribute::HdfDataAttribute(int32 id, const std::string &name) : HdfAttributeBase(id, VSfindattr(id, _HDF_VDATA, name.c_str()), VDATA) {
+hdf4cpp::HdfDataAttribute::HdfDataAttribute(int32 id, const std::string &name, const HdfDestroyerChain& chain) : HdfAttributeBase(id, VSfindattr(id, _HDF_VDATA, name.c_str()), VDATA, chain) {
     if(VSattrinfo(id, _HDF_VDATA, index, nullptr, &dataType, &_size, nullptr) == FAIL) {
         raiseException(STATUS_RETURN_FAIL);
     }

+ 10 - 15
lib/HdfFile.cpp

@@ -20,6 +20,8 @@ hdf4cpp::HdfFile::HdfFile(const std::string& path) : HdfObject(HFILE, FILE) {
 
     Vstart(vId);
 
+    chain.push_back(new HdfFileDestroyer(sId, vId));
+
     int32 loneSize = Vlone(vId, nullptr, 0);
     std::vector<int32> refs((size_t) loneSize);
     Vlone(vId, refs.data(), loneSize);
@@ -42,7 +44,6 @@ hdf4cpp::HdfFile::HdfFile(HdfFile&& file) : HdfObject(file.getType(), file.getCl
     loneRefs.clear();
 }
 hdf4cpp::HdfFile& hdf4cpp::HdfFile::operator=(HdfFile&& file) {
-    destroy();
     setType(file.getType());
     setClassType(file.getClassType());
     sId = file.sId;
@@ -52,13 +53,7 @@ hdf4cpp::HdfFile& hdf4cpp::HdfFile::operator=(HdfFile&& file) {
     file.loneRefs.clear();
     return *this;
 }
-void hdf4cpp::HdfFile::destroy() {
-    SDend(sId);
-    Vend(vId);
-    Hclose(vId);
-}
 hdf4cpp::HdfFile::~HdfFile() {
-    destroy();
 }
 int32 hdf4cpp::HdfFile::getSId() const {
     return sId;
@@ -87,11 +82,11 @@ hdf4cpp::HdfItem hdf4cpp::HdfFile::get(const std::string& name) const {
             if(id == FAIL) {
                 raiseException(INVALID_ID);
             }
-            return HdfItem(new HdfDataItem(id), sId, vId);
+            return HdfItem(new HdfDataItem(id, chain), sId, vId);
         }
-        return HdfItem(new HdfGroupItem(id), sId, vId);
+        return HdfItem(new HdfGroupItem(id, chain), sId, vId);
     }
-    return HdfItem(new HdfDatasetItem(id), sId, vId);
+    return HdfItem(new HdfDatasetItem(id, chain), sId, vId);
 }
 std::vector<int32> hdf4cpp::HdfFile::getDatasetIds(const std::string &name) const {
     std::vector<int32> ids;
@@ -130,20 +125,20 @@ std::vector<hdf4cpp::HdfItem> hdf4cpp::HdfFile::getAll(const std::string& name)
     std::vector<int32> ids;
     ids = getDatasetIds(name);
     for(const auto& id : ids) {
-        items.push_back(HdfItem(new HdfDatasetItem(id), sId, vId));
+        items.push_back(HdfItem(new HdfDatasetItem(id, chain), sId, vId));
     }
     ids = getGroupIds(name);
     for(const auto& id : ids) {
-        items.push_back(HdfItem(new HdfGroupItem(id), sId, vId));
+        items.push_back(HdfItem(new HdfGroupItem(id, chain), sId, vId));
     }
     return std::move(items);
 }
 hdf4cpp::HdfAttribute hdf4cpp::HdfFile::getAttribute(const std::string &name) {
-    return HdfAttribute(new HdfDatasetAttribute(sId, name));
+    return HdfAttribute(new HdfDatasetAttribute(sId, name, chain));
 }
 hdf4cpp::HdfFile::Iterator hdf4cpp::HdfFile::begin() const {
-    return Iterator(this, 0);
+    return Iterator(this, 0, chain);
 }
 hdf4cpp::HdfFile::Iterator hdf4cpp::HdfFile::end() const {
-    return Iterator(this, (int32) loneRefs.size());
+    return Iterator(this, (int32) loneRefs.size(), chain);
 }

+ 16 - 16
lib/HdfItem.cpp

@@ -7,7 +7,7 @@
 #include <hdf/mfhdf.h>
 #include <sstream>
 
-hdf4cpp::HdfDatasetItem::HdfDatasetItem(int32 id) : HdfItemBase(id, SDATA) {
+hdf4cpp::HdfDatasetItem::HdfDatasetItem(int32 id, const HdfDestroyerChain& chain) : HdfItemBase(id, SDATA, chain) {
     _size = 1;
     std::for_each(dims.begin(), dims.end(), [this](const int32 &t) {
         _size *= t;
@@ -18,12 +18,13 @@ hdf4cpp::HdfDatasetItem::HdfDatasetItem(int32 id) : HdfItemBase(id, SDATA) {
     SDgetinfo(id, _name, &size, dim, &dataType, nullptr);
     dims = std::vector<int32>(dim, dim + size);
     name = std::string(_name);
+    this->chain.push_back(new HdfDatasetItemDestroyer(id));
 }
 std::vector<int32> hdf4cpp::HdfDatasetItem::getDims() {
     return dims;
 }
 hdf4cpp::HdfAttribute hdf4cpp::HdfDatasetItem::getAttribute(const std::string &name) const {
-    return HdfAttribute(new HdfDatasetAttribute(id, name));
+    return HdfAttribute(new HdfDatasetAttribute(id, name, chain));
 }
 std::string hdf4cpp::HdfDatasetItem::getName() const {
     return name;
@@ -35,21 +36,21 @@ int32 hdf4cpp::HdfDatasetItem::getDataType() const {
     return dataType;
 }
 hdf4cpp::HdfDatasetItem::~HdfDatasetItem() {
-    SDendaccess(id);
 }
 intn hdf4cpp::HdfDatasetItem::size() const {
     return _size;
 }
-hdf4cpp::HdfGroupItem::HdfGroupItem(int32 id) : HdfItemBase(id, VGROUP) {
+hdf4cpp::HdfGroupItem::HdfGroupItem(int32 id, const HdfDestroyerChain& chain) : HdfItemBase(id, VGROUP, chain) {
     char _name[MAX_NAME_LENGTH];
     Vgetname(id, _name);
     name = std::string(_name);
+    this->chain.push_back(new HdfGroupItemDestroyer(id));
 }
 std::vector<int32> hdf4cpp::HdfGroupItem::getDims() {
     raiseException(INVALID_OPERATION);
 }
 hdf4cpp::HdfAttribute hdf4cpp::HdfGroupItem::getAttribute(const std::string &name) const {
-    return HdfAttribute(new HdfGroupAttribute(id, name));
+    return HdfAttribute(new HdfGroupAttribute(id, name, chain));
 }
 std::string hdf4cpp::HdfGroupItem::getName() const {
     return name;
@@ -58,7 +59,6 @@ int32 hdf4cpp::HdfGroupItem::getId() const {
     return id;
 }
 hdf4cpp::HdfGroupItem::~HdfGroupItem() {
-    Vdetach(id);
 }
 intn hdf4cpp::HdfGroupItem::size() const {
     raiseException(INVALID_OPERATION);
@@ -66,7 +66,7 @@ intn hdf4cpp::HdfGroupItem::size() const {
 int32 hdf4cpp::HdfGroupItem::getDataType() const {
     raiseException(INVALID_OPERATION);
 }
-hdf4cpp::HdfDataItem::HdfDataItem(int32 id) : HdfItemBase(id, VDATA) {
+hdf4cpp::HdfDataItem::HdfDataItem(int32 id, const HdfDestroyerChain& chain) : HdfItemBase(id, VDATA, chain) {
     char fieldNameList[MAX_NAME_LENGTH];
     char _name[MAX_NAME_LENGTH];
     VSinquire(id, &nrRecords, &interlace, fieldNameList, &recordSize, _name);
@@ -76,12 +76,12 @@ hdf4cpp::HdfDataItem::HdfDataItem(int32 id) : HdfItemBase(id, VDATA) {
     while(getline(in, token, ',')) {
         fieldNames.push_back(token);
     }
+    this->chain.push_back(new HdfDataItemDestroyer(id));
 }
 hdf4cpp::HdfDataItem::~HdfDataItem() {
-    VSdetach(id);
 }
 hdf4cpp::HdfAttribute hdf4cpp::HdfDataItem::getAttribute(const std::string &name) const {
-    return HdfAttribute(new HdfDataAttribute(id, name));
+    return HdfAttribute(new HdfDataAttribute(id, name, chain));
 }
 int32 hdf4cpp::HdfDataItem::getId() const {
     return id;
@@ -102,10 +102,10 @@ int32 hdf4cpp::HdfDataItem::getDataType() const {
     return 0;
 }
 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(item),
+                                                                     sId(sId),
+                                                                     vId(vId) {}
+hdf4cpp::HdfItem::HdfItem(HdfItem&& other) : HdfObject(other.getType(), other.getClassType(), std::move(other.chain)),
                                              item(std::move(other.item)),
                                              sId(other.sId),
                                              vId(other.vId) {}
@@ -129,16 +129,16 @@ intn hdf4cpp::HdfItem::size() const {
     return item->size();
 }
 hdf4cpp::HdfItem::Iterator hdf4cpp::HdfItem::begin() const {
-    return Iterator(sId, vId, item->getId(), 0, getType());
+    return Iterator(sId, vId, item->getId(), 0, getType(), chain);
 }
 hdf4cpp::HdfItem::Iterator hdf4cpp::HdfItem::end() const {
     switch(item->getType()) {
         case VGROUP: {
             int32 size = Vntagrefs(item->getId());
-            return Iterator(sId, vId, item->getId(), size, getType());
+            return Iterator(sId, vId, item->getId(), size, getType(), chain);
         }
         default: {
-            return Iterator(sId, vId, item->getId(), 0, getType());
+            return Iterator(sId, vId, item->getId(), 0, getType(), chain);
         }
     }
 }

+ 21 - 0
tests/HdfFileTest.cpp

@@ -212,4 +212,25 @@ TEST_F(HdfFileTest, VDataAttributes) {
     std::vector<int32> vec;
     attribute.get(vec);
     ASSERT_EQ(vec, std::vector<int32>({1, 2, 3, 3, 2, 1}));
+}
+
+TEST_F(HdfFileTest, SdataDestroyer) {
+    HdfAttribute attribute = file.get("DataWithAttributes").getAttribute("Integer");
+    std::vector<int32> vec;
+    attribute.get(vec);
+    ASSERT_EQ(vec, std::vector<int32>({12345}));
+}
+
+TEST_F(HdfFileTest, VgroupDestroyer) {
+    HdfAttribute attribute = file.get("GroupWithOnlyAttribute").getAttribute("Egy");
+    std::vector<int8> vec;
+    attribute.get(vec);
+    ASSERT_EQ(vec, std::vector<int8>({1}));
+}
+
+TEST_F(HdfFileTest, VdataDestroyer) {
+    HdfAttribute attribute = file.get("Vdata").getAttribute("attribute");
+    std::vector<int32> vec;
+    attribute.get(vec);
+    ASSERT_EQ(vec, std::vector<int32>({1, 2, 3, 3, 2, 1}));
 }