|
MythTV
0.26-pre
|
00001 #include <QCoreApplication> 00002 #include <QDateTime> 00003 #include <QFileInfo> 00004 00005 #include "filetransfer.h" 00006 #include "ringbuffer.h" 00007 #include "mythmiscutil.h" 00008 #include "mythsocket.h" 00009 #include "programinfo.h" 00010 #include "mythlogging.h" 00011 00012 FileTransfer::FileTransfer(QString &filename, MythSocket *remote, 00013 bool usereadahead, int timeout_ms) : 00014 readthreadlive(true), readsLocked(false), 00015 rbuffer(RingBuffer::Create(filename, false, usereadahead, timeout_ms, true)), 00016 sock(remote), ateof(false), lock(QMutex::NonRecursive), 00017 refLock(QMutex::NonRecursive), refCount(0), writemode(false) 00018 { 00019 pginfo = new ProgramInfo(filename); 00020 pginfo->MarkAsInUse(true, kFileTransferInUseID); 00021 rbuffer->Start(); 00022 } 00023 00024 FileTransfer::FileTransfer(QString &filename, MythSocket *remote, bool write) : 00025 readthreadlive(true), readsLocked(false), 00026 rbuffer(RingBuffer::Create(filename, write)), 00027 sock(remote), ateof(false), lock(QMutex::NonRecursive), 00028 refLock(QMutex::NonRecursive), refCount(0), writemode(write) 00029 { 00030 pginfo = new ProgramInfo(filename); 00031 pginfo->MarkAsInUse(true, kFileTransferInUseID); 00032 00033 if (write) 00034 remote->useReadyReadCallback(false); 00035 rbuffer->Start(); 00036 } 00037 00038 FileTransfer::~FileTransfer() 00039 { 00040 Stop(); 00041 00042 if (rbuffer) 00043 { 00044 delete rbuffer; 00045 rbuffer = NULL; 00046 } 00047 00048 if (pginfo) 00049 { 00050 pginfo->MarkAsInUse(false, kFileTransferInUseID); 00051 delete pginfo; 00052 } 00053 } 00054 00055 void FileTransfer::UpRef(void) 00056 { 00057 QMutexLocker locker(&refLock); 00058 refCount++; 00059 } 00060 00061 bool FileTransfer::DownRef(void) 00062 { 00063 int count = 0; 00064 { 00065 QMutexLocker locker(&refLock); 00066 count = --refCount; 00067 } 00068 00069 if (count < 0) 00070 delete this; 00071 00072 return (count < 0); 00073 } 00074 00075 bool FileTransfer::isOpen(void) 00076 { 00077 if (rbuffer && rbuffer->IsOpen()) 00078 return true; 00079 return false; 00080 } 00081 00082 bool FileTransfer::ReOpen(QString newFilename) 00083 { 00084 if (!writemode) 00085 return false; 00086 00087 if (rbuffer) 00088 return rbuffer->ReOpen(newFilename); 00089 00090 return false; 00091 } 00092 00093 void FileTransfer::Stop(void) 00094 { 00095 if (readthreadlive) 00096 { 00097 readthreadlive = false; 00098 LOG(VB_FILE, LOG_INFO, "calling StopReads()"); 00099 rbuffer->StopReads(); 00100 QMutexLocker locker(&lock); 00101 readsLocked = true; 00102 } 00103 00104 if (writemode) 00105 rbuffer->WriterFlush(); 00106 00107 if (pginfo) 00108 pginfo->UpdateInUseMark(); 00109 } 00110 00111 void FileTransfer::Pause(void) 00112 { 00113 LOG(VB_FILE, LOG_INFO, "calling StopReads()"); 00114 rbuffer->StopReads(); 00115 QMutexLocker locker(&lock); 00116 readsLocked = true; 00117 00118 if (pginfo) 00119 pginfo->UpdateInUseMark(); 00120 } 00121 00122 void FileTransfer::Unpause(void) 00123 { 00124 LOG(VB_FILE, LOG_INFO, "calling StartReads()"); 00125 rbuffer->StartReads(); 00126 { 00127 QMutexLocker locker(&lock); 00128 readsLocked = false; 00129 } 00130 readsUnlockedCond.wakeAll(); 00131 00132 if (pginfo) 00133 pginfo->UpdateInUseMark(); 00134 } 00135 00136 int FileTransfer::RequestBlock(int size) 00137 { 00138 if (!readthreadlive || !rbuffer) 00139 return -1; 00140 00141 int tot = 0; 00142 int ret = 0; 00143 00144 QMutexLocker locker(&lock); 00145 while (readsLocked) 00146 readsUnlockedCond.wait(&lock, 100 /*ms*/); 00147 00148 requestBuffer.resize(max((size_t)max(size,0) + 128, requestBuffer.size())); 00149 char *buf = &requestBuffer[0]; 00150 while (tot < size && !rbuffer->GetStopReads() && readthreadlive) 00151 { 00152 int request = size - tot; 00153 00154 ret = rbuffer->Read(buf, request); 00155 00156 if (rbuffer->GetStopReads() || ret <= 0) 00157 break; 00158 00159 if (!sock->writeData(buf, (uint)ret)) 00160 { 00161 tot = -1; 00162 break; 00163 } 00164 00165 tot += ret; 00166 if (ret < request) 00167 break; // we hit eof 00168 } 00169 00170 if (pginfo) 00171 pginfo->UpdateInUseMark(); 00172 00173 return (ret < 0) ? -1 : tot; 00174 } 00175 00176 int FileTransfer::WriteBlock(int size) 00177 { 00178 if (!writemode || !rbuffer) 00179 return -1; 00180 00181 int tot = 0; 00182 int ret = 0; 00183 00184 QMutexLocker locker(&lock); 00185 00186 requestBuffer.resize(max((size_t)max(size,0) + 128, requestBuffer.size())); 00187 char *buf = &requestBuffer[0]; 00188 while (tot < size) 00189 { 00190 int request = size - tot; 00191 00192 if (!sock->readData(buf, (uint)request)) 00193 break; 00194 00195 ret = rbuffer->Write(buf, request); 00196 00197 if (ret <= 0) 00198 break; 00199 00200 tot += request; 00201 } 00202 00203 if (pginfo) 00204 pginfo->UpdateInUseMark(); 00205 00206 return (ret < 0) ? -1 : tot; 00207 } 00208 00209 long long FileTransfer::Seek(long long curpos, long long pos, int whence) 00210 { 00211 if (pginfo) 00212 pginfo->UpdateInUseMark(); 00213 00214 if (!rbuffer) 00215 return -1; 00216 if (!readthreadlive) 00217 return -1; 00218 00219 ateof = false; 00220 00221 Pause(); 00222 00223 if (whence == SEEK_CUR) 00224 { 00225 long long desired = curpos + pos; 00226 long long realpos = rbuffer->GetReadPosition(); 00227 00228 pos = desired - realpos; 00229 } 00230 00231 long long ret = rbuffer->Seek(pos, whence); 00232 00233 Unpause(); 00234 00235 if (pginfo) 00236 pginfo->UpdateInUseMark(); 00237 00238 return ret; 00239 } 00240 00241 uint64_t FileTransfer::GetFileSize(void) 00242 { 00243 if (pginfo) 00244 pginfo->UpdateInUseMark(); 00245 00246 return QFileInfo(rbuffer->GetFilename()).size(); 00247 } 00248 00249 void FileTransfer::SetTimeout(bool fast) 00250 { 00251 if (pginfo) 00252 pginfo->UpdateInUseMark(); 00253 00254 rbuffer->SetOldFile(fast); 00255 } 00256 00257 /* vim: set expandtab tabstop=4 shiftwidth=4: */
1.7.6.1