00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <unistd.h>
00013
00014 #include <mythtv/mythcontext.h>
00015 #include "fileobs.h"
00016 #include "qdir.h"
00017
00018 RipFile::RipFile(const QString &a_base, const QString &an_extension,
00019 bool auto_remove_bad) : base_name(a_base), extension(an_extension),
00020 active_file(NULL), bytes_written(0),
00021 use_multiple_files(true),
00022 auto_remove_bad_rips(auto_remove_bad)
00023 {
00024 filesize = gContext->GetNumSetting("MTDRipSize", 0) * 1024 * 1024;
00025 files.setAutoDelete(true);
00026 }
00027
00028 bool RipFile::open(int mode, bool multiple_files)
00029 {
00030 use_multiple_files = multiple_files;
00031 access_mode = mode;
00032 QString filename = base_name + "_001of";
00033 active_file = new QFile(filename);
00034 files.append(active_file);
00035 return active_file->open(mode);
00036
00037
00038
00039
00040
00041
00042 }
00043
00044 QStringList RipFile::close()
00045 {
00046 QStringList output_file_names;
00047
00048 auto_remove_bad_rips = false;
00049 if(active_file)
00050 {
00051 active_file->close();
00052 }
00053 if(files.count() == 1)
00054 {
00055 QString new_name = base_name + extension;
00056 if(!QDir::current().rename(active_file->name(), new_name))
00057 {
00058 VERBOSE(VB_IMPORTANT,
00059 QString("Couldn't rename a ripped file on close ... "
00060 " that sucks.\n"
00061 " old name: \"%1\"\n"
00062 " new name: \"%1\"")
00063 .arg(active_file->name()).arg(new_name));
00064 }
00065 else
00066 {
00067 active_file->setName(new_name);
00068 output_file_names.push_back(new_name);
00069 }
00070 }
00071 else
00072 {
00073 QFile *iter;
00074 for(iter = files.first(); iter; iter = files.next())
00075 {
00076 QString new_name = iter->name() + QString("%1").arg(files.count()) +
00077 extension;
00078 if(!QDir::current().rename(iter->name(), new_name))
00079 {
00080 VERBOSE(VB_IMPORTANT, QString("Couldn't rename '%1' to '%2'")
00081 .arg(iter->name()).arg(new_name));
00082 }
00083 else
00084 {
00085 iter->setName(new_name);
00086 output_file_names.push_back(new_name);
00087 }
00088 }
00089 }
00090 return output_file_names;
00091 }
00092
00093 void RipFile::remove()
00094 {
00095 active_file->close();
00096 QFile *iter;
00097 for(iter = files.first(); iter; iter=files.next())
00098 {
00099 iter->remove();
00100 }
00101 files.clear();
00102 }
00103
00104 QString RipFile::name()
00105 {
00106 return active_file->name();
00107 }
00108
00109 bool RipFile::writeBlocks(unsigned char *the_data, int how_much)
00110 {
00111 if(filesize > 0 && how_much + bytes_written > filesize)
00112 {
00113
00114
00115
00116 active_file->close();
00117
00118
00119
00120
00121
00122 QString number_extension;
00123 number_extension.sprintf("_%03dof", files.count() + 1);
00124 QString filename = base_name + number_extension;
00125 QFile *new_file = new QFile(filename);
00126 active_file = new_file;
00127 files.append(new_file);
00128 if(!active_file->open(access_mode))
00129 {
00130 VERBOSE(VB_IMPORTANT,
00131 "couldn't open another file in a set of rip files.");
00132 return false;
00133 }
00134 bytes_written = 0;
00135 }
00136 int result = write(active_file->handle(), the_data, how_much);
00137 if(result < 0)
00138 {
00139 VERBOSE(VB_IMPORTANT, "Got a negative result while writing blocks."
00140 " World may end shortly.");
00141 return false;
00142 }
00143 if(result == 0)
00144 {
00145 if(how_much == 0)
00146 {
00147 VERBOSE(VB_IMPORTANT, "Ripfile wrote 0 bytes, but that's all it"
00148 " was asked to. Unlikely coincidence?");
00149 }
00150 else
00151 {
00152 VERBOSE(VB_IMPORTANT, "Ripfile writing 0 bytes of data. That's"
00153 " probably not a good sign.");
00154 return false;
00155 }
00156 }
00157 if(result != how_much)
00158 {
00159 VERBOSE(VB_IMPORTANT, QString("Ripfile tried to write %1 bytes, but"
00160 " only managed to write %2")
00161 .arg(how_much).arg(result));
00162 return false;
00163 }
00164 bytes_written += result;
00165 return true;
00166 }
00167
00168 RipFile::~RipFile()
00169 {
00170 if (active_file && auto_remove_bad_rips)
00171 {
00172 remove();
00173 }
00174 files.clear();
00175 }