MythTV  master
fileutils.cpp
Go to the documentation of this file.
1 // libmyth* headers
2 #include "exitcodes.h"
3 #include "mythlogging.h"
4 #include "ringbuffer.h"
5 #include "mythdownloadmanager.h"
6 
7 // local headers
8 #include "fileutils.h"
9 
11 {
12  int result = GENERIC_EXIT_OK;
13 
14  if (cmdline.toString("infile").isEmpty())
15  {
16  LOG(VB_GENERAL, LOG_ERR, "Missing --infile option");
18  }
19  QString src = cmdline.toString("infile");
20 
21  if (cmdline.toString("outfile").isEmpty())
22  {
23  LOG(VB_GENERAL, LOG_ERR, "Missing --outfile option");
25  }
26  QString dest = cmdline.toString("outfile");
27 
28  const int readSize = 2 * 1024 * 1024;
29  char *buf = new char[readSize];
30  if (!buf)
31  {
32  LOG(VB_GENERAL, LOG_ERR, "ERROR, unable to allocate copy buffer ");
33  return GENERIC_EXIT_NOT_OK;
34  }
35 
36  LOG(VB_GENERAL, LOG_INFO, QString("Copying %1 to %2").arg(src).arg(dest));
37  RingBuffer *srcRB = RingBuffer::Create(src, false);
38  if (!srcRB)
39  {
40  LOG(VB_GENERAL, LOG_ERR, "ERROR, couldn't create Read RingBuffer");
41  delete[] buf;
42  return GENERIC_EXIT_NOT_OK;
43  }
44 
45  if (!srcRB->IsOpen())
46  {
47  LOG(VB_GENERAL, LOG_ERR, "ERROR, srcRB is not open");
48  delete[] buf;
49  delete srcRB;
50  return GENERIC_EXIT_NOT_OK;
51  }
52 
53  RingBuffer *destRB = RingBuffer::Create(dest, true);
54  if (!destRB)
55  {
56  LOG(VB_GENERAL, LOG_ERR, "ERROR, couldn't create Write RingBuffer");
57  delete[] buf;
58  delete srcRB;
59  return GENERIC_EXIT_NOT_OK;
60  }
61 
62  if (!destRB->IsOpen())
63  {
64  LOG(VB_GENERAL, LOG_ERR, "ERROR, destRB is not open");
65  delete[] buf;
66  delete srcRB;
67  delete destRB;
68  return GENERIC_EXIT_NOT_OK;
69  }
70  destRB->WriterSetBlocking(true);
71 
72  long long totalBytes = srcRB->GetRealFileSize();
73  long long totalBytesCopied = 0;
74  bool ok = true;
75  int r;
76  while (ok && ((r = srcRB->Read(buf, readSize)) > 0))
77  {
78  int ret = destRB->Write(buf, r);
79  if (ret < 0)
80  {
81  LOG(VB_GENERAL, LOG_ERR,
82  QString("ERROR, couldn't write at offset %1")
83  .arg(totalBytesCopied));
84  ok = false;
85  }
86  else
87  totalBytesCopied += ret;
88 
89  int percentComplete = totalBytesCopied * 100 / totalBytes;
90  if ((percentComplete % 5) == 0)
91  LOG(VB_GENERAL, LOG_INFO,
92  QString("%1 bytes copied, %2%% complete")
93  .arg(totalBytesCopied).arg(percentComplete));
94  }
95 
96  LOG(VB_GENERAL, LOG_INFO,
97  QString("Wrote %1 bytes total").arg(totalBytesCopied));
98 
99  LOG(VB_GENERAL, LOG_INFO, "Waiting for write buffer to flush");
100 
101  delete[] buf;
102  delete srcRB;
103  delete destRB;
104 
105  if (!ok)
106  result = GENERIC_EXIT_NOT_OK;
107 
108  return result;
109 }
110 
112 {
113  int result = GENERIC_EXIT_OK;
114 
115  if (cmdline.toString("infile").isEmpty())
116  {
117  LOG(VB_GENERAL, LOG_ERR, "Missing --infile option");
119  }
120  QString url = cmdline.toString("infile");
121 
122  if (cmdline.toString("outfile").isEmpty())
123  {
124  LOG(VB_GENERAL, LOG_ERR, "Missing --outfile option");
126  }
127  QString dest = cmdline.toString("outfile");
128 
129  bool ok = GetMythDownloadManager()->download(url, dest);
130 
131  if (!ok)
132  {
133  LOG(VB_GENERAL, LOG_INFO, "Error downloading file.");
134  result = GENERIC_EXIT_NOT_OK;
135  }
136  else
137  {
138  LOG(VB_GENERAL, LOG_INFO, "File downloaded.");
139  }
140 
141  return result;
142 }
143 
145 {
146  utilMap["copyfile"] = &CopyFile;
147  utilMap["download"] = &DownloadFile;
148 }
149 
150 /* vim: set expandtab tabstop=4 shiftwidth=4: */
static int DownloadFile(const MythUtilCommandLineParser &cmdline)
Definition: fileutils.cpp:111
#define GENERIC_EXIT_OK
Exited with no error.
Definition: exitcodes.h:10
bool WriterSetBlocking(bool lock=true)
Calls ThreadedFileWriter::SetBlocking(bool)
static RingBuffer * Create(const QString &xfilename, bool write, bool usereadahead=true, int timeout_ms=kDefaultOpenTimeout, bool stream_only=false)
Creates a RingBuffer instance.
Definition: ringbuffer.cpp:104
unsigned char r
Definition: ParseText.cpp:329
static int CopyFile(const MythUtilCommandLineParser &cmdline)
Definition: fileutils.cpp:10
QMap< QString, UtilFunc > UtilMap
Definition: mythutil.h:16
QString toString(const QString &key) const
Returns stored QVariant as a QString, falling to default if not provided.
MythDownloadManager * GetMythDownloadManager(void)
Gets the pointer to the MythDownloadManager singleton.
bool download(const QString &url, const QString &dest, const bool reload=false)
Downloads a URL to a file in blocking mode.
virtual bool IsOpen(void) const =0
Returns true if open for either reading or writing.
MythCommFlagCommandLineParser cmdline
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
long long GetRealFileSize(void) const
Returns the size of the file we are reading/writing, or -1 if the query fails.
Definition: ringbuffer.cpp:497
int Read(void *buf, int count)
This is the public method for reading from a file, it calls the appropriate read method if the file i...
void registerFileUtils(UtilMap &utilMap)
Definition: fileutils.cpp:144
int Write(const void *buf, uint count)
Writes buffer to ThreadedFileWriter::Write(const void*,uint)
Implements a file/stream reader/writer.
#define GENERIC_EXIT_INVALID_CMDLINE
Command line parse error.
Definition: exitcodes.h:15
#define GENERIC_EXIT_NOT_OK
Exited with error.
Definition: exitcodes.h:11