File indexing completed on 2024-05-12 03:47:02

0001 /*
0002     File                 : OriginParser.cpp
0003     Description          : Origin file parser base class
0004     --------------------------------------------------------------------
0005     SPDX-FileCopyrightText: 2008 Alex Kargovsky <kargovsky@yumr.phys.msu.su>
0006     SPDX-FileCopyrightText: 2017 Stefan Gerlach <stefan.gerlach@uni.kn>
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #include "OriginParser.h"
0011 #include <cctype>
0012 #include <locale>
0013 
0014 using namespace std;
0015 using namespace Origin;
0016 
0017 bool OriginParser::iequals(const string &s1, const string &s2, const std::locale &loc) const
0018 {
0019     bool equal = s1.size() == s2.size();
0020     for (unsigned int n = 0; n < s1.size() && equal; ++n) {
0021         if (std::toupper(s1[n], loc) != std::toupper(s2[n], loc))
0022             equal = false;
0023     }
0024     return equal;
0025 }
0026 
0027 vector<Origin::SpreadSheet>::difference_type
0028 OriginParser::findSpreadByName(const string &name) const
0029 {
0030     for (vector<SpreadSheet>::const_iterator it = spreadSheets.begin(); it != spreadSheets.end();
0031          ++it) {
0032         if (iequals(it->name, name, locale()))
0033             return it - spreadSheets.begin();
0034     }
0035     return -1;
0036 }
0037 
0038 vector<Origin::Excel>::difference_type OriginParser::findExcelByName(const string &name) const
0039 {
0040     for (vector<Excel>::const_iterator it = excels.begin(); it != excels.end(); ++it) {
0041         if (iequals(it->name, name, locale()))
0042             return it - excels.begin();
0043     }
0044     return -1;
0045 }
0046 
0047 vector<Origin::SpreadColumn>::difference_type
0048 OriginParser::findSpreadColumnByName(vector<Origin::SpreadSheet>::size_type spread,
0049                                      const string &name) const
0050 {
0051     for (vector<SpreadColumn>::const_iterator it = spreadSheets[spread].columns.begin();
0052          it != spreadSheets[spread].columns.end(); ++it) {
0053         if (it->name == name)
0054             return it - spreadSheets[spread].columns.begin();
0055     }
0056     return -1;
0057 }
0058 
0059 vector<Origin::SpreadColumn>::difference_type
0060 OriginParser::findExcelColumnByName(vector<Origin::Excel>::size_type excel,
0061                                     vector<Origin::SpreadSheet>::size_type sheet,
0062                                     const string &name) const
0063 {
0064     for (vector<SpreadColumn>::const_iterator it = excels[excel].sheets[sheet].columns.begin();
0065          it != excels[excel].sheets[sheet].columns.end(); ++it) {
0066         if (it->name == name)
0067             return it - excels[excel].sheets[sheet].columns.begin();
0068     }
0069     return -1;
0070 }
0071 
0072 vector<Origin::Matrix>::difference_type OriginParser::findMatrixByName(const string &name) const
0073 {
0074     for (vector<Matrix>::const_iterator it = matrixes.begin(); it != matrixes.end(); ++it) {
0075         if (iequals(it->name, name, locale()))
0076             return it - matrixes.begin();
0077     }
0078     return -1;
0079 }
0080 
0081 vector<Origin::Function>::difference_type OriginParser::findFunctionByName(const string &name) const
0082 {
0083     for (vector<Function>::const_iterator it = functions.begin(); it != functions.end(); ++it) {
0084         if (iequals(it->name, name, locale()))
0085             return it - functions.begin();
0086     }
0087     return -1;
0088 }
0089 
0090 pair<string, string> OriginParser::findDataByIndex(unsigned int index) const
0091 {
0092     for (vector<SpreadSheet>::const_iterator it = spreadSheets.begin(); it != spreadSheets.end();
0093          ++it) {
0094         for (vector<SpreadColumn>::const_iterator it1 = it->columns.begin();
0095              it1 != it->columns.end(); ++it1) {
0096             if (it1->index == index)
0097                 return make_pair("T_" + it->name, it1->name);
0098         }
0099     }
0100 
0101     for (vector<Matrix>::const_iterator it = matrixes.begin(); it != matrixes.end(); ++it) {
0102         for (vector<MatrixSheet>::const_iterator it1 = it->sheets.begin(); it1 != it->sheets.end();
0103              ++it1) {
0104             if (it1->index == index)
0105                 return make_pair("M_" + it->name, it1->name);
0106         }
0107     }
0108 
0109     for (vector<Excel>::const_iterator it = excels.begin(); it != excels.end(); ++it) {
0110         for (vector<SpreadSheet>::const_iterator it1 = it->sheets.begin(); it1 != it->sheets.end();
0111              ++it1) {
0112             for (vector<SpreadColumn>::const_iterator it2 = it1->columns.begin();
0113                  it2 != it1->columns.end(); ++it2) {
0114                 if (it2->index == index) {
0115                     int sheetno = (int)(it1 - it->sheets.begin()) + 1;
0116                     string sheetsuffix = string("@") + std::to_string(sheetno);
0117                     if (sheetno > 1)
0118                         return make_pair("E_" + it->name + sheetsuffix, it2->name);
0119                     else
0120                         return make_pair("E_" + it->name, it2->name);
0121                 }
0122             }
0123         }
0124     }
0125 
0126     for (vector<Function>::const_iterator it = functions.begin(); it != functions.end(); ++it) {
0127         if (it->index == index)
0128             return make_pair("F_" + it->name, it->name);
0129     }
0130 
0131     return pair<string, string>();
0132 }
0133 
0134 pair<ProjectNode::NodeType, string> OriginParser::findObjectByIndex(unsigned int index) const
0135 {
0136     for (vector<SpreadSheet>::const_iterator it = spreadSheets.begin(); it != spreadSheets.end();
0137          ++it) {
0138         if (it->objectID == (int)index)
0139             return make_pair(ProjectNode::SpreadSheet, it->name);
0140     }
0141 
0142     for (vector<Matrix>::const_iterator it = matrixes.begin(); it != matrixes.end(); ++it) {
0143         if (it->objectID == (int)index)
0144             return make_pair(ProjectNode::Matrix, it->name);
0145     }
0146 
0147     for (vector<Excel>::const_iterator it = excels.begin(); it != excels.end(); ++it) {
0148         if (it->objectID == (int)index)
0149             return make_pair(ProjectNode::Excel, it->name);
0150     }
0151 
0152     for (vector<Graph>::const_iterator it = graphs.begin(); it != graphs.end(); ++it) {
0153         if (it->objectID == (int)index) {
0154             if (it->is3D)
0155                 return make_pair(ProjectNode::Graph3D, it->name);
0156             else
0157                 return make_pair(ProjectNode::Graph, it->name);
0158         }
0159     }
0160 
0161     return pair<ProjectNode::NodeType, string>();
0162 }
0163 
0164 pair<ProjectNode::NodeType, Origin::Window>
0165 OriginParser::findWindowObjectByIndex(unsigned int index) const
0166 {
0167     for (vector<SpreadSheet>::const_iterator it = spreadSheets.begin(); it != spreadSheets.end();
0168          ++it) {
0169         if (it->objectID == (int)index)
0170             return make_pair(ProjectNode::SpreadSheet, (Origin::Window)(*it));
0171     }
0172 
0173     for (vector<Matrix>::const_iterator it = matrixes.begin(); it != matrixes.end(); ++it) {
0174         if (it->objectID == (int)index)
0175             return make_pair(ProjectNode::Matrix, (Origin::Window)(*it));
0176     }
0177 
0178     for (vector<Excel>::const_iterator it = excels.begin(); it != excels.end(); ++it) {
0179         if (it->objectID == (int)index)
0180             return make_pair(ProjectNode::Excel, (Origin::Window)(*it));
0181     }
0182 
0183     for (vector<Graph>::const_iterator it = graphs.begin(); it != graphs.end(); ++it) {
0184         if (it->objectID == (int)index) {
0185             if (it->is3D)
0186                 return make_pair(ProjectNode::Graph3D, (Origin::Window)(*it));
0187             else
0188                 return make_pair(ProjectNode::Graph, (Origin::Window)(*it));
0189         }
0190     }
0191 
0192     return pair<ProjectNode::NodeType, Origin::Window>();
0193 }
0194 
0195 void OriginParser::convertSpreadToExcel(vector<Origin::SpreadSheet>::size_type spread)
0196 {
0197     // add new Excel sheet
0198     excels.push_back(Excel(spreadSheets[spread].name, spreadSheets[spread].label,
0199                            spreadSheets[spread].maxRows, spreadSheets[spread].hidden,
0200                            spreadSheets[spread].loose));
0201 
0202     for (vector<SpreadColumn>::iterator it = spreadSheets[spread].columns.begin();
0203          it != spreadSheets[spread].columns.end(); ++it) {
0204         unsigned int index = 0;
0205         int pos = (int)(it->name.find_last_of("@"));
0206         if (pos != -1) {
0207             index = strtol(it->name.substr(pos + 1).c_str(), nullptr, 10) - 1;
0208             it->name = it->name.substr(0, pos);
0209         }
0210 
0211         if (excels.back().sheets.size() <= index)
0212             excels.back().sheets.resize(index + 1);
0213 
0214         excels.back().sheets[index].columns.push_back(*it);
0215     }
0216 
0217     spreadSheets.erase(spreadSheets.begin() + spread);
0218 }
0219 
0220 int OriginParser::findColumnByName(int spread, const string &name)
0221 {
0222     size_t columns = spreadSheets[spread].columns.size();
0223     for (unsigned int i = 0; i < columns; i++) {
0224         string colName = spreadSheets[spread].columns[i].name;
0225         if (colName.size() >= 11)
0226             colName.resize(11);
0227 
0228         if (name == colName)
0229             return i;
0230     }
0231     return -1;
0232 }