General Purpose Geodetic Library
SgIoExternalFilter.cpp
Go to the documentation of this file.
1 /*
2  *
3  * This file is a part of Space Geodetic Library. The library is used by
4  * nuSolve, a part of CALC/SOLVE system, and designed to make analysis of
5  * geodetic VLBI observations.
6  * Copyright (C) 2010-2020 Sergei Bolotin.
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  *
21  */
22 
23 #include <unistd.h>
24 
25 #include <SgIoExternalFilter.h>
26 
27 
28 
29 /*=======================================================================================================
30 *
31 * SgIoExternalFilter's METHODS:
32 *
33 *======================================================================================================*/
34 // static first:
36 {
37  return "SgExternalFilter";
38 };
39 
40 
41 
42 //
43 FILE* SgIoExternalFilter::openFlt(const QString& fileName, QFile& file, QTextStream& ts,
44  FilterDirection d) const
45 {
46  FILE *p=NULL;
47  if (d == FLTD_Udefined)
48  return NULL;
49 
50  const QString &cmd=d==FLTD_Input?command2read_:command2write_;
51  const char* popenFlag(d==FLTD_Input?"r":"w");
52 
53  if ((p=popen(qPrintable(cmd + " \"" + fileName + "\""), popenFlag)))
54  {
55  file.open(p, d==FLTD_Input?QIODevice::ReadOnly:(QIODevice::WriteOnly|QIODevice::Truncate));
56  ts.setDevice(&file);
57  }
58  else
60  "::openFlt(): got an error: " + QString(strerror(errno)));
61 
62  return p;
63 };
64 
65 
66 
67 //
68 void SgIoExternalFilter::closeFlt(FILE*& p, QFile& file, QTextStream& ts)
69 {
70  file.close();
71  if (p)
72  {
73  pclose(p);
74  p = NULL;
75  };
76  ts.setDevice(NULL);
77 };
78 
79 
80 
81 //
83 {
84  if (command2read_ == "NONE" || command2write_ == "NONE")
85  return true; // cannot to check
86 
87  QString strWrite("QWERTY1234567890qwerty"), strRead, tmpNam;
88  QFile f;
89  QTextStream ts;
90  FILE *pipe=NULL;
91  const char *sFileTemplate="/tmp/SgLib_XXXXXX";
92  char *tmpl=strdup(sFileTemplate);
93 
94  if ( !(pipe=openFlt((tmpNam=mktemp(tmpl)), f, ts, FLTD_Output)) )
95  {
96  free(tmpl);
97  return false;
98  };
99 
100  ts << strWrite;
101  closeFlt(pipe, f, ts);
102  free(tmpl);
103  /*
104  logger->write(SgLogger::DBG, SgLogger::IO, className() +
105  "::selfCheck(): file \"" + tmpNam + "\" has been created");
106  */
107  if ( !(pipe=openFlt(tmpNam, f, ts, FLTD_Input)) )
108  return false;
109 
110  ts >> strRead;
111  closeFlt(pipe, f, ts);
112 
113  if (unlink(qPrintable(tmpNam)) == -1)
115  "::selfCheck(): file \"" + tmpNam + "\" cannot be deleted: " + QString(strerror(errno)));
116  /*
117  else
118  logger->write(SgLogger::DBG, SgLogger::IO, className() +
119  "::selfCheck(): file \"" + tmpNam + "\" deleted");
120  */
121  return strWrite==strRead;
122 };
123 /*=====================================================================================================*/
124 
125 
126 
127 
128 
129 
130 /*=======================================================================================================
131 *
132 * SgIoExtFilterHandler's METHODS:
133 *
134 *======================================================================================================*/
135 // static first:
137 {
138  return "SgIoExtFilterHandler";
139 };
140 
141 
142 
143 //
145 {
146  addFilter("GZIP", "gz", "gzip -dc", "gzip -c >");
147  addFilter("BZIP2", "bz2", "bzip2 -dc", "bzip2 -c >");
148 // addFilter("Compress", "Z", "compress -dc", "compress -c >");
149 };
150 
151 
152 
153 //
155 {
156  for (QMap<QString, const SgIoExternalFilter*>::iterator it=filterByExt_.begin();
157  it!=filterByExt_.end(); it++)
158  delete it.value();
159  filterByExt_.clear();
160 };
161 
162 
163 
164 //
166 {
167  if (!filter)
168  {
170  "::addFilter(): the filter is NULL");
171  return false;
172  }
173  else if (!filter->getDefaultExtension().size())
174  {
176  "::addFilter(): the default file extension of the filter is empty");
177  return false;
178  }
179  else if (filterByExt_.contains(filter->getDefaultExtension()))
180  {
182  "::addFilter(): the default file extension \"" + filter->getDefaultExtension() +
183  "\" already registered");
184  return false;
185  };
186 
187  filterByExt_.insert(filter->getDefaultExtension(), filter);
188  return true;
189 };
190 
191 
192 
193 //
195 {
196  if (!filter)
197  {
199  "::removeFilter(): the filter is NULL");
200  return false;
201  }
202  else if (!filter->getDefaultExtension().size())
203  {
205  "::removeFilter(): the default file extension of the filter is empty");
206  return false;
207  }
208  else if (!filterByExt_.contains(filter->getDefaultExtension()))
209  {
211  "::removeFilter(): the default file extension \"" + filter->getDefaultExtension() +
212  "\" is not registered");
213  return false;
214  };
215 
216  filterByExt_.remove(filter->getDefaultExtension());
217  return true;
218 };
219 
220 
221 
222 //
223 bool SgIoExtFilterHandler::removeFilter(const QString& extension)
224 {
225  const SgIoExternalFilter* filter=NULL;
226  if (!extension.size())
227  {
229  "::removeFilter(): the default file extension is empty");
230  return false;
231  }
232  else if (!filterByExt_.contains(extension))
233  {
235  "::removeFilter(): the default file extension \"" + filter->getDefaultExtension() +
236  "\" is not registered");
237  return false;
238  }
239  else
240  filter = filterByExt_.value(extension);
241 
242  filterByExt_.remove(extension);
243  if (filter)
244  delete filter;
245 
246  return true;
247 };
248 
249 
250 
251 //
253 {
254  int idx=fileName.lastIndexOf('.');
255  QString ext(-1<idx?fileName.mid(idx + 1):"");
256 
257  if (filterByExt_.contains(ext))
258  return filterByExt_.value(ext);
259  return NULL;
260 };
261 
262 
263 
264 //
265 FILE* SgIoExtFilterHandler::openFlt(const QString& fileName, QFile& file, QTextStream& ts,
266  FilterDirection d)
267 {
268  const SgIoExternalFilter *filter=lookupFilterByFileName(fileName);
269  if (filter)
270  return filter->openFlt(fileName, file, ts, d);
271 
272  // not found: unknown format/uncompressed data:
273  file.setFileName(fileName);
274  if (file.open(d==FLTD_Input?QIODevice::ReadOnly:(QIODevice::WriteOnly|QIODevice::Truncate)))
275  ts.setDevice(&file);
276  else
277  {
279  "::openFlt(): cannot open file \"" + file.fileName() + "\"");
280  ts.setDevice(NULL);
281  };
282  return NULL;
283 };
284 
285 
286 
287 
288 
289 
290 
291 
292 
293 
294 
295 /*=====================================================================================================*/
296 //
297 // constants:
298 //
299 
300 
302 
303 
304 /*=====================================================================================================*/
305 
306 /*=====================================================================================================*/
SgIoExtFilterHandler compressors
FilterDirection
@ FLTD_Output
@ FLTD_Input
@ FLTD_Udefined
SgLogger * logger
Definition: SgLogger.cpp:231
bool addFilter(const SgIoExternalFilter *filter)
static const QString className()
const SgIoExternalFilter * lookupFilterByFileName(const QString &fileName)
bool removeFilter(const SgIoExternalFilter *filter)
QMap< QString, const SgIoExternalFilter * > filterByExt_
FILE * openFlt(const QString &fileName, QFile &file, QTextStream &ts, FilterDirection)
const QString & getDefaultExtension() const
static void closeFlt(FILE *&p, QFile &file, QTextStream &ts)
FILE * openFlt(const QString &fileName, QFile &file, QTextStream &ts, FilterDirection) const
static const QString className()
virtual void write(LogLevel, quint32, const QString &, bool=false)
Definition: SgLogger.cpp:88