Browse Source

reading from vdata
tests
creating namespace over the classes

Patrik Kovacs 6 years ago
parent
commit
42838dac34

+ 4 - 0
include/hdf4cpp/HdfAttribute.h

@@ -12,6 +12,8 @@
 #include <map>
 #include <memory>
 
+namespace hdf4cpp {
+
 class HdfAttributeBase {
 public:
     HdfAttributeBase(int32 id, int32 index) : id(id), index(index) {}
@@ -98,4 +100,6 @@ private:
     std::unique_ptr<HdfAttributeBase> attribute;
 };
 
+}
+
 #endif //HDF4CPP_HDFATTRIBUTE_H

+ 5 - 1
include/hdf4cpp/HdfDefines.h

@@ -11,7 +11,9 @@
 #define MAX_DIMENSION 32
 #define MAX_NAME_LENGTH 100
 
-enum Type {DATASET, GROUP, NONE};
+namespace hdf4cpp {
+
+enum Type {SDATA, VGROUP, VDATA, NONE};
 
 const std::multimap<int32, int32> typeSizeMap = {
         {DFNT_CHAR, SIZE_CHAR},
@@ -33,4 +35,6 @@ const std::multimap<int32, int32> typeSizeMap = {
         {DFNT_UCHAR16, SIZE_UCHAR16},
 };
 
+}
+
 #endif //HDF4CPP_HDFDEFINES_H

+ 5 - 1
include/hdf4cpp/HdfFile.h

@@ -11,7 +11,7 @@
 #include <hdf4cpp/HdfItem.h>
 #include <hdf4cpp/HdfAttribute.h>
 
-
+namespace hdf4cpp {
 
 class HdfFile {
   public:
@@ -32,9 +32,11 @@ class HdfFile {
   private:
     int32 getDatasetId(const std::string& name);
     int32 getGroupId(const std::string& name);
+    int32 getDataId(const std::string& name);
 
     std::vector<int32> getDatasetIds(const std::string& name);
     std::vector<int32> getGroupIds(const std::string& name);
+    std::vector<int32> getDataIds(const std::string& name);
 
     int32 sId;
     int32 vId;
@@ -82,4 +84,6 @@ private:
     int32 index;
 };
 
+}
+
 #endif //GRASP_SEGMENTER_HDFFILE_H

+ 212 - 12
include/hdf4cpp/HdfItem.h

@@ -14,6 +14,7 @@
 #include <vector>
 #include <hdf/hdf.h>
 
+namespace hdf4cpp {
 
 struct Range {
     int32 begin;
@@ -23,8 +24,25 @@ struct Range {
     Range(int32 begin = 0, int32 quantity = 0, int32 stride = 1) : begin(begin), quantity(quantity), stride(stride) {}
 
     intn size() const {
+        if(!stride) {
+            return FAIL;
+        }
         return quantity / stride;
     }
+
+    bool check(const int32& dim) const {
+        return begin >= 0 ||
+               begin < dim ||
+               quantity >= 0 ||
+               begin + quantity <= dim ||
+               stride > 0;
+    }
+
+    static void fill(std::vector<Range>& ranges, const std::vector<int32>& dims) {
+        for(int i = ranges.size(); i < dims.size(); ++i) {
+            ranges.push_back(Range(0, dims[i]));
+        }
+    }
 };
 
 class HdfItemBase {
@@ -65,7 +83,7 @@ public:
                 throw std::runtime_error("HDF4CPP: hdf data set type not supported");
             }
             dest.resize(length);
-            return read(dest.data(), ranges);
+            return read(dest, ranges);
         } else {
             return false;
         }
@@ -85,7 +103,6 @@ public:
 protected:
     int32 id;
 
-    virtual bool read(void *dest, const std::vector<Range>& ranges) = 0;
     virtual int32 getDataType() const = 0;
 };
 
@@ -101,12 +118,60 @@ public:
     intn size() const;
     HdfAttribute getAttribute(const std::string& name);
 
+    template <class T> bool read(std::vector<T>& dest, std::vector<Range>& ranges) {
+        if(_size == FAIL) {
+            return false;
+        }
+        if(!isValid()) {
+            return false;
+        }
+        std::vector<int32> dims = getDims();
+        Range::fill(ranges, dims);
+        intn length = 1;
+        for(int i = 0; i < ranges.size(); ++i) {
+            if(!ranges[i].check(dims[i])) {
+                return false;
+                // TODO or throw exception (ask Moritz)
+            }
+            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");
+            }
+            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;
+        }
+    }
+
+    template <class T> bool 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);
+    }
+
 private:
     intn _size;
     int32 dataType;
     std::string name;
 
