/****************************************************************************** * * Copyright (C) 1997-2015 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its * documentation under the terms of the GNU General Public License is hereby * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * * Documents produced by Doxygen are derivative works derived from the * input used in their production; they are not affected by this license. * */ #include #include #include #include "resourcemgr.h" #include "util.h" #include "version.h" #include "message.h" #include "config.h" class ResourceMgr::Private { public: std::map resources; }; ResourceMgr &ResourceMgr::instance() { static ResourceMgr theInstance; return theInstance; } ResourceMgr::ResourceMgr() : p(std::make_unique()) { } ResourceMgr::~ResourceMgr() { } void ResourceMgr::registerResources(std::initializer_list resources) { for (auto &res : resources) { p->resources.insert({res.name,res}); } } bool ResourceMgr::writeCategory(const QCString &categoryName,const QCString &targetDir) const { for (auto &kv : p->resources) { Resource &res = kv.second; if (res.category==categoryName) { std::string pathName = targetDir.str()+"/"+res.name; std::ofstream f(pathName,std::ofstream::out | std::ofstream::binary); bool ok=false; if (f.is_open()) { f.write(reinterpret_cast(res.data),res.size); ok = !f.fail(); } if (!ok) { err("Failed to write resource '%s' to directory '%s'\n",res.name,qPrint(targetDir)); return FALSE; } } } return TRUE; } bool ResourceMgr::copyResourceAs(const QCString &name,const QCString &targetDir,const QCString &targetName,bool append) const { std::string pathName = targetDir.str()+"/"+targetName.str(); std::ios_base::openmode mode = std::ofstream::out | std::ofstream::binary; if (append) mode |= std::ofstream::app; const Resource *res = get(name); if (res) { switch (res->type) { case Resource::Verbatim: { std::ofstream f(pathName,mode); bool ok=false; if (f.is_open()) { f.write(reinterpret_cast(res->data),res->size); ok = !f.fail(); } if (ok) { return TRUE; } } break; case Resource::Luminance: { QCString n = name; n = n.left(n.length()-4)+".png"; // replace .lum by .png uchar *data = (uchar*)res->data; ushort width = (data[0]<<8)+data[1]; ushort height = (data[2]<<8)+data[3]; ColoredImgDataItem images[2]; images[0].name = n.data(); images[0].width = width; images[0].height = height; images[0].content = &data[4]; images[0].alpha = 0; images[1].name = 0; // terminator writeColoredImgData(targetDir,images); return TRUE; } break; case Resource::LumAlpha: { QCString n = name; n = n.left(n.length()-5)+".png"; // replace .luma by .png uchar *data = (uchar*)res->data; ushort width = (data[0]<<8)+data[1]; ushort height = (data[2]<<8)+data[3]; ColoredImgDataItem images[2]; images[0].name = n.data(); images[0].width = width; images[0].height = height; images[0].content = &data[4]; images[0].alpha = &data[4+width*height]; images[1].name = 0; // terminator writeColoredImgData(targetDir,images); return TRUE; } break; case Resource::CSS: { std::ofstream t(pathName,mode); if (t.is_open()) { QCString buf(res->size+1); memcpy(buf.rawData(),res->data,res->size); buf = replaceColorMarkers(buf); if (name=="navtree.css") { t << substitute(buf,"$width",QCString().setNum(Config_getInt(TREEVIEW_WIDTH))+"px"); } else { t << substitute(buf,"$doxygenversion",getDoxygenVersion()); } return TRUE; } } break; case Resource::SVG: { std::ofstream t(pathName,mode); if (t.is_open()) { QCString buf(res->size+1); memcpy(buf.rawData(),res->data,res->size); t << replaceColorMarkers(buf); return TRUE; } } } } else { err("requested resource '%s' not compiled in!\n",qPrint(name)); } return FALSE; } bool ResourceMgr::copyResource(const QCString &name,const QCString &targetDir) const { return copyResourceAs(name,targetDir,name); } const Resource *ResourceMgr::get(const QCString &name) const { auto it = p->resources.find(name.str()); if (it!=p->resources.end()) return &it->second; return 0; } QCString ResourceMgr::getAsString(const QCString &name) const { const Resource *res = get(name); if (res) { QCString result(res->size+1); memcpy(result.rawData(),res->data,res->size); return result; } else { return QCString(); } }