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 
22 Decompress::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 
30 {
31 }
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 }
POSIXApplication::output
virtual Result output(const char *string) const
Print text to output.
Definition: POSIXApplication.cpp:33
BufferedFile
Provides a buffered abstract interface to a file.
Definition: BufferedFile.h:34
String::length
Size length() const
Same as count().
Definition: String.cpp:105
Decompress::Decompress
Decompress(int argc, char **argv)
Constructor.
Definition: Decompress.cpp:22
String
Abstraction of strings.
Definition: String.h:41
Lz4Decompressor::getUncompressedSize
u64 getUncompressedSize() const
Get size of the uncompressed data.
Definition: Lz4Decompressor.cpp:125
Decompress::decompressFile
Result decompressFile(const String inputFilename) const
Decompress the given file.
Definition: Decompress.cpp:54
Decompress::~Decompress
virtual ~Decompress()
Destructor.
Definition: Decompress.cpp:29
Lz4Decompressor::initialize
Result initialize()
Initialize the decompressor.
Definition: Lz4Decompressor.cpp:35
BufferedFile::Result
Result
Result codes.
Definition: BufferedFile.h:41
POSIXApplication
POSIX-compatible application.
Definition: POSIXApplication.h:35
Decompress::exec
virtual Result exec()
Execute the application.
Definition: Decompress.cpp:33
Application::Success
@ Success
Definition: Application.h:55
Application::arguments
const ArgumentContainer & arguments() const
Get program arguments.
Definition: Application.cpp:112
ArgumentParser::setDescription
void setDescription(const String &desc)
Set program description.
Definition: ArgumentParser.cpp:95
Lz4Decompressor::Success
@ Success
Definition: Lz4Decompressor.h:72
BufferedFile::buffer
const void * buffer() const
Get file buffer.
Definition: BufferedFile.cpp:48
Application::IOError
@ IOError
Definition: Application.h:57
Lz4Decompressor.h
BufferedFile::read
Result read()
Read the file (buffered)
Definition: BufferedFile.cpp:58
DEBUG
#define DEBUG(msg)
Output a debug message to standard output.
Definition: Log.h:89
Application::InvalidArgument
@ InvalidArgument
Definition: Application.h:58
Decompress.h
Vector::count
virtual Size count() const
Returns the number of items inside the Vector.
Definition: Vector.h:204
Size
unsigned int Size
Any sane size indicator cannot go negative.
Definition: Types.h:128
BufferedFile.h
Application::Result
Result
Result codes.
Definition: Application.h:53
Lz4Decompressor::Result
Result
Result codes.
Definition: Lz4Decompressor.h:70
String::substring
String substring(const Size index, const Size size=0) const
Returns a part of the String as a copy.
Definition: String.cpp:314
ArgumentParser::registerPositional
Result registerPositional(const char *name, const char *description, Size count=1)
Register a positional argument.
Definition: ArgumentParser.cpp:119
Application::parser
ArgumentParser & parser()
Get program arguments parser.
Definition: Application.cpp:102
BufferedFile::size
const Size size() const
Get file size.
Definition: BufferedFile.cpp:53
Lz4Decompressor::read
Result read(void *buffer, const Size size) const
Reads compressed data.
Definition: Lz4Decompressor.cpp:130
ERROR
#define ERROR(msg)
Output an error message.
Definition: Log.h:61
u8
unsigned char u8
Unsigned 8-bit number.
Definition: Types.h:59
BufferedFile::Success
@ Success
Definition: BufferedFile.h:43
Lz4Decompressor
Decompress data using the LZ4 algorithm created by Yann Collet.
Definition: Lz4Decompressor.h:39
String::endsWith
bool endsWith(const String &suffix) const
Tests if this String ends with the specified suffix.
Definition: String.cpp:210
Vector< Argument * >
ArgumentContainer::getPositionals
const Vector< Argument * > & getPositionals() const
Get positional arguments.
Definition: ArgumentContainer.cpp:39
BufferedFile::path
const char * path() const
Get file path.
Definition: BufferedFile.cpp:43