Merge pull request #84 from markondej/exception_handling

Exception handling
pull/85/head
Marcin Kondej 2019-09-26 11:24:10 +02:00 zatwierdzone przez GitHub
commit 13ee37062c
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
5 zmienionych plików z 33 dodań i 142 usunięć

Wyświetl plik

@ -1,53 +0,0 @@
/*
fm_transmitter - use Raspberry Pi as FM transmitter
Copyright (c) 2019, Marcin Kondej
All rights reserved.
See https://github.com/markondej/fm_transmitter
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be
used to endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "error_reporter.hpp"
ErrorReporter::ErrorReporter() :
errorMessage(std::string())
{
}
ErrorReporter::ErrorReporter(std::string message) :
errorMessage(message)
{
}
ErrorReporter::~ErrorReporter() throw()
{
}
const char *ErrorReporter::what() const throw()
{
return errorMessage.c_str();
}

Wyświetl plik

@ -1,52 +0,0 @@
/*
fm_transmitter - use Raspberry Pi as FM transmitter
Copyright (c) 2019, Marcin Kondej
All rights reserved.
See https://github.com/markondej/fm_transmitter
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be
used to endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ERROR_REPORTER_HPP
#define ERROR_REPORTER_HPP
#include <exception>
#include <string>
class ErrorReporter : public std::exception
{
public:
ErrorReporter();
ErrorReporter(std::string message);
virtual ~ErrorReporter() throw();
virtual const char *what() const throw();
protected:
std::string errorMessage;
};
#endif // ERROR_REPORTER_HPP

Wyświetl plik

@ -2,14 +2,11 @@ EXECUTABLE = fm_transmitter
VERSION = 0.9.3
FLAGS = -Wall -O3 -std=c++11
all: main.o mailbox.o error_reporter.o sample.o wave_reader.o transmitter.o
g++ -L/opt/vc/lib -lm -lpthread -lbcm_host -o $(EXECUTABLE) main.o mailbox.o sample.o error_reporter.o wave_reader.o transmitter.o
all: main.o mailbox.o sample.o wave_reader.o transmitter.o
g++ -L/opt/vc/lib -lm -lpthread -lbcm_host -o $(EXECUTABLE) main.o mailbox.o sample.o wave_reader.o transmitter.o
mailbox.o: mailbox.c mailbox.h
g++ $(FLAGS) -c mailbox.c
error_reporter.o: error_reporter.cpp error_reporter.hpp
g++ $(FLAGS) -c error_reporter.cpp
sample.o: sample.cpp sample.hpp
g++ $(FLAGS) -c sample.cpp

Wyświetl plik

@ -32,7 +32,6 @@
*/
#include "transmitter.hpp"
#include "error_reporter.hpp"
#include "mailbox.h"
#include <bcm_host.h>
#include <thread>
@ -131,13 +130,13 @@ Transmitter::Transmitter()
{
int memFd;
if ((memFd = open("/dev/mem", O_RDWR | O_SYNC)) < 0) {
throw ErrorReporter("Cannot open /dev/mem (permission denied)");
throw std::runtime_error("Cannot open /dev/mem (permission denied)");
}
peripherals = mmap(nullptr, getPeripheralsSize(), PROT_READ | PROT_WRITE, MAP_SHARED, memFd, getPeripheralsVirtBaseAddress());
close(memFd);
if (peripherals == MAP_FAILED) {
throw ErrorReporter("Cannot obtain access to peripherals (mmap error)");
throw std::runtime_error("Cannot obtain access to peripherals (mmap error)");
}
}
@ -274,7 +273,7 @@ void Transmitter::closeClockOutput(volatile ClockRegisters *clock)
void Transmitter::transmit(WaveReader &reader, double frequency, double bandwidth, uint8_t dmaChannel, bool preserveCarrierOnExit)
{
if (transmitting) {
throw ErrorReporter("Cannot play, transmitter already in use");
throw std::runtime_error("Cannot play, transmitter already in use");
}
transmitting = true;
@ -298,7 +297,7 @@ void Transmitter::transmit(WaveReader &reader, double frequency, double bandwidt
} else {
transmitViaCpu(reader, bufferSize);
}
} catch (ErrorReporter &catched) {
} catch (std::runtime_error &catched) {
closeClockOutput(output);
throw catched;
}
@ -318,9 +317,9 @@ void Transmitter::transmitViaCpu(WaveReader &reader, uint32_t bufferSize)
sampleOffset = 0;
buffer = samples;
bool eof = samples->size() < bufferSize, exceptionCatched = false;
bool eof = samples->size() < bufferSize, errorCatched = false;
std::thread txThread(Transmitter::transmitThread);
ErrorReporter exception;
std::string errorMessage;
usleep(BUFFER_TIME / 2);
@ -339,24 +338,24 @@ void Transmitter::transmitViaCpu(WaveReader &reader, uint32_t bufferSize)
}
usleep(BUFFER_TIME / 2);
}
} catch (ErrorReporter &catched) {
exceptionCatched = true;
exception = catched;
} catch (std::runtime_error &catched) {
errorMessage = std::string(catched.what());
errorCatched = true;
}
transmitting = false;
txThread.join();
if (buffer != nullptr) {
delete buffer;
}
if (exceptionCatched) {
throw exception;
if (errorCatched) {
throw std::runtime_error(errorMessage);
}
}
void Transmitter::transmitViaDma(WaveReader &reader, uint32_t bufferSize, uint8_t dmaChannel)
{
if (dmaChannel > 15) {
throw ErrorReporter("DMA channel number out of range (0 - 15)");
throw std::runtime_error("DMA channel number out of range (0 - 15)");
}
std::vector<Sample> *samples = reader.getSamples(bufferSize, transmitting);
@ -372,7 +371,7 @@ void Transmitter::transmitViaDma(WaveReader &reader, uint32_t bufferSize, uint8_
AllocatedMemory dmaMemory = allocateMemory(sizeof(uint32_t) * (bufferSize + 1) + sizeof(DMAControllBlock) * (2 * bufferSize));
if (!dmaMemory.size) {
delete samples;
throw ErrorReporter("Cannot allocate memory");
throw std::runtime_error("Cannot allocate memory");
}
volatile PWMRegisters *pwm = initPwmController();
@ -412,8 +411,8 @@ void Transmitter::transmitViaDma(WaveReader &reader, uint32_t bufferSize, uint8_
delete samples;
volatile DMARegisters *dma = startDma(dmaMemory, dmaCb, dmaChannel);
bool exceptionCatched = false;
ErrorReporter exception;
bool errorCatched = false;
std::string errorMessage;
usleep(BUFFER_TIME / 4);
try {
@ -437,9 +436,9 @@ void Transmitter::transmitViaDma(WaveReader &reader, uint32_t bufferSize, uint8_
}
delete samples;
}
} catch (ErrorReporter &catched) {
exceptionCatched = true;
exception = catched;
} catch (std::runtime_error &catched) {
errorMessage = std::string(catched.what());
errorCatched = true;
}
cbOffset = (cbOffset < 2 * bufferSize) ? cbOffset : 0;
@ -454,8 +453,8 @@ void Transmitter::transmitViaDma(WaveReader &reader, uint32_t bufferSize, uint8_
freeMemory(dmaMemory);
transmitting = false;
if (exceptionCatched) {
throw exception;
if (errorCatched) {
throw std::runtime_error(errorMessage);
}
}

Wyświetl plik

@ -32,7 +32,7 @@
*/
#include "wave_reader.hpp"
#include "error_reporter.hpp"
#include <stdexcept>
#include <cstring>
#include <unistd.h>
#include <fcntl.h>
@ -48,13 +48,13 @@ WaveReader::WaveReader(std::string filename, bool &continueFlag) :
}
if (fileDescriptor == -1) {
throw ErrorReporter(std::string("Cannot open ") + getFilename() + std::string(", file does not exist"));
throw std::runtime_error(std::string("Cannot open ") + getFilename() + std::string(", file does not exist"));
}
try {
readData(sizeof(PCMWaveHeader::chunkID) + sizeof(PCMWaveHeader::chunkSize) + sizeof(PCMWaveHeader::format), true, continueFlag);
if ((std::string(reinterpret_cast<char *>(header.chunkID), 4) != std::string("RIFF")) || (std::string(reinterpret_cast<char *>(header.format), 4) != std::string("WAVE"))) {
throw ErrorReporter(std::string("Error while opening ") + getFilename() + std::string(", WAVE file expected"));
throw std::runtime_error(std::string("Error while opening ") + getFilename() + std::string(", WAVE file expected"));
}
readData(sizeof(PCMWaveHeader::subchunk1ID) + sizeof(PCMWaveHeader::subchunk1Size), true, continueFlag);
@ -62,7 +62,7 @@ WaveReader::WaveReader(std::string filename, bool &continueFlag) :
sizeof(PCMWaveHeader::sampleRate) + sizeof(PCMWaveHeader::byteRate) + sizeof(PCMWaveHeader::blockAlign) +
sizeof(PCMWaveHeader::bitsPerSample);
if ((std::string(reinterpret_cast<char *>(header.subchunk1ID), 4) != std::string("fmt ")) || (header.subchunk1Size < subchunk1MinSize)) {
throw ErrorReporter(std::string("Error while opening ") + getFilename() + std::string(", data corrupted"));
throw std::runtime_error(std::string("Error while opening ") + getFilename() + std::string(", data corrupted"));
}
readData(header.subchunk1Size, true, continueFlag);
@ -70,14 +70,14 @@ WaveReader::WaveReader(std::string filename, bool &continueFlag) :
(header.byteRate != (header.bitsPerSample >> 3) * header.channels * header.sampleRate) ||
(header.blockAlign != (header.bitsPerSample >> 3) * header.channels) ||
(((header.bitsPerSample >> 3) != 1) && ((header.bitsPerSample >> 3) != 2))) {
throw ErrorReporter(std::string("Error while opening ") + getFilename() + std::string(", unsupported WAVE format"));
throw std::runtime_error(std::string("Error while opening ") + getFilename() + std::string(", unsupported WAVE format"));
}
readData(sizeof(PCMWaveHeader::subchunk2ID) + sizeof(PCMWaveHeader::subchunk2Size), true, continueFlag);
if (std::string(reinterpret_cast<char *>(header.subchunk2ID), 4) != std::string("data")) {
throw ErrorReporter(std::string("Error while opening ") + getFilename() + std::string(", data corrupted"));
throw std::runtime_error(std::string("Error while opening ") + getFilename() + std::string(", data corrupted"));
}
} catch (ErrorReporter &error) {
} catch (std::runtime_error &error) {
if (fileDescriptor != STDIN_FILENO) {
close(fileDescriptor);
}
@ -107,7 +107,7 @@ std::vector<uint8_t> *WaveReader::readData(uint32_t bytesToRead, bool headerByte
if (((bytes == -1) && ((fileDescriptor != STDIN_FILENO) || (errno != EAGAIN))) ||
((static_cast<uint32_t>(bytes) < bytesToRead) && headerBytes && (fileDescriptor != STDIN_FILENO))) {
delete data;
throw ErrorReporter(std::string("Error while opening ") + getFilename() + std::string(", data corrupted"));
throw std::runtime_error(std::string("Error while opening ") + getFilename() + std::string(", data corrupted"));
}
if (bytes > 0) {
bytesRead += bytes;
@ -128,9 +128,9 @@ std::vector<uint8_t> *WaveReader::readData(uint32_t bytesToRead, bool headerByte
if (headerBytes) {
if (data == NULL) {
throw ErrorReporter("Cannot obtain header, program interrupted");
throw std::runtime_error("Cannot obtain header, program interrupted");
}
memcpy(&(reinterpret_cast<uint8_t *>(&header))[headerOffset], &(*data)[0], bytesRead);
std::memcpy(&(reinterpret_cast<uint8_t *>(&header))[headerOffset], &(*data)[0], bytesRead);
headerOffset += bytesRead;
delete data;
data = NULL;
@ -156,7 +156,7 @@ std::vector<Sample> *WaveReader::getSamples(uint32_t quantity, bool &continueFla
try {
data = readData(bytesToRead, false, continueFlag);
} catch (ErrorReporter &error) {
} catch (std::runtime_error &error) {
delete samples;
throw error;
}