FreeNOS
Decompress.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2020 Niek Linnenbank
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include <BufferedFile.h>
19#include <Lz4Decompressor.h>
20#include "Decompress.h"
21
22Decompress::Decompress(int argc, char **argv)
23 : POSIXApplication(argc, argv)
24{
25 parser().setDescription("Decompress a compressed file");
26 parser().registerPositional("FILE", "file(s) to decompress", 0);
27}
28
32
34{
35 Result result = Success, ret = Success;
36 const Vector<Argument *> & positionals = arguments().getPositionals();
37
38 // Decompress all given files. */
39 for (Size i = 0; i < positionals.count(); i++)
40 {
41 // Decompress the file. */
42 result = decompressFile(*(positionals[i]->getValue()));
43
44 // Update exit code if needed
45 if (result != Success)
46 {
47 ret = result;
48 }
49 }
50 // Done
51 return ret;
52}
53
55{
56 const char *lz4Extension = ".lz4";
57
58 DEBUG("file = " << *inputFilename);
59
60 // File must have the LZ4 extension
61 if (!inputFilename.endsWith(lz4Extension))
62 {
63 ERROR("input file name does not end with " << lz4Extension);
64 return InvalidArgument;
65 }
66
67 // Determine output name (without extension)
68 const String outputFilename =
69 inputFilename.substring(0, inputFilename.length() - String::length(lz4Extension));
70
71 // Create buffered files
72 BufferedFile input(*inputFilename);
73 BufferedFile output(*outputFilename);
74
75 // Read the input file
76 if (input.read() != BufferedFile::Success)
77 {
78 ERROR("failed to read input file " << input.path());
79 return IOError;
80 }
81
82 // Initialize decompressor
83 Lz4Decompressor lz4(input.buffer(), input.size());
84 const Lz4Decompressor::Result result = lz4.initialize();
85 if (result != Lz4Decompressor::Success)
86 {
87 ERROR("failed to initialize LZ4 decompressor: result = " << (int) result);
88 return IOError;
89 }
90
91 // Allocate temporary buffer
92 const Size originalSize = lz4.getUncompressedSize();
93 u8 *uncompressed = new u8[originalSize];
94
95 // Decompress entire file
96 const Lz4Decompressor::Result readResult = lz4.read(uncompressed, originalSize);
97 if (readResult != Lz4Decompressor::Success)
98 {
99 ERROR("failed to decompress file " << *inputFilename << ": result = " << (int) readResult);
100 delete[] uncompressed;
101 return IOError;
102 }
103
104 // Write to output file
105 const BufferedFile::Result writeResult = output.write(uncompressed, originalSize);
106 if (writeResult != BufferedFile::Success)
107 {
108 ERROR("failed to write output file " << *outputFilename << ": result = " << (int) writeResult);
109 delete[] uncompressed;
110 return IOError;
111 }
112
113 // Cleanup resources
114 delete[] uncompressed;
115 return Success;
116}
Result
Result codes.
Definition Application.h:54
const ArgumentContainer & arguments() const
Get program arguments.
ArgumentParser & parser()
Get program arguments parser.
const Vector< Argument * > & getPositionals() const
Get positional arguments.
void setDescription(const String &desc)
Set program description.
Result registerPositional(const char *name, const char *description, Size count=1)
Register a positional argument.
Provides a buffered abstract interface to a file.
const Size size() const
Get file size.
Result
Result codes.
Result read()
Read the file (buffered)
const char * path() const
Get file path.
const void * buffer() const
Get file buffer.
Result decompressFile(const String inputFilename) const
Decompress the given file.
virtual Result exec()
Execute the application.
virtual ~Decompress()
Destructor.
Decompress(int argc, char **argv)
Constructor.
Decompress data using the LZ4 algorithm created by Yann Collet.
Result initialize()
Initialize the decompressor.
u64 getUncompressedSize() const
Get size of the uncompressed data.
Result
Result codes.
Result read(void *buffer, const Size size) const
Reads compressed data.
POSIX-compatible application.
virtual Result output(const char *string) const
Print text to output.
Abstraction of strings.
Definition String.h:42
String substring(const Size index, const Size size=0) const
Returns a part of the String as a copy.
Definition String.cpp:314
Size length() const
Same as count().
Definition String.cpp:105
bool endsWith(const String &suffix) const
Tests if this String ends with the specified suffix.
Definition String.cpp:210
Vectors are dynamically resizeable Arrays.
Definition Vector.h:42
virtual Size count() const
Returns the number of items inside the Vector.
Definition Vector.h:204
#define ERROR(msg)
Output an error message.
Definition Log.h:61
unsigned int Size
Any sane size indicator cannot go negative.
Definition Types.h:128
#define DEBUG(msg)
Output a debug message to standard output.
Definition Log.h:89
unsigned char u8
Unsigned 8-bit number.
Definition Types.h:59