summaryrefslogtreecommitdiff
path: root/tools/llvm-rc/ResourceFileWriter.h
diff options
context:
space:
mode:
Diffstat (limited to 'tools/llvm-rc/ResourceFileWriter.h')
-rw-r--r--tools/llvm-rc/ResourceFileWriter.h195
1 files changed, 195 insertions, 0 deletions
diff --git a/tools/llvm-rc/ResourceFileWriter.h b/tools/llvm-rc/ResourceFileWriter.h
new file mode 100644
index 000000000000..20bd4bd73679
--- /dev/null
+++ b/tools/llvm-rc/ResourceFileWriter.h
@@ -0,0 +1,195 @@
+//===-- ResourceSerializator.h ----------------------------------*- C++-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===---------------------------------------------------------------------===//
+//
+// This defines a visitor serializing resources to a .res stream.
+//
+//===---------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVMRC_RESOURCESERIALIZATOR_H
+#define LLVM_TOOLS_LLVMRC_RESOURCESERIALIZATOR_H
+
+#include "ResourceScriptStmt.h"
+#include "ResourceVisitor.h"
+
+#include "llvm/Support/Endian.h"
+
+namespace llvm {
+
+class MemoryBuffer;
+
+namespace rc {
+
+struct SearchParams {
+ std::vector<std::string> Include; // Additional folders to search for files.
+ std::vector<std::string> NoInclude; // Folders to exclude from file search.
+ StringRef InputFilePath; // The full path of the input file.
+};
+
+class ResourceFileWriter : public Visitor {
+public:
+ ResourceFileWriter(const SearchParams &Params,
+ std::unique_ptr<raw_fd_ostream> Stream)
+ : Params(Params), FS(std::move(Stream)), IconCursorID(1) {
+ assert(FS && "Output stream needs to be provided to the serializator");
+ }
+
+ Error visitNullResource(const RCResource *) override;
+ Error visitAcceleratorsResource(const RCResource *) override;
+ Error visitCursorResource(const RCResource *) override;
+ Error visitDialogResource(const RCResource *) override;
+ Error visitHTMLResource(const RCResource *) override;
+ Error visitIconResource(const RCResource *) override;
+ Error visitMenuResource(const RCResource *) override;
+ Error visitVersionInfoResource(const RCResource *) override;
+ Error visitStringTableResource(const RCResource *) override;
+ Error visitUserDefinedResource(const RCResource *) override;
+
+ Error visitCaptionStmt(const CaptionStmt *) override;
+ Error visitCharacteristicsStmt(const CharacteristicsStmt *) override;
+ Error visitFontStmt(const FontStmt *) override;
+ Error visitLanguageStmt(const LanguageResource *) override;
+ Error visitStyleStmt(const StyleStmt *) override;
+ Error visitVersionStmt(const VersionStmt *) override;
+
+ // Stringtables are output at the end of .res file. We need a separate
+ // function to do it.
+ Error dumpAllStringTables();
+
+ bool AppendNull; // Append '\0' to each existing STRINGTABLE element?
+
+ struct ObjectInfo {
+ uint16_t LanguageInfo;
+ uint32_t Characteristics;
+ uint32_t VersionInfo;
+
+ Optional<uint32_t> Style;
+ StringRef Caption;
+ struct FontInfo {
+ uint32_t Size;
+ StringRef Typeface;
+ uint32_t Weight;
+ bool IsItalic;
+ uint32_t Charset;
+ };
+ Optional<FontInfo> Font;
+
+ ObjectInfo() : LanguageInfo(0), Characteristics(0), VersionInfo(0) {}
+ } ObjectData;
+
+ struct StringTableInfo {
+ // Each STRINGTABLE bundle depends on ID of the bundle and language
+ // description.
+ using BundleKey = std::pair<uint16_t, uint16_t>;
+ // Each bundle is in fact an array of 16 strings.
+ struct Bundle {
+ std::array<Optional<StringRef>, 16> Data;
+ ObjectInfo DeclTimeInfo;
+ Bundle(const ObjectInfo &Info) : DeclTimeInfo(Info) {}
+ };
+ std::map<BundleKey, Bundle> BundleData;
+ // Bundles are listed in the order of their first occurence.
+ std::vector<BundleKey> BundleList;
+ } StringTableData;
+
+private:
+ Error handleError(Error Err, const RCResource *Res);
+
+ Error
+ writeResource(const RCResource *Res,
+ Error (ResourceFileWriter::*BodyWriter)(const RCResource *));
+
+ // NullResource
+ Error writeNullBody(const RCResource *);
+
+ // AcceleratorsResource
+ Error writeSingleAccelerator(const AcceleratorsResource::Accelerator &,
+ bool IsLastItem);
+ Error writeAcceleratorsBody(const RCResource *);
+
+ // CursorResource and IconResource
+ Error visitIconOrCursorResource(const RCResource *);
+ Error visitIconOrCursorGroup(const RCResource *);
+ Error visitSingleIconOrCursor(const RCResource *);
+ Error writeSingleIconOrCursorBody(const RCResource *);
+ Error writeIconOrCursorGroupBody(const RCResource *);
+
+ // DialogResource
+ Error writeSingleDialogControl(const Control &, bool IsExtended);
+ Error writeDialogBody(const RCResource *);
+
+ // HTMLResource
+ Error writeHTMLBody(const RCResource *);
+
+ // MenuResource
+ Error writeMenuDefinition(const std::unique_ptr<MenuDefinition> &,
+ uint16_t Flags);
+ Error writeMenuDefinitionList(const MenuDefinitionList &List);
+ Error writeMenuBody(const RCResource *);
+
+ // StringTableResource
+ Error visitStringTableBundle(const RCResource *);
+ Error writeStringTableBundleBody(const RCResource *);
+ Error insertStringIntoBundle(StringTableInfo::Bundle &Bundle,
+ uint16_t StringID, StringRef String);
+
+ // User defined resource
+ Error writeUserDefinedBody(const RCResource *);
+
+ // VersionInfoResource
+ Error writeVersionInfoBody(const RCResource *);
+ Error writeVersionInfoBlock(const VersionInfoBlock &);
+ Error writeVersionInfoValue(const VersionInfoValue &);
+
+ const SearchParams &Params;
+
+ // Output stream handling.
+ std::unique_ptr<raw_fd_ostream> FS;
+
+ uint64_t tell() const { return FS->tell(); }
+
+ uint64_t writeObject(const ArrayRef<uint8_t> Data);
+
+ template <typename T> uint64_t writeInt(const T &Value) {
+ support::detail::packed_endian_specific_integral<T, support::little,
+ support::unaligned>
+ Object(Value);
+ return writeObject(Object);
+ }
+
+ template <typename T> uint64_t writeObject(const T &Value) {
+ return writeObject(ArrayRef<uint8_t>(
+ reinterpret_cast<const uint8_t *>(&Value), sizeof(T)));
+ }
+
+ template <typename T> void writeObjectAt(const T &Value, uint64_t Position) {
+ FS->pwrite((const char *)&Value, sizeof(T), Position);
+ }
+
+ Error writeCString(StringRef Str, bool WriteTerminator = true);
+
+ Error writeIdentifier(const IntOrString &Ident);
+ Error writeIntOrString(const IntOrString &Data);
+
+ void writeRCInt(RCInt);
+
+ Error appendFile(StringRef Filename);
+
+ void padStream(uint64_t Length);
+
+ Expected<std::unique_ptr<MemoryBuffer>> loadFile(StringRef File) const;
+
+ // Icon and cursor IDs are allocated starting from 1 and increasing for
+ // each icon/cursor dumped. This maintains the current ID to be allocated.
+ uint16_t IconCursorID;
+};
+
+} // namespace rc
+} // namespace llvm
+
+#endif