Kstars

ksfilereader.h
1 /*
2  SPDX-FileCopyrightText: 2007 James B. Bowlin <[email protected]>
3 
4  SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #pragma once
8 
9 #include <QFile>
10 #include <QObject>
11 #include <QTextStream>
12 
13 class QString;
14 
15 /**
16  * @class KSFileReader
17  * I totally rewrote this because the earlier scheme of reading all the lines of
18  * a file into a buffer before processing is actually extremely inefficient
19  * because it makes it impossible to interleave file reading and data processing
20  * which all modern computers can do. It also force large data files to be
21  * split up into many smaller files which made dealing with the data much more
22  * difficult and made the code to read in the data needlessly complicated. A
23  * simple subclassing of QTextStream fixed all of the above problems (IMO).
24  *
25  * I had added periodic progress reports based on line number to several parts
26  * of the code that read in large files. So I combined that duplicated code
27  * into one place which was naturally here. The progress code causes almost
28  * nothing extra to take place when reading a file that does not use it. The
29  * only thing extra is incrementing the line number. For files that you want to
30  * emit periodic progress reports, you call setProgress() once setting up the
31  * message to display and the intervals the message will be emitted. Then
32  * inside the loop you call showProgress(). This is an extra call in the read
33  * loop but it just does an integer compare and almost always returns. We could
34  * inline it to reduce the call overhead but I don't think it makes a bit of
35  * difference considering all of the processing that takes place when we read in
36  * a line from a data file.
37  *
38  * NOTE: We no longer close the file like the previous version did. I've
39  * changed the code where this was assumed.
40  *
41  * There are two ways to use this class. One is pass in a QFile& in the
42  * constructor which is included only for backward compatibility. The preferred
43  * way is to just instantiate KSFileReader with no parameters and then use the
44  * open( QString fname ) method to let this class handle the file opening which
45  * helps take unneeded complexity out of the calling classes. I didn't make a
46  * constructor with the filename in it because we need to be able to inform the
47  * caller of an error opening the file, hence the bool open(filename) method.
48  *
49  *
50  * -- James B. Bowlin
51  */
52 
53 class KSFileReader : public QObject, public QTextStream
54 {
55  Q_OBJECT
56 
57  public:
58  /**
59  * @short this is the preferred constructor. You can then use
60  * the open() method to let this class open the file for you.
61  */
62  explicit KSFileReader(qint64 maxLen = 1024);
63 
64  /**
65  * Constructor
66  * @param file is a previously opened (for reading) file.
67  * @param maxLen sets the maximum line length before wrapping. Setting
68  * this parameter should help efficiency. The little max-length.pl
69  * script will tell you the maximum line length of files.
70  */
71  explicit KSFileReader(QFile &file, qint64 maxLen = 1024);
72 
73  /**
74  * @short opens the file fname from the QStandardPaths::AppLocalDataLocation directory and uses that
75  * file for the QTextStream.
76  *
77  * @param fname the name of the file to open
78  * @return returns true on success. Prints an error message and returns
79  * false on failure.
80  */
81  bool open(const QString &fname);
82 
83  /**
84  * @short opens the file with full path fname and uses that
85  * file for the QTextStream. open() locates QStandardPaths::AppLocalDataLocation behind the scenes,
86  * so passing fname such that
87  * QString fname = KSPaths::locate(QStandardPaths::AppLocalDataLocation, "file_name" );
88  * is equivalent
89  *
90  * @param fname full path to directory + name of the file to open
91  * @return returns true on success. Prints an error message and returns
92  * false on failure.
93  */
94  bool openFullPath(const QString &fname);
95 
96  /**
97  * @return true if we are not yet at the end of the file.
98  * (I added this to be compatible with existing code.)
99  */
100  bool hasMoreLines() const { return !QTextStream::atEnd(); }
101 
102  /**
103  * @short increments the line number and returns the next line from the file as a QString.
104  */
105  inline QString readLine()
106  {
107  m_curLine++;
108  return QTextStream::readLine(m_maxLen);
109  }
110 
111  /** @short returns the current line number */
112  int lineNumber() const { return m_curLine; }
113 
114  /**
115  * @short Prepares this instance to emit progress reports on how much
116  * of the file has been read (in percent).
117  * @param label the label
118  * @param lastLine the number of lines to be read
119  * @param numUpdates the number of progress reports to send
120  */
121  void setProgress(QString label, unsigned int lastLine, unsigned int numUpdates = 10);
122 
123  /**
124  * @short emits progress reports when required and updates bookkeeping
125  * for when to send the next report. This might seem slow at first
126  * glance but almost all the time we are just doing an integer compare
127  * and returning. If you are worried about speed we can inline it.
128  * It could also safely be included in the readLine() method since
129  * m_targetLine is set to MAXUINT in the constructor.
130  */
131  void showProgress();
132 
133  signals:
134  void progressText(const QString &message);
135 
136  private:
137  QFile m_file;
138  qint64 m_maxLen;
139  unsigned int m_curLine { 0 };
140 
141  unsigned int m_totalLines { 0 };
142  unsigned int m_targetLine { UINT_MAX };
143  unsigned int m_targetIncrement { 0 };
144  QString m_label;
145 };
Q_OBJECTQ_OBJECT
bool openFullPath(const QString &fname)
opens the file with full path fname and uses that file for the QTextStream.
bool open(const QString &fname)
opens the file fname from the QStandardPaths::AppLocalDataLocation directory and uses that file for t...
KSFileReader(qint64 maxLen=1024)
this is the preferred constructor.
void setProgress(QString label, unsigned int lastLine, unsigned int numUpdates=10)
Prepares this instance to emit progress reports on how much of the file has been read (in percent).
bool atEnd() const const
bool hasMoreLines() const
Definition: ksfilereader.h:100
QString readLine(qint64 maxlen)
void showProgress()
emits progress reports when required and updates bookkeeping for when to send the next report.
QString readLine()
increments the line number and returns the next line from the file as a QString.
Definition: ksfilereader.h:105
int lineNumber() const
returns the current line number
Definition: ksfilereader.h:112
QString message
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Fri Aug 12 2022 04:00:54 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.