blob: 0d248c0349e69b9a9a4fb191c3d4ba29858b3b7b [file] [log] [blame]
Marek Sokolowski8f193432017-09-29 17:14:09 +00001//===-- ResourceSerializator.h ----------------------------------*- C++-*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===---------------------------------------------------------------------===//
9//
10// This defines a visitor serializing resources to a .res stream.
11//
12//===---------------------------------------------------------------------===//
13
14#ifndef LLVM_TOOLS_LLVMRC_RESOURCESERIALIZATOR_H
15#define LLVM_TOOLS_LLVMRC_RESOURCESERIALIZATOR_H
16
17#include "ResourceScriptStmt.h"
18#include "ResourceVisitor.h"
19
20#include "llvm/Support/Endian.h"
21
22namespace llvm {
23namespace rc {
24
25class ResourceFileWriter : public Visitor {
26public:
27 ResourceFileWriter(std::unique_ptr<raw_fd_ostream> Stream)
Zachary Turnerc3ab0132017-10-06 21:25:44 +000028 : FS(std::move(Stream)), IconCursorID(1) {
Marek Sokolowski8f193432017-09-29 17:14:09 +000029 assert(FS && "Output stream needs to be provided to the serializator");
30 }
31
32 Error visitNullResource(const RCResource *) override;
Marek Sokolowski22fccd62017-09-29 19:07:44 +000033 Error visitAcceleratorsResource(const RCResource *) override;
Zachary Turnerc3ab0132017-10-06 21:25:44 +000034 Error visitCursorResource(const RCResource *) override;
Marek Sokolowski7f7745c2017-09-30 00:38:52 +000035 Error visitDialogResource(const RCResource *) override;
Marek Sokolowski8f193432017-09-29 17:14:09 +000036 Error visitHTMLResource(const RCResource *) override;
Zachary Turnerc3ab0132017-10-06 21:25:44 +000037 Error visitIconResource(const RCResource *) override;
Marek Sokolowski42f494d2017-09-29 22:25:05 +000038 Error visitMenuResource(const RCResource *) override;
Zachary Turner07bc04f2017-10-06 21:26:06 +000039 Error visitVersionInfoResource(const RCResource *) override;
Marek Sokolowski8f193432017-09-29 17:14:09 +000040
Zachary Turner420090a2017-10-06 20:51:20 +000041 Error visitCaptionStmt(const CaptionStmt *) override;
Marek Sokolowski22fccd62017-09-29 19:07:44 +000042 Error visitCharacteristicsStmt(const CharacteristicsStmt *) override;
Zachary Turner420090a2017-10-06 20:51:20 +000043 Error visitFontStmt(const FontStmt *) override;
Marek Sokolowski8f193432017-09-29 17:14:09 +000044 Error visitLanguageStmt(const LanguageResource *) override;
Zachary Turner420090a2017-10-06 20:51:20 +000045 Error visitStyleStmt(const StyleStmt *) override;
Marek Sokolowski22fccd62017-09-29 19:07:44 +000046 Error visitVersionStmt(const VersionStmt *) override;
Marek Sokolowski8f193432017-09-29 17:14:09 +000047
48 struct ObjectInfo {
49 uint16_t LanguageInfo;
Marek Sokolowski22fccd62017-09-29 19:07:44 +000050 uint32_t Characteristics;
51 uint32_t VersionInfo;
Marek Sokolowski8f193432017-09-29 17:14:09 +000052
Zachary Turner420090a2017-10-06 20:51:20 +000053 Optional<uint32_t> Style;
54 StringRef Caption;
55 struct FontInfo {
56 uint32_t Size;
57 StringRef Typeface;
58 uint32_t Weight;
59 bool IsItalic;
60 uint32_t Charset;
61 };
62 Optional<FontInfo> Font;
63
Marek Sokolowski22fccd62017-09-29 19:07:44 +000064 ObjectInfo() : LanguageInfo(0), Characteristics(0), VersionInfo(0) {}
Marek Sokolowski8f193432017-09-29 17:14:09 +000065 } ObjectData;
66
67private:
68 Error handleError(Error &&Err, const RCResource *Res);
69
70 Error
71 writeResource(const RCResource *Res,
72 Error (ResourceFileWriter::*BodyWriter)(const RCResource *));
73
Marek Sokolowski22fccd62017-09-29 19:07:44 +000074 // NullResource
Marek Sokolowski8f193432017-09-29 17:14:09 +000075 Error writeNullBody(const RCResource *);
Marek Sokolowski22fccd62017-09-29 19:07:44 +000076
77 // AcceleratorsResource
78 Error writeSingleAccelerator(const AcceleratorsResource::Accelerator &,
79 bool IsLastItem);
80 Error writeAcceleratorsBody(const RCResource *);
81
Zachary Turnerc3ab0132017-10-06 21:25:44 +000082 // CursorResource and IconResource
83 Error visitIconOrCursorResource(const RCResource *);
84 Error visitIconOrCursorGroup(const RCResource *);
85 Error visitSingleIconOrCursor(const RCResource *);
86 Error writeSingleIconOrCursorBody(const RCResource *);
87 Error writeIconOrCursorGroupBody(const RCResource *);
88
Marek Sokolowski7f7745c2017-09-30 00:38:52 +000089 // DialogResource
90 Error writeSingleDialogControl(const Control &, bool IsExtended);
91 Error writeDialogBody(const RCResource *);
92
Marek Sokolowski22fccd62017-09-29 19:07:44 +000093 // HTMLResource
Marek Sokolowski8f193432017-09-29 17:14:09 +000094 Error writeHTMLBody(const RCResource *);
95
Marek Sokolowski42f494d2017-09-29 22:25:05 +000096 // MenuResource
97 Error writeMenuDefinition(const std::unique_ptr<MenuDefinition> &,
98 uint16_t Flags);
99 Error writeMenuDefinitionList(const MenuDefinitionList &List);
100 Error writeMenuBody(const RCResource *);
101
Zachary Turner07bc04f2017-10-06 21:26:06 +0000102 // VersionInfoResource
103 Error writeVersionInfoBody(const RCResource *);
104 Error writeVersionInfoBlock(const VersionInfoBlock &);
105 Error writeVersionInfoValue(const VersionInfoValue &);
106
Marek Sokolowski8f193432017-09-29 17:14:09 +0000107 // Output stream handling.
108 std::unique_ptr<raw_fd_ostream> FS;
109
110 uint64_t tell() const { return FS->tell(); }
111
112 uint64_t writeObject(const ArrayRef<uint8_t> Data);
113
114 template <typename T> uint64_t writeInt(const T &Value) {
115 support::detail::packed_endian_specific_integral<T, support::little,
116 support::unaligned>
117 Object(Value);
118 return writeObject(Object);
119 }
120
121 template <typename T> uint64_t writeObject(const T &Value) {
122 return writeObject(ArrayRef<uint8_t>(
123 reinterpret_cast<const uint8_t *>(&Value), sizeof(T)));
124 }
125
126 template <typename T> void writeObjectAt(const T &Value, uint64_t Position) {
127 FS->pwrite((const char *)&Value, sizeof(T), Position);
128 }
129
130 Error writeCString(StringRef Str, bool WriteTerminator = true);
131
132 Error writeIdentifier(const IntOrString &Ident);
133 Error writeIntOrString(const IntOrString &Data);
134
Zachary Turner07bc04f2017-10-06 21:26:06 +0000135 void writeRCInt(RCInt);
136
Marek Sokolowski8f193432017-09-29 17:14:09 +0000137 Error appendFile(StringRef Filename);
138
139 void padStream(uint64_t Length);
Zachary Turnerc3ab0132017-10-06 21:25:44 +0000140
141 // Icon and cursor IDs are allocated starting from 1 and increasing for
142 // each icon/cursor dumped. This maintains the current ID to be allocated.
143 uint16_t IconCursorID;
Marek Sokolowski8f193432017-09-29 17:14:09 +0000144};
145
146} // namespace rc
147} // namespace llvm
148
149#endif