File indexing completed on 2024-03-24 15:18:46

0001 /***************************************************************************
0002     File                 : OriginFile.cpp
0003     --------------------------------------------------------------------
0004     Copyright            : (C) 2005-2008, 2017 Stefan Gerlach
0005     Copyright            : (C) 2007-2008 Alex Kargovsky, Ion Vasilief
0006     Email (use @ for *)  : kargovsky*yumr.phys.msu.su, ion_vasilief*yahoo.fr
0007     Description          : Origin file import class
0008 
0009  ***************************************************************************/
0010 
0011 /***************************************************************************
0012  *                                                                         *
0013  *  This program is free software; you can redistribute it and/or modify   *
0014  *  it under the terms of the GNU General Public License as published by   *
0015  *  the Free Software Foundation; either version 2 of the License, or      *
0016  *  (at your option) any later version.                                    *
0017  *                                                                         *
0018  *  This program is distributed in the hope that it will be useful,        *
0019  *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
0020  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
0021  *  GNU General Public License for more details.                           *
0022  *                                                                         *
0023  *   You should have received a copy of the GNU General Public License     *
0024  *   along with this program; if not, write to the Free Software           *
0025  *   Foundation, Inc., 51 Franklin Street, Fifth Floor,                    *
0026  *   Boston, MA  02110-1301  USA                                           *
0027  *                                                                         *
0028  ***************************************************************************/
0029 
0030 #include "config.h"
0031 #include "OriginFile.h"
0032 #include <fstream>
0033 #include <string>
0034 
0035 OriginFile::OriginFile(const string& fileName)
0036 :   fileVersion(0), buildVersion(0), ioError(0)
0037 {
0038     ifstream file(fileName.c_str(), ios_base::binary);
0039 
0040     if (!file.is_open())
0041     {
0042         ioError = errno;
0043         return;
0044     }
0045 
0046 #ifdef GENERATE_CODE_FOR_LOG
0047     FILE *logfile = nullptr;
0048     logfile = fopen("./opjfile.log", "w");
0049     if (logfile == nullptr)
0050     {
0051         ioError = errno;
0052         return;
0053     }
0054 #endif // GENERATE_CODE_FOR_LOG
0055 
0056     string vers;
0057     getline(file, vers);
0058     long majorVersion = strtol(vers.substr(5,1).c_str(),nullptr,10);
0059     //char locale_decpoint = vers[6];
0060     buildVersion = strtol(vers.substr(7).c_str(),nullptr,10);
0061     //long buildNumber = strtol(vers.substr(12).c_str(),0,10);
0062     file.close();
0063 
0064     LOG_PRINT(logfile, "File: %s\n", fileName.c_str())
0065 
0066     // translate version
0067     unsigned int newFileVersion = 0;
0068     if (majorVersion == 3) {
0069         if (buildVersion < 830)
0070             fileVersion = 350;
0071         else
0072             fileVersion = 410;
0073     } else if (buildVersion >= 110 && buildVersion <= 141) // 4.1
0074         fileVersion = 410;
0075     else if (buildVersion <= 210) // 5.0
0076         fileVersion = 500;
0077     else if (buildVersion < 2624) // 6.0
0078         fileVersion = 600;
0079     else if (buildVersion < 2628) // 6.0 SR1
0080         fileVersion = 601;
0081     else if (buildVersion < 2635) // 6.0 SR4
0082         fileVersion = 604;
0083     else if (buildVersion < 2656) // 6.1
0084         fileVersion = 610;
0085     else if (buildVersion < 2659) // 7.0 SR0 (2656-2658)
0086         fileVersion = 700;
0087     else if (buildVersion < 2664) // 7.0 SR1 (2659-2663)
0088         fileVersion = 701;
0089     else if (buildVersion < 2672) // 7.0 SR2 (2664-2671)
0090         fileVersion = 702;
0091     else if (buildVersion < 2673) // 7.0 SR3 (2672-2672)
0092         fileVersion = 703;
0093     else if (buildVersion < 2766) // 7.0 SR4 (2673-2765)
0094         fileVersion = 704;
0095     else if (buildVersion < 2878) // 7.5 (2766-2877)
0096         fileVersion = 750;
0097     else if (buildVersion < 2881) // 8.0 SR0 (2878-2880)
0098         fileVersion = 800;
0099     else if (buildVersion < 2892) // 8.0 SR1,SR2,SR3 (2878-2891)
0100         fileVersion = 801;
0101     else if (buildVersion < 2944) // 8.0 SR4, 8.1 SR1-SR4 (2891-2943)
0102         fileVersion = 810;
0103     else if (buildVersion < 2947) // 8.5 SR0, SR1 (2944-2946)
0104         fileVersion = 850;
0105     else if (buildVersion < 2962) // 8.5.1 SR0, SR1, SR2
0106         fileVersion = 851;
0107     else if (buildVersion < 2980) // 8.6 SR0, SR1, SR2, SR3
0108         fileVersion = 860;
0109     else if (buildVersion < 3025) // 9.0 SR0, SR1, SR2
0110         fileVersion = 900;
0111     else if (buildVersion < 3078) // 9.1 SR0, SR1, SR2, SR3
0112         fileVersion = 910;
0113     else if (buildVersion < 3117) { // 2015 (9.2) SR0, SR1, SR2
0114         fileVersion = 920;
0115         newFileVersion = 20150;
0116     } else if (buildVersion < 3169) { // 2016 (9.3.0) SR0
0117         fileVersion = 930;
0118         newFileVersion = 20160;
0119     } else if (buildVersion < 3172) { // 2016.1 (9.3.1), 2016.2 (9.3.2) SR1, SR2
0120         fileVersion = 931;
0121         newFileVersion = 20161;
0122     } else if (buildVersion < 3225) { // 2017.0 (9.4.0.220) SR0 3224
0123         fileVersion = 940;
0124         newFileVersion = 20170;
0125     } else if (buildVersion < 3228) { // 2017.1 (9.4.1.354), 2017.2 (9.4.2.380) SR1, SR2 3227
0126         fileVersion = 941;
0127         newFileVersion = 20171;
0128     } else if (buildVersion < 3269) { // 2018.0 (9.5.0.193), 2018.1 (9.5.1.195) SR0, SR1 3268
0129         fileVersion = 950;
0130         newFileVersion = 20180;
0131     } else if (buildVersion < 3296) { // 2018b.0 (9.5.5.409) SR0, SR1 3295
0132         fileVersion = 955;
0133         newFileVersion = 20185;
0134     } else if (buildVersion < 3331) { // 2019.0 (9.6.0.172) SR0 3330
0135         fileVersion = 960;
0136         newFileVersion = 20190;
0137     } else if (buildVersion < 3360) { // 2019b.0 (9.6.5.169) SR0 3359
0138         fileVersion = 965;
0139         newFileVersion = 20195;
0140     } else {
0141         // > 2019bSR0
0142         fileVersion = 966;
0143         newFileVersion = 20196;
0144         LOG_PRINT(logfile, "Found project version 2019b.1 (9.6.6) or newer\n")
0145     }
0146 
0147     if (newFileVersion == 0) {
0148         LOG_PRINT(logfile, "Found project version %.2f\n", fileVersion/100.0)
0149     } else if (fileVersion < 941) {
0150         LOG_PRINT(logfile, "Found project version %.1f (%.2f)\n", newFileVersion/10.0, fileVersion/100.0)
0151     }
0152 
0153     // Close logfile, will be reopened in parser routine.
0154     // There are ways to keep logfile open and pass it to parser routine,
0155     // but I choose to do the same as with 'file', close it and reopen in 'parse'
0156     // routines.
0157 #ifdef GENERATE_CODE_FOR_LOG
0158     fclose(logfile);
0159 #endif // GENERATE_CODE_FOR_LOG
0160     parser.reset(createOriginAnyParser(fileName));
0161     ioError=0;
0162 }
0163 
0164 bool OriginFile::parse()
0165 {
0166     if (ioError != 0)
0167         return false;
0168     parser->buildVersion = buildVersion;
0169     parser->fileVersion = fileVersion;
0170     return parser->parse();
0171 }
0172 
0173 double OriginFile::version() const
0174 {
0175     return (parser->fileVersion)/100.0;
0176 }
0177 
0178 const tree<Origin::ProjectNode>* OriginFile::project() const
0179 {
0180     return &parser->projectTree;
0181 }
0182 
0183 vector<Origin::SpreadColumn>::size_type OriginFile::datasetCount() const
0184 {
0185     return parser->datasets.size();
0186 }
0187 
0188 Origin::SpreadColumn& OriginFile::dataset(vector<Origin::SpreadColumn>::size_type ds) const
0189 {
0190     return parser->datasets[ds];
0191 }
0192 
0193 vector<Origin::SpreadSheet>::size_type OriginFile::spreadCount() const
0194 {
0195     return parser->spreadSheets.size();
0196 }
0197 
0198 Origin::SpreadSheet& OriginFile::spread(vector<Origin::SpreadSheet>::size_type s) const
0199 {
0200     return parser->spreadSheets[s];
0201 }
0202 
0203 vector<Origin::Matrix>::size_type OriginFile::matrixCount() const
0204 {
0205     return parser->matrixes.size();
0206 }
0207 
0208 Origin::Matrix& OriginFile::matrix(vector<Origin::Matrix>::size_type m) const
0209 {
0210     return parser->matrixes[m];
0211 }
0212 
0213 vector<Origin::Function>::size_type OriginFile::functionCount() const
0214 {
0215     return parser->functions.size();
0216 }
0217 
0218 vector<Origin::Function>::difference_type OriginFile::functionIndex(const string& name) const
0219 {
0220     return parser->findFunctionByName(name);
0221 }
0222 
0223 Origin::Function& OriginFile::function(vector<Origin::Function>::size_type f) const
0224 {
0225     return parser->functions[f];
0226 }
0227 
0228 vector<Origin::Graph>::size_type OriginFile::graphCount() const
0229 {
0230     return parser->graphs.size();
0231 }
0232 
0233 Origin::Graph& OriginFile::graph(vector<Origin::Graph>::size_type g) const
0234 {
0235     return parser->graphs[g];
0236 }
0237 
0238 vector<Origin::Note>::size_type OriginFile::noteCount() const
0239 {
0240     return parser->notes.size();
0241 }
0242 
0243 Origin::Note& OriginFile::note(vector<Origin::Note>::size_type n) const
0244 {
0245     return parser->notes[n];
0246 }
0247 
0248 vector<Origin::Excel>::size_type OriginFile::excelCount() const
0249 {
0250     return parser->excels.size();
0251 }
0252 
0253 Origin::Excel& OriginFile::excel(vector<Origin::Excel>::size_type e) const
0254 {
0255     return parser->excels[e];
0256 }
0257 
0258 string OriginFile::resultsLogString() const
0259 {
0260     return parser->resultsLog;
0261 }
0262 
0263 string liboriginVersionString() { return LIBORIGIN_VERSION_STRING; }
0264 
0265 unsigned int liboriginVersion() { return LIBORIGIN_VERSION; }
0266 
0267 unsigned int liboriginVersionMajor() { return LIBORIGIN_VERSION_MAJOR; }
0268 
0269 unsigned int liboriginVersionMinor() { return LIBORIGIN_VERSION_MINOR; }
0270 
0271 unsigned int liboriginVersionBugfix() { return LIBORIGIN_VERSION_BUGFIX; }