brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.7 KiB · a13af45 Raw
228 lines · c
1//===-- ResourceSerializator.h ----------------------------------*- C++-*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===---------------------------------------------------------------------===//8//9// This defines a visitor serializing resources to a .res stream.10//11//===---------------------------------------------------------------------===//12 13#ifndef LLVM_TOOLS_LLVMRC_RESOURCESERIALIZATOR_H14#define LLVM_TOOLS_LLVMRC_RESOURCESERIALIZATOR_H15 16#include "ResourceScriptStmt.h"17#include "ResourceVisitor.h"18 19#include "llvm/ADT/StringRef.h"20#include "llvm/Support/Endian.h"21 22#include <map>23 24namespace llvm {25 26class MemoryBuffer;27 28namespace rc {29 30enum CodePage {31  CpAcp = 0,        // The current used codepage. Since there's no such32                    // notion in LLVM what codepage it actually means,33                    // this only allows ASCII.34  CpWin1252 = 1252, // A codepage where most 8 bit values correspond to35                    // unicode code points with the same value.36  CpUtf8 = 65001,   // UTF-8.37};38 39struct WriterParams {40  std::vector<std::string> Include;   // Additional folders to search for files.41  bool NoInclude;                     // Ignore the INCLUDE variable.42  StringRef InputFilePath;            // The full path of the input file.43  int CodePage = CpAcp;               // The codepage for interpreting characters.44};45 46class ResourceFileWriter : public Visitor {47public:48  ResourceFileWriter(const WriterParams &Params,49                     std::unique_ptr<raw_fd_ostream> Stream)50      : Params(Params), FS(std::move(Stream)), IconCursorID(1) {51    assert(FS && "Output stream needs to be provided to the serializator");52  }53 54  Error visitNullResource(const RCResource *) override;55  Error visitAcceleratorsResource(const RCResource *) override;56  Error visitCursorResource(const RCResource *) override;57  Error visitDialogResource(const RCResource *) override;58  Error visitHTMLResource(const RCResource *) override;59  Error visitIconResource(const RCResource *) override;60  Error visitMenuResource(const RCResource *) override;61  Error visitMenuExResource(const RCResource *) override;62  Error visitVersionInfoResource(const RCResource *) override;63  Error visitStringTableResource(const RCResource *) override;64  Error visitUserDefinedResource(const RCResource *) override;65 66  Error visitCaptionStmt(const CaptionStmt *) override;67  Error visitCharacteristicsStmt(const CharacteristicsStmt *) override;68  Error visitClassStmt(const ClassStmt *) override;69  Error visitExStyleStmt(const ExStyleStmt *) override;70  Error visitFontStmt(const FontStmt *) override;71  Error visitLanguageStmt(const LanguageResource *) override;72  Error visitStyleStmt(const StyleStmt *) override;73  Error visitVersionStmt(const VersionStmt *) override;74  Error visitMenuStmt(const MenuStmt *) override;75 76  // Stringtables are output at the end of .res file. We need a separate77  // function to do it.78  Error dumpAllStringTables();79 80  bool AppendNull = false; // Append '\0' to each existing STRINGTABLE element?81 82  struct ObjectInfo {83    uint16_t LanguageInfo;84    uint32_t Characteristics;85    uint32_t VersionInfo;86 87    std::optional<uint32_t> Style;88    std::optional<uint32_t> ExStyle;89    StringRef Caption;90    struct FontInfo {91      uint32_t Size;92      StringRef Typeface;93      uint32_t Weight;94      bool IsItalic;95      uint32_t Charset;96    };97    std::optional<FontInfo> Font;98    IntOrString Class;99    IntOrString Menu;100 101    ObjectInfo()102        : LanguageInfo(0), Characteristics(0), VersionInfo(0),103          Class(StringRef()), Menu(StringRef()) {}104  } ObjectData;105 106  struct StringTableInfo {107    // Each STRINGTABLE bundle depends on ID of the bundle and language108    // description.109    using BundleKey = std::pair<uint16_t, uint16_t>;110    // Each bundle is in fact an array of 16 strings.111    struct Bundle {112      std::array<std::optional<std::vector<StringRef>>, 16> Data;113      ObjectInfo DeclTimeInfo;114      uint16_t MemoryFlags;115      Bundle(const ObjectInfo &Info, uint16_t Flags)116          : DeclTimeInfo(Info), MemoryFlags(Flags) {}117    };118    std::map<BundleKey, Bundle> BundleData;119    // Bundles are listed in the order of their first occurrence.120    std::vector<BundleKey> BundleList;121  } StringTableData;122 123private:124  Error handleError(Error Err, const RCResource *Res);125 126  Error127  writeResource(const RCResource *Res,128                Error (ResourceFileWriter::*BodyWriter)(const RCResource *));129 130  // NullResource131  Error writeNullBody(const RCResource *);132 133  // AcceleratorsResource134  Error writeSingleAccelerator(const AcceleratorsResource::Accelerator &,135                               bool IsLastItem);136  Error writeAcceleratorsBody(const RCResource *);137 138  // BitmapResource139  Error visitBitmapResource(const RCResource *) override;140  Error writeBitmapBody(const RCResource *);141 142  // CursorResource and IconResource143  Error visitIconOrCursorResource(const RCResource *);144  Error visitIconOrCursorGroup(const RCResource *);145  Error visitSingleIconOrCursor(const RCResource *);146  Error writeSingleIconOrCursorBody(const RCResource *);147  Error writeIconOrCursorGroupBody(const RCResource *);148 149  // DialogResource150  Error writeSingleDialogControl(const Control &, bool IsExtended);151  Error writeDialogBody(const RCResource *);152 153  // HTMLResource154  Error writeHTMLBody(const RCResource *);155 156  // MenuResource157  Error writeMenuDefinition(const std::unique_ptr<MenuDefinition> &,158                            uint16_t Flags);159  Error writeMenuExDefinition(const std::unique_ptr<MenuDefinition> &,160                              uint16_t Flags);161  Error writeMenuDefinitionList(const MenuDefinitionList &List);162  Error writeMenuExDefinitionList(const MenuDefinitionList &List);163  Error writeMenuBody(const RCResource *);164  Error writeMenuExBody(const RCResource *);165 166  // StringTableResource167  Error visitStringTableBundle(const RCResource *);168  Error writeStringTableBundleBody(const RCResource *);169  Error insertStringIntoBundle(StringTableInfo::Bundle &Bundle,170                               uint16_t StringID,171                               const std::vector<StringRef> &String);172 173  // User defined resource174  Error writeUserDefinedBody(const RCResource *);175 176  // VersionInfoResource177  Error writeVersionInfoBody(const RCResource *);178  Error writeVersionInfoBlock(const VersionInfoBlock &);179  Error writeVersionInfoValue(const VersionInfoValue &);180 181  const WriterParams &Params;182 183  // Output stream handling.184  std::unique_ptr<raw_fd_ostream> FS;185 186  uint64_t tell() const { return FS->tell(); }187 188  uint64_t writeObject(const ArrayRef<uint8_t> Data);189 190  template <typename T> uint64_t writeInt(const T &Value) {191    support::detail::packed_endian_specific_integral<192        T, llvm::endianness::little, support::unaligned>193        Object(Value);194    return writeObject(Object);195  }196 197  template <typename T> uint64_t writeObject(const T &Value) {198    return writeObject(ArrayRef<uint8_t>(199        reinterpret_cast<const uint8_t *>(&Value), sizeof(T)));200  }201 202  template <typename T> void writeObjectAt(const T &Value, uint64_t Position) {203    FS->pwrite((const char *)&Value, sizeof(T), Position);204  }205 206  Error writeCString(StringRef Str, bool WriteTerminator = true);207 208  Error writeIdentifier(const IntOrString &Ident);209  Error writeIntOrString(const IntOrString &Data);210 211  void writeRCInt(RCInt);212 213  Error appendFile(StringRef Filename);214 215  void padStream(uint64_t Length);216 217  Expected<std::unique_ptr<MemoryBuffer>> loadFile(StringRef File) const;218 219  // Icon and cursor IDs are allocated starting from 1 and increasing for220  // each icon/cursor dumped. This maintains the current ID to be allocated.221  uint16_t IconCursorID;222};223 224} // namespace rc225} // namespace llvm226 227#endif228