From 14c7f45cdae826f88dc539c8c38dd95caf305731 Mon Sep 17 00:00:00 2001 From: Maurus Cuelenaere Date: Fri, 11 Jul 2008 15:50:46 +0000 Subject: Add zook's ZenUtils to SVN git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18010 a1c6a512-1295-4272-9138-f99709370657 --- .../libraries/pelib-0.9/pelib/ResourceDirectory.h | 735 +++++++++++++++++++++ 1 file changed, 735 insertions(+) create mode 100755 utils/zenutils/libraries/pelib-0.9/pelib/ResourceDirectory.h (limited to 'utils/zenutils/libraries/pelib-0.9/pelib/ResourceDirectory.h') diff --git a/utils/zenutils/libraries/pelib-0.9/pelib/ResourceDirectory.h b/utils/zenutils/libraries/pelib-0.9/pelib/ResourceDirectory.h new file mode 100755 index 0000000000..a0bba4c9b3 --- /dev/null +++ b/utils/zenutils/libraries/pelib-0.9/pelib/ResourceDirectory.h @@ -0,0 +1,735 @@ +/* +* ResourceDirectory.cpp - Part of the PeLib library. +* +* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com) +* All rights reserved. +* +* This software is licensed under the zlib/libpng License. +* For more details see http://www.opensource.org/licenses/zlib-license.php +* or the license information file (license.htm) in the root directory +* of PeLib. +*/ + +#ifndef RESOURCEDIRECTORY_H +#define RESOURCEDIRECTORY_H + +#include "PeLibInc.h" + +namespace PeLib +{ + class ResourceElement; + + /// The class ResourceChild is used to store information about a resource node. + class ResourceChild + { + friend class ResourceElement; + friend class ResourceDirectory; + friend class ResourceNode; + friend class ResourceLeaf; + + /// Stores name and offset of a resource node. + PELIB_IMG_RES_DIR_ENTRY entry; + /// A pointer to one of the node's child nodes. + ResourceElement* child; + + public: + /// Function which compares a resource ID to the node's resource ID. + bool equalId(dword wId) const; // EXPORT + /// Function which compares a string to the node's resource name. + bool equalName(std::string strName) const; // EXPORT + /// Predicate that determines if a child is identified by name or by ID. + bool isNamedResource() const; // EXPORT + /// Used for sorting a node's children. + bool operator<(const ResourceChild& rc) const; // EXPORT + /// Returns the size of a resource child. +// unsigned int size() const; + + /// Standard constructor. Does absolutely nothing. + ResourceChild(); + /// Makes a deep copy of a ResourceChild object. + ResourceChild(const ResourceChild& rhs); + /// Makes a deep copy of a ResourceChild object. + ResourceChild& operator=(const ResourceChild& rhs); + /// Deletes a ResourceChild object. + ~ResourceChild(); + }; + + /// Base class for ResourceNode and ResourceLeaf, the elements of the resource tree. + /// \todo write + class ResourceElement + { + friend class ResourceChild; + friend class ResourceNode; + friend class ResourceLeaf; + + protected: + /// Stores RVA of the resource element in the file. + unsigned int uiElementRva; + + /// Reads the next resource element from the InputBuffer. + virtual int read(InputBuffer&, unsigned int, unsigned int/*, const std::string&*/) = 0; + /// Writes the next resource element into the OutputBuffer. + virtual void rebuild(OutputBuffer&, unsigned int&, unsigned int, const std::string&) const = 0; + + public: + /// Returns the RVA of the element in the file. + unsigned int getElementRva() const; // EXPORT + /// Indicates if the resource element is a leaf or a node. + virtual bool isLeaf() const = 0; // EXPORT + /// Corrects erroneous valeus in the ResourceElement. + virtual void makeValid() = 0; // EXPORT + /// Returns the size of a resource element. +// virtual unsigned int size() const = 0; + /// Necessary virtual destructor. + virtual ~ResourceElement() {} + }; + + /// ResourceLeafs represent the leafs of the resource tree: The actual resources. + class ResourceLeaf : public ResourceElement + { + friend class ResourceChild; + friend class ResourceDirectory; + template friend struct fixNumberOfEntries; + + private: + /// The resource data. + std::vector m_data; + /// PeLib equivalent of the Win32 structure IMAGE_RESOURCE_DATA_ENTRY + PELIB_IMAGE_RESOURCE_DATA_ENTRY entry; + + protected: + int read(InputBuffer& inpBuffer, unsigned int uiOffset, unsigned int rva/*, const std::string&*/); + /// Writes the next resource leaf into the OutputBuffer. + void rebuild(OutputBuffer&, unsigned int& uiOffset, unsigned int uiRva, const std::string&) const; + + public: + /// Indicates if the resource element is a leaf or a node. + bool isLeaf() const; // EXPORT + /// Corrects erroneous valeus in the ResourceLeaf. + void makeValid(); // EXPORT + /// Reads the next resource leaf from the InputBuffer. + /// Returns the size of a resource lead. +// unsigned int size() const; + + /// Returns the resource data of this resource leaf. + std::vector getData() const; // EXPORT + /// Sets the resource data of this resource leaf. + void setData(const std::vector& vData); // EXPORT + + /// Returns the OffsetToData value of this resource leaf. + dword getOffsetToData() const; // EXPORT + /// Returns the Size value of this resource leaf. + dword getSize() const; // EXPORT + /// Returns the CodePage value of this resource leaf. + dword getCodePage() const; // EXPORT + /// Returns the Reserved value of this resource leaf. + dword getReserved() const; // EXPORT + + /// Sets the OffsetToData value of this resource leaf. + void setOffsetToData(dword dwValue); // EXPORT + /// Sets the Size value of this resource leaf. + void setSize(dword dwValue); // EXPORT + /// Sets the CodePage value of this resource leaf. + void setCodePage(dword dwValue); // EXPORT + /// Sets the Reserved value of this resource leaf. + void setReserved(dword dwValue); // EXPORT + }; + + /// ResourceNodes represent the nodes in the resource tree. + class ResourceNode : public ResourceElement + { + friend class ResourceChild; + friend class ResourceDirectory; + template friend struct fixNumberOfEntries; + + /// The node's children. + std::vector children; + /// The node's header. Equivalent to IMAGE_RESOURCE_DIRECTORY from the Win32 API. + PELIB_IMAGE_RESOURCE_DIRECTORY header; + + protected: + /// Reads the next resource node. + int read(InputBuffer& inpBuffer, unsigned int uiOffset, unsigned int rva/*, const std::string&*/); + /// Writes the next resource node into the OutputBuffer. + void rebuild(OutputBuffer&, unsigned int& uiOffset, unsigned int uiRva, const std::string&) const; + + public: + /// Indicates if the resource element is a leaf or a node. + bool isLeaf() const; // EXPORT + /// Corrects erroneous valeus in the ResourceNode. + void makeValid(); // EXPORT + + /// Returns the node's number of children. + unsigned int getNumberOfChildren() const; // EXPORT + /// Adds another child to node. + void addChild(); // EXPORT + /// Returns a node's child. + ResourceElement* getChild(unsigned int uiIndex); // EXPORT + /// Removes a node's child. + void removeChild(unsigned int uiIndex); // EXPORT + + /// Returns the name of one of the node's children. + std::string getChildName(unsigned int uiIndex) const; // EXPORT + /// Returns the Name value of one of the node's children. + dword getOffsetToChildName(unsigned int uiIndex) const; // EXPORT + /// Returns the OffsetToData value of one of the node's children. + dword getOffsetToChildData(unsigned int uiIndex) const; // EXPORT + + /// Sets the name of one of the node's children. + void setChildName(unsigned int uiIndex, const std::string& strNewName); // EXPORT + /// Sets the Name value of one of the node's children. + void setOffsetToChildName(unsigned int uiIndex, dword dwNewOffset); // EXPORT + /// Sets the OffsetToData value of one of the node's children. + void setOffsetToChildData(unsigned int uiIndex, dword dwNewOffset); // EXPORT + + /// Returns the node's Characteristics value. + dword getCharacteristics() const; // EXPORT + /// Returns the node's TimeDateStamp value. + dword getTimeDateStamp() const; // EXPORT + /// Returns the node's MajorVersion value. + word getMajorVersion() const; // EXPORT + /// Returns the node's MinorVersion value. + word getMinorVersion() const; // EXPORT + /// Returns the node's NumberOfNamedEntries value. + word getNumberOfNamedEntries() const; // EXPORT + /// Returns the node's NumberOfIdEntries value. + word getNumberOfIdEntries() const; // EXPORT + + /// Sets the node's Characteristics value. + void setCharacteristics(dword value); // EXPORT + /// Sets the node's TimeDateStamp value. + void setTimeDateStamp(dword value); // EXPORT + /// Sets the node's MajorVersion value. + void setMajorVersion(word value); // EXPORT + /// Sets the node's MinorVersion value. + void setMinorVersion(word value); // EXPORT + /// Sets the node's NumberOfNamedEntries value. + void setNumberOfNamedEntries(word value); // EXPORT + /// Sets the node's NumberOfIdEntries value. + void setNumberOfIdEntries(word value); // EXPORT + + /// Returns the size of a resource node. +// unsigned int size() const; + }; + + /// Auxiliary functor which is used to search through the resource tree. + /** + * Traits class for the template functions of ResourceDirectory. + * It's used to find out which function to use when searching for resource nodes or resource leafs + * in a node's children vector. + **/ + template + struct ResComparer + { + /// Pointer to a member function of ResourceChild + typedef bool(ResourceChild::*CompFunc)(T) const; + + /// Return 0 for all unspecialized versions of ResComparer. + static CompFunc comp(); + }; + + /// Auxiliary functor which is used to search through the resource tree. + /** + * ResComparer is used when a resource element is searched for by ID. + **/ + template<> + struct ResComparer + { + /// Pointer to a member function of ResourceChild + typedef bool(ResourceChild::*CompFunc)(dword) const; + + /// Return the address of the ResourceChild member function that compares the ids of resource elements. + static CompFunc comp() + { + return &ResourceChild::equalId; + } + }; + + /// Auxiliary functor which is used to search through the resource tree. + /** + * This specializd version of ResComparer is used when a resource element is searched for by name. + **/ + template<> + struct ResComparer + { + /// Pointer to a member function of ResourceChild + typedef bool(ResourceChild::*CompFunc)(std::string) const; + + /// Return the address of the ResourceChild member function that compares the names of resource elements. + static CompFunc comp() + { + return &ResourceChild::equalName; + } + }; + + /// Unspecialized function that's used as base template for the specialized versions below. + template + struct fixNumberOfEntries + { + /// Fixes a resource node's header. + static void fix(ResourceNode*); + }; + + /// Fixes NumberOfIdEntries value of a node. + template<> + struct fixNumberOfEntries + { + /// Fixes a resource node's NumberOfIdEntries value. + static void fix(ResourceNode* node) + { + node->header.NumberOfIdEntries = (unsigned int)node->children.size() - std::count_if(node->children.begin(), node->children.end(), std::mem_fun_ref(&ResourceChild::isNamedResource)); + } + }; + + /// Fixes NumberOfNamedEntries value of a node. + template<> + struct fixNumberOfEntries + { + /// Fixes a resource node's NumberOfNamedEntries value. + static void fix(ResourceNode* node) + { + node->header.NumberOfNamedEntries = static_cast(std::count_if(node->children.begin(), node->children.end(), std::mem_fun_ref(&ResourceChild::isNamedResource))); + } + }; + + /// Class that represents the resource directory of a PE file. + /** + * The class ResourceDirectory represents the resource directory of a PE file. This class is fundamentally + * different from the other classes of the PeLib library due to the structure of the ResourceDirectory. + * For once, it's possible to manipulate the ResourceDirectory through a set of "high level" functions and + * and through a set of "low level" functions. The "high level" functions are the functions inside the + * ResourceDirectory class with the exception of getRoot.

