"Fossies" - the Fresh Open Source Software Archive

Member "labplot-2.8.2/src/backend/datasources/filters/AbstractFileFilter.cpp" (24 Feb 2021, 9145 Bytes) of package /linux/privat/labplot-2.8.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "AbstractFileFilter.cpp" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.8.1_vs_2.8.2.

    1 /***************************************************************************
    2 File                 : AbstractFileFilter.h
    3 Project              : LabPlot
    4 Description          : file I/O-filter related interface
    5 --------------------------------------------------------------------
    6 Copyright            : (C) 2009-2017 Alexander Semke (alexander.semke@web.de)
    7 Copyright            : (C) 2017 Stefan Gerlach (stefan.gerlach@uni.kn)
    8 ***************************************************************************/
    9 
   10 /***************************************************************************
   11  *                                                                         *
   12  *  This program is free software; you can redistribute it and/or modify   *
   13  *  it under the terms of the GNU General Public License as published by   *
   14  *  the Free Software Foundation; either version 2 of the License, or      *
   15  *  (at your option) any later version.                                    *
   16  *                                                                         *
   17  *  This program is distributed in the hope that it will be useful,        *
   18  *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
   19  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
   20  *  GNU General Public License for more details.                           *
   21  *                                                                         *
   22  *   You should have received a copy of the GNU General Public License     *
   23  *   along with this program; if not, write to the Free Software           *
   24  *   Foundation, Inc., 51 Franklin Street, Fifth Floor,                    *
   25  *   Boston, MA  02110-1301  USA                                           *
   26  *                                                                         *
   27  ***************************************************************************/
   28 
   29 #include "backend/datasources/filters/AbstractFileFilter.h"
   30 #include "backend/datasources/filters/NgspiceRawAsciiFilter.h"
   31 #include "backend/datasources/filters/NgspiceRawBinaryFilter.h"
   32 #include "backend/lib/macros.h"
   33 
   34 #include <QDateTime>
   35 #include <QImageReader>
   36 #include <QProcess>
   37 #include <QLocale>
   38 #include <KLocalizedString>
   39 
   40 bool AbstractFileFilter::isNan(const QString& s) {
   41     const static QStringList nanStrings{"NA", "NAN", "N/A", "-NA", "-NAN", "NULL"};
   42     if (nanStrings.contains(s, Qt::CaseInsensitive))
   43         return true;
   44 
   45     return false;
   46 }
   47 
   48 AbstractColumn::ColumnMode AbstractFileFilter::columnMode(const QString& valueString, const QString& dateTimeFormat, QLocale::Language lang) {
   49     return columnMode(valueString, dateTimeFormat, QLocale(lang));
   50 }
   51 
   52 /*!
   53  * return the column mode for the given value string and settings \c dateTimeFormat and \c locale.
   54  * in case \c dateTimeFormat is empty, all possible datetime formats are tried out to determine the valid datetime object.
   55  */
   56 AbstractColumn::ColumnMode AbstractFileFilter::columnMode(const QString& valueString, const QString& dateTimeFormat, const QLocale& locale) {
   57     //TODO: use BigInt as default integer?
   58     if (valueString.size() == 0)    // empty string treated as integer (meaning the non-empty strings will determine the data type)
   59         return AbstractColumn::ColumnMode::Integer;
   60 
   61     if (isNan(valueString))
   62         return AbstractColumn::ColumnMode::Numeric;
   63 
   64     // check if integer first
   65     bool ok;
   66     int intValue = locale.toInt(valueString, &ok);
   67     DEBUG(Q_FUNC_INFO << ", " << STDSTRING(valueString) << " : toInt " << intValue << " ?: " << ok);
   68     Q_UNUSED(intValue)
   69     if (ok || isNan(valueString))
   70         return AbstractColumn::ColumnMode::Integer;
   71 
   72     //check big integer
   73     qint64 bigIntValue = locale.toLongLong(valueString, &ok);
   74     DEBUG(Q_FUNC_INFO << ", " << STDSTRING(valueString) << " : toBigInt " << bigIntValue << " ?: " << ok);
   75     Q_UNUSED(bigIntValue)
   76     if (ok || isNan(valueString))
   77         return AbstractColumn::ColumnMode::BigInt;
   78 
   79     //try to convert to a double
   80     auto mode = AbstractColumn::ColumnMode::Numeric;
   81     double value = locale.toDouble(valueString, &ok);
   82     DEBUG(Q_FUNC_INFO << ", " << STDSTRING(valueString) << " : toDouble " << value << " ?: " << ok);
   83     Q_UNUSED(value)
   84 
   85     //if not a number, check datetime. if that fails: string
   86     if (!ok) {
   87         QDateTime valueDateTime;
   88         if (dateTimeFormat.isEmpty()) {
   89             for (const auto& format : AbstractColumn::dateTimeFormats()) {
   90                 valueDateTime = QDateTime::fromString(valueString, format);
   91                 if (valueDateTime.isValid())
   92                     break;
   93             }
   94         } else
   95             valueDateTime = QDateTime::fromString(valueString, dateTimeFormat);
   96 
   97         if (valueDateTime.isValid())
   98             mode = AbstractColumn::ColumnMode::DateTime;
   99         else {
  100             DEBUG(Q_FUNC_INFO << ", DATETIME invalid! String: " << STDSTRING(valueString) << " DateTime format: " << STDSTRING(dateTimeFormat))
  101             mode = AbstractColumn::ColumnMode::Text;
  102         }
  103     }
  104 
  105     return mode;
  106 }
  107 
  108 QString AbstractFileFilter::dateTimeFormat(const QString& valueString) {
  109     QDateTime valueDateTime;
  110     for (const auto& format : AbstractColumn::dateTimeFormats()) {
  111         valueDateTime = QDateTime::fromString(valueString, format);
  112         if (valueDateTime.isValid())
  113             return format;
  114     }
  115     return QLatin1String("yyyy-MM-dd hh:mm:ss.zzz");
  116 }
  117 
  118 /*
  119 returns the list of all supported locales for numeric data
  120 */
  121 QStringList AbstractFileFilter::numberFormats() {
  122     QStringList formats;
  123     for (int l = 0; l < ENUM_COUNT(QLocale, Language); ++l)
  124         formats << QLocale::languageToString((QLocale::Language)l);
  125 
  126     return formats;
  127 }
  128 
  129 AbstractFileFilter::FileType AbstractFileFilter::fileType(const QString& fileName) {
  130     QString fileInfo;
  131 #ifndef HAVE_WINDOWS
  132     //check, if we can guess the file type by content
  133     QProcess proc;
  134     proc.start("file", QStringList() << "-b" << "-z" << fileName);
  135     if (!proc.waitForFinished(1000)) {
  136         proc.kill();
  137         DEBUG("ERROR: reading file type of file" << STDSTRING(fileName));
  138         return FileType::Binary;
  139     }
  140     fileInfo = proc.readLine();
  141 #endif
  142 
  143     FileType fileType;
  144     QByteArray imageFormat = QImageReader::imageFormat(fileName);
  145     if (fileInfo.contains(QLatin1String("JSON")) || fileName.endsWith(QLatin1String("json"), Qt::CaseInsensitive)
  146         //json file can be compressed. add all formats supported by KFilterDev, \sa KCompressionDevice::CompressionType
  147         || fileName.endsWith(QLatin1String("json.gz"), Qt::CaseInsensitive)
  148         || fileName.endsWith(QLatin1String("json.bz2"), Qt::CaseInsensitive)
  149         || fileName.endsWith(QLatin1String("json.lzma"), Qt::CaseInsensitive)
  150         || fileName.endsWith(QLatin1String("json.xz"), Qt::CaseInsensitive)
  151         || fileName.endsWith(QLatin1String("har"), Qt::CaseInsensitive) ) {
  152         //*.json files can be recognized as ASCII. so, do the check for the json-extension as first.
  153         fileType = FileType::JSON;
  154     } else if (fileInfo.contains(QLatin1String("ASCII"))
  155         || fileName.endsWith(QLatin1String("txt"), Qt::CaseInsensitive)
  156         || fileName.endsWith(QLatin1String("csv"), Qt::CaseInsensitive)
  157         || fileName.endsWith(QLatin1String("dat"), Qt::CaseInsensitive)
  158         || fileInfo.contains(QLatin1String("compressed data"))/* for gzipped ascii data */ ) {
  159         if (NgspiceRawAsciiFilter::isNgspiceAsciiFile(fileName))
  160             fileType = FileType::NgspiceRawAscii;
  161         else //probably ascii data
  162             fileType = FileType::Ascii;
  163     }
  164 #ifdef HAVE_HDF5
  165     else if (fileInfo.contains(QLatin1String("Hierarchical Data Format"))
  166         || fileName.endsWith(QLatin1String("h5"), Qt::CaseInsensitive)
  167         || fileName.endsWith(QLatin1String("hdf"), Qt::CaseInsensitive)
  168         || fileName.endsWith(QLatin1String("hdf5"), Qt::CaseInsensitive) )
  169         fileType = FileType::HDF5;
  170 #endif
  171 #ifdef HAVE_NETCDF
  172     else if (fileInfo.contains(QLatin1String("NetCDF Data Format"))
  173         || fileName.endsWith(QLatin1String("nc"), Qt::CaseInsensitive)
  174         || fileName.endsWith(QLatin1String("netcdf"), Qt::CaseInsensitive)
  175         || fileName.endsWith(QLatin1String("cdf"), Qt::CaseInsensitive))
  176         fileType = FileType::NETCDF;
  177 #endif
  178 #ifdef HAVE_FITS
  179     else if (fileInfo.contains(QLatin1String("FITS image data"))
  180         || fileName.endsWith(QLatin1String("fits"), Qt::CaseInsensitive)
  181         || fileName.endsWith(QLatin1String("fit"), Qt::CaseInsensitive)
  182         || fileName.endsWith(QLatin1String("fts"), Qt::CaseInsensitive))
  183         fileType = FileType::FITS;
  184 #endif
  185 #ifdef HAVE_ZIP
  186     else if (fileInfo.contains(QLatin1String("ROOT")) //can be "ROOT Data Format" or "ROOT file Version ??? (Compression: 1)"
  187         ||  fileName.endsWith(QLatin1String("root"), Qt::CaseInsensitive)) // TODO find out file description
  188         fileType = FileType::ROOT;
  189 #endif
  190     else if (fileInfo.contains("image") || fileInfo.contains("bitmap") || !imageFormat.isEmpty())
  191         fileType = FileType::Image;
  192     else if (NgspiceRawBinaryFilter::isNgspiceBinaryFile(fileName))
  193         fileType = FileType::NgspiceRawBinary;
  194     else
  195         fileType = FileType::Binary;
  196 
  197     return fileType;
  198 }
  199 
  200 /*!
  201   returns the list of all supported data file formats
  202 */
  203 QStringList AbstractFileFilter::fileTypes() {
  204     return (QStringList() << i18n("ASCII data")
  205         << i18n("Binary data")
  206         << i18n("Image")
  207         << i18n("Hierarchical Data Format 5 (HDF5)")
  208         << i18n("Network Common Data Format (NetCDF)")
  209         << i18n("Flexible Image Transport System Data Format (FITS)")
  210         << i18n("JSON data")
  211         << i18n("ROOT (CERN) Histograms")
  212         << "Ngspice RAW ASCII"
  213         << "Ngspice RAW Binary"
  214     );
  215 }