diff options
Diffstat (limited to 'responsevdrdir.c')
-rw-r--r-- | responsevdrdir.c | 781 |
1 files changed, 781 insertions, 0 deletions
diff --git a/responsevdrdir.c b/responsevdrdir.c new file mode 100644 index 0000000..50949d5 --- /dev/null +++ b/responsevdrdir.c @@ -0,0 +1,781 @@ +/* + * responsevdrdir.c: VDR on Smart TV plugin + * + * Copyright (C) 2012, 2013 T. Lohmar + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + */ + + +#include "responsevdrdir.h" +#include "httpresource.h" +#include "smarttvfactory.h" +#include <vector> +#include <cstdlib> + +#ifndef STANDALONE +#include <vdr/recording.h> +//#include <vdr/channels.h> +//#include <vdr/timers.h> +//#include <vdr/videodir.h> +//#include <vdr/epg.h> +#else +#include <sys/stat.h> + +#endif + +//#define MAXLEN 4096 +#define DEBUGPREFIX "mReqId= " << mRequest->mReqId << " fd= " << mRequest->mFd +#define OKAY 0 +#define ERROR (-1) +#define DEBUG + +struct sVdrFileEntry { + uint64_t sSize; + uint64_t sFirstOffset; + int sIdx; + + sVdrFileEntry () {}; + sVdrFileEntry (uint64_t s, uint64_t t, int i) + : sSize(s), sFirstOffset(t), sIdx(i) {}; +}; + + + +// 8 Byte Per Entry +struct tIndexPes { + uint32_t offset; + uint8_t type; // standalone + uint8_t number; // standalone + uint16_t reserved; + }; + + +// 8 Byte per entry +struct tIndexTs { + uint64_t offset:40; // up to 1TB per file (not using long long int here - must definitely be exactly 64 bit!) + int reserved:7; // reserved for future use + int independent:1; // marks frames that can be displayed by themselves (for trick modes) + uint16_t number:16; // up to 64K files per recording + }; + + +cResponseVdrDir::cResponseVdrDir(cHttpResource* req) : cResponseBase(req), mIsRecording(false), + mStreamToEnd(false), mRecProgress(0.0), mVdrIdx(0), mFile(NULL), mFileStructure() { +} + +cResponseVdrDir::~cResponseVdrDir() { + if (mFile != NULL) { + *(mLog->log())<< DEBUGPREFIX + << " ERROR: mFile still open. Closing now..." << endl; + fclose(mFile); + mFile = NULL; + } +} + + +bool cResponseVdrDir::isTimeRequest(struct stat *statbuf) { + +#ifndef STANDALONE + vector<sQueryAVP> avps; + mRequest->parseQueryLine(&avps); + string time_str = ""; + string mode = ""; + float time = 0.0; + + if (mRequest->getQueryAttributeValue(&avps, "time", time_str) != OKAY){ + return false; + } + + if (mRequest->getQueryAttributeValue(&avps, "mode", mode) == OKAY){ + if (mode.compare ("streamtoend") ==0) { + mStreamToEnd = true; + } + } + + if (mIsRecording) + mStreamToEnd = true; + + time = atof(time_str.c_str()); + *(mLog->log())<< DEBUGPREFIX + << " Found a Time Parameter: " << time + << " streamToEnd= " << ((mStreamToEnd) ? "true" : "false") + << endl; + + mRequest->mDir = mRequest->mPath; + cRecording *rec = Recordings.GetByName(mRequest->mPath.c_str()); + if (rec == NULL) { + *(mLog->log())<< DEBUGPREFIX + << " Error: Did not find recording= " << mRequest->mPath << endl; + sendError(404, "Not Found", NULL, "File not found."); + return true; + } + + double fps = rec->FramesPerSecond(); + double dur = rec->NumFrames() * fps; + bool is_pes = rec->IsPesRecording(); + if (dur < time) { + sendError(400, "Bad Request", NULL, "Time to large."); + return true; + } + + int start_frame = int(time * fps) -25; + + FILE* idx_file= NULL; + + if (is_pes){ + idx_file = fopen(((mRequest->mDir) +"/index.vdr").c_str(), "r"); + // sendError(400, "Bad Request", NULL, "PES not yet supported."); + // return true; + } + else { + idx_file = fopen(((mRequest->mDir) +"/index").c_str(), "r"); + } + + if (idx_file == NULL){ + *(mLog->log()) << DEBUGPREFIX + << " failed to open idx file = "<< (mRequest->mDir +"/index").c_str() + << endl; + sendError(404, "Not Found", NULL, "Failed to open Index file"); + return OKAY; + } + + int buffered_frames = 50; + char *index_buf = new char[8 *buffered_frames]; // 50 indexes + + *(mLog->log()) << DEBUGPREFIX + << " seeking to start_frame= " << start_frame + << " fps= " << fps << endl; + fseek(idx_file, start_frame * 8, SEEK_SET); + + int buffered_indexes = fread(index_buf, 8, (buffered_frames), idx_file); + + fclose(idx_file); + + if(buffered_indexes <= 0 ) { + *(mLog->log())<<DEBUGPREFIX + << " issue while reading, buffered_indexes <=0" << endl; + delete[] index_buf; + sendError(404, "Not Found", NULL, "Failed to read Index file"); + return OKAY; + } + + *(mLog->log()) << DEBUGPREFIX + << " Finding I-Frame now" << endl; + + + bool found_it = false; + int i = 0; + + uint32_t offset = 0; + int idx =0; + int type =0; + + for (i= 0; i < buffered_indexes; i++){ + if (is_pes) { + tIndexPes in_read_pes; + memcpy (&in_read_pes, &(index_buf[i*8]), 8); + type = in_read_pes.type == 1; + idx = in_read_pes.number; + offset = in_read_pes.offset; + } + else{ + tIndexTs in_read_ts; + memcpy (&in_read_ts, &(index_buf[i*8]), 8); + type = in_read_ts.independent; + idx = in_read_ts.number; + offset = in_read_ts.offset; + } + + *(mLog->log()) << DEBUGPREFIX + << " Frame= " << i + << " idx= "<< idx + << " offset= " << offset + << " type= " << type + << endl; + if (type){ + found_it = true; + break; + } + } + + if (!found_it) { + delete[] index_buf; + sendError(404, "Not Found", NULL, "Failed to read Index file"); + return OKAY; + } + + mVdrIdx = idx; + + *(mLog->log()) << DEBUGPREFIX + << " idx= "<< mVdrIdx + << " offset= " << offset + << endl; + + delete[] index_buf; + + char pathbuf[4096]; + snprintf(pathbuf, sizeof(pathbuf), mFileStructure.c_str(), (mRequest->mPath).c_str(), mVdrIdx); + + *(mLog->log()) << DEBUGPREFIX + << " Opening Path= " + << pathbuf << endl; + if (openFile(pathbuf) != OKAY) { + sendError(403, "Forbidden", NULL, "Access denied."); + return true; + } + + fseek(mFile, offset, SEEK_SET); + + if (mStreamToEnd) { + sendHeaders(200, "OK", NULL, "video/mpeg", -1, -1); + return true; + } + + uint64_t file_size = 0; + bool more_to_go = true; + int vdr_idx = mVdrIdx; + + while (more_to_go) { + snprintf(pathbuf, sizeof(pathbuf), mFileStructure.c_str(), (mRequest->mPath).c_str(), vdr_idx); + if (stat(pathbuf, statbuf) >= 0) { + *(mLog->log())<< " found for " << pathbuf << endl; + file_size += statbuf->st_size; + } + else { + more_to_go = false; + } + vdr_idx ++; + } + mRemLength = file_size - offset; + + *(mLog->log()) << DEBUGPREFIX + << " Done. Start Streaming " + << endl; + + if ((mRequest->rangeHdr).isRangeRequest) { + snprintf(pathbuf, sizeof(pathbuf), "Content-Range: bytes 0-%lld/%lld", (mRemLength -1), mRemLength); + sendHeaders(206, "Partial Content", pathbuf, "video/mpeg", mRemLength, statbuf->st_mtime); + } + else { + sendHeaders(200, "OK", NULL, "video/mpeg", mRemLength, -1); + } + return true; +#else + return false; +#endif +} + +// Needed by createRecordings.xml and byCreateManifest +void cResponseVdrDir::checkRecording() { + // sets mIsRecording to true when the recording is still on-going + mIsRecording = false; + +#ifndef STANDALONE + time_t now = time(NULL); + + // cRecordings* recordings = mFactory->getRecordings(); + cRecordings* recordings = &Recordings; +#ifndef DEBUG + *(mLog->log())<< DEBUGPREFIX + << " GetByName(" <<(mRequest->mPath).c_str() << ")" + << endl; +#endif + cRecording* rec = recordings->GetByName((mRequest->mPath).c_str()); + if (rec != NULL) { + const cEvent *ev = rec->Info()->GetEvent(); + if (ev != NULL) { + if (now < ev->EndTime()) { + // still recording + mIsRecording = true; + + // mRecProgress * curFileSize = estimated File Size + mRecProgress = (ev->EndTime() - ev->StartTime()) *1.1 / (rec->NumFrames() / rec->FramesPerSecond()); + // mRecProgress = (ev->EndTime() - ev->StartTime()) *1.0/ (now - ev->StartTime()); +#ifndef DEBUG + *(mLog->log())<< DEBUGPREFIX + << " **** is still recording for mIsRecording= " + << mIsRecording + << " mRecProgress= " << mRecProgress << endl; +#endif + } + } + +#ifndef DEBUG + *(mLog->log())<< DEBUGPREFIX + << " checking, whether recording is on-going" + << " now= " << now << " start= " << rec->Start() + << " curDur= " << rec->LengthInSeconds() + << endl; +#endif + } +#ifndef DEBUG + else { + *(mLog->log())<< DEBUGPREFIX + << " **** Recording Entry Not found **** " << endl; + } +#endif +#endif +} + + + +int cResponseVdrDir::sendVdrDir(struct stat *statbuf) { + +#ifndef DEBUG + *(mLog->log())<< DEBUGPREFIX << " *** sendVdrDir mPath= " << mRequest->mPath << endl; +#endif + + char pathbuf[4096]; + char f[400]; + int vdr_idx = 0; + uint64_t total_file_size = 0; + // int ret = OKAY; + string vdr_dir = mRequest->mPath; + vector<sVdrFileEntry> file_sizes; + bool more_to_go = true; + + if (isHeadRequest()) + return OKAY; + + checkRecording(); + + mVdrIdx = 1; + mFileStructure = "%s/%03d.vdr"; + + snprintf(pathbuf, sizeof(pathbuf), mFileStructure.c_str(), (mRequest->mPath).c_str(), 1); + if (stat(pathbuf, statbuf) < 0) { + mFileStructure = "%s/%05d.ts"; +#ifndef DEBUG + *(mLog->log())<< DEBUGPREFIX << " using dir format: " << mFileStructure.c_str() << endl; +#endif + } + + // The range request functions are activated, when a time header is detected + if (isTimeRequest(statbuf)) { + *(mLog->log())<< DEBUGPREFIX + << " isTimeRequest is true" + << endl; + return OKAY; + } + + // --- looup all vdr files in the dir --- + while (more_to_go) { + vdr_idx ++; + snprintf(pathbuf, sizeof(pathbuf), mFileStructure.c_str(), (mRequest->mPath).c_str(), vdr_idx); + if (stat(pathbuf, statbuf) >= 0) { +#ifndef DEBUG + *(mLog->log())<< " found for " << pathbuf << endl; +#endif + file_sizes.push_back(sVdrFileEntry(statbuf->st_size, total_file_size, vdr_idx)); + total_file_size += statbuf->st_size; + } + else { + more_to_go = false; + } + } + if (file_sizes.size() < 1) { + // There seems to be vdr video file in the directory + *(mLog->log())<< DEBUGPREFIX + << " No video file in the directory" + << endl; + sendError(404, "Not Found", NULL, "File not found."); + return OKAY; + } + +#ifndef DEBUG + *(mLog->log())<< DEBUGPREFIX + << " vdr filesize list " + << DEBUGHDR << endl; + for (uint i = 0; i < file_sizes.size(); i++) + *(mLog->log())<< " i= " << i << " size= " << file_sizes[i].sSize << " firstOffset= " << file_sizes[i].sFirstOffset << endl; + *(mLog->log())<< " total_file_size= " << total_file_size << endl << endl; +#endif + + // total_file_size (on disk) + + // ---------------- file sizes --------------------- + + uint cur_idx = 0; + +#ifndef DEBUG + if (mIsRecording) { + snprintf(f, sizeof(f), " CurFileSize= %lld mRecProgress= %f ExtFileSize= %lld", total_file_size, mRecProgress, (long long int)(mRecProgress * total_file_size)); + *(mLog->log()) << DEBUGPREFIX + << endl << " isRecording: " << f + << endl; + } +#endif + + if (!(mRequest->rangeHdr).isRangeRequest) { + snprintf(pathbuf, sizeof(pathbuf), mFileStructure.c_str(), (mRequest->mPath).c_str(), file_sizes[cur_idx].sIdx); + + if (openFile(pathbuf) != OKAY) { + sendError(403, "Forbidden", NULL, "Access denied."); + return OKAY; + } + + mRemLength = total_file_size; + + sendHeaders(200, "OK", NULL, "video/mpeg", ((mIsRecording) ? (mRecProgress * total_file_size): total_file_size ), statbuf->st_mtime); + } + else { // Range request + // idenify the first file +#ifndef DEBUG + *(mLog->log()) << DEBUGPREFIX + << endl <<" --- Range Request Handling ---" + << DEBUGHDR << endl; +#endif + if (mIsRecording && ((mRequest->rangeHdr).begin > total_file_size)) { + *(mLog->log()) << DEBUGPREFIX + << " ERROR: Not yet available" << endl; + sendError(404, "Not Found", NULL, "File not found."); + return OKAY; + } + cur_idx = file_sizes.size() -1; + for (uint i = 1; i < file_sizes.size(); i++) { + if ((mRequest->rangeHdr).begin < file_sizes[i].sFirstOffset ) { + cur_idx = i -1; + break; + } + } + +#ifndef DEBUG + *(mLog->log())<< " Identified Record i= " << cur_idx << " file_sizes[i].sFirstOffset= " + << file_sizes[cur_idx].sFirstOffset << " rangeHdr.begin= " << rangeHdr.begin + << " vdr_no= " << file_sizes[cur_idx].sIdx << endl; +#endif + + mVdrIdx = file_sizes[cur_idx].sIdx; + snprintf(pathbuf, sizeof(pathbuf), mFileStructure.c_str(), (mRequest->mPath).c_str(), file_sizes[cur_idx].sIdx); +#ifndef DEBUG + *(mLog->log())<< " file identified= " << pathbuf << endl; +#endif + if (openFile(pathbuf) != OKAY) { + *(mLog->log())<< "----- fopen failed dump ----------" << endl; + *(mLog->log())<< DEBUGPREFIX + << " vdr filesize list " + << endl; + for (uint i = 0; i < file_sizes.size(); i++) + *(mLog->log())<< " i= " << i << " size= " << file_sizes[i].sSize << " firstOffset= " << file_sizes[i].sFirstOffset << endl; + *(mLog->log())<< " total_file_size= " << total_file_size << endl << endl; + + *(mLog->log())<< " Identified Record i= " << cur_idx << " file_sizes[i].sFirstOffset= " + << file_sizes[cur_idx].sFirstOffset << " rangeHdr.begin= " << (mRequest->rangeHdr).begin + << " vdr_no= " << file_sizes[cur_idx].sIdx << endl; + *(mLog->log())<< "---------------" << endl; + sendError(403, "Forbidden", NULL, "Access denied."); + return OKAY; + } + mRequest->mDir = mRequest->mPath; + mRequest->mPath = pathbuf; +#ifndef DEBUG + *(mLog->log())<< " Seeking into file= " << (rangeHdr.begin - file_sizes[cur_idx].sFirstOffset) + << " cur_idx= " << cur_idx + << " file_sizes[cur_idx].sFirstOffset= " << file_sizes[cur_idx].sFirstOffset + << endl; +#endif + fseek(mFile, ((mRequest->rangeHdr).begin - file_sizes[cur_idx].sFirstOffset), SEEK_SET); + if ((mRequest->rangeHdr).end == 0) + (mRequest->rangeHdr).end = ((mIsRecording) ? (mRecProgress * total_file_size): total_file_size); + + mRemLength = ((mRequest->rangeHdr).end-(mRequest->rangeHdr).begin); + + snprintf(f, sizeof(f), "Content-Range: bytes %lld-%lld/%lld", (mRequest->rangeHdr).begin, ((mRequest->rangeHdr).end -1), + ((mIsRecording) ? (long long int)(mRecProgress * total_file_size): total_file_size)); + + sendHeaders(206, "Partial Content", f, "video/mpeg", ((mRequest->rangeHdr).end-(mRequest->rangeHdr).begin), statbuf->st_mtime); + } + +#ifndef DEBUG + *(mLog->log())<< " ***** Yes, vdr dir found ***** mPath= " << mRequest->mPath << endl; +#endif + + return OKAY; // handleRead() done +} + + + + +//----------------------------------------------------------------- +// ----- Send Segment ----- +//----------------------------------------------------------------- + +int cResponseVdrDir::sendMediaSegment (struct stat *statbuf) { + if (isHeadRequest()) + return OKAY; + +#ifndef STANDALONE + + *(mLog->log()) << DEBUGPREFIX << " sendMediaSegment " << mRequest->mPath << endl; + size_t pos = (mRequest->mPath).find_last_of ("/"); + + mRequest->mDir = (mRequest->mPath).substr(0, pos); + string seg_name = (mRequest->mPath).substr(pos+1); + int seg_number; + + int seg_dur = mRequest->mFactory->getConfig()->getSegmentDuration(); + int frames_per_seg = 0; + + sscanf(seg_name.c_str(), "%d-seg.ts", &seg_number); + + //FIXME: Do some consistency checks on the seg_number + //* Does the segment exist + + cRecordings* recordings = &Recordings; + cRecording* rec = recordings->GetByName((mRequest->mDir).c_str()); + if (rec != NULL) { + frames_per_seg = seg_dur * rec->FramesPerSecond(); + } + else { + *(mLog->log()) << DEBUGPREFIX << " ERROR: Ooops, rec is NULL, assuming 25 fps " << endl; + frames_per_seg = seg_dur * 25; + } + //FIXME: HD Fix + // frames_per_seg = seg_dur * 25; + + *(mLog->log()) << DEBUGPREFIX + << " mDir= " << mRequest->mDir + << " seg_name= " << seg_name + << " seg_number= "<< seg_number + << " fps= " << rec->FramesPerSecond() + << " frames_per_seg= " << frames_per_seg + << endl; + int start_frame_count = (seg_number -1) * frames_per_seg; + + FILE* idx_file = fopen((mRequest->mDir +"/index").c_str(), "r"); + if (idx_file == NULL){ + *(mLog->log()) << DEBUGPREFIX + << " failed to open idx file = "<< (mRequest->mDir +"/index").c_str() + << endl; + sendError(404, "Not Found", NULL, "Failed to open Index file"); + return OKAY; + } + + char *index_buf = new char[(frames_per_seg +3) *8]; + + // fseek to start_frame_count * sizeof(in_read) + fseek(idx_file, start_frame_count * 8, SEEK_SET); + + // read to (seg_number * frames_per_seg +1) * sizeof(in_read) + // buffersize is frames_per_seg * seg_number * sizeof(in_read) + int buffered_indexes = fread(index_buf, 8, (frames_per_seg +2), idx_file); + + fclose(idx_file); + + if(buffered_indexes <= 0 ) { + *(mLog->log())<<DEBUGPREFIX + << " issue while reading" << endl; + delete[] index_buf; + sendError(404, "Not Found", NULL, "Failed to read Index file"); + return OKAY; + } + + // Reading the segment + mFileStructure = "%s/%05d.ts"; + int start_offset = -1; + int start_idx = -1; + + tIndexTs in_read_ts; + memcpy (&in_read_ts, &(index_buf[0]), 8); + + start_offset = in_read_ts.offset; + start_idx = in_read_ts.number; + + char seg_fn[200]; + mVdrIdx = start_idx; + + snprintf(seg_fn, sizeof(seg_fn), mFileStructure.c_str(), (mRequest->mDir).c_str(), mVdrIdx); + (mRequest->mPath) = seg_fn; + + /* + * Now we determine the end of the segment + */ + memcpy (&in_read_ts, &(index_buf[(frames_per_seg)*8]), 8); + + int end_idx = in_read_ts.number; + int end_offset = in_read_ts.offset; + + /*#ifndef DEBUG*/ + *(mLog->log()) << DEBUGPREFIX + << " GenSegment: start (no/idx)= " << start_idx << " / " << start_offset + << " to (no/idx)= " << end_idx << " / " << end_offset + << endl; + /*#endif*/ + + delete[] index_buf; + + int rem_len = 0; + bool error = false; + if (start_idx == end_idx){ + mRemLength = (end_offset - start_offset); + +#ifndef DEBUG + *(mLog->log()) << DEBUGPREFIX + << " start_idx == end_idx: mRemLength= " <<mRemLength + << endl; +#endif + } + else { +#ifndef DEBUG + *(mLog->log()) << DEBUGPREFIX + << " start_idx < end_idx " + << endl; +#endif + snprintf(seg_fn, sizeof(seg_fn), mFileStructure.c_str(), (mRequest->mDir).c_str(), mVdrIdx); + if (stat(seg_fn, statbuf) < 0) { + *(mLog->log()) << DEBUGPREFIX + << " file= " <<seg_fn << " does not exist" + << endl; + error= true; + // issue: + } + rem_len = statbuf->st_size - start_offset; // remaining length of the first segment + + // loop over all idx files between start_idx and end_idx + for (int idx = (start_idx+1); idx < end_idx; idx ++) { + snprintf(seg_fn, sizeof(seg_fn), mFileStructure.c_str(), (mRequest->mDir).c_str(), idx); + if (stat(seg_fn, statbuf) < 0) { + *(mLog->log()) << DEBUGPREFIX + << " for loop file= " <<seg_fn << " does not exist" + << endl; + error = true; + break; + // issue: + } + rem_len += statbuf->st_size; // remaining length of the first segment + } + rem_len += end_offset; // + mRemLength = rem_len; + snprintf(seg_fn, sizeof(seg_fn), mFileStructure.c_str(), (mRequest->mDir).c_str(), mVdrIdx); + +#ifndef DEBUG + *(mLog->log()) << DEBUGPREFIX + << " start_idx= " << start_idx << " != end_idx= "<< end_idx <<": mRemLength= " <<mRemLength + << endl; +#endif + } + + if (error){ + sendError(404, "Not Found", NULL, "Not all inputs exists"); + return OKAY; + } + + // mContentType = VDRDIR; + + if (openFile(seg_fn) != OKAY) { + *(mLog->log())<< DEBUGPREFIX << " Failed to open file= " << seg_fn + << " mRemLength= " << mRemLength<< endl; + sendError(404, "Not Found", NULL, "File not found."); + return OKAY; + } + fseek(mFile, start_offset, SEEK_SET); + + sendHeaders(200, "OK", NULL, "video/mpeg", mRemLength, -1); + +#endif + return OKAY; +} + +int cResponseVdrDir::openFile(const char *name) { + mFile = fopen(name, "r"); + if (!mFile) { + *(mLog->log())<< DEBUGPREFIX + << " fopen failed pathbuf= " << name + << endl; + // sendError(403, "Forbidden", NULL, "Access denied."); + return ERROR; + } + return OKAY; +} + + +int cResponseVdrDir::fillDataBlk() { + char pathbuf[4096]; + + if (mError) + return ERROR; + + mBlkPos = 0; + int to_read = 0; + + + // Range requests are assumed to be all open + if (mFile == NULL) { + *(mLog->log()) << DEBUGPREFIX << " no open file anymore " + << "--> Done " << endl; + return ERROR; + } + if ((mRemLength == 0) && !mStreamToEnd){ +#ifndef DEBUG + *(mLog->log()) << DEBUGPREFIX << " mRemLength is zero " + << "--> Done " << endl; +#endif + fclose(mFile); + mFile = NULL; + return ERROR; + } + if (!mStreamToEnd) + to_read = ((mRemLength > MAXLEN) ? MAXLEN : mRemLength); + else + to_read = MAXLEN; + + mBlkLen = fread(mBlkData, 1, to_read, mFile); + if (!mStreamToEnd) + mRemLength -= mBlkLen; + + if ((mRemLength == 0) && (!mStreamToEnd)) { +#ifndef DEBUG + *(mLog->log()) << DEBUGPREFIX << " last Block read " + << "--> Almost Done " << endl; +#endif + return OKAY; + } + + // if (mBlkLen != MAXLEN) { // thlo verify + if (mBlkLen != to_read) { + fclose(mFile); + mFile = NULL; + mVdrIdx ++; + + snprintf(pathbuf, sizeof(pathbuf), mFileStructure.c_str(), (mRequest->mDir).c_str(), mVdrIdx); + mRequest->mPath = pathbuf; + + if (openFile(pathbuf) != OKAY) { + *(mLog->log())<< DEBUGPREFIX << " Failed to open file= " << pathbuf << " mRemLength= " << mRemLength<< endl; + mFile = NULL; + if (mBlkLen == 0) { + *(mLog->log()) << DEBUGPREFIX << " mBlkLen is zero --> Done " << endl; + return ERROR; + } + else + *(mLog->log()) << DEBUGPREFIX << " Still data to send mBlkLen= " << mBlkLen <<" --> continue " << endl; + return OKAY; + } // Error: Open next file failed + + if (mBlkLen == 0) { + if (!mStreamToEnd) + to_read = ((mRemLength > MAXLEN) ? MAXLEN : mRemLength); + else + to_read = MAXLEN; + mBlkLen = fread(mBlkData, 1, to_read, mFile); + if (!mStreamToEnd) + mRemLength -= mBlkLen ; + } + } + return OKAY; +} |