X-Git-Url: http://code.vuplus.com/gitweb/?p=vuplus_dvbapp;a=blobdiff_plain;f=lib%2Fbase%2Frawfile.cpp;h=e32b262ad612813633cb283b7276430f6f0eb55f;hp=415608ca70c42463f21fb4dcca69fd2d09527442;hb=HEAD;hpb=d25fab33b0d6348c7b28b5060dc7d1ff42bacc44 diff --git a/lib/base/rawfile.cpp b/lib/base/rawfile.cpp index 415608c..e32b262 100644 --- a/lib/base/rawfile.cpp +++ b/lib/base/rawfile.cpp @@ -1,11 +1,16 @@ +#include #include #include #include #include +DEFINE_REF(eRawFile); + eRawFile::eRawFile() + :m_lock(false) { m_fd = -1; + m_file = 0; m_splitsize = 0; m_totallength = 0; m_current_offset = 0; @@ -20,30 +25,57 @@ eRawFile::~eRawFile() close(); } -int eRawFile::open(const char *filename) +int eRawFile::open(const char *filename, int cached) { close(); + m_cached = cached; m_basename = filename; scan(); m_current_offset = 0; m_last_offset = 0; - m_fd = ::open(filename, O_RDONLY | O_LARGEFILE); - return m_fd; + if (!m_cached) + { + m_fd = ::open(filename, O_RDONLY | O_LARGEFILE); + return m_fd; + } else + { + m_file = ::fopen64(filename, "rb"); + if (!m_file) + return -1; + return 0; + } } void eRawFile::setfd(int fd) { close(); + m_cached = 0; m_nrfiles = 1; m_fd = fd; } off_t eRawFile::lseek(off_t offset, int whence) { + eSingleLocker l(m_lock); + m_current_offset = lseek_internal(offset, whence); + return m_current_offset; +} + +off_t eRawFile::lseek_internal(off_t offset, int whence) +{ // eDebug("lseek: %lld, %d", offset, whence); /* if there is only one file, use the native lseek - the file could be growing! */ if (m_nrfiles < 2) - return ::lseek(m_fd, offset, whence); + { + if (!m_cached) + return ::lseek(m_fd, offset, whence); + else + { + if (::fseeko(m_file, offset, whence) < 0) + perror("fseeko"); + return ::ftello(m_file); + } + } switch (whence) { case SEEK_SET: @@ -64,16 +96,34 @@ off_t eRawFile::lseek(off_t offset, int whence) int eRawFile::close() { - int ret = ::close(m_fd); - m_fd = -1; - return ret; + if (m_cached) + { + if (!m_file) + return -1; + ::fclose(m_file); + m_file = 0; + return 0; + } else + { + int ret = ::close(m_fd); + m_fd = -1; + return ret; + } } -ssize_t eRawFile::read(void *buf, size_t count) +ssize_t eRawFile::read(off_t offset, void *buf, size_t count) { -// eDebug("read: %p, %d", buf, count); + eSingleLocker l(m_lock); + + if (offset != m_current_offset) + { + m_current_offset = lseek_internal(offset, SEEK_SET); + if (m_current_offset < 0) + return m_current_offset; + } + switchOffset(m_current_offset); - + if (m_nrfiles >= 2) { if (m_current_offset + count > m_totallength) @@ -82,7 +132,13 @@ ssize_t eRawFile::read(void *buf, size_t count) return 0; } - int ret = ::read(m_fd, buf, count); + int ret; + + if (!m_cached) + ret = ::read(m_fd, buf, count); + else + ret = ::fread(buf, 1, count, m_file); + if (ret > 0) m_current_offset = m_last_offset += ret; return ret; @@ -90,7 +146,10 @@ ssize_t eRawFile::read(void *buf, size_t count) int eRawFile::valid() { - return m_fd != -1; + if (!m_cached) + return m_fd != -1; + else + return !!m_file; } void eRawFile::scan() @@ -99,13 +158,26 @@ void eRawFile::scan() m_totallength = 0; while (m_nrfiles < 1000) /* .999 is the last possible */ { - int f = openFile(m_nrfiles); - if (f < 0) - break; - if (!m_nrfiles) - m_splitsize = ::lseek(f, 0, SEEK_END); - m_totallength += ::lseek(f, 0, SEEK_END); - ::close(f); + if (!m_cached) + { + int f = openFileUncached(m_nrfiles); + if (f < 0) + break; + if (!m_nrfiles) + m_splitsize = ::lseek(f, 0, SEEK_END); + m_totallength += ::lseek(f, 0, SEEK_END); + ::close(f); + } else + { + FILE *f = openFileCached(m_nrfiles); + if (!f) + break; + ::fseeko(f, 0, SEEK_END); + if (!m_nrfiles) + m_splitsize = ::ftello(f); + m_totallength += ::ftello(f); + ::fclose(f); + } ++m_nrfiles; } @@ -123,7 +195,10 @@ int eRawFile::switchOffset(off_t off) { // eDebug("-> %d", filenr); close(); - m_fd = openFile(filenr); + if (!m_cached) + m_fd = openFileUncached(filenr); + else + m_file = openFileCached(filenr); m_last_offset = m_base_offset = m_splitsize * filenr; m_current_file = filenr; } @@ -132,18 +207,35 @@ int eRawFile::switchOffset(off_t off) if (off != m_last_offset) { -// eDebug("%llx != %llx", off, m_last_offset); - m_last_offset = ::lseek(m_fd, off - m_base_offset, SEEK_SET) + m_base_offset; -// eDebug("offset now %llx", m_last_offset); + if (!m_cached) + m_last_offset = ::lseek(m_fd, off - m_base_offset, SEEK_SET) + m_base_offset; + else + { + ::fseeko(m_file, off - m_base_offset, SEEK_SET); + m_last_offset = ::ftello(m_file) + m_base_offset; + } return m_last_offset; } else { -// eDebug("offset already ok"); return m_last_offset; } } -int eRawFile::openFile(int nr) +/* m_cached */ +FILE *eRawFile::openFileCached(int nr) +{ + std::string filename = m_basename; + if (nr) + { + char suffix[5]; + snprintf(suffix, 5, ".%03d", nr); + filename += suffix; + } + return ::fopen64(filename.c_str(), "rb"); +} + +/* !m_cached */ +int eRawFile::openFileUncached(int nr) { std::string filename = m_basename; if (nr) @@ -152,5 +244,15 @@ int eRawFile::openFile(int nr) snprintf(suffix, 5, ".%03d", nr); filename += suffix; } - return ::open(filename.c_str(), O_RDONLY); + return ::open(filename.c_str(), O_RDONLY | O_LARGEFILE); +} + +off_t eRawFile::length() +{ + return m_totallength; +} + +off_t eRawFile::offset() +{ + return m_last_offset; }