QTfrontend/util/FileEngine.cpp
branchwebgl
changeset 8330 aaefa587e277
parent 8206 1633a6510834
child 8714 ab201a62d115
--- a/QTfrontend/util/FileEngine.cpp	Sun Dec 02 00:03:16 2012 +0100
+++ b/QTfrontend/util/FileEngine.cpp	Tue Dec 25 04:45:22 2012 +0100
@@ -1,322 +1,380 @@
-/* borrowed from https://github.com/skhaz/qt-physfs-wrapper
- * TODO: add copyright header, determine license
- */
-
-#include "hwpacksmounter.h"
-#include "FileEngine.h"
-
-
-const QString FileEngineHandler::scheme = "physfs:/";
-
-FileEngine::FileEngine(const QString& filename)
-: _handler(NULL)
-, _flags(0)
-{
-    setFileName(filename);
-}
-
-FileEngine::~FileEngine()
-{
-    close();
-}
-
-bool FileEngine::open(QIODevice::OpenMode openMode)
-{
-    close();
-
-    if (openMode & QIODevice::WriteOnly) {
-        _handler = PHYSFS_openWrite(_filename.toUtf8().constData());
-        _flags = QAbstractFileEngine::WriteOwnerPerm | QAbstractFileEngine::WriteUserPerm | QAbstractFileEngine::FileType;
-    }
-
-    else if (openMode & QIODevice::ReadOnly) {
-        _handler = PHYSFS_openRead(_filename.toUtf8().constData());
-    }
-
-    else if (openMode & QIODevice::Append) {
-        _handler = PHYSFS_openAppend(_filename.toUtf8().constData());
-    }
-
-    else {
-        qWarning("Bad file open mode: %d", (int)openMode);
-    }
-
-    if (!_handler) {
-        qWarning("Failed to open %s, reason: %s", _filename.toUtf8().constData(), PHYSFS_getLastError());
-        return false;
-    }
-
-    return true;
-}
-
-bool FileEngine::close()
-{
-    if (isOpened()) {
-        int result = PHYSFS_close(_handler);
-        _handler = NULL;
-        return result != 0;
-    }
-
-    return true;
-}
-
-bool FileEngine::flush()
-{
-    return PHYSFS_flush(_handler) != 0;
-}
-
-qint64 FileEngine::size() const
-{
-    return _size;
-}
-
-qint64 FileEngine::pos() const
-{
-    return PHYSFS_tell(_handler);
-}
-
-bool FileEngine::seek(qint64 pos)
-{
-    return PHYSFS_seek(_handler, pos) != 0;
-}
-
-bool FileEngine::isSequential() const
-{
-    return false;
-}
-
-bool FileEngine::remove()
-{
-    return PHYSFS_delete(_filename.toUtf8().constData()) != 0;
-}
-
-bool FileEngine::mkdir(const QString &dirName, bool createParentDirectories) const
-{
-    Q_UNUSED(createParentDirectories);
-    return PHYSFS_mkdir(dirName.toUtf8().constData()) != 0;
-}
-
-bool FileEngine::rmdir(const QString &dirName, bool recurseParentDirectories) const
-{
-    Q_UNUSED(recurseParentDirectories);
-    return PHYSFS_delete(dirName.toUtf8().constData()) != 0;
-}
-
-bool FileEngine::caseSensitive() const
-{
-    return true;
-}
-
-bool FileEngine::isRelativePath() const
-{
-    return true;
-}
-
-QAbstractFileEngineIterator * FileEngine::beginEntryList(QDir::Filters filters, const QStringList &filterNames)
-{
-    return new FileEngineIterator(filters, filterNames, entryList(filters, filterNames));
-}
-
-QStringList FileEngine::entryList(QDir::Filters filters, const QStringList &filterNames) const
-{
-    Q_UNUSED(filters);
-
-    QString file;
-    QStringList result;
-    char **files = PHYSFS_enumerateFiles(_filename.toUtf8().constData());
-
-    for (char **i = files; *i != NULL; i++) {
-        file = QString::fromUtf8(*i);
-
-        if (filterNames.isEmpty() || QDir::match(filterNames, file)) {
-            result << file;
-        }
-    }
-
-    PHYSFS_freeList(files);
-
-    return result;
-}
-
-QAbstractFileEngine::FileFlags FileEngine::fileFlags(FileFlags type) const
-{
-    return type & _flags;
-}
-
-QString FileEngine::fileName(FileName file) const
-{
-    switch(file)
-    {
-        case QAbstractFileEngine::AbsolutePathName:
-        {
-            QString s(PHYSFS_getWriteDir());
-            return s;
-        }
-        case QAbstractFileEngine::BaseName:
-        {
-            int l = _filename.lastIndexOf('/');
-            QString s = _filename.mid(l + 1);
-            return s;
-        }
-        case QAbstractFileEngine::DefaultName:
-        case QAbstractFileEngine::AbsoluteName:
-        default:
-        {
-            QString s = "physfs:/" + _filename;
-            return s;
-        }
-    }
-}
-
-QDateTime FileEngine::fileTime(FileTime time) const
-{
-
-    switch (time)
-    {
-        case QAbstractFileEngine::ModificationTime:
-        default:
-            return _datetime;
-            break;
-    };
-}
-
-void FileEngine::setFileName(const QString &file)
-{
-    if(file.startsWith(FileEngineHandler::scheme))
-        _filename = file.mid(FileEngineHandler::scheme.size());
-    else
-        _filename = file;
-
-    PHYSFS_Stat stat;
-    if (PHYSFS_stat(_filename.toUtf8().constData(), &stat) != 0) {
-        _size = stat.filesize;
-        _datetime = QDateTime::fromTime_t(stat.modtime);
-//        _flags |= QAbstractFileEngine::WriteUserPerm;
-        _flags |= QAbstractFileEngine::ReadUserPerm;
-        _flags |= QAbstractFileEngine::ExistsFlag;
-
-        switch (stat.filetype)
-        {
-            case PHYSFS_FILETYPE_REGULAR:
-                _flags |= QAbstractFileEngine::FileType;
-                break;
-
-            case PHYSFS_FILETYPE_DIRECTORY:
-                _flags |= QAbstractFileEngine::DirectoryType;
-                break;
-            case PHYSFS_FILETYPE_SYMLINK:
-                _flags |= QAbstractFileEngine::LinkType;
-                break;
-            default: ;
-        }
-    }
-}
-
-bool FileEngine::atEnd() const
-{
-    return PHYSFS_eof(_handler) != 0;
-}
-
-qint64 FileEngine::read(char *data, qint64 maxlen)
-{
-    return PHYSFS_readBytes(_handler, data, maxlen);
-}
-
-qint64 FileEngine::write(const char *data, qint64 len)
-{
-    return PHYSFS_writeBytes(_handler, data, len);
-}
-
-bool FileEngine::isOpened() const
-{
-    return _handler != NULL;
-}
-
-QFile::FileError FileEngine::error() const
-{
-    return QFile::UnspecifiedError;
-}
-
-QString FileEngine::errorString() const
-{
-    return PHYSFS_getLastError();
-}
-
-bool FileEngine::supportsExtension(Extension extension) const
-{
-    return extension == QAbstractFileEngine::AtEndExtension;
-}
-
-
-
-FileEngineHandler::FileEngineHandler(char *argv0)
-{
-    PHYSFS_init(argv0);
-}
-
-FileEngineHandler::~FileEngineHandler()
-{
-    PHYSFS_deinit();
-}
-
-QAbstractFileEngine* FileEngineHandler::create(const QString &filename) const
-{
-    if (filename.startsWith(scheme))
-        return new FileEngine(filename.mid(scheme.size()));
-    else
-        return NULL;
-}
-
-void FileEngineHandler::mount(const QString &path)
-{
-    PHYSFS_mount(path.toUtf8().constData(), NULL, 1);
-}
-
-void FileEngineHandler::mount(const QString & path, const QString & mountPoint)
-{
-    PHYSFS_mount(path.toUtf8().constData(), mountPoint.toUtf8().constData(), 1);
-}
-
-void FileEngineHandler::setWriteDir(const QString &path)
-{
-    PHYSFS_setWriteDir(path.toUtf8().constData());
-}
-
-void FileEngineHandler::mountPacks()
-{
-    hedgewarsMountPackages();
-}
-
-
-FileEngineIterator::FileEngineIterator(QDir::Filters filters, const QStringList &nameFilters, const QStringList &entries)
-    : QAbstractFileEngineIterator(filters, nameFilters)
-{
-    m_entries = entries;
-
-    /* heck.. docs are unclear on this
-     * QDirIterator puts iterator before first entry
-     * but QAbstractFileEngineIterator example puts iterator on first entry
-     * though QDirIterator approach seems to be the right one
-     */
-
-    m_index = -1;
-}
-
-bool FileEngineIterator::hasNext() const
-{
-    return m_index < m_entries.size() - 1;
-}
-
-QString FileEngineIterator::next()
-{
-   if (!hasNext())
-       return QString();
-
-   ++m_index;
-   return currentFilePath();
-}
-
-QString FileEngineIterator::currentFileName() const
-{
-    return m_entries.at(m_index);
-}
+/* borrowed from https://github.com/skhaz/qt-physfs-wrapper
+ * TODO: add copyright header, determine license
+ */
+
+#include "hwpacksmounter.h"
+#include "FileEngine.h"
+
+
+const QString FileEngineHandler::scheme = "physfs:/";
+
+FileEngine::FileEngine(const QString& filename)
+    : m_handle(NULL)
+    , m_size(0)
+    , m_flags(0)
+    , m_bufferSet(false)
+    , m_readWrite(false)
+{
+    setFileName(filename);
+}
+
+FileEngine::~FileEngine()
+{
+    close();
+}
+
+bool FileEngine::open(QIODevice::OpenMode openMode)
+{
+    close();
+
+    if ((openMode & QIODevice::ReadWrite) == QIODevice::ReadWrite) {
+        m_handle = PHYSFS_openAppend(m_fileName.toUtf8().constData());
+        if(m_handle)
+        {
+            m_readWrite = true;
+            seek(0);
+        }
+    }
+
+    else if (openMode & QIODevice::WriteOnly) {
+        m_handle = PHYSFS_openWrite(m_fileName.toUtf8().constData());
+        m_flags = QAbstractFileEngine::WriteOwnerPerm | QAbstractFileEngine::WriteUserPerm | QAbstractFileEngine::FileType;
+    }
+
+    else if (openMode & QIODevice::ReadOnly) {
+        m_handle = PHYSFS_openRead(m_fileName.toUtf8().constData());
+    }
+
+    else if (openMode & QIODevice::Append) {
+        m_handle = PHYSFS_openAppend(m_fileName.toUtf8().constData());
+    }
+
+    else {
+        qWarning("[PHYSFS] Bad file open mode: %d", (int)openMode);
+    }
+
+    if (!m_handle) {
+        qWarning("[PHYSFS] Failed to open %s, reason: %s", m_fileName.toUtf8().constData(), PHYSFS_getLastError());
+        return false;
+    }
+
+    return true;
+}
+
+bool FileEngine::close()
+{
+    if (isOpened()) {
+        int result = PHYSFS_close(m_handle);
+        m_handle = NULL;
+        return result != 0;
+    }
+
+    return true;
+}
+
+bool FileEngine::flush()
+{
+    return PHYSFS_flush(m_handle) != 0;
+}
+
+qint64 FileEngine::size() const
+{
+    return m_size;
+}
+
+qint64 FileEngine::pos() const
+{
+    return PHYSFS_tell(m_handle);
+}
+
+bool FileEngine::setSize(qint64 size)
+{
+    if(size == 0)
+    {
+        m_size = 0;
+        return open(QIODevice::WriteOnly);
+    }
+    else
+        return false;
+}
+
+bool FileEngine::seek(qint64 pos)
+{
+    bool ok = PHYSFS_seek(m_handle, pos) != 0;
+
+    return ok;
+}
+
+bool FileEngine::isSequential() const
+{
+    return false;
+}
+
+bool FileEngine::remove()
+{
+    return PHYSFS_delete(m_fileName.toUtf8().constData()) != 0;
+}
+
+bool FileEngine::mkdir(const QString &dirName, bool createParentDirectories) const
+{
+    Q_UNUSED(createParentDirectories);
+
+    return PHYSFS_mkdir(dirName.toUtf8().constData()) != 0;
+}
+
+bool FileEngine::rmdir(const QString &dirName, bool recurseParentDirectories) const
+{
+    Q_UNUSED(recurseParentDirectories);
+
+    return PHYSFS_delete(dirName.toUtf8().constData()) != 0;
+}
+
+bool FileEngine::caseSensitive() const
+{
+    return true;
+}
+
+bool FileEngine::isRelativePath() const
+{
+    return false;
+}
+
+QAbstractFileEngineIterator * FileEngine::beginEntryList(QDir::Filters filters, const QStringList &filterNames)
+{
+    return new FileEngineIterator(filters, filterNames, entryList(filters, filterNames));
+}
+
+QStringList FileEngine::entryList(QDir::Filters filters, const QStringList &filterNames) const
+{
+    Q_UNUSED(filters);
+
+    QString file;
+    QStringList result;
+    char **files = PHYSFS_enumerateFiles(m_fileName.toUtf8().constData());
+
+    for (char **i = files; *i != NULL; i++) {
+        file = QString::fromUtf8(*i);
+
+        if (filterNames.isEmpty() || QDir::match(filterNames, file)) {
+            result << file;
+        }
+    }
+
+    PHYSFS_freeList(files);
+
+    return result;
+}
+
+QAbstractFileEngine::FileFlags FileEngine::fileFlags(FileFlags type) const
+{
+    return type & m_flags;
+}
+
+QString FileEngine::fileName(FileName file) const
+{
+    switch(file)
+    {
+        case QAbstractFileEngine::AbsolutePathName:
+        {
+            QString s(PHYSFS_getWriteDir());
+            return s;
+        }
+        case QAbstractFileEngine::BaseName:
+        {
+            int l = m_fileName.lastIndexOf('/');
+            QString s = m_fileName.mid(l + 1);
+            return s;
+        }
+        case QAbstractFileEngine::DefaultName:
+        case QAbstractFileEngine::AbsoluteName:
+        default:
+        {
+            QString s = "physfs:/" + m_fileName;
+            return s;
+        }
+    }
+}
+
+QDateTime FileEngine::fileTime(FileTime time) const
+{
+    switch (time)
+    {
+        case QAbstractFileEngine::ModificationTime:
+        default:
+            return m_date;
+            break;
+    };
+}
+
+void FileEngine::setFileName(const QString &file)
+{
+    if(file.startsWith(FileEngineHandler::scheme))
+        m_fileName = file.mid(FileEngineHandler::scheme.size());
+    else
+        m_fileName = file;
+    PHYSFS_Stat stat;
+    if (PHYSFS_stat(m_fileName.toUtf8().constData(), &stat) != 0) {
+        m_size = stat.filesize;
+        m_date = QDateTime::fromTime_t(stat.modtime);
+//        m_flags |= QAbstractFileEngine::WriteOwnerPerm;
+        m_flags |= QAbstractFileEngine::ReadOwnerPerm;
+        m_flags |= QAbstractFileEngine::ReadUserPerm;
+        m_flags |= QAbstractFileEngine::ExistsFlag;
+        m_flags |= QAbstractFileEngine::LocalDiskFlag;
+
+        switch (stat.filetype)
+        {
+            case PHYSFS_FILETYPE_REGULAR:
+                m_flags |= QAbstractFileEngine::FileType;
+                break;
+            case PHYSFS_FILETYPE_DIRECTORY:
+                m_flags |= QAbstractFileEngine::DirectoryType;
+                break;
+            case PHYSFS_FILETYPE_SYMLINK:
+                m_flags |= QAbstractFileEngine::LinkType;
+                break;
+            default: ;
+        }
+    }
+}
+
+bool FileEngine::atEnd() const
+{
+    return PHYSFS_eof(m_handle) != 0;
+}
+
+qint64 FileEngine::read(char *data, qint64 maxlen)
+{
+    if(m_readWrite)
+    {
+        if(pos() == 0)
+            open(QIODevice::ReadOnly);
+        else
+            return -1;
+    }
+
+    qint64 len = PHYSFS_readBytes(m_handle, data, maxlen);
+    return len;
+}
+
+qint64 FileEngine::readLine(char *data, qint64 maxlen)
+{
+    if(!m_bufferSet)
+    {
+        PHYSFS_setBuffer(m_handle, 4096);
+        m_bufferSet = true;
+    }
+
+    qint64 bytesRead = 0;
+    while(PHYSFS_readBytes(m_handle, data, 1)
+          && maxlen
+          && (*data == '\n'))
+    {
+        ++data;
+        --maxlen;
+        ++bytesRead;
+    }
+
+    return bytesRead;
+}
+
+qint64 FileEngine::write(const char *data, qint64 len)
+{
+    return PHYSFS_writeBytes(m_handle, data, len);
+}
+
+bool FileEngine::isOpened() const
+{
+    return m_handle != NULL;
+}
+
+QFile::FileError FileEngine::error() const
+{
+    return QFile::UnspecifiedError;
+}
+
+QString FileEngine::errorString() const
+{
+    return PHYSFS_getLastError();
+}
+
+bool FileEngine::supportsExtension(Extension extension) const
+{
+    return
+            (extension == QAbstractFileEngine::AtEndExtension)
+            || (extension == QAbstractFileEngine::FastReadLineExtension)
+            ;
+}
+
+
+FileEngineHandler::FileEngineHandler(char *argv0)
+{
+    PHYSFS_init(argv0);
+}
+
+FileEngineHandler::~FileEngineHandler()
+{
+    PHYSFS_deinit();
+}
+
+QAbstractFileEngine* FileEngineHandler::create(const QString &filename) const
+{
+    if (filename.startsWith(scheme))
+        return new FileEngine(filename);
+    else
+        return NULL;
+}
+
+void FileEngineHandler::mount(const QString &path)
+{
+    PHYSFS_mount(path.toUtf8().constData(), NULL, 1);
+}
+
+void FileEngineHandler::mount(const QString & path, const QString & mountPoint)
+{
+    PHYSFS_mount(path.toUtf8().constData(), mountPoint.toUtf8().constData(), 1);
+}
+
+void FileEngineHandler::setWriteDir(const QString &path)
+{
+    PHYSFS_setWriteDir(path.toUtf8().constData());
+}
+
+void FileEngineHandler::mountPacks()
+{
+    hedgewarsMountPackages();
+}
+
+
+FileEngineIterator::FileEngineIterator(QDir::Filters filters, const QStringList &nameFilters, const QStringList &entries)
+    : QAbstractFileEngineIterator(filters, nameFilters)
+{
+    m_entries = entries;
+
+    /* heck.. docs are unclear on this
+     * QDirIterator puts iterator before first entry
+     * but QAbstractFileEngineIterator example puts iterator on first entry
+     * though QDirIterator approach seems to be the right one
+     */
+
+    m_index = -1;
+}
+
+bool FileEngineIterator::hasNext() const
+{
+    return m_index < m_entries.size() - 1;
+}
+
+QString FileEngineIterator::next()
+{
+   if (!hasNext())
+       return QString();
+
+   ++m_index;
+   return currentFilePath();
+}
+
+QString FileEngineIterator::currentFileName() const
+{
+    return m_entries.at(m_index);
+}