summaryrefslogtreecommitdiff
path: root/library/icon_buffer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'library/icon_buffer.cpp')
-rw-r--r--library/icon_buffer.cpp91
1 files changed, 38 insertions, 53 deletions
diff --git a/library/icon_buffer.cpp b/library/icon_buffer.cpp
index 81d14146..20ff60f7 100644
--- a/library/icon_buffer.cpp
+++ b/library/icon_buffer.cpp
@@ -9,7 +9,6 @@
#include <map>
#include <queue>
#include <set>
-#include <boost/thread.hpp>
#ifdef FFS_WIN
#include <wx/msw/wrapwin.h> //includes "windows.h"
@@ -24,43 +23,38 @@
using ffs3::IconBuffer;
-namespace
-{
#ifdef FFS_WIN
-Zstring getFileExtension(const Zstring& filename)
+IconBuffer::BasicString IconBuffer::getFileExtension(const BasicString& filename)
{
- const Zstring shortName = filename.AfterLast(DefaultChar('\\')); //warning: using windows file name separator!
- const size_t pos = shortName.Find(DefaultChar('.'), true);
- return pos == Zstring::npos ?
- Zstring() :
- Zstring(shortName.c_str() + pos + 1);
+ const BasicString shortName = filename.AfterLast(Zchar('\\')); //warning: using windows file name separator!
+
+ return shortName.find(Zchar('.')) != BasicString::npos ?
+ filename.AfterLast(Zchar('.')) :
+ BasicString();
}
//test for extension for icons that physically have to be retrieved from disc
-bool isPriceyExtension(const Zstring& extension)
+bool IconBuffer::isPriceyExtension(const IconBuffer::BasicString& extension)
{
- static std::set<Zstring, LessFilename> exceptions;
- static bool isInitalized = false;
- if (!isInitalized)
+ static std::set<BasicString, LessFilename> exceptions;
+ if (exceptions.empty())
{
- isInitalized = true;
- exceptions.insert(DefaultStr("exe"));
- exceptions.insert(DefaultStr("lnk"));
- exceptions.insert(DefaultStr("ico"));
- exceptions.insert(DefaultStr("ani"));
- exceptions.insert(DefaultStr("cur"));
- exceptions.insert(DefaultStr("url"));
- exceptions.insert(DefaultStr("msc"));
- exceptions.insert(DefaultStr("scr"));
+ exceptions.insert(Zstr("exe"));
+ exceptions.insert(Zstr("lnk"));
+ exceptions.insert(Zstr("ico"));
+ exceptions.insert(Zstr("ani"));
+ exceptions.insert(Zstr("cur"));
+ exceptions.insert(Zstr("url"));
+ exceptions.insert(Zstr("msc"));
+ exceptions.insert(Zstr("scr"));
}
return exceptions.find(extension) != exceptions.end();
}
#endif
-}
-//################################################################################################################################################
+//################################################################################################################################################
class IconBuffer::IconHolder //handle HICON/GdkPixbuf ownership WITHOUT ref-counting to allow thread-safe usage (in contrast to wxIcon)
{
public:
@@ -139,7 +133,7 @@ const wxIcon& IconBuffer::getDirectoryIcon() //one folder icon should be suffici
fileInfo.hIcon = 0; //initialize hIcon
//NOTE: CoInitializeEx()/CoUninitialize() implicitly called by wxWidgets on program startup!
- if (::SHGetFileInfo(DefaultStr("dummy"), //Windows Seven doesn't like this parameter to be an empty string
+ if (::SHGetFileInfo(Zstr("dummy"), //Windows Seven doesn't like this parameter to be an empty string
FILE_ATTRIBUTE_DIRECTORY,
&fileInfo,
sizeof(fileInfo),
@@ -152,14 +146,14 @@ const wxIcon& IconBuffer::getDirectoryIcon() //one folder icon should be suffici
}
#elif defined FFS_LINUX
- folderIcon = getAssociatedIcon(DefaultStr("/usr/")).toWxIcon(); //all directories will look like "/usr/"
+ folderIcon = getAssociatedIcon(Zstr("/usr/")).toWxIcon(); //all directories will look like "/usr/"
#endif
}
return folderIcon;
}
-IconBuffer::IconHolder IconBuffer::getAssociatedIcon(const Zstring& filename)
+IconBuffer::IconHolder IconBuffer::getAssociatedIcon(const BasicString& filename)
{
#ifdef FFS_WIN
//despite what docu says about SHGetFileInfo() it can't handle all relative filenames, e.g. "\DirName"
@@ -231,15 +225,14 @@ IconBuffer::IconHolder IconBuffer::getAssociatedIcon(const Zstring& filename)
#endif
}
-
#ifdef FFS_WIN
-IconBuffer::IconHolder IconBuffer::getAssociatedIconByExt(const Zstring& extension)
+IconBuffer::IconHolder IconBuffer::getAssociatedIconByExt(const BasicString& extension)
{
SHFILEINFO fileInfo;
fileInfo.hIcon = 0; //initialize hIcon -> fix for weird error: SHGetFileInfo() might return successfully WITHOUT filling fileInfo.hIcon!!
//no read-access to disk! determine icon by extension
- ::SHGetFileInfo((Zstring(DefaultStr("dummy.")) + extension).c_str(), //Windows Seven doesn't like this parameter to be without short name
+ ::SHGetFileInfo((Zstr("dummy.") + extension).c_str(), //Windows Seven doesn't like this parameter to be without short name
FILE_ATTRIBUTE_NORMAL,
&fileInfo,
sizeof(fileInfo),
@@ -250,12 +243,6 @@ IconBuffer::IconHolder IconBuffer::getAssociatedIconByExt(const Zstring& extensi
#endif
-//---------------------------------------------------------------------------------------------------
-typedef std::vector<DefaultChar> BasicString; //simple thread safe string class: std::vector is guaranteed to not use reference counting, Effective STL, item 13
-//avoid reference-counted objects as shared data: NOT THREADSAFE!!! (implicitly shared variables: ref-count + c-string)
-//---------------------------------------------------------------------------------------------------
-
-
class IconBuffer::WorkerThread
{
public:
@@ -308,7 +295,7 @@ void IconBuffer::WorkerThread::setWorkload(const std::vector<Zstring>& load) //(
shared.workload.clear();
for (std::vector<Zstring>::const_iterator i = load.begin(); i != load.end(); ++i)
- shared.workload.push_back(FileName(i->c_str(), i->c_str() + i->length() + 1)); //make DEEP COPY from Zstring (include null-termination)!
+ shared.workload.push_back(FileName(i->c_str())); //make DEEP COPY from Zstring
}
shared.condition.notify_one();
@@ -344,20 +331,20 @@ void IconBuffer::WorkerThread::doWork()
//do work: get the file icon.
while (true)
{
- Zstring fileName;
+ BasicString fileName;
{
boost::lock_guard<boost::mutex> dummy(shared.mutex);
if (shared.workload.empty())
break; //enter waiting state
- fileName = &shared.workload.back()[0]; //deep copy (includes NULL-termination)
+ fileName = shared.workload.back(); //deep copy
shared.workload.pop_back();
}
- if (iconBuffer.requestFileIcon(fileName)) //thread safety: Zstring okay, won't be reference-counted in requestIcon()
+ if (iconBuffer.requestFileIcon(fileName.c_str())) //thread safety: Zstring okay, won't be reference-counted in requestIcon()
continue; //icon already in buffer: skip
#ifdef FFS_WIN
- const Zstring extension = getFileExtension(fileName); //thread-safe: no sharing!
+ const BasicString extension = getFileExtension(fileName); //thread-safe: no sharing!
if (isPriceyExtension(extension)) //"pricey" extensions are stored with fullnames and are read from disk, while cheap ones require just the extension
{
const IconHolder newIcon = IconBuffer::getAssociatedIcon(fileName);
@@ -377,8 +364,8 @@ void IconBuffer::WorkerThread::doWork()
//---------------------------------------------------------------------------------------------------
-class IconBuffer::IconDB : public std::map<Zstring, IconBuffer::IconHolder> {}; //entryName/icon -> ATTENTION: avoid ref-counting for this shared data structure!!! (== don't copy instances between threads)
-class IconBuffer::IconDbSequence : public std::queue<Zstring> {}; //entryName
+class IconBuffer::IconDB : public std::map<BasicString, IconBuffer::IconHolder> {}; //entryName/icon -> ATTENTION: avoid ref-counting for this shared data structure!
+class IconBuffer::IconDbSequence : public std::queue<BasicString> {}; //entryName
//---------------------------------------------------------------------------------------------------
@@ -405,10 +392,11 @@ bool IconBuffer::requestFileIcon(const Zstring& fileName, wxIcon* icon)
#ifdef FFS_WIN
//"pricey" extensions are stored with fullnames and are read from disk, while cheap ones require just the extension
- const Zstring extension = getFileExtension(fileName);
- IconDB::const_iterator i = buffer->find(isPriceyExtension(extension) ? fileName : extension);
+ const BasicString extension = getFileExtension(fileName.c_str());
+ const BasicString searchString = isPriceyExtension(extension) ? fileName.c_str() : extension.c_str();
+ IconDB::const_iterator i = buffer->find(searchString);
#elif defined FFS_LINUX
- IconDB::const_iterator i = buffer->find(fileName);
+ IconDB::const_iterator i = buffer->find(fileName.c_str());
#endif
if (i == buffer->end())
@@ -427,17 +415,14 @@ void IconBuffer::setWorkload(const std::vector<Zstring>& load)
}
-void IconBuffer::insertIntoBuffer(const DefaultChar* entryName, const IconHolder& icon) //called by worker thread
+void IconBuffer::insertIntoBuffer(const BasicString& entryName, const IconHolder& icon) //called by worker thread
{
boost::lock_guard<boost::mutex> dummy(lockIconDB);
- //thread safety, ref-counting: (implicitly) make deep copy!
- const Zstring fileNameZ = entryName;
-
- const std::pair<IconDB::iterator, bool> rc = buffer->insert(std::make_pair(fileNameZ, icon)); //thread saftey: icon uses ref-counting! But is NOT shared with main thread!
-
+ //thread saftey: icon uses ref-counting! But is NOT shared with main thread!
+ const std::pair<IconDB::iterator, bool> rc = buffer->insert(std::make_pair(entryName, icon));
if (rc.second) //if insertion took place
- bufSequence->push(fileNameZ); //note: sharing Zstring with IconDB!!!
+ bufSequence->push(entryName); //note: sharing Zstring with IconDB!!!
assert(buffer->size() == bufSequence->size());
bgstack15