-    bool read(void *dest, const std::vector<Range>& ranges);
     int32 getDataType() const;
 };
 
@@ -126,7 +191,107 @@ public:
 private:
     std::string name;
 
-    bool read(void *dest, const std::vector<Range>& ranges);
+    int32 getDataType() const;
+};
+
+class HdfDataItem : public HdfItemBase {
+public:
+    HdfDataItem(int32 id);
+
+    ~HdfDataItem();
+
+    Type getType() const;
+
+    int32 getId() const;
+
+    std::string getName() const;
+
+    std::vector<int32> getDims();
+
+    intn size() const;
+
+    HdfAttribute getAttribute(const std::string &name) {}
+
+    template<class T>
+    bool read(std::vector<T> &dest, const std::string &field, int32 records) {
+        if (!records) {
+            records = nrRecords;
+        }
+
+        if (VSsetfields(id, field.c_str()) == FAIL) {
+            return false;
+        }
+
+        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");
+        }
+
+        size_t size = records * fieldSize;
+        std::vector<uint8> buff(size);
+        if (VSread(id, buff.data(), records, interlace) == FAIL) {
+            return false;
+        }
+
+        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;
+        }
+        return true;
+    }
+
+
+    template <class T> bool 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;
+        }
+
+        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");
+        }
+
+        size_t size = records * fieldSize;
+        std::vector<uint8> buff(size);
+        if(VSread(id, buff.data(), records, interlace) == FAIL) {
+            return false;
+        }
+
+        int32 divided = fieldSize / sizeof(T);
+        dest.resize(records, std::vector<T>(divided));
+        std::vector<T> linearDest(records * divided);
+        VOIDP buffptrs[1];
+        buffptrs[0] = linearDest.data();
+        VSfpack(id, _HDF_VSUNPACK, field.c_str(), buff.data(), size, records, field.c_str(), buffptrs);
+        int i = 0;
+        int j;
+        while(i < records) {
+            j = 0;
+            while(j < divided) {
+                dest[i][j] = linearDest[i * divided + j];
+                ++j;
+            }
+            ++i;
+        }
+        return true;
+    }
+
+private:
+    intn _size;
+    std::string name;
+
+    int32 nrRecords;
+    int32 interlace;
+    int32 recordSize;
+    std::vector<std::string> fieldNames;
+
     int32 getDataType() const;
 };
 
@@ -143,20 +308,53 @@ public:
     intn size() const;
     HdfAttribute getAttribute(const std::string& name);
 
-    template <class T> bool read(std::vector<T> &dest, const std::vector<Range>& ranges) {
-        if(isValid()) {
-            return item->read(dest, ranges);
-        } else {
+    template <class T> bool read(std::vector<T>& dest) {
+        if(!isValid()) {
+            return false;
+        }
+
+        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);
+            }
+            default:
+                return false;
+        }
+    }
+
+    template <class T> bool read(std::vector<T>& dest, std::vector<Range> ranges) {
+        if(!isValid()) {
             return false;
         }
+
+        switch(item->getType()) {
+            case SDATA: {
+                HdfDatasetItem *dItem = dynamic_cast<HdfDatasetItem *>(item.get());
+                return dItem->read(dest, ranges);
+            }
+            default:
+                return false;
+        }
     }
 
-    template <class T> bool read(std::vector<T> &dest) {
-        if(isValid()) {
-            return item->read(dest);
-        } else {
+    template <class T> bool read(std::vector<T>& dest, const std::string& field, int32 records = 0) {
+        if(!isValid()) {
             return false;
         }
+
+        switch(item->getType()) {
+            case VDATA: {
+                HdfDataItem *vItem = dynamic_cast<HdfDataItem*>(item.get());
+                return vItem->read(dest, field, records);
+            }
+            default:
+                return false;
+        }
     }
 
     class Iterator;
@@ -224,4 +422,6 @@ private:
     int32 index;
 };
 
+}
+
 #endif //HDF4CPP_HDFITEM_H

+ 16 - 16
lib/HdfAttribute.cpp

@@ -6,7 +6,7 @@
 #include <hdf4cpp/HdfAttribute.h>
 #include <stdexcept>
 
