~openhommdev/openhomm/gui

« back to all changes in this revision

Viewing changes to src/core/hrFilesystem.cpp

  • Committer: Stanislav Ershov
  • Date: 2010-02-13 02:09:31 UTC
  • Revision ID: digital.stream.of.mind@gmail.com-20100213020931-1vbccidqx8hoxa27
hrFilesystem:
  -added plain directory mounting
  -added more error handlings
  -added new overloaded function 'void hrFilesystem::mount(const QStringList&)'

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 
23
23
fileSystemCache hrFilesystem::_cache;
24
24
 
25
 
const char * MOUNT_SUCCESSFULLY = "Successfully mounted: %s";
26
 
const char * MOUNT_FAILED       = "Failed to mount: %s";
 
25
const char * MOUNT_SUCCESSFULLY = "\tSuccessfully mounted!";
 
26
const char * MOUNT_FAILED       = "\tFailed to mount!";
 
27
 
 
28
/**
 
29
*  Find a case-correct path.
 
30
 *  @param path a case-insensitive path
 
31
 *  @param baseDir a existing base directory. Certainly does not require case correction.
 
32
 *  @return Right path or null string on error.
 
33
 */
 
34
QString hrFilesystem::adjustCaseInPath(const QString &path, const QDir &baseDir)
 
35
{
 
36
    QStringList pathElements = path.split('/');
 
37
    QDir current = baseDir;
 
38
 
 
39
    for ( int j = 0; j < pathElements.size()-1; j++ )
 
40
    {
 
41
        QString next = pathElements[j];
 
42
 
 
43
        if (!current.exists(next))
 
44
        {
 
45
            QStringList candidates = current.entryList(QStringList() << next, QDir::Dirs | QDir::Readable ); // flag QDir::CaseSensitive does not set by default and this is that we need
 
46
 
 
47
            if (candidates.size() == 0)
 
48
            {
 
49
                qCritical("Directory `%s` not found in directory `%s`", qPrintable(next), qPrintable(current.path()));
 
50
                return QString();
 
51
            }
 
52
 
 
53
            if (candidates.size() != 1)
 
54
                qWarning("Ambiguous element `%s` in directory `%s`, selecting `%s`", qPrintable(next), qPrintable(current.path()), qPrintable(candidates.first()));
 
55
 
 
56
            next = candidates.first();
 
57
        }
 
58
 
 
59
        if (!current.cd(next))
 
60
        {
 
61
            qCritical("Cannot enter directory `%s` in directory `%s`", qPrintable(next), qPrintable(current.path()));
 
62
            return QString();
 
63
        }
 
64
    }
 
65
 
 
66
    QString last = pathElements.last();
 
67
 
 
68
    if (!current.exists(last))
 
69
    {
 
70
        QStringList candidates = current.entryList(QStringList() << last, QDir::Dirs | QDir::Files | QDir::Readable ); // flag QDir::CaseSensitive does not set by default and this is that we need
 
71
 
 
72
        if (candidates.size() == 0)
 
73
        {
 
74
            qCritical("File or directory `%s` not found in directory `%s`", qPrintable(last), qPrintable(current.path()));
 
75
            return QString();
 
76
        }
 
77
 
 
78
        if (candidates.size() != 1)
 
79
            qWarning("Ambiguous element `%s` in directory `%s`, selecting `%s`", qPrintable(last), qPrintable(current.path()), qPrintable(candidates.first()));
 
80
 
 
81
        last = candidates.first();
 
82
    }
 
83
    return current.filePath(last);
 
84
}
27
85
 
