[cig-commits] r13816 - cs/cigma/trunk/src

luis at geodynamics.org luis at geodynamics.org
Mon Jan 12 14:09:35 PST 2009


Author: luis
Date: 2009-01-12 14:09:34 -0800 (Mon, 12 Jan 2009)
New Revision: 13816

Modified:
   cs/cigma/trunk/src/h5attr.cpp
Log:
Refactored h5attr.cpp, and added list operation on object if attribute name is not given

Modified: cs/cigma/trunk/src/h5attr.cpp
===================================================================
--- cs/cigma/trunk/src/h5attr.cpp	2009-01-12 22:09:33 UTC (rev 13815)
+++ cs/cigma/trunk/src/h5attr.cpp	2009-01-12 22:09:34 UTC (rev 13816)
@@ -1,3 +1,4 @@
+#include <cstdlib>
 #include <iostream>
 #include <string>
 #include <vector>
@@ -12,6 +13,7 @@
 
 #include "H5Cpp.h"
 
+
 using namespace std;
 using namespace boost;
 namespace po = boost::program_options;
@@ -20,6 +22,12 @@
 
 // ----------------------------------------------------------------------------
 
+bool verbose = false;
+bool overwrite = true;
+
+
+// ----------------------------------------------------------------------------
+
 void split_on_colon(const string& s, vector<string>& ss)
 {
     boost::split(ss, s, boost::is_any_of(":"), boost::token_compress_on);
@@ -56,8 +64,205 @@
     return true;
 }
 
+H5::H5Object* getobj(H5::H5File* file, const string& location)
+{
+    H5::H5Object* obj = 0;
+    try
+    {
+        obj = new H5::Group(file->openGroup(location));
+    }
+    catch (H5::Exception error)
+    {
+    }
+    if (obj == 0)
+    {
+        try
+        {
+            obj = new H5::DataSet(file->openDataSet(location));
+        }
+        catch (H5::Exception error)
+        {
+        }
+    }
+    return obj;
+}
 
+int setattr(H5::H5Object *obj, const string& attr_name, const string& attr_dtype, const string& attr_value)
+{
+    TRI_LOG_STR("setattr()");
+    H5::Attribute* attr = 0;
+    try
+    {
+        shared_ptr<H5::DataType> datatype;
 
+        if (attr_dtype == "string")
+        {
+            datatype = shared_ptr<H5::DataType>(new H5::StrType(0, H5T_VARIABLE));
+        }
+        else if (attr_dtype == "integer")
+        {
+            datatype = shared_ptr<H5::DataType>(new H5::DataType(H5::PredType::NATIVE_INT));
+        }
+        else if (attr_dtype == "float")
+        {
+            datatype = shared_ptr<H5::DataType>(new H5::DataType(H5::PredType::NATIVE_FLOAT));
+        }
+        else if (attr_dtype == "double")
+        {
+            datatype = shared_ptr<H5::DataType>(new H5::DataType(H5::PredType::NATIVE_DOUBLE));
+        }
+        else
+        {
+            cout << "Error: Invalid type '" << attr_dtype << "'" << endl;
+            cout << "Known types are string, integer, float, double" << endl;
+            return -1;
+        }
+
+        H5::DataSpace dataspace(H5S_SCALAR);
+
+        try
+        {
+            attr = new H5::Attribute(obj->openAttribute(attr_name));
+        }
+        catch (H5::AttributeIException e)
+        {
+        }
+        if (attr != 0)
+        {
+            if (overwrite)
+            {
+                try
+                {
+                    delete attr;
+                    attr = 0;
+
+                    obj->removeAttr(attr_name);
+                }
+                catch (H5::AttributeIException e)
+                {
+                }
+            }
+            else
+            {
+                cout << "Error: Cannot overwrite existing attribute '" << attr_name << "'" << endl;
+                return -1;
+            }
+        }
+
+        attr = new H5::Attribute(obj->createAttribute(attr_name, *datatype, dataspace));
+        TRI_LOG(attr);
+
+        if (attr_dtype == "string")
+        {
+            attr->write(*datatype, attr_value);
+            TRI_LOG(attr_value);
+        }
+        else if (attr_dtype == "integer")
+        {
+            int value = lexical_cast<int>(attr_value);
+            attr->write(*datatype, &value);
+            TRI_LOG(value);
+        }
+        else if (attr_dtype == "float")
+        {
+            float value = lexical_cast<float>(attr_value);
+            attr->write(*datatype, &value);
+            TRI_LOG(value);
+        }
+        else if (attr_dtype == "double")
+        {
+            double value = lexical_cast<double>(attr_value);
+            attr->write(*datatype, &value);
+            TRI_LOG(value);
+        }
+    }
+    catch (H5::Exception error)
+    {
+        cout << "Error: Could not set attribute '" << attr_name << "'" << endl;
+        if (verbose) { error.printError(); }
+        return -1;
+    }
+    catch (boost::bad_lexical_cast e)
+    {
+        cout << "Error: Could not cast value '" << attr_value << "' to " << attr_dtype << endl;
+        return -1;
+    }
+    if (attr) { delete attr; }
+    return 0;
+}
+
+int getattr(H5::H5Object *obj, const string& attr_name, string& attr_dtype, string& attr_value)
+{
+    TRI_LOG_STR("getattr()");
+    H5::Attribute* attr = 0;
+    ostringstream stream;
+    try
+    {
+        attr = new H5::Attribute(obj->openAttribute(attr_name));
+
+        H5T_class_t typeclass = attr->getTypeClass();
+        TRI_LOG(typeclass);
+
+        if (typeclass == H5T_STRING)
+        {
+            string value;
+            H5::DataType datatype = attr->getDataType();
+            if (datatype.isVariableStr())
+            {
+                H5::StrType tid(0, H5T_VARIABLE);
+                attr->read(tid, value);
+            }
+            else
+            {
+                size_t size = datatype.getSize();
+                char* buf = new char[size+1];
+                attr->read(datatype, buf);
+                buf[size] = '\0';
+                value = buf;
+                delete [] buf;
+            }
+            attr_dtype = "string";
+            attr_value = value;
+        }
+        else if (typeclass == H5T_INTEGER)
+        {
+            long value;
+            attr->read(H5::PredType::NATIVE_LONG, &value);
+            stream << value << std::ends;
+            attr_dtype = "integer";
+            attr_value = stream.str();
+        }
+        else if (typeclass == H5T_FLOAT)
+        {
+            double value;
+            attr->read(H5::PredType::NATIVE_DOUBLE, &value);
+            stream << value << std::ends;
+            attr_dtype = "double";
+            attr_value = stream.str();
+        }
+        else
+        {
+            cout << "Error: No handler for typeclass " << typeclass << endl;
+            return -1;
+        }
+    }
+    catch (H5::Exception error)
+    {
+        cout << "Error: Could not get attribute '" << attr_name << "'" << endl;
+        if (attr) { delete attr; }
+        if (verbose) { error.printError(); }
+    }
+    if (attr) { delete attr; }
+    return 0;
+}
+
+void listOp(H5::H5Object& loc, const string name, void *data)
+{
+    string dtype, value;
+    getattr(&loc, name, dtype, value);
+    cout << name << " = " << value << endl;
+}
+
 // ----------------------------------------------------------------------------
 
 int main(int argc, char *argv[])
