Kstars

binarylistcomponent.h
1 /*
2  SPDX-FileCopyrightText: 2018 Valentin Boettcher <[email protected]>
3 
4  SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #pragma once
8 
9 #include <QDataStream>
10 #include <QDebug>
11 
12 #include "listcomponent.h"
13 #include "binarylistcomponent.h"
14 #include "auxiliary/kspaths.h"
15 
16 //TODO: Error Handling - SERIOUSLY
17 
18 /**
19  * @class BinaryListComponent
20  * @short provides functionality for loading the component data from Binary
21  * @author Valentin Boettcher
22  * @version 1.0
23  *
24  * This class is an abstract Template which requires that the type `T` is some child of
25  * `SkyObject` and the type `Component` is some child of `ListComponent`. The class `T`
26  * must provide a static `TYPE` property of the type `SkyObject::TYPE`. This is required
27  * because access to the `type()` method is inconvenient here!
28  *
29  * The derived class must provide a `void loadFromText()` method, which loads the component
30  * via `addListObject` or similar. (This method implements parsing etc, and cannot be
31  * abstracted by this class.)
32  *
33  * Finally, one has to add this template as a friend class upon deriving it.
34  * This is a concession to the already present architecture.
35  *
36  * File paths are determent by the means of KSPaths::writableLocation.
37  */
38 template <class T, typename Component>
40 {
41 public:
42  /**
43  * @brief BinaryListComponent
44  * @param parent a reference to the inheriting child
45  * @param basename the base filename for the binary
46  *
47  * Sets the file extensions to `dat` for text and `bin` for binary.
48  */
49  BinaryListComponent(Component* parent, QString basename);
50 
51  /**
52  * @brief BinaryListComponent
53  * @param parent a reference to the inheriting child
54  * @param basename the base filename for the binary
55  * @param txtExt text data file extension
56  * @param binExt binary data file extension
57  */
58  BinaryListComponent(Component* parent, QString basename, QString txtExt, QString binExt);
59 
60 protected:
61  /**
62  * @brief loadData
63  * @short Calls `loadData(false)`
64  */
65  virtual void loadData();
66 
67  /**
68  * @brief loadData
69  * @short Load the component data from binary (if available) or from text
70  * @param dropBinaryFile whether to drop the current binary (and to recreate it)
71  *
72  * Tip: If you want to reload the data and recreate the binfile, just call
73  * loadData(true).
74  */
75  virtual void loadData(bool dropBinaryFile);
76 
77  /**
78  * @brief loadDataFromBinary
79  * @short Opens the default binfile and calls `loadDataFromBinary([FILE])`
80  */
81  virtual void loadDataFromBinary();
82 
83  /**
84  * @brief loadDataFromBinary
85  * @param binfile the binary file
86  * @short Loads the component data from the given binary.
87  */
88  virtual void loadDataFromBinary(QFile &binfile);
89 
90  /**
91  * @brief writeBinary
92  * @short Opens the default binfile and calls `writeBinary([FILE])`
93  */
94  virtual void writeBinary();
95 
96  /**
97  * @brief writeBinary
98  * @param binfile
99  * @short Writes the component data to the specified binary. (Destructive)
100  */
101  virtual void writeBinary(QFile &binfile);
102 
103  /**
104  * @brief loadDataFromText
105  * @short Load the component data from text.
106  *
107  * This method shall be implemented by those who derive this class.
108  *
109  * This method should load the component data from text by the use of
110  * `addListObject` or similar.
111  */
112  virtual void loadDataFromText() = 0;
113 
114  // TODO: Rename, and integrate it into a wrapper
115  //virtual void updateDataFile() = 0; // legacy from current implementation!
116 
117  /**
118  * @brief dropBinary
119  * @short Removes the binary file.
120  * @return True if operation succeeds
121  */
122  virtual bool dropBinary();
123 
124  /**
125  * @brief dropText
126  * @short Removes the text file.
127  * @return True if operation succeeds
128  */
129  virtual bool dropText();
130 
131  /**
132  * @brief clearData
133  * @short Removes the current component data where necessary.
134  */
135  virtual void clearData();
136 
137  QString filepath_txt;
138  QString filepath_bin;
139 
140 // Don't allow the children to mess with the Binary Version!
141 private:
143  Component* parent;
144 };
145 
146 template<class T, typename Component>
148 
149 template<class T, typename Component>
150  BinaryListComponent<T, Component>::BinaryListComponent(Component *parent, QString basename, QString txtExt, QString binExt) : parent { parent }
151 {
152  filepath_bin = QDir(KSPaths::writableLocation(QStandardPaths::AppLocalDataLocation)).filePath(basename + '.' + binExt);
153  filepath_txt = QDir(KSPaths::writableLocation(QStandardPaths::AppLocalDataLocation)).filePath(basename + '.' + txtExt);
154 }
155 
156 template<class T, typename Component>
158 {
159  loadData(false);
160 }
161 
162 template<class T, typename Component>
164 {
165  // Clear old Stuff (in case of reload)
166  clearData();
167 
168  // Drop Binary file for a fresh reload
169  if(dropBinaryFile)
170  dropBinary();
171 
172  QFile binfile(filepath_bin);
173  if (binfile.exists()) {
174  loadDataFromBinary(binfile);
175  } else {
176  loadDataFromText();
177  writeBinary(binfile);
178  }
179 }
180 
181 template<class T, typename Component>
183 {
184  QFile binfile(filepath_bin);
185  loadDataFromBinary(binfile);
186 }
187 
188 template<class T, typename Component>
190 {
191  // Open our binary file and create a Stream
192  if (binfile.open(QIODevice::ReadOnly))
193  {
194  QDataStream in(&binfile);
195 
196  // Use the specified binary version
197  // TODO: Place this into the config
198  in.setVersion(binversion);
200 
201  while(!in.atEnd()){
202  T *new_object = nullptr;
203  in >> new_object;
204 
205  parent->appendListObject(new_object);
206  // Add name to the list of object names
207  parent->objectNames(T::TYPE).append(new_object->name());
208  parent->objectLists(T::TYPE).append(QPair<QString, const SkyObject *>(new_object->name(), new_object));
209  }
210  binfile.close();
211  }
212  else qWarning() << "Failed loading binary data from" << binfile.fileName();
213 }
214 
215 template<class T, typename Component>
217 {
218  QFile binfile(filepath_bin);
219  writeBinary(binfile);
220 }
221 
222 template<class T, typename Component>
224 {
225  // Open our file and create a stream
227  QDataStream out(&binfile);
228  out.setVersion(binversion);
230 
231  // Now just dump out everything
232  for(auto object : parent->m_ObjectList){
233  out << *((T*)object);
234  }
235 
236  binfile.close();
237 }
238 
239 template<class T, typename Component>
241 {
242  return QFile::remove(filepath_bin);
243 }
244 
245 template<class T, typename Component>
247 {
248  return QFile::remove(filepath_txt);
249 }
250 
251 template<class T, typename Component>
253 {
254  // Clear lists
255  qDeleteAll(parent->m_ObjectList);
256  parent->m_ObjectList.clear();
257  parent->m_ObjectHash.clear();
258 
259  parent->objectLists(T::TYPE).clear();
260  parent->objectNames(T::TYPE).clear();
261 }
void setVersion(int v)
bool atEnd() const const
bool remove()
virtual bool open(QIODevice::OpenMode mode) override
provides functionality for loading the component data from Binary
virtual void writeBinary()
writeBinary
virtual void loadDataFromText()=0
loadDataFromText
bool exists() const const
virtual QString fileName() const const override
virtual bool dropText()
dropText
virtual bool dropBinary()
dropBinary
BinaryListComponent(Component *parent, QString basename)
BinaryListComponent.
virtual void loadData()
loadData
virtual void loadDataFromBinary()
loadDataFromBinary
virtual void close() override
QString filePath(const QString &fileName) const const
virtual void clearData()
clearData
void setFloatingPointPrecision(QDataStream::FloatingPointPrecision precision)
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Dec 11 2023 04:03:16 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.