28
86
bool hrFilesystem::mount(const QString &path)
29
87
{
30
 
    QStringList pathElements = path.split('/');
31
 
 
32
 
    QDir current(hrSettings::get().gameDir());
33
 
 
34
 
    QString normalPath = hrSettings::get().gameDir() + '/' ;
35
 
 
36
 
    for ( int j = 0; j < pathElements.size(); j++ )
37
 
    {
38
 
        QStringList el = current.entryList(QStringList() << pathElements[j], QDir::Dirs | QDir::Files );
39
 
        if ( el.size() != 0 )
40
 
        {
41
 
            normalPath += el[0] + '/';
42
 
            if ( current.exists(el[0]) )
43
 
                current.cd(el[0]);
44
 
        }
45
 
    }
46
 
 
47
 
    normalPath.remove(normalPath.length() -1, 1); // remove last slash
 
88
    QDir gameRoot = hrSettings::get().gameDir();
 
89
 
 
90
    Q_ASSERT(gameRoot.exists());
 
91
 
 
92
    QString normalPath = adjustCaseInPath(path,gameRoot);
 
93
 
 
94
    if (normalPath.isNull() || !QFile::exists(normalPath))
 
95
        return false;
 
96
 
48
97
    qDebug("Trying to mount: %s", qPrintable(normalPath));
49
98
 
50
 
    if ( normalPath.indexOf(".lod", 0, Qt::CaseInsensitive) != -1 )
 
99
    if ( normalPath.endsWith(".lod", Qt::CaseInsensitive) )
51
100
    {
52
101
        if ( hrLodEngine::fillInternalCache(normalPath) )
53
 
            qDebug(MOUNT_SUCCESSFULLY, qPrintable(normalPath));
 
102
            qDebug(MOUNT_SUCCESSFULLY);
54
103
        else
55
 
            qCritical(MOUNT_FAILED, qPrintable(normalPath));
 
104
            qCritical(MOUNT_FAILED);
56
105
    }
57
 
    else if ( normalPath.indexOf(".snd", 0, Qt::CaseInsensitive) != -1 )
 
106
    else if ( normalPath.endsWith(".snd", Qt::CaseInsensitive) )
58
107
    {
59
108
        if ( hrSndEngine::fillInternalCache(normalPath) )
60
 
            qDebug(MOUNT_SUCCESSFULLY, qPrintable(normalPath));
61
 
        else
62
 
            qCritical(MOUNT_FAILED, qPrintable(normalPath));
 
109
            qDebug(MOUNT_SUCCESSFULLY);
 
110
        else
 
111
            qCritical(MOUNT_FAILED);
 
112
    }
 
113
    else
 
114
    {
 
115
        if ( !mountDir(normalPath))
 
116
            qCritical("\tUnsupported archive type");
 
117
        else
 
118
            qDebug(MOUNT_SUCCESSFULLY);
63
119
    }
64
120
 
65
121
    return true;
 
122
 
 
123
}
 
124
/*!
 
125
  \overload
 
126
*/
 
127
 
 
128
void hrFilesystem::mount(const QStringList &path_list)
 
129
{
 
130
    for ( int i = 0; i < path_list.size(); i++)
 
131
        mount(path_list[i]);
66
132
}
67
133
 
68
134
/*!
71
137
bool hrFilesystem::umount(const QString &path)
72
138
{
73
139
    Q_UNUSED(path);
74
 
    return true;
 
140
    return false;
75
141
}
76
142
 
77
143
void hrFilesystem::fillGeneralCache(const QString &filename, const QString &archive)
79
145
    _cache.insert(filename, archive);
80
146
}
81
147
 
 
148
void hrFilesystem::walkDirectory(const QString &path, QStringList &fileList)
 
149
{
 
150
    QFileInfo info(path);
 
151
 
 
152
    if ( info.isDir() )
 
153
    {
 
154
        QDir mounted(path);
 
155
        QFileInfoList entries = mounted.entryInfoList();
 
156
 
 
157
        for ( int i = 0; i < entries.size(); i++)
 
158
        {
 
159
            if ( entries[i].fileName() == "." || entries[i].fileName() == "..")
 
160
                continue;
 
161
 
 
162
            if ( entries[i].isDir() )
 
163
            {
 
164
                walkDirectory(entries[i].absoluteFilePath(), fileList);
 
165
                continue;
 
166
            }
 
167
 
 
168
            fileList.append(entries[i].absoluteFilePath());
 
169
        }
 
170
    }
 
171
}
 
172
 
 
173
bool hrFilesystem::mountDir(const QString &path)
 
174
{
 
175
    QFileInfo info(path);
 
176
 
 
177
    if ( info.isDir() )
 
178
    {
 
179
        QStringList fileList;
 
180
        walkDirectory(path, fileList);
 
181
 
 
182
        for ( int i = 0; i < fileList.size(); i++)
 
183
        {
 
184
            fileList[i].remove(path);
 
185
            fileList[i].remove(0, 1); // remove first '/'
 
186
            hrFilesystem::fillGeneralCache(fileList[i], path);
 
187
        }
 
188
    }
 
189
 
 
190
    return info.isDir();
 
191
}
 
192
 
82
193
/*!
83
194
  Try to find archive where the file located.
84
195
  @param filename Filename to found.
91
202
        return _cache[filename];
92
203
    }
93
204
 
94
 
    qWarning() << "Not found " << filename << __FILE__ << __LINE__;
 
205
    QList<QString> keys = _cache.keys();
 
206
    QStringList keys_string(keys);
 
207
    QStringList results;
 
208
 
 
209
    results = keys_string.filter(filename,  Qt::CaseInsensitive);
 
210
 
 
211
    if ( results.size() > 0 )
 
212
        return _cache[results[0]];
 
213
 
95
214
    return QString();
96
215
}
97
216