-HdfDatasetAttribute::HdfDatasetAttribute(int32 id, const std::string& name) : HdfAttributeBase(id, SDfindattr(id, name.c_str())) {
+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];
@@ -16,16 +16,16 @@ HdfDatasetAttribute::HdfDatasetAttribute(int32 id, const std::string& name) : Hd
         _size = FAIL;
     }
 }
-Type HdfDatasetAttribute::getType() const {
-    return DATASET;
+hdf4cpp::Type hdf4cpp::HdfDatasetAttribute::getType() const {
+    return VDATA;
 }
-intn HdfDatasetAttribute::size() const {
+intn hdf4cpp::HdfDatasetAttribute::size() const {
     return _size;
 }
-int32 HdfDatasetAttribute::getDataType() const {
+int32 hdf4cpp::HdfDatasetAttribute::getDataType() const {
     return dataType;
 }
-bool HdfDatasetAttribute::get(void *dest) {
+bool hdf4cpp::HdfDatasetAttribute::get(void *dest) {
     if(!isValid()) {
         return false;
     }
@@ -39,7 +39,7 @@ bool HdfDatasetAttribute::get(void *dest) {
 
     return SDreadattr(id, index, dest) != FAIL;
 }
-HdfGroupAttribute::HdfGroupAttribute(int32 id, const std::string& name) : HdfAttributeBase(id, -1), _size(FAIL) {
+hdf4cpp::HdfGroupAttribute::HdfGroupAttribute(int32 id, const std::string& name) : HdfAttributeBase(id, -1), _size(FAIL) {
     int32 nrAtts = Vnattrs2(id);
     for(intn i = 0; i < nrAtts; ++i) {
         char names[MAX_NAME_LENGTH];
@@ -54,31 +54,31 @@ HdfGroupAttribute::HdfGroupAttribute(int32 id, const std::string& name) : HdfAtt
         }
     }
 }
-Type HdfGroupAttribute::getType() const {
-    return GROUP;
+hdf4cpp::Type hdf4cpp::HdfGroupAttribute::getType() const {
+    return VGROUP;
 }
-intn HdfGroupAttribute::size() const {
+intn hdf4cpp::HdfGroupAttribute::size() const {
     return _size;
 }
-int32 HdfGroupAttribute::getDataType() const {
+int32 hdf4cpp::HdfGroupAttribute::getDataType() const {
     return dataType;
 }
-bool HdfGroupAttribute::get(void *dest) {
+bool hdf4cpp::HdfGroupAttribute::get(void *dest) {
     return Vgetattr2(id, index, dest) != FAIL;
 }
-HdfAttribute::HdfAttribute(HdfAttribute &&other) : attribute(std::move(other.attribute)) {
+hdf4cpp::HdfAttribute::HdfAttribute(HdfAttribute &&other) : attribute(std::move(other.attribute)) {
 }
-bool HdfAttribute::isValid() const {
+bool hdf4cpp::HdfAttribute::isValid() const {
     return attribute && attribute->isValid();
 }
-Type HdfAttribute::getType() const {
+hdf4cpp::Type hdf4cpp::HdfAttribute::getType() const {
     if(isValid()) {
         return attribute->getType();
     } else {
         return NONE;
     }
 }
-intn HdfAttribute::size() const {
+intn hdf4cpp::HdfAttribute::size() const {
     if(isValid()) {
         return attribute->size();
     } else {

+ 21 - 13
lib/HdfFile.cpp

@@ -10,7 +10,7 @@
 
 
 
-HdfFile::HdfFile(const std::string& path) {
+hdf4cpp::HdfFile::HdfFile(const std::string& path) {
     sId = SDstart(path.c_str(), DFACC_READ);
     vId = Hopen(path.c_str(), DFACC_READ, 0);
     Vstart(vId);
@@ -19,31 +19,39 @@ HdfFile::HdfFile(const std::string& path) {
     loneRefs.resize((size_t) loneSize);
     Vlone(vId, loneRefs.data(), loneSize);
 }
-HdfFile::~HdfFile() {
+hdf4cpp::HdfFile::~HdfFile() {
     SDend(sId);
     Vend(vId);
     Hclose(vId);
 }
-int32 HdfFile::getDatasetId(const std::string &name) {
+int32 hdf4cpp::HdfFile::getDatasetId(const std::string &name) {
     int32 index = SDnametoindex(sId, name.c_str());
     return (index == FAIL) ? (FAIL) : (SDselect(sId, index));
 }
-int32 HdfFile::getGroupId(const std::string &name) {
+int32 hdf4cpp::HdfFile::getGroupId(const std::string &name) {
     int32 ref = Vfind(vId, name.c_str());
     return (!ref) ? (FAIL) : (Vattach(vId, ref, "r"));
 }
-HdfItem HdfFile::get(const std::string& name) {
+int32 hdf4cpp::HdfFile::getDataId(const std::string &name) {
+    int32 ref = VSfind(vId, name.c_str());
+    return (!ref) ? (FAIL) : (VSattach(vId, ref, "r"));
+}
+hdf4cpp::HdfItem hdf4cpp::HdfFile::get(const std::string& name) {
     int32 id = getDatasetId(name);
     if(id == FAIL) {
         id = getGroupId(name);
         if(id == FAIL) {
-            return HdfItem(nullptr, sId, vId);
+            id = getDataId(name);
+            if(id == FAIL) {
+                return HdfItem(nullptr, sId, vId);
+            }
+            return HdfItem(new HdfDataItem(id), sId, vId);
         }
         return HdfItem(new HdfGroupItem(id), sId, vId);
     }
     return HdfItem(new HdfDatasetItem(id), sId, vId);
 }
-std::vector<int32> HdfFile::getDatasetIds(const std::string &name) {
+std::vector<int32> hdf4cpp::HdfFile::getDatasetIds(const std::string &name) {
     std::vector<int32> ids;
     char nameDataset[MAX_NAME_LENGTH];
     int32 datasets, attrs;
@@ -60,7 +68,7 @@ std::vector<int32> HdfFile::getDatasetIds(const std::string &name) {
     }
     return ids;
 }
-std::vector<int32> HdfFile::getGroupIds(const std::string &name) {
+std::vector<int32> hdf4cpp::HdfFile::getGroupIds(const std::string &name) {
     std::vector<int32> ids;
     char nameGroup[MAX_NAME_LENGTH];
     int32 ref = Vgetid(vId, -1);
@@ -76,7 +84,7 @@ std::vector<int32> HdfFile::getGroupIds(const std::string &name) {
     }
     return ids;
 }
-std::vector<HdfItem> HdfFile::getAll(const std::string& name) {
+std::vector<hdf4cpp::HdfItem> hdf4cpp::HdfFile::getAll(const std::string& name) {
     std::vector<HdfItem> items;
     std::vector<int32> ids;
     ids = getDatasetIds(name);
@@ -89,16 +97,16 @@ std::vector<HdfItem> HdfFile::getAll(const std::string& name) {
     }
     return std::move(items);
 }
-HdfAttribute HdfFile::getAttribute(const std::string &name) {
+hdf4cpp::HdfAttribute hdf4cpp::HdfFile::getAttribute(const std::string &name) {
     return HdfAttribute(new HdfDatasetAttribute(sId, name));
 }
-bool HdfFile::isValid() {
+bool hdf4cpp::HdfFile::isValid() {
     return sId != FAIL || vId != FAIL;
 }
-HdfFile::Iterator HdfFile::begin() const {
+hdf4cpp::HdfFile::Iterator hdf4cpp::HdfFile::begin() const {
     return Iterator(this, 0);
 }
-HdfFile::Iterator HdfFile::end() const {
+hdf4cpp::HdfFile::Iterator hdf4cpp::HdfFile::end() const {
     int32 size;
     size = Vlone(vId, nullptr, 0);
     if(size == FAIL) {

+ 67 - 43
lib/HdfItem.cpp

@@ -4,10 +4,9 @@
 
 #include <hdf4cpp/HdfItem.h>
 #include <hdf/mfhdf.h>
-#include <algorithm>
-#include <iostream>
+#include <sstream>
 
-HdfDatasetItem::HdfDatasetItem(int32 id) : HdfItemBase(id) {
+hdf4cpp::HdfDatasetItem::HdfDatasetItem(int32 id) : HdfItemBase(id) {
     if(id == FAIL) {
         _size = FAIL;
     } else {
@@ -23,119 +22,144 @@ HdfDatasetItem::HdfDatasetItem(int32 id) : HdfItemBase(id) {
         name = std::string(_name);
     }
 }
-std::vector<int32> HdfDatasetItem::getDims() {
+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);
 }
-bool HdfDatasetItem::read(void *dest, const std::vector<Range>& ranges) {
-    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) != FAIL;
-}
-HdfAttribute HdfDatasetItem::getAttribute(const std::string &name) {
+hdf4cpp::HdfAttribute hdf4cpp::HdfDatasetItem::getAttribute(const std::string &name) {
     return HdfAttribute(new HdfDatasetAttribute(id, name));
 }
-Type HdfDatasetItem::getType() const {
-    return DATASET;
+hdf4cpp::Type hdf4cpp::HdfDatasetItem::getType() const {
+    return SDATA;
 }
-std::string HdfDatasetItem::getName() const {
+std::string hdf4cpp::HdfDatasetItem::getName() const {
     return name;
 }
-int32 HdfDatasetItem::getId() const {
+int32 hdf4cpp::HdfDatasetItem::getId() const {
     return id;
 }
-int32 HdfDatasetItem::getDataType() const {
+int32 hdf4cpp::HdfDatasetItem::getDataType() const {
     return dataType;
 }
-HdfDatasetItem::~HdfDatasetItem() {
+hdf4cpp::HdfDatasetItem::~HdfDatasetItem() {
     if(isValid()) {
         SDendaccess(id);
     }
 }
-intn HdfDatasetItem::size() const {
+intn hdf4cpp::HdfDatasetItem::size() const {
     return _size;
 }
-HdfGroupItem::HdfGroupItem(int32 id) : HdfItemBase(id) {
+hdf4cpp::HdfGroupItem::HdfGroupItem(int32 id) : HdfItemBase(id) {
     char _name[MAX_NAME_LENGTH];
     Vgetname(id, _name);
     name = std::string(_name);
 }
-std::vector<int32> HdfGroupItem::getDims() {
+std::vector<int32> hdf4cpp::HdfGroupItem::getDims() {
     throw std::runtime_error("HDF4CPP: getDims not defined for HdfGroupItem");
 }
-bool HdfGroupItem::read(void *, const std::vector<Range>&) {
-    throw std::runtime_error("HDF4CPP: read not defined for HdfGroupItem");
-}
-HdfAttribute HdfGroupItem::getAttribute(const std::string &name) {
+hdf4cpp::HdfAttribute hdf4cpp::HdfGroupItem::getAttribute(const std::string &name) {
     return HdfAttribute(new HdfGroupAttribute(id, name));
 }
-Type HdfGroupItem::getType() const {
-    return GROUP;
+hdf4cpp::Type hdf4cpp::HdfGroupItem::getType() const {
+    return VGROUP;
 }
-std::string HdfGroupItem::getName() const {
+std::string hdf4cpp::HdfGroupItem::getName() const {
     return name;
 }
-int32 HdfGroupItem::getId() const {
+int32 hdf4cpp::HdfGroupItem::getId() const {
     return id;
 }
-HdfGroupItem::~HdfGroupItem() {
+hdf4cpp::HdfGroupItem::~HdfGroupItem() {
     if(isValid()) {
         Vdetach(id);
     }
 }
-intn HdfGroupItem::size() const {
+intn hdf4cpp::HdfGroupItem::size() const {
     throw std::runtime_error("HdfFile: read not defined for HdfGroupItem");
 }
-int32 HdfGroupItem::getDataType() const {
+int32 hdf4cpp::HdfGroupItem::getDataType() const {
     throw std::runtime_error("HDF4CPP: no data type for HdfGroup");
 }
-HdfItem::HdfItem(HdfItem&& other) : item(std::move(other.item)), sId(other.sId), vId(other.vId) {
+hdf4cpp::HdfDataItem::HdfDataItem(int32 id) : HdfItemBase(id) {
+    char fieldNameList[MAX_NAME_LENGTH];
+    char _name[MAX_NAME_LENGTH];
+    VSinquire(id, &nrRecords, &interlace, fieldNameList, &recordSize, _name);
+    name = std::string(_name);
+    std::istringstream in(fieldNameList);
+    std::string token;
+    while(getline(in, token, ',')) {
+        fieldNames.push_back(token);
+    }
+}
+hdf4cpp::HdfDataItem::~HdfDataItem() {
+    if(isValid()) {
+        Vdetach(id);
+    }
+}
+hdf4cpp::Type hdf4cpp::HdfDataItem::getType() const {
+    return VDATA;
+}
+int32 hdf4cpp::HdfDataItem::getId() const {
+    return id;
+}
+std::string hdf4cpp::HdfDataItem::getName() const {
+    return name;
+}
+std::vector<int32> hdf4cpp::HdfDataItem::getDims() {
+    std::vector<int32> dims;
+    dims.push_back(nrRecords);
+    dims.push_back((int32) fieldNames.size());
+    return dims;
+}
+intn hdf4cpp::HdfDataItem::size() const {
+    return nrRecords * (int32) fieldNames.size();
+}
+int32 hdf4cpp::HdfDataItem::getDataType() const {
+    return 0;
+}
+hdf4cpp::HdfItem::HdfItem(HdfItem&& other) : item(std::move(other.item)), sId(other.sId), vId(other.vId) {
 }
-std::vector<int32> HdfItem::getDims() {
+std::vector<int32> hdf4cpp::HdfItem::getDims() {
     if(isValid()) {
         return item->getDims();
     } else {
         return std::vector<int32>();
     }
 }
-HdfAttribute HdfItem::getAttribute(const std::string &name) {
+hdf4cpp::HdfAttribute hdf4cpp::HdfItem::getAttribute(const std::string &name) {
     return item->getAttribute(name);
 }
-Type HdfItem::getType() const {
+hdf4cpp::Type hdf4cpp::HdfItem::getType() const {
     if(isValid()) {
         return item->getType();
     } else {
         return NONE;
     }
 }
-std::string HdfItem::getName() const {
+std::string hdf4cpp::HdfItem::getName() const {
     if(isValid()) {
         return item->getName();
     } else {
         return std::string();
     }
 }
-bool HdfItem::isValid() const {
+bool hdf4cpp::HdfItem::isValid() const {
     return item && item->isValid();
 }
-intn HdfItem::size() const {
+intn hdf4cpp::HdfItem::size() const {
     if(isValid()) {
         return item->size();
     } else {
         return FAIL;
     }
 }
-HdfItem::Iterator HdfItem::begin() const {
+hdf4cpp::HdfItem::Iterator hdf4cpp::HdfItem::begin() const {
     return Iterator(sId, vId, item->getId(), 0);
 }
-HdfItem::Iterator HdfItem::end() const {
+hdf4cpp::HdfItem::Iterator hdf4cpp::HdfItem::end() const {
     int32 size = Vntagrefs(item->getId());
     if(size == FAIL) {
         return Iterator(sId, vId, item->getId(), 0);

+ 29 - 1
tests/HdfFileTest.cpp

@@ -5,9 +5,13 @@
 #include <gtest/gtest.h>
 #include <hdf4cpp/HdfFile.h>
 
+using namespace hdf4cpp;
+
 class HdfFileTest : public ::testing::Test {
 protected:
-    HdfFileTest() : file(std::string(TEST_DATA_PATH) + "small_test.hdf") {}
+    HdfFileTest() : file(std::string(TEST_DATA_PATH) + "small_test.hdf"),
+                    fileModis("/home/patrik/test_data/modis/MOD021KM.A2008002.0000.006.2014221053223.hdf"),
+                    fileNew("/home/patrik/CLionProjects/Python-scripts/scripts/small_test.hdf") {}
 
     void writeOut(const HdfItem& item, std::ostream& out, const std::string& tab = std::string()) {
         if(!item.isValid()) return;
@@ -24,6 +28,8 @@ protected:
     }
 
     HdfFile file;
+    HdfFile fileModis;
+    HdfFile fileNew;
 };
 
 TEST_F(HdfFileTest, FileValidity) {
@@ -210,4 +216,26 @@ TEST_F(HdfFileTest, ItemIterator3) {
 TEST_F(HdfFileTest, HiddenGroup) {
     HdfItem item = file.get("RIG0.0");
     ASSERT_TRUE(item.isValid());
+}
+
+TEST_F(HdfFileTest, VDataRead) {
+    ASSERT_TRUE(file.isValid());
+    HdfItem item = file.get("Vdata");
+    ASSERT_TRUE(item.isValid());
+    std::vector<int32> vec;
+    ASSERT_TRUE(item.read(vec, "age"));
+    ASSERT_EQ(vec, std::vector<int32>({39, 19, 55}));
+}
+
+TEST_F(HdfFileTest, VDataRead1) {
+    ASSERT_TRUE(file.isValid());
+    HdfItem item = file.get("Vdata");
+    ASSERT_TRUE(item.isValid());
+    std::vector<std::vector<char> > vec;
+    ASSERT_TRUE(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) {
+        ASSERT_EQ(std::string(vec[i].data()), exp[i]);
+    }
 }

BIN
tests/test_data/small_test.hdf