private:
friend class WindowsResourceParser;
- static uint32_t StringCount;
- static uint32_t DataCount;
-
- static std::unique_ptr<TreeNode> createStringNode();
+ // Index is the StringTable vector index for this node's name.
+ static std::unique_ptr<TreeNode> createStringNode(uint32_t Index);
static std::unique_ptr<TreeNode> createIDNode();
+ // DataIndex is the Data vector index that the data node points at.
static std::unique_ptr<TreeNode> createDataNode(uint16_t MajorVersion,
uint16_t MinorVersion,
uint32_t Characteristics,
- uint32_t Origin);
+ uint32_t Origin,
+ uint32_t DataIndex);
- explicit TreeNode(bool IsStringNode);
+ explicit TreeNode(uint32_t StringIndex);
TreeNode(uint16_t MajorVersion, uint16_t MinorVersion,
- uint32_t Characteristics, uint32_t Origin);
+ uint32_t Characteristics, uint32_t Origin, uint32_t DataIndex);
bool addEntry(const ResourceEntryRef &Entry, uint32_t Origin,
- bool &IsNewTypeString, bool &IsNewNameString,
+ std::vector<std::vector<uint8_t>> &Data,
+ std::vector<std::vector<UTF16>> &StringTable,
TreeNode *&Result);
- TreeNode &addTypeNode(const ResourceEntryRef &Entry, bool &IsNewTypeString);
- TreeNode &addNameNode(const ResourceEntryRef &Entry, bool &IsNewNameString);
+ TreeNode &addTypeNode(const ResourceEntryRef &Entry,
+ std::vector<std::vector<UTF16>> &StringTable);
+ TreeNode &addNameNode(const ResourceEntryRef &Entry,
+ std::vector<std::vector<UTF16>> &StringTable);
bool addLanguageNode(const ResourceEntryRef &Entry, uint32_t Origin,
+ std::vector<std::vector<uint8_t>> &Data,
TreeNode *&Result);
bool addDataChild(uint32_t ID, uint16_t MajorVersion, uint16_t MinorVersion,
uint32_t Characteristics, uint32_t Origin,
- TreeNode *&Result);
+ uint32_t DataIndex, TreeNode *&Result);
TreeNode &addIDChild(uint32_t ID);
- TreeNode &addNameChild(ArrayRef<UTF16> NameRef, bool &IsNewString);
+ TreeNode &addNameChild(ArrayRef<UTF16> NameRef,
+ std::vector<std::vector<UTF16>> &StringTable);
bool IsDataNode = false;
uint32_t StringIndex;
// 8-byte because it makes everyone happy.
const uint32_t SECTION_ALIGNMENT = sizeof(uint64_t);
-uint32_t WindowsResourceParser::TreeNode::StringCount = 0;
-uint32_t WindowsResourceParser::TreeNode::DataCount = 0;
-
WindowsResource::WindowsResource(MemoryBufferRef Source)
: Binary(Binary::ID_WinRes, Source) {
size_t LeadingSize = WIN_RES_MAGIC_SIZE + WIN_RES_NULL_ENTRY_SIZE;
InputFilenames.push_back(WR->getFileName());
bool End = false;
while (!End) {
- Data.push_back(Entry.getData());
-
- bool IsNewTypeString = false;
- bool IsNewNameString = false;
TreeNode *Node;
- bool IsNewNode =
- Root.addEntry(Entry, Origin, IsNewTypeString, IsNewNameString, Node);
+ bool IsNewNode = Root.addEntry(Entry, Origin, Data, StringTable, Node);
if (!IsNewNode) {
Duplicates.push_back(makeDuplicateResourceError(
Entry, InputFilenames[Node->Origin], WR->getFileName()));
}
- if (IsNewTypeString)
- StringTable.push_back(Entry.getTypeString());
-
- if (IsNewNameString)
- StringTable.push_back(Entry.getNameString());
-
RETURN_IF_ERROR(Entry.moveNext(End));
}
Root.print(Writer, "Resource Tree");
}
-bool WindowsResourceParser::TreeNode::addEntry(const ResourceEntryRef &Entry,
- uint32_t Origin,
- bool &IsNewTypeString,
- bool &IsNewNameString,
- TreeNode *&Result) {
- TreeNode &TypeNode = addTypeNode(Entry, IsNewTypeString);
- TreeNode &NameNode = TypeNode.addNameNode(Entry, IsNewNameString);
- return NameNode.addLanguageNode(Entry, Origin, Result);
+bool WindowsResourceParser::TreeNode::addEntry(
+ const ResourceEntryRef &Entry, uint32_t Origin,
+ std::vector<std::vector<uint8_t>> &Data,
+ std::vector<std::vector<UTF16>> &StringTable, TreeNode *&Result) {
+ TreeNode &TypeNode = addTypeNode(Entry, StringTable);
+ TreeNode &NameNode = TypeNode.addNameNode(Entry, StringTable);
+ return NameNode.addLanguageNode(Entry, Origin, Data, Result);
}
-WindowsResourceParser::TreeNode::TreeNode(bool IsStringNode) {
- if (IsStringNode)
- StringIndex = StringCount++;
-}
+WindowsResourceParser::TreeNode::TreeNode(uint32_t StringIndex)
+ : StringIndex(StringIndex) {}
WindowsResourceParser::TreeNode::TreeNode(uint16_t MajorVersion,
uint16_t MinorVersion,
uint32_t Characteristics,
- uint32_t Origin)
- : IsDataNode(true), MajorVersion(MajorVersion), MinorVersion(MinorVersion),
- Characteristics(Characteristics), Origin(Origin) {
- DataIndex = DataCount++;
-}
+ uint32_t Origin, uint32_t DataIndex)
+ : IsDataNode(true), DataIndex(DataIndex), MajorVersion(MajorVersion),
+ MinorVersion(MinorVersion), Characteristics(Characteristics),
+ Origin(Origin) {}
std::unique_ptr<WindowsResourceParser::TreeNode>
-WindowsResourceParser::TreeNode::createStringNode() {
- return std::unique_ptr<TreeNode>(new TreeNode(true));
+WindowsResourceParser::TreeNode::createStringNode(uint32_t Index) {
+ return std::unique_ptr<TreeNode>(new TreeNode(Index));
}
std::unique_ptr<WindowsResourceParser::TreeNode>
WindowsResourceParser::TreeNode::createIDNode() {
- return std::unique_ptr<TreeNode>(new TreeNode(false));
+ return std::unique_ptr<TreeNode>(new TreeNode(0));
}
std::unique_ptr<WindowsResourceParser::TreeNode>
WindowsResourceParser::TreeNode::createDataNode(uint16_t MajorVersion,
uint16_t MinorVersion,
uint32_t Characteristics,
- uint32_t Origin) {
- return std::unique_ptr<TreeNode>(
- new TreeNode(MajorVersion, MinorVersion, Characteristics, Origin));
+ uint32_t Origin,
+ uint32_t DataIndex) {
+ return std::unique_ptr<TreeNode>(new TreeNode(
+ MajorVersion, MinorVersion, Characteristics, Origin, DataIndex));
}
-WindowsResourceParser::TreeNode &
-WindowsResourceParser::TreeNode::addTypeNode(const ResourceEntryRef &Entry,
- bool &IsNewTypeString) {
+WindowsResourceParser::TreeNode &WindowsResourceParser::TreeNode::addTypeNode(
+ const ResourceEntryRef &Entry,
+ std::vector<std::vector<UTF16>> &StringTable) {
if (Entry.checkTypeString())
- return addNameChild(Entry.getTypeString(), IsNewTypeString);
+ return addNameChild(Entry.getTypeString(), StringTable);
else
return addIDChild(Entry.getTypeID());
}
-WindowsResourceParser::TreeNode &
-WindowsResourceParser::TreeNode::addNameNode(const ResourceEntryRef &Entry,
- bool &IsNewNameString) {
+WindowsResourceParser::TreeNode &WindowsResourceParser::TreeNode::addNameNode(
+ const ResourceEntryRef &Entry,
+ std::vector<std::vector<UTF16>> &StringTable) {
if (Entry.checkNameString())
- return addNameChild(Entry.getNameString(), IsNewNameString);
+ return addNameChild(Entry.getNameString(), StringTable);
else
return addIDChild(Entry.getNameID());
}
bool WindowsResourceParser::TreeNode::addLanguageNode(
- const ResourceEntryRef &Entry, uint32_t Origin, TreeNode *&Result) {
- return addDataChild(Entry.getLanguage(), Entry.getMajorVersion(),
- Entry.getMinorVersion(), Entry.getCharacteristics(),
- Origin, Result);
+ const ResourceEntryRef &Entry, uint32_t Origin,
+ std::vector<std::vector<uint8_t>> &Data, TreeNode *&Result) {
+ bool Added = addDataChild(Entry.getLanguage(), Entry.getMajorVersion(),
+ Entry.getMinorVersion(), Entry.getCharacteristics(),
+ Origin, Data.size(), Result);
+ if (Added)
+ Data.push_back(Entry.getData());
+ return Added;
}
bool WindowsResourceParser::TreeNode::addDataChild(
uint32_t ID, uint16_t MajorVersion, uint16_t MinorVersion,
- uint32_t Characteristics, uint32_t Origin, TreeNode *&Result) {
- auto NewChild =
- createDataNode(MajorVersion, MinorVersion, Characteristics, Origin);
+ uint32_t Characteristics, uint32_t Origin, uint32_t DataIndex,
+ TreeNode *&Result) {
+ auto NewChild = createDataNode(MajorVersion, MinorVersion, Characteristics,
+ Origin, DataIndex);
auto ElementInserted = IDChildren.emplace(ID, std::move(NewChild));
Result = ElementInserted.first->second.get();
return ElementInserted.second;
return *(Child->second);
}
-WindowsResourceParser::TreeNode &
-WindowsResourceParser::TreeNode::addNameChild(ArrayRef<UTF16> NameRef,
- bool &IsNewString) {
+WindowsResourceParser::TreeNode &WindowsResourceParser::TreeNode::addNameChild(
+ ArrayRef<UTF16> NameRef, std::vector<std::vector<UTF16>> &StringTable) {
std::string NameString;
convertUTF16LEToUTF8String(NameRef, NameString);
auto Child = StringChildren.find(NameString);
if (Child == StringChildren.end()) {
- auto NewChild = createStringNode();
- IsNewString = true;
+ auto NewChild = createStringNode(StringTable.size());
+ StringTable.push_back(NameRef);
WindowsResourceParser::TreeNode &Node = *NewChild;
StringChildren.emplace(NameString, std::move(NewChild));
return Node;