@@ -66,9 +271,7 @@
     string attr_name;
     string attr_loc;
     string attr_value;
-    string attr_type = "string";
-    bool verbose = false;
-    bool overwrite = true;
+    string attr_dtype = "string";
 
     po::options_description all, opts, other;
     po::positional_options_description args;
@@ -78,7 +281,7 @@
         ("location,l", po::value<string>(&attr_loc), "Where to store the attribute <file:path>")
         ("name,n", po::value<string>(&attr_name), "Name of the  attribute")
         ("value,v", po::value<string>(&attr_value), "Value of the attribute")
-        ("type,t", po::value<string>(&attr_type), "Type of attribute (default 'string')")
+        ("type,t", po::value<string>(&attr_dtype), "Type of attribute (default 'string')")
         ;
 
     other.add_options()
@@ -139,16 +342,9 @@
     TRI_LOG(attr_loc);
     TRI_LOG(attr_name);
     TRI_LOG(attr_value);
-    TRI_LOG(attr_type);
+    TRI_LOG(attr_dtype);
     TRI_LOG(overwrite);
 
-    // Check that attribute name is not empty
-    if (attr_name == "")
-    {
-        cout << "Error: Attribute name not specified (use --name option)" << endl;
-        return -1;
-    }
-
     // Validate location
     std::pair<string,string> path;
     if (!split_path(attr_loc, path))
@@ -188,183 +384,41 @@
     }
 
     // Load location
-    H5::H5Object* obj = 0;
-    try
-    {
-        obj = new H5::Group(file->openGroup(location));
-    }
-    catch (H5::Exception error)
-    {
-    }
+    H5::H5Object* obj = getobj(file, location);
     if (obj == 0)
     {
-        try
-        {
-            obj = new H5::DataSet(file->openDataSet(location));
-        }
-        catch (H5::Exception error)
-        {
-        }
-    }
-    if (obj == 0)
-    {
         cout << "Error: Could not open location '" << location << "'" << endl;
         return -1;
     }
 
