QTfrontend/util/FileEngine.cpp
branchwebgl
changeset 8330 aaefa587e277
parent 8206 1633a6510834
child 8714 ab201a62d115
equal deleted inserted replaced
8116:d24257910f8d 8330:aaefa587e277
     7 
     7 
     8 
     8 
     9 const QString FileEngineHandler::scheme = "physfs:/";
     9 const QString FileEngineHandler::scheme = "physfs:/";
    10 
    10 
    11 FileEngine::FileEngine(const QString& filename)
    11 FileEngine::FileEngine(const QString& filename)
    12 : _handler(NULL)
    12     : m_handle(NULL)
    13 , _flags(0)
    13     , m_size(0)
       
    14     , m_flags(0)
       
    15     , m_bufferSet(false)
       
    16     , m_readWrite(false)
    14 {
    17 {
    15     setFileName(filename);
    18     setFileName(filename);
    16 }
    19 }
    17 
    20 
    18 FileEngine::~FileEngine()
    21 FileEngine::~FileEngine()
    22 
    25 
    23 bool FileEngine::open(QIODevice::OpenMode openMode)
    26 bool FileEngine::open(QIODevice::OpenMode openMode)
    24 {
    27 {
    25     close();
    28     close();
    26 
    29 
    27     if (openMode & QIODevice::WriteOnly) {
    30     if ((openMode & QIODevice::ReadWrite) == QIODevice::ReadWrite) {
    28         _handler = PHYSFS_openWrite(_filename.toUtf8().constData());
    31         m_handle = PHYSFS_openAppend(m_fileName.toUtf8().constData());
    29         _flags = QAbstractFileEngine::WriteOwnerPerm | QAbstractFileEngine::WriteUserPerm | QAbstractFileEngine::FileType;
    32         if(m_handle)
       
    33         {
       
    34             m_readWrite = true;
       
    35             seek(0);
       
    36         }
       
    37     }
       
    38 
       
    39     else if (openMode & QIODevice::WriteOnly) {
       
    40         m_handle = PHYSFS_openWrite(m_fileName.toUtf8().constData());
       
    41         m_flags = QAbstractFileEngine::WriteOwnerPerm | QAbstractFileEngine::WriteUserPerm | QAbstractFileEngine::FileType;
    30     }
    42     }
    31 
    43 
    32     else if (openMode & QIODevice::ReadOnly) {
    44     else if (openMode & QIODevice::ReadOnly) {
    33         _handler = PHYSFS_openRead(_filename.toUtf8().constData());
    45         m_handle = PHYSFS_openRead(m_fileName.toUtf8().constData());
    34     }
    46     }
    35 
    47 
    36     else if (openMode & QIODevice::Append) {
    48     else if (openMode & QIODevice::Append) {
    37         _handler = PHYSFS_openAppend(_filename.toUtf8().constData());
    49         m_handle = PHYSFS_openAppend(m_fileName.toUtf8().constData());
    38     }
    50     }
    39 
    51 
    40     else {
    52     else {
    41         qWarning("Bad file open mode: %d", (int)openMode);
    53         qWarning("[PHYSFS] Bad file open mode: %d", (int)openMode);
    42     }
    54     }
    43 
    55 
    44     if (!_handler) {
    56     if (!m_handle) {
    45         qWarning("Failed to open %s, reason: %s", _filename.toUtf8().constData(), PHYSFS_getLastError());
    57         qWarning("[PHYSFS] Failed to open %s, reason: %s", m_fileName.toUtf8().constData(), PHYSFS_getLastError());
    46         return false;
    58         return false;
    47     }
    59     }
    48 
    60 
    49     return true;
    61     return true;
    50 }
    62 }
    51 
    63 
    52 bool FileEngine::close()
    64 bool FileEngine::close()
    53 {
    65 {
    54     if (isOpened()) {
    66     if (isOpened()) {
    55         int result = PHYSFS_close(_handler);
    67         int result = PHYSFS_close(m_handle);
    56         _handler = NULL;
    68         m_handle = NULL;
    57         return result != 0;
    69         return result != 0;
    58     }
    70     }
    59 
    71 
    60     return true;
    72     return true;
    61 }
    73 }
    62 
    74 
    63 bool FileEngine::flush()
    75 bool FileEngine::flush()
    64 {
    76 {
    65     return PHYSFS_flush(_handler) != 0;
    77     return PHYSFS_flush(m_handle) != 0;
    66 }
    78 }
    67 
    79 
    68 qint64 FileEngine::size() const
    80 qint64 FileEngine::size() const
    69 {
    81 {
    70     return _size;
    82     return m_size;
    71 }
    83 }
    72 
    84 
    73 qint64 FileEngine::pos() const
    85 qint64 FileEngine::pos() const
    74 {
    86 {
    75     return PHYSFS_tell(_handler);
    87     return PHYSFS_tell(m_handle);
       
    88 }
       
    89 
       
    90 bool FileEngine::setSize(qint64 size)
       
    91 {
       
    92     if(size == 0)
       
    93     {
       
    94         m_size = 0;
       
    95         return open(QIODevice::WriteOnly);
       
    96     }
       
    97     else
       
    98         return false;
    76 }
    99 }
    77 
   100 
    78 bool FileEngine::seek(qint64 pos)
   101 bool FileEngine::seek(qint64 pos)
    79 {
   102 {
    80     return PHYSFS_seek(_handler, pos) != 0;
   103     bool ok = PHYSFS_seek(m_handle, pos) != 0;
       
   104 
       
   105     return ok;
    81 }
   106 }
    82 
   107 
    83 bool FileEngine::isSequential() const
   108 bool FileEngine::isSequential() const
    84 {
   109 {
    85     return false;
   110     return false;
    86 }
   111 }
    87 
   112 
    88 bool FileEngine::remove()
   113 bool FileEngine::remove()
    89 {
   114 {
    90     return PHYSFS_delete(_filename.toUtf8().constData()) != 0;
   115     return PHYSFS_delete(m_fileName.toUtf8().constData()) != 0;
    91 }
   116 }
    92 
   117 
    93 bool FileEngine::mkdir(const QString &dirName, bool createParentDirectories) const
   118 bool FileEngine::mkdir(const QString &dirName, bool createParentDirectories) const
    94 {
   119 {
    95     Q_UNUSED(createParentDirectories);
   120     Q_UNUSED(createParentDirectories);
       
   121 
    96     return PHYSFS_mkdir(dirName.toUtf8().constData()) != 0;
   122     return PHYSFS_mkdir(dirName.toUtf8().constData()) != 0;
    97 }
   123 }
    98 
   124 
    99 bool FileEngine::rmdir(const QString &dirName, bool recurseParentDirectories) const
   125 bool FileEngine::rmdir(const QString &dirName, bool recurseParentDirectories) const
   100 {
   126 {
   101     Q_UNUSED(recurseParentDirectories);
   127     Q_UNUSED(recurseParentDirectories);
       
   128 
   102     return PHYSFS_delete(dirName.toUtf8().constData()) != 0;
   129     return PHYSFS_delete(dirName.toUtf8().constData()) != 0;
   103 }
   130 }
   104 
   131 
   105 bool FileEngine::caseSensitive() const
   132 bool FileEngine::caseSensitive() const
   106 {
   133 {
   107     return true;
   134     return true;
   108 }
   135 }
   109 
   136 
   110 bool FileEngine::isRelativePath() const
   137 bool FileEngine::isRelativePath() const
   111 {
   138 {
   112     return true;
   139     return false;
   113 }
   140 }
   114 
   141 
   115 QAbstractFileEngineIterator * FileEngine::beginEntryList(QDir::Filters filters, const QStringList &filterNames)
   142 QAbstractFileEngineIterator * FileEngine::beginEntryList(QDir::Filters filters, const QStringList &filterNames)
   116 {
   143 {
   117     return new FileEngineIterator(filters, filterNames, entryList(filters, filterNames));
   144     return new FileEngineIterator(filters, filterNames, entryList(filters, filterNames));
   121 {
   148 {
   122     Q_UNUSED(filters);
   149     Q_UNUSED(filters);
   123 
   150 
   124     QString file;
   151     QString file;
   125     QStringList result;
   152     QStringList result;
   126     char **files = PHYSFS_enumerateFiles(_filename.toUtf8().constData());
   153     char **files = PHYSFS_enumerateFiles(m_fileName.toUtf8().constData());
   127 
   154 
   128     for (char **i = files; *i != NULL; i++) {
   155     for (char **i = files; *i != NULL; i++) {
   129         file = QString::fromUtf8(*i);
   156         file = QString::fromUtf8(*i);
   130 
   157 
   131         if (filterNames.isEmpty() || QDir::match(filterNames, file)) {
   158         if (filterNames.isEmpty() || QDir::match(filterNames, file)) {
   138     return result;
   165     return result;
   139 }
   166 }
   140 
   167 
   141 QAbstractFileEngine::FileFlags FileEngine::fileFlags(FileFlags type) const
   168 QAbstractFileEngine::FileFlags FileEngine::fileFlags(FileFlags type) const
   142 {
   169 {
   143     return type & _flags;
   170     return type & m_flags;
   144 }
   171 }
   145 
   172 
   146 QString FileEngine::fileName(FileName file) const
   173 QString FileEngine::fileName(FileName file) const
   147 {
   174 {
   148     switch(file)
   175     switch(file)
   152             QString s(PHYSFS_getWriteDir());
   179             QString s(PHYSFS_getWriteDir());
   153             return s;
   180             return s;
   154         }
   181         }
   155         case QAbstractFileEngine::BaseName:
   182         case QAbstractFileEngine::BaseName:
   156         {
   183         {
   157             int l = _filename.lastIndexOf('/');
   184             int l = m_fileName.lastIndexOf('/');
   158             QString s = _filename.mid(l + 1);
   185             QString s = m_fileName.mid(l + 1);
   159             return s;
   186             return s;
   160         }
   187         }
   161         case QAbstractFileEngine::DefaultName:
   188         case QAbstractFileEngine::DefaultName:
   162         case QAbstractFileEngine::AbsoluteName:
   189         case QAbstractFileEngine::AbsoluteName:
   163         default:
   190         default:
   164         {
   191         {
   165             QString s = "physfs:/" + _filename;
   192             QString s = "physfs:/" + m_fileName;
   166             return s;
   193             return s;
   167         }
   194         }
   168     }
   195     }
   169 }
   196 }
   170 
   197 
   171 QDateTime FileEngine::fileTime(FileTime time) const
   198 QDateTime FileEngine::fileTime(FileTime time) const
   172 {
   199 {
   173 
       
   174     switch (time)
   200     switch (time)
   175     {
   201     {
   176         case QAbstractFileEngine::ModificationTime:
   202         case QAbstractFileEngine::ModificationTime:
   177         default:
   203         default:
   178             return _datetime;
   204             return m_date;
   179             break;
   205             break;
   180     };
   206     };
   181 }
   207 }
   182 
   208 
   183 void FileEngine::setFileName(const QString &file)
   209 void FileEngine::setFileName(const QString &file)
   184 {
   210 {
   185     if(file.startsWith(FileEngineHandler::scheme))
   211     if(file.startsWith(FileEngineHandler::scheme))
   186         _filename = file.mid(FileEngineHandler::scheme.size());
   212         m_fileName = file.mid(FileEngineHandler::scheme.size());
   187     else
   213     else
   188         _filename = file;
   214         m_fileName = file;
   189 
       
   190     PHYSFS_Stat stat;
   215     PHYSFS_Stat stat;
   191     if (PHYSFS_stat(_filename.toUtf8().constData(), &stat) != 0) {
   216     if (PHYSFS_stat(m_fileName.toUtf8().constData(), &stat) != 0) {
   192         _size = stat.filesize;
   217         m_size = stat.filesize;
   193         _datetime = QDateTime::fromTime_t(stat.modtime);
   218         m_date = QDateTime::fromTime_t(stat.modtime);
   194 //        _flags |= QAbstractFileEngine::WriteUserPerm;
   219 //        m_flags |= QAbstractFileEngine::WriteOwnerPerm;
   195         _flags |= QAbstractFileEngine::ReadUserPerm;
   220         m_flags |= QAbstractFileEngine::ReadOwnerPerm;
   196         _flags |= QAbstractFileEngine::ExistsFlag;
   221         m_flags |= QAbstractFileEngine::ReadUserPerm;
       
   222         m_flags |= QAbstractFileEngine::ExistsFlag;
       
   223         m_flags |= QAbstractFileEngine::LocalDiskFlag;
   197 
   224 
   198         switch (stat.filetype)
   225         switch (stat.filetype)
   199         {
   226         {
   200             case PHYSFS_FILETYPE_REGULAR:
   227             case PHYSFS_FILETYPE_REGULAR:
   201                 _flags |= QAbstractFileEngine::FileType;
   228                 m_flags |= QAbstractFileEngine::FileType;
   202                 break;
   229                 break;
   203 
       
   204             case PHYSFS_FILETYPE_DIRECTORY:
   230             case PHYSFS_FILETYPE_DIRECTORY:
   205                 _flags |= QAbstractFileEngine::DirectoryType;
   231                 m_flags |= QAbstractFileEngine::DirectoryType;
   206                 break;
   232                 break;
   207             case PHYSFS_FILETYPE_SYMLINK:
   233             case PHYSFS_FILETYPE_SYMLINK:
   208                 _flags |= QAbstractFileEngine::LinkType;
   234                 m_flags |= QAbstractFileEngine::LinkType;
   209                 break;
   235                 break;
   210             default: ;
   236             default: ;
   211         }
   237         }
   212     }
   238     }
   213 }
   239 }
   214 
   240 
   215 bool FileEngine::atEnd() const
   241 bool FileEngine::atEnd() const
   216 {
   242 {
   217     return PHYSFS_eof(_handler) != 0;
   243     return PHYSFS_eof(m_handle) != 0;
   218 }
   244 }
   219 
   245 
   220 qint64 FileEngine::read(char *data, qint64 maxlen)
   246 qint64 FileEngine::read(char *data, qint64 maxlen)
   221 {
   247 {
   222     return PHYSFS_readBytes(_handler, data, maxlen);
   248     if(m_readWrite)
       
   249     {
       
   250         if(pos() == 0)
       
   251             open(QIODevice::ReadOnly);
       
   252         else
       
   253             return -1;
       
   254     }
       
   255 
       
   256     qint64 len = PHYSFS_readBytes(m_handle, data, maxlen);
       
   257     return len;
       
   258 }
       
   259 
       
   260 qint64 FileEngine::readLine(char *data, qint64 maxlen)
       
   261 {
       
   262     if(!m_bufferSet)
       
   263     {
       
   264         PHYSFS_setBuffer(m_handle, 4096);
       
   265         m_bufferSet = true;
       
   266     }
       
   267 
       
   268     qint64 bytesRead = 0;
       
   269     while(PHYSFS_readBytes(m_handle, data, 1)
       
   270           && maxlen
       
   271           && (*data == '\n'))
       
   272     {
       
   273         ++data;
       
   274         --maxlen;
       
   275         ++bytesRead;
       
   276     }
       
   277 
       
   278     return bytesRead;
   223 }
   279 }
   224 
   280 
   225 qint64 FileEngine::write(const char *data, qint64 len)
   281 qint64 FileEngine::write(const char *data, qint64 len)
   226 {
   282 {
   227     return PHYSFS_writeBytes(_handler, data, len);
   283     return PHYSFS_writeBytes(m_handle, data, len);
   228 }
   284 }
   229 
   285 
   230 bool FileEngine::isOpened() const
   286 bool FileEngine::isOpened() const
   231 {
   287 {
   232     return _handler != NULL;
   288     return m_handle != NULL;
   233 }
   289 }
   234 
   290 
   235 QFile::FileError FileEngine::error() const
   291 QFile::FileError FileEngine::error() const
   236 {
   292 {
   237     return QFile::UnspecifiedError;
   293     return QFile::UnspecifiedError;
   242     return PHYSFS_getLastError();
   298     return PHYSFS_getLastError();
   243 }
   299 }
   244 
   300 
   245 bool FileEngine::supportsExtension(Extension extension) const
   301 bool FileEngine::supportsExtension(Extension extension) const
   246 {
   302 {
   247     return extension == QAbstractFileEngine::AtEndExtension;
   303     return
   248 }
   304             (extension == QAbstractFileEngine::AtEndExtension)
   249 
   305             || (extension == QAbstractFileEngine::FastReadLineExtension)
       
   306             ;
       
   307 }
   250 
   308 
   251 
   309 
   252 FileEngineHandler::FileEngineHandler(char *argv0)
   310 FileEngineHandler::FileEngineHandler(char *argv0)
   253 {
   311 {
   254     PHYSFS_init(argv0);
   312     PHYSFS_init(argv0);
   260 }
   318 }
   261 
   319 
   262 QAbstractFileEngine* FileEngineHandler::create(const QString &filename) const
   320 QAbstractFileEngine* FileEngineHandler::create(const QString &filename) const
   263 {
   321 {
   264     if (filename.startsWith(scheme))
   322     if (filename.startsWith(scheme))
   265         return new FileEngine(filename.mid(scheme.size()));
   323         return new FileEngine(filename);
   266     else
   324     else
   267         return NULL;
   325         return NULL;
   268 }
   326 }
   269 
   327 
   270 void FileEngineHandler::mount(const QString &path)
   328 void FileEngineHandler::mount(const QString &path)