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

0001 
0002 /*
0003     File                 : OriginFile.cpp
0004     Description          : Origin file import class
0005     --------------------------------------------------------------------
0006     SPDX-FileCopyrightText: 2005-2008, 2017-2023 Stefan Gerlach <stefan.gerlach@uni.kn>
0007     SPDX-FileCopyrightText: 2007-2008 Alex Kargovsky <kargovsky*yumr.phys.msu.su>
0008     SPDX-FileCopyrightText: 2007-2008 Ion Vasilief <ion_vasilief*yahoo.fr>
0009     SPDX-License-Identifier: GPL-2.0-or-later
0010 */
0011 
0012 #include "config.h"
0013 #include "OriginFile.h"
0014 
0015 #include <fstream>
0016 #include <string>
0017 
0018 using namespace std;
0019 
0020 OriginFile::OriginFile(const string &fileName) : fileVersion(0), buildVersion(0), ioError(0)
0021 {
0022     ifstream file(fileName.c_str(), ios_base::binary);
0023 
0024     if (!file.is_open()) {
0025         ioError = errno;
0026         return;
0027     }
0028 
0029 #ifdef GENERATE_CODE_FOR_LOG
0030     FILE *logfile = nullptr;
0031     logfile = fopen("./opjfile.log", "w");
0032     if (logfile == nullptr) {
0033         ioError = errno;
0034         return;
0035     }
0036 #endif // GENERATE_CODE_FOR_LOG
0037     LOG_PRINT(logfile, "File: %s\n", fileName.c_str())
0038 
0039     string vers;
0040     getline(file, vers);
0041     file.close();
0042 
0043     long majorVersion = strtol(vers.substr(5, 1).c_str(), nullptr, 10);
0044     // char locale_decpoint = vers[6];
0045     buildVersion = strtol(vers.substr(7).c_str(), nullptr, 10);
0046     // long buildNumber = strtol(vers.substr(12).c_str(),0,10);
0047 
0048     // translate version
0049     // see https://www.originlab.com/index.aspx?go=SUPPORT&pid=3325
0050     unsigned int newFileVersion = 0;
0051     if (majorVersion == 3) {
0052         if (buildVersion < 830)
0053             fileVersion = 350;
0054         else
0055             fileVersion = 410;
0056     } else if (buildVersion >= 110 && buildVersion <= 141) // 4.1
0057         fileVersion = 410;
0058     else if (buildVersion <= 210) // 5.0
0059         fileVersion = 500;
0060     else if (buildVersion < 2624) // 6.0
0061         fileVersion = 600;
0062     else if (buildVersion < 2628) // 6.0 SR1
0063         fileVersion = 601;
0064     else if (buildVersion < 2635) // 6.0 SR4
0065         fileVersion = 604;
0066     else if (buildVersion < 2656) // 6.1
0067         fileVersion = 610;
0068     else if (buildVersion < 2659) // 7.0 SR0 (2656-2658)
0069         fileVersion = 700;
0070     else if (buildVersion < 2664) // 7.0 SR1 (2659-2663)
0071         fileVersion = 701;
0072     else if (buildVersion < 2672) // 7.0 SR2 (2664-2671)
0073         fileVersion = 702;
0074     else if (buildVersion < 2673) // 7.0 SR3 (2672-2672)
0075         fileVersion = 703;
0076     else if (buildVersion < 2766) // 7.0 SR4 (2673-2765)
0077         fileVersion = 704;
0078     else if (buildVersion < 2878) // 7.5 (2766-2877)
0079         fileVersion = 750;
0080     else if (buildVersion < 2881) // 8.0 SR0 (2878-2880)
0081         fileVersion = 800;
0082     else if (buildVersion < 2892) // 8.0 SR1,SR2,SR3 (2878-2891)
0083         fileVersion = 801;
0084     else if (buildVersion < 2944) // 8.0 SR4, 8.1 SR1-SR4 (2891-2943)
0085         fileVersion = 810;
0086     else if (buildVersion < 2947) // 8.5 SR0, SR1 (2944-2946)
0087         fileVersion = 850;
0088     else if (buildVersion < 2962) // 8.5.1 SR0, SR1, SR2
0089         fileVersion = 851;
0090     else if (buildVersion < 2980) // 8.6 SR0, SR1, SR2, SR3
0091         fileVersion = 860;
0092     else if (buildVersion < 3025) // 9.0 SR0, SR1, SR2
0093         fileVersion = 900;
0094     else if (buildVersion < 3078) // 9.1 SR0, SR1, SR2, SR3
0095         fileVersion = 910;
0096     else if (buildVersion < 3117) { // 2015 (9.2) SR0, SR1, SR2
0097         fileVersion = 920;
0098         newFileVersion = 20150;
0099     } else if (buildVersion < 3169) { // 2016 (9.3.0) SR0
0100         fileVersion = 930;
0101         newFileVersion = 20160;
0102     } else if (buildVersion < 3172) { // 2016.1 (9.3.1), 2016.2 (9.3.2) SR1, SR2
0103         fileVersion = 931;
0104         newFileVersion = 20161;
0105     } else if (buildVersion < 3225) { // 2017.0 (9.4.0.220) SR0 3224
0106         fileVersion = 940;
0107         newFileVersion = 20170;
0108     } else if (buildVersion < 3228) { // 2017.1 (9.4.1.354), 2017.2 (9.4.2.380) SR1, SR2 3227
0109         fileVersion = 941;
0110         newFileVersion = 20171;
0111     } else if (buildVersion < 3269) { // 2018.0 (9.5.0.193), 2018.1 (9.5.1.195) SR0, SR1 3268
0112         fileVersion = 950;
0113         newFileVersion = 20180;
0114     } else if (buildVersion < 3296) { // 2018b.0 (9.5.5.409) SR0, SR1 3295
0115         fileVersion = 955;
0116         newFileVersion = 20185;
0117     } else if (buildVersion < 3331) { // 2019.0 (9.6.0.172) SR0 3330
0118         fileVersion = 960;
0119         newFileVersion = 20190;
0120     } else if (buildVersion < 3360) { // 2019b.0 (9.6.5.169) SR0 3359
0121         fileVersion = 965;
0122         newFileVersion = 20195;
0123     } else if (buildVersion < 3381) { // 2020.0 (9.7.0.185), 2020.1 (9.7.0.188) SR0, SR1 3380
0124         fileVersion = 970;
0125         newFileVersion = 20200;
0126     } else if (buildVersion < 3426) { // 2020b.0 (9.7.5.184) SR0 3425
0127         fileVersion = 975;
0128         newFileVersion = 20205;
0129     } else if (buildVersion < 3446) { // 2021.0 (9.8.0.200) SR0 3445
0130         fileVersion = 980;
0131         newFileVersion = 20210;
0132     } else if (buildVersion < 3479) { // 2021b.0 (9.8.5.201), 2021b.1 (9.8.5.204), 2021b.2
0133                                       // (9.8.5.212) SR0, SR1, SR2 3478
0134         fileVersion = 985;
0135         newFileVersion = 20215;
0136     } else if (buildVersion < 3522) { // 2022 (9.90.220) SR0
0137         fileVersion = 990;
0138         newFileVersion = 20220;
0139     } else if (buildVersion < 3523) { // 2022 (9.90.225) SR1
0140         fileVersion = 990;
0141         newFileVersion = 20221;
0142     } else if (buildVersion < 3552) { // 2022b (9.95.167) SR0, OriginViewer 9.9.5 (9.95.63) 3534
0143         fileVersion = 995;
0144         newFileVersion = 20225;
0145         // 2023 does not support OPJ anymore, but newer OriginViewer may do.
0146     } else {
0147         // > 2022b
0148         fileVersion = 1000;
0149         newFileVersion = 20230;
0150         LOG_PRINT(logfile, "Found project version 2023 (10.0.0) or newer\n")
0151     }
0152 
0153     if (newFileVersion == 0) {
0154         LOG_PRINT(logfile, "Found project version %.2f\n", fileVersion / 100.0)
0155     } else if (fileVersion < 941) {
0156         LOG_PRINT(logfile, "Found project version %.1f (%.2f)\n", newFileVersion / 10.0,
0157                   fileVersion / 100.0)
0158     }
0159 
0160     // Close logfile, will be reopened in parser routine.
0161     // There are ways to keep logfile open and pass it to parser routine,
0162     // but I choose to do the same as with 'file', close it and reopen in 'parse'
0163     // routines.
0164     parser.reset(createOriginAnyParser(fileName));
0165     ioError = 0;
0166 
0167 #ifdef GENERATE_CODE_FOR_LOG
0168     fclose(logfile);
0169 #endif
0170 }
0171 
0172 bool OriginFile::parse()
0173 {
0174     if (ioError != 0)
0175         return false;
0176     parser->buildVersion = buildVersion;
0177     parser->fileVersion = fileVersion;
0178     return parser->parse();
0179 }
0180 
0181 double OriginFile::version() const
0182 {
0183     return (parser->fileVersion) / 100.0;
0184 }
0185 
0186 const tree<Origin::ProjectNode> *OriginFile::project() const
0187 {
0188     return &parser->projectTree;
0189 }
0190 
0191 vector<Origin::SpreadColumn>::size_type OriginFile::datasetCount() const
0192 {
0193     return parser->datasets.size();
0194 }
0195 
0196 Origin::SpreadColumn &OriginFile::dataset(vector<Origin::SpreadColumn>::size_type ds) const
0197 {
0198     return parser->datasets[ds];
0199 }
0200 
0201 vector<Origin::SpreadSheet>::size_type OriginFile::spreadCount() const
0202 {
0203     return parser->spreadSheets.size();
0204 }
0205 
0206 Origin::SpreadSheet &OriginFile::spread(vector<Origin::SpreadSheet>::size_type s) const
0207 {
0208     return parser->spreadSheets[s];
0209 }
0210 
0211 vector<Origin::Matrix>::size_type OriginFile::matrixCount() const
0212 {
0213     return parser->matrixes.size();
0214 }
0215 
0216 Origin::Matrix &OriginFile::matrix(vector<Origin::Matrix>::size_type m) const
0217 {
0218     return parser->matrixes[m];
0219 }
0220 
0221 vector<Origin::Function>::size_type OriginFile::functionCount() const
0222 {
0223     return parser->functions.size();
0224 }
0225 
0226 vector<Origin::Function>::difference_type OriginFile::functionIndex(const string &name) const
0227 {
0228     return parser->findFunctionByName(name);
0229 }
0230 
0231 Origin::Function &OriginFile::function(vector<Origin::Function>::size_type f) const
0232 {
0233     return parser->functions[f];
0234 }
0235 
0236 vector<Origin::Graph>::size_type OriginFile::graphCount() const
0237 {
0238     return parser->graphs.size();
0239 }
0240 
0241 Origin::Graph &OriginFile::graph(vector<Origin::Graph>::size_type g) const
0242 {
0243     return parser->graphs[g];
0244 }
0245 
0246 vector<Origin::Note>::size_type OriginFile::noteCount() const
0247 {
0248     return parser->notes.size();
0249 }
0250 
0251 Origin::Note &OriginFile::note(vector<Origin::Note>::size_type n) const
0252 {
0253     return parser->notes[n];
0254 }
0255 
0256 vector<Origin::Excel>::size_type OriginFile::excelCount() const
0257 {
0258     return parser->excels.size();
0259 }
0260 
0261 Origin::Excel &OriginFile::excel(vector<Origin::Excel>::size_type e) const
0262 {
0263     return parser->excels[e];
0264 }
0265 
0266 string OriginFile::resultsLogString() const
0267 {
0268     return parser->resultsLog;
0269 }
0270 
0271 string liboriginVersionString()
0272 {
0273     return LIBORIGIN_VERSION_STRING;
0274 }
0275 
0276 unsigned int liboriginVersion()
0277 {
0278     return LIBORIGIN_VERSION;
0279 }
0280 
0281 unsigned int liboriginVersionMajor()
0282 {
0283     return LIBORIGIN_VERSION_MAJOR;
0284 }
0285 
0286 unsigned int liboriginVersionMinor()
0287 {
0288     return LIBORIGIN_VERSION_MINOR;
0289 }
0290 
0291 unsigned int liboriginVersionPatch()
0292 {
0293     return LIBORIGIN_VERSION_PATCH;
0294 }