From 2cd61f6059f4111747780aac3d95672a46a59caa Mon Sep 17 00:00:00 2001
From: Thomas Fischer <thomas.fischer@ufz.de>
Date: Fri, 11 Jan 2019 13:14:47 +0100
Subject: [PATCH] [GO2OGS] Impl. of Property.

---
 Applications/FileIO/GocadIO/Property.cpp | 150 +++++++++++++++++++++++
 Applications/FileIO/GocadIO/Property.h   |  51 ++++++++
 2 files changed, 201 insertions(+)
 create mode 100644 Applications/FileIO/GocadIO/Property.cpp
 create mode 100644 Applications/FileIO/GocadIO/Property.h

diff --git a/Applications/FileIO/GocadIO/Property.cpp b/Applications/FileIO/GocadIO/Property.cpp
new file mode 100644
index 00000000000..e185ea29158
--- /dev/null
+++ b/Applications/FileIO/GocadIO/Property.cpp
@@ -0,0 +1,150 @@
+/**
+ *
+ * @copyright
+ * Copyright (c) 2012-2019, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/LICENSE.txt
+ */
+
+#include <algorithm>
+#include <iterator>
+#include <sstream>
+
+#include <boost/tokenizer.hpp>
+
+#include "Property.h"
+
+#include "BaseLib/StringTools.h"
+
+namespace FileIO
+{
+namespace Gocad
+{
+
+std::ostream& operator<<(std::ostream& os, Property const& p)
+{
+    return os << "'" << p._property_name << "' '" << p._property_id << "' '"
+              << p._property_data_type << "' '" << p._property_data_fname
+              << "'";
+}
+
+Property parseGocadPropertyMetaData(std::string& line, std::istream& in,
+                                    std::string const& path)
+{
+    boost::char_separator<char> sep("\t ");
+    boost::tokenizer<boost::char_separator<char>> tokens(line, sep);
+    auto tok_it(tokens.begin());
+    // A property section in Gocad file starts with a line
+    // PROPERTY id "property_name"
+    if (*tok_it != "PROPERTY")
+    {
+        ERR("Expected PROPERTY keyword but '%s' found.", tok_it->c_str());
+        throw std::runtime_error(
+            "In parseGocadPropertyMetaData() expected PROPERTY keyword not "
+            "found.");
+    }
+    tok_it++;
+
+    Property prop;
+    prop._property_id = std::stoul(*tok_it);
+    tok_it++;
+    prop._property_name = *tok_it;
+    tok_it++;
+    while (tok_it != tokens.end())
+    {
+        prop._property_name += " " + *tok_it;
+        tok_it++;
+    }
+    BaseLib::trim(prop._property_name, '\"');
+
+    auto checkPropertyID =
+        [](boost::tokenizer<boost::char_separator<char>>::iterator& tok_it,
+           Property const& prop) {
+            if (!prop.checkID(*tok_it))
+            {
+                throw std::runtime_error(
+                    "parseGocadPropertyMetaData(): id mismatch.");
+            }
+        };
+
+    while (std::getline(in, line))
+    {
+        if (line.empty())
+        {
+            continue;
+        }
+        if (line.back() == '\r')
+        {
+            line.pop_back();
+        }
+        tokens.assign(line);
+
+        tok_it = tokens.begin();
+        // this is the last entry of the property
+        if (*tok_it == "PROP_FILE")
+        {
+            checkPropertyID(++tok_it, prop);
+            tok_it++;
+            std::string tmp(*tok_it);
+            tok_it++;
+            while (tok_it != tokens.end())
+            {
+                tmp += " " + *tok_it;
+                tok_it++;
+            }
+            BaseLib::trim(tmp, '\"');
+            if (tmp.front() == ' ')
+            {
+                tmp.erase(tmp.begin());
+            }
+            prop._property_data_fname = path + tmp;
+            return prop;
+        }
+
+        if (*tok_it == "PROPERTY_CLASS")
+        {
+            checkPropertyID(++tok_it, prop);
+            tok_it++;
+            prop._property_class_name = *tok_it;
+        }
+
+        if (*tok_it == "PROPERTY_SUBCLASS")
+        {
+            checkPropertyID(++tok_it, prop);
+            tok_it++;
+            if (*tok_it != "QUANTITY" && *tok_it != "ENUM")
+            {
+                ERR("Expected keywords QUANTITY or ENUM, but found '%s'.",
+                    tok_it->c_str());
+                throw std::runtime_error(
+                    "parseGocadPropertyMetaData(): Expected keywords QUANTITY "
+                    "or ENUM, but found '" +
+                    *tok_it + "'.");
+            }
+            if (*tok_it == "QUANTITY")
+            {
+                tok_it++;
+                prop._property_data_type = *tok_it;
+            }
+        }
+
+        if (*tok_it == "PROP_UNIT" || *tok_it == "PROP_ORIGINAL_UNIT")
+        {
+            checkPropertyID(++tok_it, prop);
+            tok_it++;
+            prop._property_unit = *tok_it;
+        }
+
+        if (*tok_it == "PROP_NO_DATA_VALUE")
+        {
+            checkPropertyID(++tok_it, prop);
+            tok_it++;
+            prop._property_no_data_value = std::stoul(*tok_it);
+        }
+    }
+    return prop;
+}
+
+}  // end namespace Gocad
+}  // end namespace FileIO
diff --git a/Applications/FileIO/GocadIO/Property.h b/Applications/FileIO/GocadIO/Property.h
new file mode 100644
index 00000000000..e2ef25c0c17
--- /dev/null
+++ b/Applications/FileIO/GocadIO/Property.h
@@ -0,0 +1,51 @@
+/**
+ *
+ * @copyright
+ * Copyright (c) 2012-2019, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/LICENSE.txt
+ */
+
+#pragma once
+
+#include <cstddef>
+#include <string>
+
+#include <logog/include/logog.hpp>
+
+namespace FileIO
+{
+namespace Gocad
+{
+struct Property final
+{
+    std::size_t _property_id{};
+    std::string _property_name;
+    std::string _property_class_name;
+    std::string _property_unit;
+    std::string _property_data_type;
+    std::string _property_data_fname;
+    double _property_no_data_value{};
+
+    bool checkID(std::string const& id_string) const
+    {
+        if (_property_id != std::stoul(id_string))
+        {
+            ERR("Expected property id %d but found %d.",
+                _property_id,
+                std::stoul(id_string));
+            return false;
+        }
+        return true;
+    }
+
+    std::vector<double> _property_data;
+};
+
+std::ostream& operator<<(std::ostream& os, Property const& p);
+
+Property parseGocadPropertyMetaData(std::string& line, std::istream& in,
+                                    std::string const& path);
+}  // end namespace Gocad
+}  // end namespace FileIO
-- 
GitLab