+ * getRoot on the other hand is the first "low level" function. Use it to retrieve the root node of the + * resource tree. Then you can traverse through the tree and manipulate individual nodes and leafs + * directly using the functions provided by the classes ResourceNode and ResourceLeaf.

+ * There's another difference between the ResourceDirectory class and the other PeLib classes, which is + * once again caused by the special structure of the PE resource directory. The nodes of the resource + * tree must be in a certain order. Manipulating the resource tree does not directly sort the nodes + * correctly as this would cause more trouble than it fixes. That means it's your responsibility to + * fix the resource tree after manipulating it. PeLib makes the job easy for you, just call the + * ResourceDirectory::makeValid function.

+ * You might also wonder why there's no size() function in this class. I did not forget it. It's just + * that it's impossible to calculate the size of the resource directory without rebuilding it. So why + * should PeLib do this if you can do it just as easily by calling rebuild() and then checking the length + * of the returned vector.

+ * There are also different ways to serialize (rebuild) the resource tree as it's not a fixed structure + * that can easily be minimized like most other PE directories.

+ * This means it's entirely possible that the resource tree you read from a file differs from the one + * PeLib creates. This might cause a minor issue. The original resource tree might be smaller (due to + * different padding) so it's crucial that you check if there's enough space in the original resource + * directory before you write the rebuilt resource directory back to the file. + **/ + class ResourceDirectory + { + private: + /// The root node of the resource directory. + ResourceNode m_rnRoot; + + // Prepare for some crazy syntax below to make Digital Mars happy. + + /// Retrieves an iterator to a specified resource child. + template + std::vector::const_iterator locateResourceT(S restypeid, T resid) const; + + /// Retrieves an iterator to a specified resource child. + template + std::vector::iterator locateResourceT(S restypeid, T resid); + + /// Adds a new resource. + template + int addResourceT(S restypeid, T resid, ResourceChild& rc); + + /// Removes new resource. + template + int removeResourceT(S restypeid, T resid); + + /// Returns the data of a resource. + template + int getResourceDataT(S restypeid, T resid, std::vector& data) const; + + /// Sets the data of a resource. + template + int setResourceDataT(S restypeid, T resid, std::vector& data); + + /// Returns the ID of a resource. + template + dword getResourceIdT(S restypeid, T resid) const; + + /// Sets the ID of a resource. + template + int setResourceIdT(S restypeid, T resid, dword dwNewResId); + + /// Returns the name of a resource. + template + std::string getResourceNameT(S restypeid, T resid) const; + + /// Sets the name of a resource. + template + int setResourceNameT(S restypeid, T resid, std::string strNewResName); + + public: + ResourceNode* getRoot(); + /// Corrects a erroneous resource directory. + void makeValid(); + /// Reads the resource directory from a file. + int read(const std::string& strFilename, unsigned int uiOffset, unsigned int uiSize, unsigned int uiResDirRva); + /// Rebuilds the resource directory. + void rebuild(std::vector& vBuffer, unsigned int uiRva) const; + /// Returns the size of the rebuilt resource directory. +// unsigned int size() const; + /// Writes the resource directory to a file. + int write(const std::string& strFilename, unsigned int uiOffset, unsigned int uiRva) const; + + /// Adds a new resource type. + int addResourceType(dword dwResTypeId); + /// Adds a new resource type. + int addResourceType(const std::string& strResTypeName); + + /// Removes a resource type and all of it's resources. + int removeResourceType(dword dwResTypeId); + /// Removes a resource type and all of it's resources. + int removeResourceType(const std::string& strResTypeName); + + /// Removes a resource type and all of it's resources. + int removeResourceTypeByIndex(unsigned int uiIndex); + + /// Adds a new resource. + int addResource(dword dwResTypeId, dword dwResId); + /// Adds a new resource. + int addResource(dword dwResTypeId, const std::string& strResName); + /// Adds a new resource. + int addResource(const std::string& strResTypeName, dword dwResId); + /// Adds a new resource. + int addResource(const std::string& strResTypeName, const std::string& strResName); + + /// Removes a resource. + int removeResource(dword dwResTypeId, dword dwResId); + /// Removes a resource. + int removeResource(dword dwResTypeId, const std::string& strResName); + /// Removes a resource. + int removeResource(const std::string& strResTypeName, dword dwResId); + /// Removes a resource. + int removeResource(const std::string& strResTypeName, const std::string& strResName); + + /// Returns the number of resource types. + unsigned int getNumberOfResourceTypes() const; + + /// Returns the ID of a resource type. + dword getResourceTypeIdByIndex(unsigned int uiIndex) const; + /// Returns the name of a resource type. + std::string getResourceTypeNameByIndex(unsigned int uiIndex) const; + + /// Converts a resource type ID to an index. + int resourceTypeIdToIndex(dword dwResTypeId) const; + /// Converts a resource type name to an index. + int resourceTypeNameToIndex(const std::string& strResTypeName) const; + + /// Returns the number of resources of a certain resource type. + unsigned int getNumberOfResources(dword dwId) const; + /// Returns the number of resources of a certain resource type. + unsigned int getNumberOfResources(const std::string& strResTypeName) const; + + /// Returns the number of resources of a certain resource type. + unsigned int getNumberOfResourcesByIndex(unsigned int uiIndex) const; + + /// Returns the data of a certain resource. + void getResourceData(dword dwResTypeId, dword dwResId, std::vector& data) const; + /// Returns the data of a certain resource. + void getResourceData(dword dwResTypeId, const std::string& strResName, std::vector& data) const; + /// Returns the data of a certain resource. + void getResourceData(const std::string& strResTypeName, dword dwResId, std::vector& data) const; + /// Returns the data of a certain resource. + void getResourceData(const std::string& strResTypeName, const std::string& strResName, std::vector& data) const; + + /// Returns the data of a certain resource. + void getResourceDataByIndex(unsigned int uiResTypeIndex, unsigned int uiResIndex, std::vector& data) const; + + /// Sets the data of a certain resource. + void setResourceData(dword dwResTypeId, dword dwResId, std::vector& data); + /// Sets the data of a certain resource. + void setResourceData(dword dwResTypeId, const std::string& strResName, std::vector& data); + /// Sets the data of a certain resource. + void setResourceData(const std::string& strResTypeName, dword dwResId, std::vector& data); + /// Sets the data of a certain resource. + void setResourceData(const std::string& strResTypeName, const std::string& strResName, std::vector& data); + + /// Sets the data of a certain resource. + void setResourceDataByIndex(unsigned int uiResTypeIndex, unsigned int uiResIndex, std::vector& data); + + /// Returns the ID of a certain resource. + dword getResourceId(dword dwResTypeId, const std::string& strResName) const; + /// Returns the ID of a certain resource. + dword getResourceId(const std::string& strResTypeName, const std::string& strResName) const; + + /// Returns the ID of a certain resource. + dword getResourceIdByIndex(unsigned int uiResTypeIndex, unsigned int uiResIndex) const; + + /// Sets the ID of a certain resource. + void setResourceId(dword dwResTypeId, dword dwResId, dword dwNewResId); + /// Sets the ID of a certain resource. + void setResourceId(dword dwResTypeId, const std::string& strResName, dword dwNewResId); + /// Sets the ID of a certain resource. + void setResourceId(const std::string& strResTypeName, dword dwResId, dword dwNewResId); + /// Sets the ID of a certain resource. + void setResourceId(const std::string& strResTypeName, const std::string& strResName, dword dwNewResId); + + /// Sets the ID of a certain resource. + void setResourceIdByIndex(unsigned int uiResTypeIndex, unsigned int uiResIndex, dword dwNewResId); + + /// Returns the name of a certain resource. + std::string getResourceName(dword dwResTypeId, dword dwResId) const; + /// Returns the name of a certain resource. + std::string getResourceName(const std::string& strResTypeName, dword dwResId) const; + + /// Returns the name of a certain resource. + std::string getResourceNameByIndex(unsigned int uiResTypeIndex, unsigned int uiResIndex) const; + + /// Sets the name of a certain resource. + void setResourceName(dword dwResTypeId, dword dwResId, const std::string& strNewResName); + /// Sets the name of a certain resource. + void setResourceName(dword dwResTypeId, const std::string& strResName, const std::string& strNewResName); + /// Sets the name of a certain resource. + void setResourceName(const std::string& strResTypeName, dword dwResId, const std::string& strNewResName); + /// Sets the name of a certain resource. + void setResourceName(const std::string& strResTypeName, const std::string& strResName, const std::string& strNewResName); + + /// Sets the name of a certain resource. + void setResourceNameByIndex(unsigned int uiResTypeIndex, unsigned int uiResIndex, const std::string& strNewResName); + }; + + /** + * Looks through the entire resource tree and returns a const_iterator to the resource specified + * by the parameters. + * @param restypeid Identifier of the resource type (either ID or name). + * @param resid Identifier of the resource (either ID or name). + * @return A const_iterator to the specified resource. + **/ + template + std::vector::const_iterator ResourceDirectory::locateResourceT(S restypeid, T resid) const + { + typedef bool(ResourceChild::*CompFunc1)(S) const; + typedef bool(ResourceChild::*CompFunc2)(T) const; + + CompFunc1 comp1 = ResComparer::comp(); + CompFunc2 comp2 = ResComparer::comp(); + + std::vector::const_iterator Iter = std::find_if(m_rnRoot.children.begin(), m_rnRoot.children.end(), std::bind2nd(std::mem_fun_ref(comp1), restypeid)); + if (Iter == m_rnRoot.children.end()) + { + return Iter; + } + + ResourceNode* currNode = static_cast(Iter->child); + std::vector::const_iterator ResIter = std::find_if(currNode->children.begin(), currNode->children.end(), std::bind2nd(std::mem_fun_ref(comp2), resid)); + if (ResIter == currNode->children.end()) + { + return ResIter; + } + + return ResIter; + } + + /** + * Looks through the entire resource tree and returns an iterator to the resource specified + * by the parameters. + * @param restypeid Identifier of the resource type (either ID or name). + * @param resid Identifier of the resource (either ID or name). + * @return An iterator to the specified resource. + **/ + template + std::vector::iterator ResourceDirectory::locateResourceT(S restypeid, T resid) + { + typedef bool(ResourceChild::*CompFunc1)(S) const; + typedef bool(ResourceChild::*CompFunc2)(T) const; + + CompFunc1 comp1 = ResComparer::comp(); + CompFunc2 comp2 = ResComparer::comp(); + + std::vector::iterator Iter = std::find_if(m_rnRoot.children.begin(), m_rnRoot.children.end(), std::bind2nd(std::mem_fun_ref(comp1), restypeid)); + if (Iter == m_rnRoot.children.end()) + { + return Iter; + } + + ResourceNode* currNode = static_cast(Iter->child); + std::vector::iterator ResIter = std::find_if(currNode->children.begin(), currNode->children.end(), std::bind2nd(std::mem_fun_ref(comp2), resid)); + if (ResIter == currNode->children.end()) + { + return ResIter; + } + + return ResIter; + } + + /** + * Adds a new resource, resource type and ID are specified by the parameters. + * @param restypeid Identifier of the resource type (either ID or name). + * @param resid Identifier of the resource (either ID or name). + * @param rc ResourceChild that will be added. + **/ + template + int ResourceDirectory::addResourceT(S restypeid, T resid, ResourceChild& rc) + { + typedef bool(ResourceChild::*CompFunc1)(S) const; + typedef bool(ResourceChild::*CompFunc2)(T) const; + + CompFunc1 comp1 = ResComparer::comp(); + CompFunc2 comp2 = ResComparer::comp(); + + std::vector::iterator Iter = std::find_if(m_rnRoot.children.begin(), m_rnRoot.children.end(), std::bind2nd(std::mem_fun_ref(comp1), restypeid)); + if (Iter == m_rnRoot.children.end()) + { + return 1; + // throw Exceptions::ResourceTypeDoesNotExist(ResourceDirectoryId, __LINE__); + } + + ResourceNode* currNode = static_cast(Iter->child); + std::vector::iterator ResIter = std::find_if(currNode->children.begin(), currNode->children.end(), std::bind2nd(std::mem_fun_ref(comp2), resid)); + if (ResIter != currNode->children.end()) + { + return 1; +// throw Exceptions::EntryAlreadyExists(ResourceDirectoryId, __LINE__); + } + + rc.child = new ResourceNode; + ResourceChild rlnew; + rlnew.child = new ResourceLeaf; + ResourceNode* currNode2 = static_cast(rc.child); + currNode2->children.push_back(rlnew); + currNode->children.push_back(rc); + + fixNumberOfEntries::fix(currNode); + fixNumberOfEntries::fix(currNode2); + + return 0; + } + + /** + * Removes a resource, resource type and ID are specified by the parameters. + * @param restypeid Identifier of the resource type (either ID or name). + * @param resid Identifier of the resource (either ID or name). + **/ + template + int ResourceDirectory::removeResourceT(S restypeid, T resid) + { + typedef bool(ResourceChild::*CompFunc1)(S) const; + typedef bool(ResourceChild::*CompFunc2)(T) const; + + CompFunc1 comp1 = ResComparer::comp(); + CompFunc2 comp2 = ResComparer::comp(); + + std::vector::iterator Iter = std::find_if(m_rnRoot.children.begin(), m_rnRoot.children.end(), std::bind2nd(std::mem_fun_ref(comp1), restypeid)); + if (Iter == m_rnRoot.children.end()) + { + return 1; + //throw Exceptions::ResourceTypeDoesNotExist(ResourceDirectoryId, __LINE__); + } + + ResourceNode* currNode = static_cast(Iter->child); + std::vector::iterator ResIter = std::find_if(currNode->children.begin(), currNode->children.end(), std::bind2nd(std::mem_fun_ref(comp2), resid)); + if (ResIter == currNode->children.end()) + { + return 1; + // throw Exceptions::InvalidName(ResourceDirectoryId, __LINE__); + } + + currNode->children.erase(ResIter); + + fixNumberOfEntries::fix(currNode); + + return 0; + } + + /** + * Returns the data of a resource, resource type and ID are specified by the parameters. + * @param restypeid Identifier of the resource type (either ID or name). + * @param resid Identifier of the resource (either ID or name). + * @param data The data of the resource will be written into this vector. + **/ + template + int ResourceDirectory::getResourceDataT(S restypeid, T resid, std::vector& data) const + { + std::vector::const_iterator ResIter = locateResourceT(restypeid, resid); + ResourceNode* currNode = static_cast(ResIter->child); + ResourceLeaf* currLeaf = static_cast(currNode->children[0].child); + data.assign(currLeaf->m_data.begin(), currLeaf->m_data.end()); + + return 0; + } + + /** + * Sets the data of a resource, resource type and ID are specified by the parameters. + * @param restypeid Identifier of the resource type (either ID or name). + * @param resid Identifier of the resource (either ID or name). + * @param data The new data of the resource is taken from this vector. + **/ + template + int ResourceDirectory::setResourceDataT(S restypeid, T resid, std::vector& data) + { + std::vector::iterator ResIter = locateResourceT(restypeid, resid); + ResourceNode* currNode = static_cast(ResIter->child); + ResourceLeaf* currLeaf = static_cast(currNode->children[0].child); + currLeaf->m_data.assign(data.begin(), data.end()); + + return 0; + } + + /** + * Returns the id of a resource, resource type and ID are specified by the parameters. + * Note: Calling this function with resid == the ID of the resource makes no sense at all. + * @param restypeid Identifier of the resource type (either ID or name). + * @param resid Identifier of the resource (either ID or name). + * @return The ID of the specified resource. + **/ + template + dword ResourceDirectory::getResourceIdT(S restypeid, T resid) const + { + std::vector::const_iterator ResIter = locateResourceT(restypeid, resid); + return ResIter->entry.irde.Name; + } + + /** + * Sets the id of a resource, resource type and ID are specified by the parameters. + * @param restypeid Identifier of the resource type (either ID or name). + * @param resid Identifier of the resource (either ID or name). + * @param dwNewResId New ID of the resource. + **/ + template + int ResourceDirectory::setResourceIdT(S restypeid, T resid, dword dwNewResId) + { + std::vector::iterator ResIter = locateResourceT(restypeid, resid); + ResIter->entry.irde.Name = dwNewResId; + return 0; + } + + /** + * Returns the name of a resource, resource type and ID are specified by the parameters. + * Note: Calling this function with resid == the name of the resource makes no sense at all. + * @param restypeid Identifier of the resource type (either ID or name). + * @param resid Identifier of the resource (either ID or name). + * @return The name of the specified resource. + **/ + template + std::string ResourceDirectory::getResourceNameT(S restypeid, T resid) const + { + std::vector::const_iterator ResIter = locateResourceT(restypeid, resid); + return ResIter->entry.wstrName; + } + + /** + * Sets the name of a resource, resource type and ID are specified by the parameters. + * @param restypeid Identifier of the resource type (either ID or name). + * @param resid Identifier of the resource (either ID or name). + * @param strNewResName The new name of the resource. + **/ + template + int ResourceDirectory::setResourceNameT(S restypeid, T resid, std::string strNewResName) + { + std::vector::iterator ResIter = locateResourceT(restypeid, resid); + ResIter->entry.wstrName = strNewResName; + + return 0; + } +} + +#endif -- cgit v1.2.3