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