#ifndef _H_BUNDLEREPOSITORY
#define _H_BUNDLEREPOSITORY
#include <security_utilities/cfutilities.h>
#include <security_utilities/refcount.h>
#include <CoreFoundation/CoreFoundation.h>
#include <string>
#include <vector>
namespace Security {
class PathList {
public:
PathList();
PathList(const string &subPath, const char *suffix = NULL,
const char *envar = NULL, bool forUser = true);
virtual ~PathList();
void addDirectory(const string &dirPath);
protected:
vector<string> mPaths;
string mSuffix;
IFDEBUG(string mDebugOverride);
};
template <class Code>
class CodeRepository : public vector<RefPointer<Code> >, public PathList {
public:
CodeRepository() { } CodeRepository(const string &subPath, const char *suffix = NULL,
const char *envar = NULL, bool forUser = true)
: PathList(subPath, suffix, envar, forUser) { }
void update();
};
template <class Code>
void CodeRepository<Code>::update()
{
vector<RefPointer<Code> > result;
for (vector<string>::const_iterator it = mPaths.begin(); it != mPaths.end(); it++) {
if (CFRef<CFArrayRef> bundles = CFBundleCreateBundlesFromDirectory(NULL,
CFTempURL(*it, true), mSuffix.empty() ? NULL : CFStringRef(CFTempString(mSuffix)))) {
CFIndex count = CFArrayGetCount(bundles);
secdebug("coderep", "%p directory %s has %ld entries", this, it->c_str(), count);
for (CFIndex n = 0; n < count; n++)
try {
result.push_back(new Code((CFBundleRef)CFArrayGetValueAtIndex(bundles, n)));
} catch (...) {
secdebug("coderep", "%p exception creating %s (skipped)",
this, cfString(CFBundleRef(CFArrayGetValueAtIndex(bundles, n))).c_str());
}
} else
secdebug("coderep", "directory %s bundle read failed", it->c_str());
}
secdebug("coderep", "%p total of %ld items in list", this, result.size());
this->swap(result);
}
}
#endif //_H_BUNDLEREPOSITORY