-    H5::Attribute* attr = 0;
-    if (vm.count("value"))
+    // Check that attribute name is not empty
+    if (vm.count("name"))
     {
-        // 
-        // Set attribute value
-        //
-        TRI_LOG_STR("setattr()");
-        try
+        if (vm.count("value"))
         {
-            shared_ptr<H5::DataType> datatype;
-
-            if (attr_type == "string")
-            {
-                datatype = shared_ptr<H5::DataType>(new H5::StrType(0, H5T_VARIABLE));
-            }
-            else if (attr_type == "integer")
-            {
-                datatype = shared_ptr<H5::DataType>(new H5::DataType(H5::PredType::NATIVE_INT));
-            }
-            else if (attr_type == "float")
-            {
-                datatype = shared_ptr<H5::DataType>(new H5::DataType(H5::PredType::NATIVE_FLOAT));
-            }
-            else if (attr_type == "double")
-            {
-                datatype = shared_ptr<H5::DataType>(new H5::DataType(H5::PredType::NATIVE_DOUBLE));
-            }
-            else
-            {
-                cout << "Error: Invalid type '" << attr_type << "'" << endl;
-                cout << "Known types are string, integer, float, double" << endl;
-                return -1;
-            }
-
-            H5::DataSpace dataspace(H5S_SCALAR);
-
-            try
-            {
-                attr = new H5::Attribute(obj->openAttribute(attr_name));
-            }
-            catch (H5::AttributeIException e)
-            {
-            }
-            if (attr != 0)
-            {
-                if (overwrite)
-                {
-                    try
-                    {
-                        delete attr;
-                        attr = 0;
-
-                        obj->removeAttr(attr_name);
-                    }
-                    catch (H5::AttributeIException e)
-                    {
-                    }
-                }
-                else
-                {
-                    cout << "Error: Cannot overwrite existing attribute '" << attr_name << "'" << endl;
-                    return -1;
-                }
-            }
-
-            attr = new H5::Attribute(obj->createAttribute(attr_name, *datatype, dataspace));
-            TRI_LOG(attr);
-
-            if (attr_type == "string")
-            {
-                attr->write(*datatype, attr_value);
-                TRI_LOG(attr_value);
-            }
-            else if (attr_type == "integer")
-            {
-                int value = lexical_cast<int>(attr_value);
-                attr->write(*datatype, &value);
-                TRI_LOG(value);
-            }
-            else if (attr_type == "float")
-            {
-                float value = lexical_cast<float>(attr_value);
-                attr->write(*datatype, &value);
-                TRI_LOG(value);
-            }
-            else if (attr_type == "double")
-            {
-                double value = lexical_cast<double>(attr_value);
-                attr->write(*datatype, &value);
-                TRI_LOG(value);
-            }
+            setattr(obj, attr_name, attr_dtype, attr_value);
         }
-        catch (H5::Exception error)
+        else
         {
-            cout << "Error: Could not set attribute '" << attr_name << "'" << endl;
-            if (verbose) { error.printError(); }
-            return -1;
+            getattr(obj, attr_name, attr_dtype, attr_value);
         }
-        catch (boost::bad_lexical_cast e)
-        {
-            cout << "Error: Could not cast value '" << attr_value << "' to " << attr_type << endl;
-            return -1;
-        }
-
     }
     else
     {
-        // 
-        // Get attribute value
-        //
-        TRI_LOG_STR("getattr()");
-        try
+        if (obj->getNumAttrs() > 0)
         {
-            attr = new H5::Attribute(obj->openAttribute(attr_name));
-
-            H5T_class_t typeclass = attr->getTypeClass();
-            TRI_LOG(typeclass);
-
-            if (typeclass == H5T_STRING)
-            {
-                string value;
-                H5::StrType tid(0, H5T_VARIABLE);
-                attr->read(tid, value);
-                cout << attr_name << " = " << value << endl;
-            }
-            else if (typeclass == H5T_INTEGER)
-            {
-                long value;
-                attr->read(H5::PredType::NATIVE_LONG, &value);
-                cout << attr_name << " = " << value << endl;
-            }
-            else if (typeclass == H5T_FLOAT)
-            {
-                double value;
-                attr->read(H5::PredType::NATIVE_DOUBLE, &value);
-                cout << attr_name << " = " << value << endl;
-            }
-            else
-            {
-                cout << "Error: No handler for typeclass " << typeclass << endl;
-            }
+            // print all attributes at location
+            obj->iterateAttrs(listOp);
         }
-        catch (H5::Exception error)
+        else
         {
-            cout << "Error: Could not get attribute '" << attr_name << "'" << endl;
-            if (verbose) { error.printError(); }
-            return -1;
+            cout << "No attributes are attached to '"
+                 << location << "' in file '"
+                 << filename << "'" << endl;
         }
-
     }
 
     // Clean up
-    if (attr) { delete attr; }
     if (obj) { delete obj; }
     if (file) { delete file; }
 



More information about the CIG-COMMITS mailing list