22 #include "usModuleResourceContainer_p.h"
25 #include "usModuleUtils_p.h"
38 struct ModuleResourceContainerPrivate
40 ModuleResourceContainerPrivate(
const ModuleInfo* moduleInfo)
41 : m_ModuleInfo(moduleInfo)
46 typedef std::pair<std::string, int> NameIndexPair;
50 bool operator()(
const NameIndexPair& p1,
const NameIndexPair& p2)
const
52 return p1.first < p2.first;
56 typedef std::set<NameIndexPair, PairComp> SetType;
58 void InitSortedEntries()
60 if (m_SortedEntries.empty())
62 mz_uint numFiles = mz_zip_reader_get_num_files(&m_ZipArchive);
63 for (mz_uint fileIndex = 0; fileIndex < numFiles; ++fileIndex)
65 char fileName[MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE];
66 mz_zip_reader_get_filename(&m_ZipArchive, fileIndex, fileName, MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE);
67 m_SortedEntries.insert(std::make_pair(std::string(fileName), fileIndex));
72 const ModuleInfo* m_ModuleInfo;
75 mz_zip_archive m_ZipArchive;
77 std::set<NameIndexPair, PairComp> m_SortedEntries;
80 ModuleResourceContainer::ModuleResourceContainer(
const ModuleInfo* moduleInfo)
81 : d(new ModuleResourceContainerPrivate(moduleInfo))
83 if (mz_zip_reader_init_file(&d->m_ZipArchive, moduleInfo->location.c_str(), 0))
89 US_DEBUG <<
"Could not init zip archive for module " << moduleInfo->name;
93 ModuleResourceContainer::~ModuleResourceContainer()
97 mz_zip_reader_end(&d->m_ZipArchive);
102 bool ModuleResourceContainer::IsValid()
const
107 bool ModuleResourceContainer::GetStat(ModuleResourceContainer::Stat& stat)
const
111 int fileIndex = mz_zip_reader_locate_file(&d->m_ZipArchive, stat.filePath.c_str(), NULL, 0);
114 return GetStat(fileIndex, stat);
120 bool ModuleResourceContainer::GetStat(
int index, ModuleResourceContainer::Stat& stat)
const
126 mz_zip_archive_file_stat zipStat;
127 if (!mz_zip_reader_file_stat(&d->m_ZipArchive, index, &zipStat))
132 stat.filePath = zipStat.m_filename;
133 stat.isDir = mz_zip_reader_is_file_a_directory(&d->m_ZipArchive, index) ?
true :
false;
134 stat.modifiedTime = zipStat.m_time;
138 assert(zipStat.m_comp_size < INT_MAX);
139 assert(zipStat.m_uncomp_size < INT_MAX);
140 stat.uncompressedSize =
static_cast<int>(zipStat.m_uncomp_size);
149 return mz_zip_reader_extract_to_heap(&d->m_ZipArchive, index, NULL, 0);
152 const ModuleInfo*ModuleResourceContainer::GetModuleInfo()
const
154 return d->m_ModuleInfo;
157 void ModuleResourceContainer::GetChildren(
const std::string& resourcePath,
bool relativePaths,
158 std::vector<std::string>& names, std::vector<uint32_t>& indices)
const
160 d->InitSortedEntries();
162 ModuleResourceContainerPrivate::SetType::const_iterator iter =
163 d->m_SortedEntries.find(std::make_pair(resourcePath, 0));
164 if (iter == d->m_SortedEntries.end())
169 for (++iter; iter != d->m_SortedEntries.end(); ++iter)
171 if (resourcePath.size() > iter->first.size())
break;
172 if (iter->first.compare(0, resourcePath.size(), resourcePath) == 0)
174 std::size_t pos = iter->first.find_first_of(
'/', resourcePath.size());
175 if (pos == std::string::npos || pos == iter->first.size()-1)
179 names.push_back(iter->first.substr(resourcePath.size()));
183 names.push_back(iter->first);
185 indices.push_back(iter->second);
191 void ModuleResourceContainer::FindNodes(
const std::string& path,
const std::string& filePattern,
192 bool recurse, std::vector<ModuleResource>& resources)
const
194 std::vector<std::string> names;
195 std::vector<uint32_t> indices;
197 this->GetChildren(path,
true, names, indices);
199 for(std::size_t i = 0, s = names.size(); i < s; ++i)
201 if (*names[i].rbegin() ==
'/' && recurse)
203 this->FindNodes(path + names[i], filePattern, recurse, resources);
205 if (this->Matches(names[i], filePattern))
207 resources.push_back(ModuleResource(indices[i], *
this));
212 bool ModuleResourceContainer::Matches(
const std::string& name,
const std::string& filePattern)
const
215 if (filePattern ==
"*")
return true;
217 std::stringstream ss(filePattern);
220 while(std::getline(ss, tok,
'*'))
222 std::size_t index = name.find(tok, pos);
223 if (index == std::string::npos)
return false;
224 pos = index + tok.size();
T::Pointer GetData(const std::string &name)