Base Framework
testsuite/digest.cpp
/***************************************************************************
The Base Framework
A framework for developing platform independent applications
See COPYRIGHT.txt for details.
This framework is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
For the licensing terms refer to the file 'LICENSE'.
***************************************************************************/
#include <base/io/FileInputStream.h>
#include <base/io/FileReader.h>
#include <base/filesystem/FileSystem.h>
#include <base/filesystem/FolderInfo.h>
#include <base/string/FormatOutputStream.h>
#include <base/Application.h>
#include <base/security/Adler32.h>
#include <base/security/CRC32.h>
#include <base/security/MD5Sum.h>
#include <base/security/SHA1.h>
#include <base/security/SHA256.h>
#include <base/security/SHA384.h>
#include <base/security/SHA512.h>
using namespace com::azure::dev::base;
class DigestApplication : public Application {
private:
static const unsigned int MAJOR_VERSION = 1;
static const unsigned int MINOR_VERSION = 0;
static const unsigned int BLOCK_SIZE = 4096 * 4;
uint8 buffer[BLOCK_SIZE];
unsigned int job = 0;
public:
class Job {
public:
enum {
ADLER32,
MD5SUM,
};
};
DigestApplication()
: Application("digest")
{
job = Job::SHA1;
}
void jobAdler32(const String& path) {
FileInputStream file(path, 0);
Adler32 sum;
unsigned int count = 0;
while ((count = file.read(buffer, sizeof(buffer), true)) > 0) {
sum.push(buffer, count);
}
sum.pushEnd();
fout << HEX << setWidth(8) << NOPREFIX << ZEROPAD << sum.getValue()
<< indent(2) << path << ENDL;
}
void jobCRC32(const String& path) {
FileInputStream file(path, 0);
CRC32 sum;
unsigned int count = 0;
while ((count = file.read(buffer, sizeof(buffer), true)) > 0) {
sum.push(buffer, count);
}
sum.pushEnd();
fout << HEX << setWidth(8) << NOPREFIX << ZEROPAD << sum.getValue()
<< indent(2) << path << ENDL;
}
void jobMD5Sum(const String& path) {
FileInputStream file(path, 0);
MD5Sum sum;
unsigned int count = 0;
while ((count = file.read(buffer, sizeof(buffer), true)) > 0) {
sum.push(buffer, count);
}
sum.pushEnd();
fout << sum.getValue() << indent(2) << path << ENDL;
}
void jobSHA1(const String& path) {
FileInputStream file(path, 0);
SHA1 sum;
unsigned int count = 0;
while ((count = file.read(buffer, sizeof(buffer), true)) > 0) {
sum.push(buffer, count);
}
sum.pushEnd();
fout << sum.getValue() << indent(2) << path << ENDL;
}
void jobSHA256(const String& path) {
FileInputStream file(path, 0);
SHA256 sum;
unsigned int count = 0;
while ((count = file.read(buffer, sizeof(buffer), true)) > 0) {
sum.push(buffer, count);
}
sum.pushEnd();
fout << sum.getValue() << indent(2) << path << ENDL;
}
void jobSHA384(const String& path) {
FileInputStream file(path, 0);
SHA384 sum;
unsigned int count = 0;
while ((count = file.read(buffer, sizeof(buffer), true)) > 0) {
sum.push(buffer, count);
}
sum.pushEnd();
fout << sum.getValue() << indent(2) << path << ENDL;
}
void jobSHA512(const String& path) {
FileInputStream file(path, 0);
SHA512 sum;
unsigned int count = 0;
while ((count = file.read(buffer, sizeof(buffer), true)) > 0) {
sum.push(buffer, count);
}
sum.pushEnd();
fout << sum.getValue() << indent(2) << path << ENDL;
}
void fileDigest(const String& path) {
switch (job) {
case Job::ADLER32:
jobAdler32(path);
break;
case Job::CRC32:
jobCRC32(path);
break;
case Job::MD5SUM:
jobMD5Sum(path);
break;
case Job::SHA1:
jobSHA1(path);
break;
case Job::SHA256:
jobSHA256(path);
break;
case Job::SHA384:
jobSHA384(path);
break;
case Job::SHA512:
jobSHA512(path);
break;
}
}
void digest(const String& path)
{
unsigned int type = 0;
try {
type = FileSystem::getType(path);
} catch (FileSystemException&) {
ferr << "Error: " << "File or folder does not exist" << ENDL;
setExitCode(EXIT_CODE_ERROR);
return;
}
if (type & FileSystem::REGULAR) {
fileDigest(path);
} else if (type & FileSystem::FOLDER) {
FolderInfo folder(path);
Array<String> entries = folder.getEntries();
while (enu.hasNext()) {
const String entry = enu.next();
try {
unsigned int type = FileSystem::getType(entry);
if (type & FileSystem::REGULAR) {
fileDigest(entry);
} else if (type & FileSystem::FOLDER) {
// ignore or recursive
}
} catch (Exception&) {
}
}
} else {
ferr << "Error: " << "Invalid filesystem entry" << ENDL;
setExitCode(EXIT_CODE_ERROR);
}
}
void usage()
{
fout << "Usage: " << getFormalName()
<< " [ADLER32|CRC32|MD5SUM|SHA1|SHA256|SHA384|SHA512] file" << ENDL;
}
void main()
{
fout << getFormalName() << " version "
<< MAJOR_VERSION << '.' << MINOR_VERSION << EOL
<< "The Base Framework (Test Suite)" << EOL
<< ENDL;
Array<String> arguments = getArguments();
String jobString;
String path;
switch (arguments.getSize()) {
case 2:
jobString = arguments[0]; // job
if (jobString == "ADLER32") {
job = Job::ADLER32;
} else if (jobString == "CRC32") {
job = Job::CRC32;
} else if (jobString == "MD5SUM") {
job = Job::MD5SUM;
} else if (jobString == "SHA1") {
job = Job::SHA1;
} else if (jobString == "SHA256") {
job = Job::SHA256;
} else if (jobString == "SHA384") {
job = Job::SHA384;
} else if (jobString == "SHA512") {
job = Job::SHA512;
} else {
usage();
setExitCode(EXIT_CODE_ERROR);
return;
}
path = arguments[1]; // file path
break;
default:
usage();
}
try {
digest(path);
} catch (Exception&) {
}
}
};
APPLICATION_STUB(DigestApplication);
MD5Sum::push
MemorySize push(const uint8 *buffer, MemorySize size)
SHA384::pushEnd
void pushEnd() noexcept
Adler32::getValue
uint32 getValue() const noexcept
Definition: Adler32.h:81
SHA256::push
MemorySize push(const uint8 *buffer, MemorySize size)
PushInterface::pushEnd
virtual void pushEnd()
FileSystem::REGULAR
@ REGULAR
Definition: FileSystem.h:76
SHA1::getValue
String getValue() const noexcept
SHA1
SHA-1 message-digest.
Definition: SHA1.h:48
SHA256::pushEnd
void pushEnd() noexcept
CRC32::pushEnd
void pushEnd() noexcept
Definition: CRC32.h:74
FileInputStream::read
unsigned int read(uint8 *buffer, unsigned int size, bool nonblocking=false)
Definition: FileInputStream.h:76
SHA512
SHA-512 message-digest.
Definition: SHA512.h:49
SHA1::push
MemorySize push(const uint8 *buffer, MemorySize size)
CRC32
CRC-32.
Definition: CRC32.h:34
Exception
The general exception class.
Definition: Exception.h:40
MD5Sum::pushEnd
void pushEnd()
SHA512::getValue
String getValue() const noexcept
FolderInfo
Folder information.
Definition: FolderInfo.h:33
CRC32::push
MemorySize push(const uint8 *buffer, MemorySize size) noexcept
String
String.
Definition: String.h:102
Adler32::push
MemorySize push(const uint8 *buffer, MemorySize size) noexcept
Array::getSize
MemorySize getSize() const noexcept
Definition: Array.h:339
SHA256::getValue
String getValue() const noexcept
SHA384::getValue
String getValue() const noexcept
SHA384::push
MemorySize push(const uint8 *buffer, MemorySize size)
MD5Sum
MD5 message-digest.
Definition: MD5Sum.h:44
Application
Application.
Definition: Application.h:53
FileSystemException
File system exception.
Definition: FileSystemException.h:28
FileInputStream
File input stream.
Definition: FileInputStream.h:30
SHA512::push
MemorySize push(const uint8 *buffer, MemorySize size)
FileSystem::getType
static unsigned int getType(const String &path)
FileSystem::FOLDER
@ FOLDER
Definition: FileSystem.h:73
SHA1::pushEnd
void pushEnd() noexcept
Adler32
Adler-32.
Definition: Adler32.h:33
SHA384
SHA-384 message-digest.
Definition: SHA384.h:48
Array::getReadEnumerator
ReadEnumerator getReadEnumerator() const noexcept
Definition: Array.h:489
Array< String >
Application::EXIT_CODE_ERROR
@ EXIT_CODE_ERROR
Definition: Application.h:77
MD5Sum::getValue
String getValue() const noexcept
CRC32::getValue
uint32 getValue() const noexcept
Definition: CRC32.h:89
SHA512::pushEnd
void pushEnd() noexcept
SHA256
SHA-256 message-digest.
Definition: SHA256.h:49
FileSystem::setCurrentFolder
static void setCurrentFolder(const String &path)
FolderInfo::getEntries
Array< String > getEntries() const