llvm.org GIT mirror llvm / 31dc80f
[llvm-rc] Implement the BITMAP resource type Differential Revision: https://reviews.llvm.org/D46509 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@331670 91177308-0d34-0410-b5e6-96231b3b80d8 Martin Storsjo 1 year, 6 months ago
8 changed file(s) with 76 addition(s) and 9 deletion(s). Raw diff Collapse all Expand all
2121 ; RUN: llvm-rc /FO %t.nested-include.res %p/Inputs/include.rc
2222 ; RUN: llvm-readobj %t.nested-include.res | FileCheck --check-prefix=FOUND %s
2323
24 FOUND: Resource type (string): BITMAP
24 FOUND: Resource type (int): 2
2525 FOUND-NEXT: Resource name (string): FOO
2626 FOUND-NEXT: Data version: 0
2727 FOUND-NEXT: Memory flags: 0x30
2929 FOUND-NEXT: Version (major): 0
3030 FOUND-NEXT: Version (minor): 0
3131 FOUND-NEXT: Characteristics: 0
32 FOUND-NEXT: Data size: 110
32 FOUND-NEXT: Data size: 96
3333 FOUND-NEXT: Data: (
34 FOUND-NEXT: 0000: 424D6E00 00000000 00003600 00002800 |BMn.......6...(.|
35 FOUND-NEXT: 0010: 00000200 00000700 00000100 18000000 |................|
36 FOUND-NEXT: 0020: 00003800 00000000 00000000 00000000 |..8.............|
37 FOUND-NEXT: 0030: 00000000 00005BB3 855BB385 0000FFFF |......[..[......|
38 FOUND-NEXT: 0040: FFFFFFFF 0000FFFF FFFFFFFF 0000FFFF |................|
39 FOUND-NEXT: 0050: FFFFFFFF 00005BB3 85FFFFFF 0000FFFF |......[.........|
40 FOUND-NEXT: 0060: FF0EC9FF 0000241C EDFFFFFF 0000 |......$.......|
34 FOUND-NEXT: 0000: 28000000 02000000 07000000 01001800 |(...............|
35 FOUND-NEXT: 0010: 00000000 38000000 00000000 00000000 |....8...........|
36 FOUND-NEXT: 0020: 00000000 00000000 5BB3855B B3850000 |........[..[....|
37 FOUND-NEXT: 0030: FFFFFFFF FFFF0000 FFFFFFFF FFFF0000 |................|
38 FOUND-NEXT: 0040: FFFFFFFF FFFF0000 5BB385FF FFFF0000 |........[.......|
39 FOUND-NEXT: 0050: FFFFFF0E C9FF0000 241CEDFF FFFF0000 |........$.......|
4140 FOUND-NEXT: )
4241
4342 MISSING: llvm-rc: Error in BITMAP statement (ID foo):
436436 return writeResource(Res, &ResourceFileWriter::writeAcceleratorsBody);
437437 }
438438
439 Error ResourceFileWriter::visitBitmapResource(const RCResource *Res) {
440 return writeResource(Res, &ResourceFileWriter::writeBitmapBody);
441 }
442
439443 Error ResourceFileWriter::visitCursorResource(const RCResource *Res) {
440444 return handleError(visitIconOrCursorResource(Res), Res);
441445 }
680684 RETURN_IF_ERROR(
681685 writeSingleAccelerator(Acc, AcceleratorId == Res->Accelerators.size()));
682686 }
687 return Error::success();
688 }
689
690 // --- BitmapResource helpers. --- //
691
692 Error ResourceFileWriter::writeBitmapBody(const RCResource *Base) {
693 StringRef Filename = cast(Base)->BitmapLoc;
694 bool IsLong;
695 stripQuotes(Filename, IsLong);
696
697 auto File = loadFile(Filename);
698 if (!File)
699 return File.takeError();
700
701 StringRef Buffer = (*File)->getBuffer();
702
703 // Skip the 14 byte BITMAPFILEHEADER.
704 constexpr size_t BITMAPFILEHEADER_size = 14;
705 if (Buffer.size() < BITMAPFILEHEADER_size || Buffer[0] != 'B' ||
706 Buffer[1] != 'M')
707 return createError("Incorrect bitmap file.");
708
709 *FS << Buffer.substr(BITMAPFILEHEADER_size);
683710 return Error::success();
684711 }
685712
121121 bool IsLastItem);
122122 Error writeAcceleratorsBody(const RCResource *);
123123
124 // BitmapResource
125 Error visitBitmapResource(const RCResource *);
126 Error writeBitmapBody(const RCResource *);
127
124128 // CursorResource and IconResource
125129 Error visitIconOrCursorResource(const RCResource *);
126130 Error visitIconOrCursorGroup(const RCResource *);
6565
6666 if (TypeToken->equalsLower("ACCELERATORS"))
6767 Result = parseAcceleratorsResource();
68 else if (TypeToken->equalsLower("BITMAP"))
69 Result = parseBitmapResource();
6870 else if (TypeToken->equalsLower("CURSOR"))
6971 Result = parseCursorResource();
7072 else if (TypeToken->equalsLower("DIALOG"))
483485 TakeOptArg(7));
484486 }
485487
488 RCParser::ParseType RCParser::parseBitmapResource() {
489 ASSIGN_OR_RETURN(Arg, readString());
490 return llvm::make_unique(*Arg);
491 }
492
486493 RCParser::ParseType RCParser::parseIconResource() {
487494 ASSIGN_OR_RETURN(Arg, readString());
488495 return llvm::make_unique(*Arg);
137137 // Top-level resource parsers.
138138 ParseType parseLanguageResource();
139139 ParseType parseAcceleratorsResource();
140 ParseType parseBitmapResource();
140141 ParseType parseCursorResource();
141142 ParseType parseDialogResource(bool IsExtended);
142143 ParseType parseIconResource();
5454 OS << "\n";
5555 }
5656 return OS;
57 }
58
59 raw_ostream &BitmapResource::log(raw_ostream &OS) const {
60 return OS << "Bitmap (" << ResName << "): " << BitmapLoc << "\n";
5761 }
5862
5963 raw_ostream &CursorResource::log(raw_ostream &OS) const {
120120 // kind is equal to this type ID.
121121 RkNull = 0,
122122 RkSingleCursor = 1,
123 RkBitmap = 2,
123124 RkSingleIcon = 3,
124125 RkMenu = 4,
125126 RkDialog = 5,
301302 ResourceKind getKind() const override { return RkAccelerators; }
302303 static bool classof(const RCResource *Res) {
303304 return Res->getKind() == RkAccelerators;
305 }
306 };
307
308 // BITMAP resource. Represents a bitmap (".bmp") file.
309 //
310 // Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa380680(v=vs.85).aspx
311 class BitmapResource : public RCResource {
312 public:
313 StringRef BitmapLoc;
314
315 BitmapResource(StringRef Location) : BitmapLoc(Location) {}
316 raw_ostream &log(raw_ostream &) const override;
317
318 IntOrString getResourceType() const override { return RkBitmap; }
319 uint16_t getMemoryFlags() const override { return MfPure | MfMoveable; }
320
321 Twine getResourceTypeName() const override { return "BITMAP"; }
322 Error visit(Visitor *V) const override {
323 return V->visitBitmapResource(this);
324 }
325 ResourceKind getKind() const override { return RkBitmap; }
326 static bool classof(const RCResource *Res) {
327 return Res->getKind() == RkBitmap;
304328 }
305329 };
306330
3131 public:
3232 virtual Error visitNullResource(const RCResource *) = 0;
3333 virtual Error visitAcceleratorsResource(const RCResource *) = 0;
34 virtual Error visitBitmapResource(const RCResource *) = 0;
3435 virtual Error visitCursorResource(const RCResource *) = 0;
3536 virtual Error visitDialogResource(const RCResource *) = 0;
3637 virtual Error visitHTMLResource(const RCResource *) = 0;