Clean up some tests.

This commit is contained in:
James Grogan 2022-12-01 10:52:48 +00:00
parent b17ba8b3a7
commit c102ebb6da
64 changed files with 615 additions and 541 deletions

View file

@ -28,20 +28,18 @@ void TextEditorController::OnSave()
{ {
if(mSavePath.empty()) return; if(mSavePath.empty()) return;
File outfile(mSavePath); File outfile(mSavePath);
outfile.SetAccessMode(File::AccessMode::Write);
outfile.Open(); outfile.open(File::AccessMode::Write);
outfile.WriteText(mModel->GetDocument()->GetContent()); outfile.writeText(mModel->GetDocument()->GetContent());
outfile.Close();
} }
void TextEditorController::OnLoad() void TextEditorController::OnLoad()
{ {
if(mLoadPath.empty()) return; if(mLoadPath.empty()) return;
File infile(mLoadPath); File infile(mLoadPath);
infile.SetAccessMode(File::AccessMode::Read);
infile.Open(); infile.open(File::AccessMode::Read);
mModel->GetDocument()->SetContent(infile.ReadText()); mModel->GetDocument()->SetContent(infile.readText());
infile.Close();
} }
void TextEditorController::SetSavePath(const std::filesystem::path& path) void TextEditorController::SetSavePath(const std::filesystem::path& path)

View file

@ -20,52 +20,63 @@ std::unique_ptr<AudioDevice> AudioDevice::Create()
return std::make_unique<AudioDevice>(); return std::make_unique<AudioDevice>();
} }
void AudioDevice::SetNumChannels(unsigned numChannels) bool AudioDevice::getIsOpen() const
{ {
mNumChannels = numChannels; return mIsOpen;
} }
void AudioDevice::SetPeriod(unsigned period) unsigned AudioDevice::getNumChannels() const
{
mPeriod = period;
}
void AudioDevice::SetBufferSize(std::size_t bufferSize)
{
mBufferSize = bufferSize;
}
unsigned AudioDevice::GetNumChannels() const
{ {
return mNumChannels; return mNumChannels;
} }
unsigned AudioDevice::GetPeriod() const unsigned AudioDevice::getPeriod() const
{ {
return mPeriod; return mPeriod;
} }
std::size_t AudioDevice::GetBufferSize() const std::size_t AudioDevice::getBufferSize() const
{ {
return mBufferSize; return mBufferSize;
} }
void AudioDevice::SetSampleRate(unsigned rate) unsigned AudioDevice::getSampleRate() const
{
mSampleRate = rate;
}
unsigned AudioDevice::GetSampleRate() const
{ {
return mSampleRate; return mSampleRate;
} }
void AudioDevice::SetName(const std::string& name) std::string AudioDevice::getName() const
{
return mName;
}
void AudioDevice::setSampleRate(unsigned rate)
{
mSampleRate = rate;
}
void AudioDevice::setName(const std::string& name)
{ {
mName = name; mName = name;
} }
std::string AudioDevice::GetName() const void AudioDevice::setNumChannels(unsigned numChannels)
{ {
return mName; mNumChannels = numChannels;
} }
void AudioDevice::setPeriod(unsigned period)
{
mPeriod = period;
}
void AudioDevice::setBufferSize(std::size_t bufferSize)
{
mBufferSize = bufferSize;
}
void AudioDevice::setIsOpen(bool isOpen)
{
mIsOpen = isOpen;
}

View file

@ -7,40 +7,42 @@ class AudioDevice
{ {
public: public:
AudioDevice(); AudioDevice();
~AudioDevice(); ~AudioDevice();
static std::unique_ptr<AudioDevice> Create(); static std::unique_ptr<AudioDevice> Create();
void SetSampleRate(unsigned rate); unsigned getSampleRate() const;
unsigned GetSampleRate() const; unsigned getNumChannels() const;
void SetName(const std::string& name); unsigned getPeriod() const;
void SetNumChannels(unsigned numChannels); std::size_t getBufferSize() const;
void SetPeriod(unsigned period); bool getIsOpen() const;
void SetBufferSize(std::size_t bufferSize); std::string getName() const;
unsigned GetNumChannels() const; void setName(const std::string& name);
unsigned GetPeriod() const; void setNumChannels(unsigned numChannels);
std::size_t GetBufferSize() const; void setPeriod(unsigned period);
std::string GetName() const; void setBufferSize(std::size_t bufferSize);
void setSampleRate(unsigned rate);
void setIsOpen(bool isOpen);
private: private:
std::string mName {"unset"}; std::string mName {"unset"};
unsigned mSampleRate {44100}; unsigned mSampleRate {44100};
unsigned mNumChannels {1}; unsigned mNumChannels {1};
unsigned mPeriod {2}; unsigned mPeriod {2};
std::size_t mBufferSize{0}; std::size_t mBufferSize{0};
bool mIsOpen{false};
}; };
using AudioDevicePtr = std::unique_ptr<AudioDevice>; using AudioDevicePtr = std::unique_ptr<AudioDevice>;

View file

@ -31,22 +31,17 @@ std::unique_ptr<AudioManager> AudioManager::Create()
return std::make_unique<AudioManager>(); return std::make_unique<AudioManager>();
} }
void AudioManager::AddAudioDevice(AudioDevicePtr device) void AudioManager::addAudioDevice(AudioDevicePtr device)
{ {
mAudioDevices.push_back(std::move(device)); mAudioDevices.push_back(std::move(device));
} }
IAudioInterface* AudioManager::GetAudioInterface() std::size_t AudioManager::getNumAudioDevices() const
{
return mAudioInterface.get();
}
std::size_t AudioManager::GetNumAudioDevices() const
{ {
return mAudioDevices.size(); return mAudioDevices.size();
} }
AudioDevice* AudioManager::GetAudioDevice(unsigned idx) const AudioDevice* AudioManager::getAudioDevice(unsigned idx) const
{ {
if (idx < mAudioDevices.size()) if (idx < mAudioDevices.size())
{ {
@ -55,12 +50,11 @@ AudioDevice* AudioManager::GetAudioDevice(unsigned idx) const
return nullptr; return nullptr;
} }
void AudioManager::Play() void AudioManager::play(AudioSample* sample, unsigned duration)
{ {
if (mAudioDevices.size() == 0) if (mAudioDevices.size() == 0)
{ {
mAudioDevices.push_back(AudioDevice::Create()); mAudioDevices.push_back(AudioDevice::Create());
} }
mAudioInterface->OpenDevice(mAudioDevices[0]); mAudioInterface->play(mAudioDevices[0].get(), sample, duration);
mAudioInterface->Play(mAudioDevices[0]);
} }

View file

@ -6,30 +6,29 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
class AudioSample;
class AudioManager class AudioManager
{ {
public: public:
AudioManager(); AudioManager();
~AudioManager(); ~AudioManager();
static std::unique_ptr<AudioManager> Create(); static std::unique_ptr<AudioManager> Create();
void AddAudioDevice(AudioDevicePtr device); void addAudioDevice(AudioDevicePtr device);
std::size_t GetNumAudioDevices() const; std::size_t getNumAudioDevices() const;
AudioDevice* GetAudioDevice(unsigned idx) const; AudioDevice* getAudioDevice(unsigned idx) const;
IAudioInterface* GetAudioInterface(); void play(AudioSample* sample, unsigned duration);
void Play();
private: private:
std::vector<AudioDevicePtr> mAudioDevices; std::vector<AudioDevicePtr> mAudioDevices;
IAudioInterfaceUPtr mAudioInterface; IAudioInterfacePtr mAudioInterface;
}; };
using AudioManagerUPtr = std::unique_ptr<AudioManager>; using AudioManagerUPtr = std::unique_ptr<AudioManager>;

View file

@ -10,22 +10,22 @@ std::unique_ptr<AudioSample> AudioSample::Create()
return std::make_unique<AudioSample>(); return std::make_unique<AudioSample>();
} }
std::size_t AudioSample::GetNumChannels() const std::size_t AudioSample::getNumChannels() const
{ {
return mData.size(); return mData.size();
} }
unsigned AudioSample::GetSampleRate() const unsigned AudioSample::getSampleRate() const
{ {
return mSampleRate; return mSampleRate;
} }
unsigned AudioSample::GetBitDepth() const unsigned AudioSample::getBitDepth() const
{ {
return mBitDepth; return mBitDepth;
} }
void AudioSample::SetChannelData(const std::vector<short>& data, std::size_t channel) void AudioSample::setChannelData(const ChannelData& data, std::size_t channel)
{ {
if (mData.size() == channel) if (mData.size() == channel)
{ {
@ -37,7 +37,7 @@ void AudioSample::SetChannelData(const std::vector<short>& data, std::size_t cha
} }
} }
std::vector<short> AudioSample::GetChannelData(std::size_t channel) const AudioSample::ChannelData AudioSample::getChannelData(std::size_t channel) const
{ {
if(mData.size() > channel) if(mData.size() > channel)
{ {

View file

@ -6,22 +6,23 @@
class AudioSample class AudioSample
{ {
public: public:
using ChannelData = std::vector<short>;
AudioSample(); AudioSample();
static std::unique_ptr<AudioSample> Create(); static std::unique_ptr<AudioSample> Create();
std::vector<short> GetChannelData(std::size_t channel) const; ChannelData getChannelData(std::size_t channel) const;
void SetChannelData(const std::vector<short>& data, std::size_t channel); std::size_t getNumChannels() const;
unsigned getSampleRate() const;
unsigned getBitDepth() const;
std::size_t GetNumChannels() const; void setChannelData(const ChannelData& data, std::size_t channel);
unsigned GetSampleRate() const;
unsigned GetBitDepth() const;
private: private:
unsigned mSampleRate { 44100 }; unsigned mSampleRate { 44100 };
unsigned mBitDepth{ 16 }; unsigned mBitDepth{ 16 };
std::vector<std::vector<short> > mData; std::vector<ChannelData> mData;
}; };
using AudioSamplePtr = std::unique_ptr<AudioSample>; using AudioSamplePtr = std::unique_ptr<AudioSample>;

View file

@ -1,39 +1,39 @@
#include "AudioSynth.h" #include "AudioSynth.h"
#define _USE_MATH_DEFINES #define _USE_MATH_DEFINES
#include <cmath> #include <cmath>
#include <math.h> #include <math.h>
#include <limits> #include <limits>
#include <iostream>
AudioSynth::AudioSynth() AudioSynth::AudioSynth()
{ {
} }
AudioSamplePtr AudioSynth::GetConstant(unsigned amplitude, unsigned duration) AudioSamplePtr AudioSynth::getConstant(unsigned amplitude, unsigned duration) const
{ {
auto sample = AudioSample::Create(); auto sample = AudioSample::Create();
auto num_samples = duration * sample->GetSampleRate(); auto num_samples = duration * sample->getSampleRate();
sample->SetChannelData(std::vector<short>(num_samples, amplitude), 0); sample->setChannelData(std::vector<short>(num_samples, amplitude), 0);
return sample; return sample;
} }
AudioSamplePtr AudioSynth::GetSineWave(double freq, unsigned duration) AudioSamplePtr AudioSynth::getSineWave(double freq, unsigned duration) const
{ {
auto sample = AudioSample::Create(); auto sample = AudioSample::Create();
const auto sample_rate = sample->GetSampleRate(); const auto sample_rate = sample->getSampleRate();
const auto num_samples = sample_rate*duration; const auto num_samples = sample_rate*duration;
std::vector<short> data(num_samples, 0); std::vector<short> data(num_samples, 0);
double tick_duration = 1.0/sample_rate; const double tick_duration = 1.0/sample_rate;
double pi_2 = 2.0 * M_PI; const double pi_2 = 2.0 * M_PI;
short max_short = std::numeric_limits<short>::max(); const short max_short = std::numeric_limits<short>::max();
for(unsigned idx=0; idx<num_samples; idx++) for(unsigned idx=0; idx<num_samples; idx++)
{ {
const auto t = double(idx)*tick_duration; const auto t = double(idx)*tick_duration;
data[idx] = max_short*std::sin(pi_2*freq*t); data[idx] = max_short*std::sin(pi_2*freq*t);
} }
sample->SetChannelData(data, 0); sample->setChannelData(data, 0);
return sample; return sample;
} }

View file

@ -7,10 +7,9 @@
class AudioSynth class AudioSynth
{ {
public: public:
AudioSynth(); AudioSynth();
AudioSamplePtr GetConstant(unsigned amplitude, unsigned duration); AudioSamplePtr getConstant(unsigned amplitude, unsigned duration) const;
AudioSamplePtr GetSineWave(double freq, unsigned duration); AudioSamplePtr getSineWave(double freq, unsigned duration) const;
}; };

View file

@ -3,6 +3,5 @@
class AudioTrack class AudioTrack
{ {
public: public:
AudioTrack(); AudioTrack();
}; };

View file

@ -3,36 +3,41 @@
#include "File.h" #include "File.h"
#include "BinaryStream.h" #include "BinaryStream.h"
#include "AudioSample.h" #include "AudioSample.h"
#include "FileLogger.h"
AudioWriter::AudioWriter() AudioWriter::AudioWriter()
{ {
} }
void AudioWriter::SetPath(const std::string& path) void AudioWriter::setPath(const Path& path)
{ {
mPath = path; mPath = path;
} }
void AudioWriter::Write(const AudioSamplePtr& sample) bool AudioWriter::write(const AudioSamplePtr& sample)
{ {
if (mPath.empty()) if (mPath.empty())
{ {
return; MLOG_ERROR("Attempted to write audio with no output file path, aborting Write.");
return false;
} }
const auto sample_rate = sample->GetSampleRate(); File outfile(mPath);
const auto num_channels = sample->GetNumChannels(); if (!outfile.open(File::AccessMode::Write))
const auto bytes_per_sample = sample->GetBitDepth() / 8; {
MLOG_ERROR("Failed to open audio output file, aborting Write.");
return false;
}
auto handle = outfile.getOutHandle();
const auto sample_rate = sample->getSampleRate();
const auto num_channels = sample->getNumChannels();
const auto bytes_per_sample = sample->getBitDepth() / 8;
unsigned byte_rate = sample_rate*num_channels*bytes_per_sample; unsigned byte_rate = sample_rate*num_channels*bytes_per_sample;
File outfile(mPath);
outfile.SetAccessMode(File::AccessMode::Write);
outfile.Open(true);
auto handle = outfile.GetOutHandle();
handle->write("RIFF", 4); handle->write("RIFF", 4);
auto data = sample->GetChannelData(0); auto data = sample->getChannelData(0);
const auto num_samples = data.size(); const auto num_samples = data.size();
unsigned content_size = 36 + bytes_per_sample* num_samples*num_channels; unsigned content_size = 36 + bytes_per_sample* num_samples*num_channels;
@ -54,5 +59,6 @@ void AudioWriter::Write(const AudioSamplePtr& sample)
BinaryStream::write<int>(handle, bytes_per_sample* num_samples*num_channels); // bits/sample BinaryStream::write<int>(handle, bytes_per_sample* num_samples*num_channels); // bits/sample
handle->write(reinterpret_cast<const char*>(&data[0]), data.size()*sizeof(short)); handle->write(reinterpret_cast<const char*>(&data[0]), data.size()*sizeof(short));
outfile.Close();
return true;
} }

View file

@ -2,20 +2,20 @@
#include <string> #include <string>
#include <memory> #include <memory>
#include <filesystem>
class AudioSample; class AudioSample;
using AudioSamplePtr = std::unique_ptr<AudioSample>; using AudioSamplePtr = std::unique_ptr<AudioSample>;
using Path = std::filesystem::path;
class AudioWriter class AudioWriter
{ {
public: public:
AudioWriter(); AudioWriter();
void SetPath(const std::string& path); void setPath(const Path& path);
void Write(const AudioSamplePtr& sample);
bool write(const AudioSamplePtr& sample);
private: private:
Path mPath;
std::string mPath;
}; };

View file

@ -1,5 +1,7 @@
#include "AlsaInterface.h" #include "AlsaInterface.h"
#include "FileLogger.h" #include "FileLogger.h"
#include "AudioDevice.h"
#include "AudioSynth.h" #include "AudioSynth.h"
@ -23,13 +25,13 @@ std::unique_ptr<AlsaInterface> AlsaInterface::Create()
return std::make_unique<AlsaInterface>(); return std::make_unique<AlsaInterface>();
} }
void AlsaInterface::OpenDevice(const AudioDevicePtr& device) void AlsaInterface::openDevice(AudioDevice* device)
{ {
MLOG_INFO("Opening Device"); MLOG_INFO("Opening Device");
snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK; snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK;
if (snd_pcm_open(&mHandle, device->GetName().c_str(), stream, 0) < 0) if (snd_pcm_open(&mHandle, device->getName().c_str(), stream, 0) < 0)
{ {
MLOG_ERROR("Error opening PCM device: " + device->GetName()); MLOG_ERROR("Error opening PCM device: " + device->getName());
return; return;
} }
@ -40,92 +42,110 @@ void AlsaInterface::OpenDevice(const AudioDevicePtr& device)
return; return;
} }
SetAccessType(device); setAccessType(device);
SetSampleFormat(device); setSampleFormat(device);
SetSampleRate(device); setSampleRate(device);
SetPeriod(device); setPeriod(device);
SetBufferSize(device); setBufferSize(device);
SetChannelNumber(device); setChannelNumber(device);
/* Apply HW parameter settings to */ /* Apply HW parameter settings to */
/* PCM device and prepare device */ /* PCM device and prepare device */
if (snd_pcm_hw_params(mHandle, mHardwareParams) < 0) { if (snd_pcm_hw_params(mHandle, mHardwareParams) < 0)
{
MLOG_ERROR("Error setting HW params."); MLOG_ERROR("Error setting HW params.");
return; return;
} }
} }
void AlsaInterface::SetAccessType(const AudioDevicePtr& device) void AlsaInterface::setAccessType(AudioDevice* device)
{ {
if (snd_pcm_hw_params_set_access(mHandle, mHardwareParams, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) { if (snd_pcm_hw_params_set_access(mHandle, mHardwareParams, SND_PCM_ACCESS_RW_INTERLEAVED) < 0)
{
MLOG_ERROR("Error setting device access."); MLOG_ERROR("Error setting device access.");
return; return;
} }
} }
void AlsaInterface::SetSampleFormat(const AudioDevicePtr& device) bool AlsaInterface::setSampleFormat(AudioDevice* device)
{ {
/* Set sample format */ /* Set sample format */
if (snd_pcm_hw_params_set_format(mHandle, mHardwareParams, SND_PCM_FORMAT_S16_LE) < 0) { if (snd_pcm_hw_params_set_format(mHandle, mHardwareParams, SND_PCM_FORMAT_S16_LE) < 0)
{
MLOG_ERROR("Error setting format. "); MLOG_ERROR("Error setting format. ");
return; return false;
} }
return true;
} }
void AlsaInterface::SetSampleRate(const AudioDevicePtr& device) bool AlsaInterface::setSampleRate(AudioDevice* device)
{ {
unsigned rate = device->GetSampleRate(); unsigned rate = device->getSampleRate();
unsigned exact_rate = rate; unsigned exact_rate = rate;
if (snd_pcm_hw_params_set_rate_near(mHandle, mHardwareParams, &exact_rate, 0) < 0) if (snd_pcm_hw_params_set_rate_near(mHandle, mHardwareParams, &exact_rate, 0) < 0)
{ {
MLOG_ERROR("Error setting rate. "); MLOG_ERROR("Error setting rate. ");
return; return false;
} }
if (rate != exact_rate) {
if (rate != exact_rate)
{
MLOG_ERROR("The rate is not supported by your hardware."); MLOG_ERROR("The rate is not supported by your hardware.");
return false;
} }
return true;
} }
void AlsaInterface::SetPeriod(const AudioDevicePtr& device) bool AlsaInterface::setPeriod(AudioDevice* device)
{ {
/* Set number of periods. Periods used to be called fragments. */ /* Set number of periods. Periods used to be called fragments. */
if (snd_pcm_hw_params_set_periods(mHandle, mHardwareParams, device->GetPeriod(), 0) < 0) if (snd_pcm_hw_params_set_periods(mHandle, mHardwareParams, device->getPeriod(), 0) < 0)
{ {
MLOG_ERROR("Error setting periods. "); MLOG_ERROR("Error setting periods. ");
return; return false;
} }
return true;
} }
void AlsaInterface::SetBufferSize(const AudioDevicePtr& device) bool AlsaInterface::setBufferSize(AudioDevice* device)
{ {
int periods = static_cast<int>(device->GetPeriod()); int periods = static_cast<int>(device->getPeriod());
/* Set buffer size (in frames). The resulting latency is given by */ /* Set buffer size (in frames). The resulting latency is given by */
/* latency = periodsize * periods / (rate * bytes_per_frame) */ /* latency = periodsize * periods / (rate * bytes_per_frame) */
if (snd_pcm_hw_params_set_buffer_size(mHandle, mHardwareParams, (mPeriodSize * periods)>>2) < 0) if (snd_pcm_hw_params_set_buffer_size(mHandle, mHardwareParams, (mPeriodSize * periods)>>2) < 0)
{ {
MLOG_ERROR("Error setting buffersize. "); MLOG_ERROR("Error setting buffersize. ");
return; return false;
} }
return true;
} }
void AlsaInterface::SetChannelNumber(const AudioDevicePtr& device) bool AlsaInterface::setChannelNumber(AudioDevice* device)
{ {
/* Set number of channels */ /* Set number of channels */
if (snd_pcm_hw_params_set_channels(mHandle, mHardwareParams, device->GetNumChannels()) < 0) if (snd_pcm_hw_params_set_channels(mHandle, mHardwareParams, device->getNumChannels()) < 0)
{ {
MLOG_ERROR("Error setting channels"); MLOG_ERROR("Error setting channels");
return; return false;
} }
return true;
} }
void AlsaInterface::Play(const AudioDevicePtr& device) void AlsaInterface::play(AudioDevice* device, AudioSample* sample, unsigned duration)
{ {
if (!device->getIsOpen())
{
openDevice(device);
}
if (!device->getIsOpen())
{
return;
}
MLOG_INFO("Playing audio"); MLOG_INFO("Playing audio");
AudioSynth synth; const auto data = sample->getChannelData(0);
const unsigned duration = 100;
double freq = 440;
auto data = synth.GetSineWave(freq, duration)->GetChannelData(0);
int numFrames = mPeriodSize >> 2; int numFrames = mPeriodSize >> 2;
for(int count = 0; count < duration; count++) for(int count = 0; count < duration; count++)

View file

@ -1,40 +1,39 @@
#pragma once #pragma once
#include "IAudioInterface.h" #include "IAudioInterface.h"
#include "AudioDevice.h"
#include <memory>
#include <alsa/asoundlib.h> #include <alsa/asoundlib.h>
#include <memory>
class AlsaInterface : public IAudioInterface class AlsaInterface : public IAudioInterface
{ {
snd_pcm_t* mHandle;
snd_pcm_hw_params_t* mHardwareParams;
snd_pcm_uframes_t mPeriodSize;
public: public:
AlsaInterface(); AlsaInterface();
~AlsaInterface(); ~AlsaInterface();
static std::unique_ptr<AlsaInterface> Create(); static std::unique_ptr<AlsaInterface> Create();
void OpenDevice(const AudioDevicePtr& device) override; void play(AudioDevice* device, AudioSample* sample, unsigned duration) override;
void SetAccessType(const AudioDevicePtr& device); private:
void openDevice(AudioDevice* device) override;
void SetSampleFormat(const AudioDevicePtr& device); void setAccessType(AudioDevice* device);
void SetSampleRate(const AudioDevicePtr& device); bool setSampleFormat(AudioDevice* device);
void SetPeriod(const AudioDevicePtr& device); bool setSampleRate(AudioDevice* device);
void SetBufferSize(const AudioDevicePtr& device); bool setPeriod(AudioDevice* device);
void SetChannelNumber(const AudioDevicePtr& device); bool setBufferSize(AudioDevice* device);
void Play(const AudioDevicePtr& device) override; bool setChannelNumber(AudioDevice* device);
snd_pcm_t* mHandle;
snd_pcm_hw_params_t* mHardwareParams;
snd_pcm_uframes_t mPeriodSize;
}; };
using AlsaInterfacePtr = std::shared_ptr<AlsaInterface>; using AlsaInterfacePtr = std::unique_ptr<AlsaInterface>;

View file

@ -3,19 +3,19 @@
#include <memory> #include <memory>
class AudioDevice; class AudioDevice;
using AudioDevicePtr = std::unique_ptr<AudioDevice>; class AudioSample;
class IAudioInterface class IAudioInterface
{ {
public: public:
IAudioInterface() = default; IAudioInterface() = default;
virtual ~IAudioInterface() = default; virtual ~IAudioInterface() = default;
virtual void OpenDevice(const AudioDevicePtr& device) = 0; virtual void play(AudioDevice* device, AudioSample* sample, unsigned duration) = 0;
virtual void Play(const AudioDevicePtr& device) = 0; protected:
virtual void openDevice(AudioDevice* device) = 0;
}; };
using IAudioInterfaceUPtr = std::unique_ptr<IAudioInterface>; using IAudioInterfacePtr = std::unique_ptr<IAudioInterface>;

View file

@ -20,12 +20,12 @@ std::unique_ptr<NullAudioInterface> NullAudioInterface::Create()
return std::make_unique<NullAudioInterface>(); return std::make_unique<NullAudioInterface>();
} }
void NullAudioInterface::OpenDevice(const AudioDevicePtr& device) void NullAudioInterface::openDevice(AudioDevice* device)
{ {
} }
void NullAudioInterface::Play(const AudioDevicePtr& device) void NullAudioInterface::play(AudioDevice* device, AudioSample* sample, unsigned duration)
{ {
} }

View file

@ -9,16 +9,18 @@ class NullAudioInterface : public IAudioInterface
{ {
public: public:
NullAudioInterface(); NullAudioInterface();
~NullAudioInterface(); ~NullAudioInterface();
static std::unique_ptr<NullAudioInterface> Create(); static std::unique_ptr<NullAudioInterface> Create();
void OpenDevice(const AudioDevicePtr& device) override; void openDevice(AudioDevice* device) override;
void Play(const AudioDevicePtr& device) override; void play(AudioDevice* device, AudioSample* sample, unsigned duration) override;
private:
void openDevice(const AudioDevicePtr& device) override;
}; };
using NullAudioInterfacePtr = std::shared_ptr<NullAudioInterface>; using NullAudioInterfacePtr = std::shared_ptr<NullAudioInterface>;

View file

@ -13,7 +13,7 @@ int MidiChannelEventAdapter::ReadEvent(std::ifstream* file, char firstByte, Midi
int event_type = (firstByte & first_four_bits) >> 4; int event_type = (firstByte & first_four_bits) >> 4;
int midi_channel = (firstByte & second_four_bits) >> 4; int midi_channel = (firstByte & second_four_bits) >> 4;
unsigned byteCount = 0; unsigned byteCount = 0;
std::cout << "Channel: " << midi_channel << std::endl; //std::cout << "Channel: " << midi_channel << std::endl;
const bool isStatusByte = ByteUtils::MostSignificantBitIsOne(firstByte); const bool isStatusByte = ByteUtils::MostSignificantBitIsOne(firstByte);
if(isStatusByte) if(isStatusByte)
@ -25,7 +25,7 @@ int MidiChannelEventAdapter::ReadEvent(std::ifstream* file, char firstByte, Midi
{ {
event->SetType(lastEventType); event->SetType(lastEventType);
} }
std::cout << "MC Type " << static_cast<int>(event->GetType()) << std::endl; //std::cout << "MC Type " << static_cast<int>(event->GetType()) << std::endl;
switch(event->GetType()) switch(event->GetType())
{ {
case MidiChannelEvent::Type::NOTE_ON: case MidiChannelEvent::Type::NOTE_ON:
@ -49,7 +49,7 @@ int MidiChannelEventAdapter::ReadEvent(std::ifstream* file, char firstByte, Midi
break; break;
} }
default: default:
std::cout << "Unknown status event: " << std::bitset<8>(firstByte) << "|" << event_type <<std::endl; //std::cout << "Unknown status event: " << std::bitset<8>(firstByte) << "|" << event_type <<std::endl;
break; break;
} }
return byteCount; return byteCount;

View file

@ -15,7 +15,7 @@ int MidiMetaEventAdapter::ReadEvent(std::ifstream* file, MetaMidiEvent* event, i
event->SetType(c); event->SetType(c);
std::cout << "Meta event type: " << std::hex << int(c) << std::dec<<std::endl; //std::cout << "Meta event type: " << std::hex << int(c) << std::dec<<std::endl;
switch (event->GetType()) switch (event->GetType())
{ {

View file

@ -22,32 +22,32 @@ MidiReader::MidiReader()
} }
MidiDocument* MidiReader::GetDocument() const MidiDocument* MidiReader::getDocument() const
{ {
return mDocument.get(); return mDocument.get();
} }
bool MidiReader::ProcessHeader() bool MidiReader::processHeader()
{ {
if(!BinaryStream::checkNextDWord(mFile->GetInHandle(), HeaderLabel)) if(!BinaryStream::checkNextDWord(mFile->getInHandle(), HeaderLabel))
{ {
return false; return false;
} }
const auto length = BinaryStream::getNextDWord(mFile->GetInHandle()); const auto length = BinaryStream::getNextDWord(mFile->getInHandle());
if(!length) if(!length)
{ {
return false; return false;
} }
const auto formatType = BinaryStream::getNextWord(mFile->GetInHandle()); const auto formatType = BinaryStream::getNextWord(mFile->getInHandle());
if(!formatType) if(!formatType)
{ {
return false; return false;
} }
mDocument->SetFormatType(*formatType); mDocument->SetFormatType(*formatType);
const auto expectedTracks = BinaryStream::getNextWord(mFile->GetInHandle()); const auto expectedTracks = BinaryStream::getNextWord(mFile->getInHandle());
if(!expectedTracks) if(!expectedTracks)
{ {
return false; return false;
@ -55,52 +55,52 @@ bool MidiReader::ProcessHeader()
mDocument->SetExpectedTracks(*expectedTracks); mDocument->SetExpectedTracks(*expectedTracks);
MidiTimeDivision timeDivision; MidiTimeDivision timeDivision;
MidiTimeAdapter::ReadTimeDivision(mFile->GetInHandle(), timeDivision); MidiTimeAdapter::ReadTimeDivision(mFile->getInHandle(), timeDivision);
mDocument->SetTimeDivision(timeDivision); mDocument->SetTimeDivision(timeDivision);
return true; return true;
} }
int MidiReader::ProcessEvent(MidiTrack* track) int MidiReader::processEvent(MidiTrack* track)
{ {
int timeDelta {0}; int timeDelta {0};
unsigned byteCount {0}; unsigned byteCount {0};
byteCount += MidiTimeAdapter::ReadEventTimeDelta(mFile->GetInHandle(), timeDelta); byteCount += MidiTimeAdapter::ReadEventTimeDelta(mFile->getInHandle(), timeDelta);
char c; char c;
mFile->GetInHandle()->get(c); mFile->getInHandle()->get(c);
std::cout << "Event check: " << std::bitset<8>(c) << std::endl; //std::cout << "Event check: " << std::bitset<8>(c) << std::endl;
byteCount++; byteCount++;
if(MidiEvent::IsMetaEvent(c)) if(MidiEvent::IsMetaEvent(c))
{ {
auto event = std::make_unique<MetaMidiEvent>(); auto event = std::make_unique<MetaMidiEvent>();
event->SetTimeDelta(timeDelta); event->SetTimeDelta(timeDelta);
std::cout << "Meta event " <<std::endl; //std::cout << "Meta event " <<std::endl;
byteCount += MidiMetaEventAdapter::ReadEvent(mFile->GetInHandle(), event.get(), mLastMidiChannel); byteCount += MidiMetaEventAdapter::ReadEvent(mFile->getInHandle(), event.get(), mLastMidiChannel);
track->AddEvent(std::move(event)); track->AddEvent(std::move(event));
} }
else if(MidiEvent::IsSysExEvent(c)) else if(MidiEvent::IsSysExEvent(c))
{ {
std::cout << "Sysex event" << std::endl; //std::cout << "Sysex event" << std::endl;
} }
else else
{ // Midi event { // Midi event
auto event = std::make_unique<MidiChannelEvent>(); auto event = std::make_unique<MidiChannelEvent>();
event->SetTimeDelta(timeDelta); event->SetTimeDelta(timeDelta);
std::cout << "Midi event" << std::endl; //std::cout << "Midi event" << std::endl;
byteCount += MidiChannelEventAdapter::ReadEvent(mFile->GetInHandle(), c, event.get(), mLastChannelEventType); byteCount += MidiChannelEventAdapter::ReadEvent(mFile->getInHandle(), c, event.get(), mLastChannelEventType);
track->AddEvent(std::move(event)); track->AddEvent(std::move(event));
} }
return byteCount; return byteCount;
} }
bool MidiReader::ProcessTrackChunk(bool debug) bool MidiReader::processTrackChunk(bool debug)
{ {
if(!BinaryStream::checkNextDWord(mFile->GetInHandle(), TrackChunkLabel)) if(!BinaryStream::checkNextDWord(mFile->getInHandle(), TrackChunkLabel))
{ {
return false; return false;
} }
const auto chunkSize = BinaryStream::getNextDWord(mFile->GetInHandle()); const auto chunkSize = BinaryStream::getNextDWord(mFile->getInHandle());
if(!chunkSize) if(!chunkSize)
{ {
return false; return false;
@ -111,9 +111,9 @@ bool MidiReader::ProcessTrackChunk(bool debug)
unsigned iter_count = 0; unsigned iter_count = 0;
while(byteCount < static_cast<unsigned>(*chunkSize)) while(byteCount < static_cast<unsigned>(*chunkSize))
{ {
std::cout << "-------------" << std::endl; //std::cout << "-------------" << std::endl;
byteCount += ProcessEvent(track.get()); byteCount += processEvent(track.get());
std::cout << "Track byte count: " << byteCount << " of " << *chunkSize << std::endl; //std::cout << "Track byte count: " << byteCount << " of " << *chunkSize << std::endl;
if(debug && iter_count == 40) if(debug && iter_count == 40)
{ {
return true; return true;
@ -124,30 +124,30 @@ bool MidiReader::ProcessTrackChunk(bool debug)
return true; return true;
} }
void MidiReader::Read(const std::string& path) void MidiReader::read(const Path& path)
{ {
mFile = std::make_unique<File>(path); mFile = std::make_unique<File>(path);
mFile->Open(true); mFile->open(File::AccessMode::Read);
if(!ProcessHeader()) if(!processHeader())
{ {
MLOG_ERROR("Problem processing header"); MLOG_ERROR("Problem processing header");
return; return;
} }
int trackCount = 0; int trackCount = 0;
if(!ProcessTrackChunk(false)) if(!processTrackChunk(false))
{ {
MLOG_ERROR("Problem processing track chunk"); MLOG_ERROR("Problem processing track chunk");
return; return;
} }
trackCount++; trackCount++;
if(!ProcessTrackChunk(true)) if(!processTrackChunk(true))
{ {
MLOG_ERROR("Problem processing track chunk"); MLOG_ERROR("Problem processing track chunk");
return; return;
} }
trackCount++; trackCount++;
mFile->Close(); mFile->close();
} }

View file

@ -5,29 +5,30 @@
#include "MidiTrack.h" #include "MidiTrack.h"
#include "MidiChannelEvent.h" #include "MidiChannelEvent.h"
#include "File.h" #include "File.h"
#include <filesystem>
#include <string> #include <string>
using Path = std::filesystem::path;
class MidiReader class MidiReader
{ {
static constexpr const char TrackChunkLabel[] = "MTrk"; static constexpr const char TrackChunkLabel[] = "MTrk";
static constexpr const char HeaderLabel[] = "MThd"; static constexpr const char HeaderLabel[] = "MThd";
public: public:
MidiReader(); MidiReader();
void Read(const std::string& path); MidiDocument* getDocument() const;
MidiDocument* GetDocument() const; void read(const Path& path);
private: private:
bool processHeader();
bool ProcessHeader(); bool processTrackChunk(bool debug=false);
bool ProcessTrackChunk(bool debug=false); int processEvent(MidiTrack* track);
int ProcessEvent(MidiTrack* track);
private: private:
std::unique_ptr<File> mFile; std::unique_ptr<File> mFile;
MidiDocumentPtr mDocument; MidiDocumentPtr mDocument;
int mLastMidiChannel {0}; int mLastMidiChannel {0};

View file

@ -16,14 +16,14 @@ int MidiTimeAdapter::ReadEventTimeDelta(std::ifstream* file, int& delta)
if(!ByteUtils::MostSignificantBitIsOne(c)) if(!ByteUtils::MostSignificantBitIsOne(c))
{ {
delta = int(c); delta = int(c);
std::cout << "Time delta final: " << delta << std::endl; //std::cout << "Time delta final: " << delta << std::endl;
return byteCount; return byteCount;
} }
int working_c = c; int working_c = c;
int final_c = 0; int final_c = 0;
unsigned count = 0; unsigned count = 0;
std::cout << "Working " << std::bitset<8>(working_c) << std::endl; //std::cout << "Working " << std::bitset<8>(working_c) << std::endl;
while(unsigned(working_c >> 7) != 0) while(unsigned(working_c >> 7) != 0)
{ {
char corrected = (working_c &= ~(1UL << 7)); char corrected = (working_c &= ~(1UL << 7));
@ -33,16 +33,16 @@ int MidiTimeAdapter::ReadEventTimeDelta(std::ifstream* file, int& delta)
file->get(file_c); file->get(file_c);
byteCount++; byteCount++;
working_c = int(file_c); working_c = int(file_c);
std::cout << "Working " << std::bitset<8>(working_c) << std::endl; //std::cout << "Working " << std::bitset<8>(working_c) << std::endl;
count++; count++;
} }
std::cout << "Time delta start: " << std::bitset<16>(final_c) << std::endl; //std::cout << "Time delta start: " << std::bitset<16>(final_c) << std::endl;
final_c <<= 7; final_c <<= 7;
std::cout << "Time delta pre: " << std::bitset<16>(final_c) << std::endl; //std::cout << "Time delta pre: " << std::bitset<16>(final_c) << std::endl;
final_c |= (working_c << 7*(count-1)); final_c |= (working_c << 7*(count-1));
delta = int(final_c); delta = int(final_c);
std::cout << "Time delta final: " << delta << "|" << std::bitset<16>(final_c)<< std::endl; //std::cout << "Time delta final: " << delta << "|" << std::bitset<16>(final_c)<< std::endl;
return byteCount; return byteCount;
} }

View file

@ -21,7 +21,7 @@ std::string TemplateFile::getName() const
void TemplateFile::loadContent() void TemplateFile::loadContent()
{ {
std::cout << "Trying to load file at: " << mPath << std::endl; //std::cout << "Trying to load file at: " << mPath << std::endl;
mRawContent = File(mPath).readLines(); mRawContent = File(mPath).readLines();
mWorkingLine = 0; mWorkingLine = 0;
mWorkingNode = mRootNode.get(); mWorkingNode = mRootNode.get();
@ -183,5 +183,5 @@ void TemplateFile::onFoundExpression(const std::string& expression_string)
void TemplateFile::dumpContent() void TemplateFile::dumpContent()
{ {
auto content = mRootNode->getRawContent(); auto content = mRootNode->getRawContent();
std::cout << content << std::endl; //std::cout << content << std::endl;
} }

View file

@ -49,7 +49,7 @@ void MainApplication::initialize(CommandLineArgsUPtr commandLineArgs, std::uniqu
MLOG_INFO("Launched"); MLOG_INFO("Launched");
mDatabaseManager = DatabaseManager::Create(); mDatabaseManager = DatabaseManager::Create();
mDatabaseManager->CreateDatabase(launch_path + "/database.db"); mDatabaseManager->openDatabase(launch_path + "/database.db");
MLOG_INFO("Created DB"); MLOG_INFO("Created DB");
mNetworkManager = NetworkManager::Create(); mNetworkManager = NetworkManager::Create();
@ -122,7 +122,7 @@ void MainApplication::playAudio()
{ {
//MidiReader reader; //MidiReader reader;
//reader.Read("/home/james/sample.mid"); //reader.Read("/home/james/sample.mid");
mAudioManager->Play(); //mAudioManager->Play();
} }
void MainApplication::convertDocument(const std::string& inputPath, const std::string& outputPath) void MainApplication::convertDocument(const std::string& inputPath, const std::string& outputPath)
@ -131,7 +131,7 @@ void MainApplication::convertDocument(const std::string& inputPath, const std::s
auto output_file = File(std::filesystem::path(outputPath)); auto output_file = File(std::filesystem::path(outputPath));
MLOG_INFO("Converting: " + inputPath + " to " + outputPath); MLOG_INFO("Converting: " + inputPath + " to " + outputPath);
DocumentConverter converter; DocumentConverter converter;
converter.Convert(&input_file, &output_file); converter.convert(&input_file, &output_file);
} }
CommandLineArgs* MainApplication::getCommandLineArgs() const CommandLineArgs* MainApplication::getCommandLineArgs() const
@ -141,7 +141,7 @@ CommandLineArgs* MainApplication::getCommandLineArgs() const
void MainApplication::shutDown() void MainApplication::shutDown()
{ {
mDatabaseManager->OnShutDown(); mDatabaseManager->onShutDown();
mNetworkManager->ShutDown(); mNetworkManager->ShutDown();
MLOG_INFO("Shut down"); MLOG_INFO("Shut down");
FileLogger::GetInstance().Close(); FileLogger::GetInstance().Close();

View file

@ -4,32 +4,29 @@
#include "ByteUtils.h" #include "ByteUtils.h"
#include <streambuf> #include <streambuf>
#include <fstream>
#include <sstream> #include <sstream>
File::File(std::filesystem::path path) File::File(std::filesystem::path path)
: mFullPath(path), : mFullPath(path),
mInHandle(), mInHandle(),
mOutHandle(), mOutHandle()
mAccessMode(AccessMode::Read)
{ {
} }
std::string File::GetExtension() const File::~File()
{
close();
}
std::string File::getExtension() const
{ {
return mFullPath.extension().string(); return mFullPath.extension().string();
} }
void File::SetAccessMode(AccessMode mode)
{
mAccessMode = mode;
}
std::string File::dumpBinary() std::string File::dumpBinary()
{ {
mAccessMode = AccessMode::Read; open(AccessMode::Read);
Open();
std::stringstream sstr; std::stringstream sstr;
sstr << "Count | Binary | Decimal | ASCII \n"; sstr << "Count | Binary | Decimal | ASCII \n";
@ -46,22 +43,30 @@ std::string File::dumpBinary()
count++; count++;
} }
const auto out = sstr.str(); const auto out = sstr.str();
Close(); close();
return out; return out;
} }
std::ifstream* File::GetInHandle() const std::ifstream* File::getInHandle() const
{ {
return mInHandle.get(); return mInHandle.get();
} }
std::ofstream* File::GetOutHandle() const std::ofstream* File::getOutHandle() const
{ {
return mOutHandle.get(); return mOutHandle.get();
} }
std::optional<unsigned char> File::readNextByte() std::optional<unsigned char> File::readNextByte()
{ {
if (!mInHandle)
{
if (!open(AccessMode::Read))
{
return std::nullopt;
}
}
if (mInHandle->good()) if (mInHandle->good())
{ {
if (auto val = mInHandle->get(); val == EOF) if (auto val = mInHandle->get(); val == EOF)
@ -79,31 +84,39 @@ std::optional<unsigned char> File::readNextByte()
} }
} }
void File::Open(bool asBinary) bool File::open(AccessMode accessMode)
{ {
if(mAccessMode == AccessMode::Read) if (mFullPath.is_absolute() && !std::filesystem::exists(mFullPath.parent_path()))
{
std::filesystem::create_directories(mFullPath.parent_path());
}
if(accessMode == AccessMode::Read)
{ {
auto flags = std::ifstream::in; auto flags = std::ifstream::in;
if (asBinary)
{
//flags |= std::ifstream::binary;
}
mInHandle = std::make_unique<std::ifstream>(); mInHandle = std::make_unique<std::ifstream>();
mInHandle->open(mFullPath, flags); mInHandle->open(mFullPath, flags);
if (!mInHandle->is_open())
{
MLOG_ERROR("Failed to open file at :" << mFullPath);
return false;
}
} }
else else
{ {
auto flags = std::ofstream::out; auto flags = std::ofstream::out;
if (asBinary)
{
//flags |= std::ofstream::binary;
}
mOutHandle = std::make_unique<std::ofstream>(); mOutHandle = std::make_unique<std::ofstream>();
mOutHandle->open(mFullPath, flags); mOutHandle->open(mFullPath, flags);
if (!mOutHandle->is_open())
{
MLOG_ERROR("Failed to open file at :" << mFullPath);
return false;
}
} }
return true;
} }
void File::Close() void File::close()
{ {
if(mOutHandle) if(mOutHandle)
{ {
@ -115,27 +128,29 @@ void File::Close()
} }
} }
FileFormat::Format File::InferFormat() const FileFormat::Format File::inferFormat() const
{ {
const auto extension = GetExtension(); const auto extension = getExtension();
return FileFormat::InferFormat(extension); return FileFormat::InferFormat(extension);
} }
void File::WriteText(const std::string& text) void File::writeText(const std::string& text)
{ {
bool had_to_open{ false }; bool had_to_open{false};
if (!mOutHandle) if (!mOutHandle)
{ {
had_to_open = true; had_to_open = true;
SetAccessMode(File::AccessMode::Write); if (!open(File::AccessMode::Write))
Open(); {
return;
}
} }
(*mOutHandle) << text; (*mOutHandle) << text;
if (had_to_open) if (had_to_open)
{ {
Close(); close();
} }
} }
@ -143,12 +158,15 @@ std::vector<std::string> File::readLines()
{ {
std::vector<std::string> content; std::vector<std::string> content;
if (!PathExists()) if (!pathExists())
{ {
return content; return {};
} }
Open(false); if(!open(AccessMode::Read))
{
return {};
}
std::string str; std::string str;
while(std::getline(*mInHandle, str)) while(std::getline(*mInHandle, str))
@ -156,23 +174,26 @@ std::vector<std::string> File::readLines()
content.push_back(str); content.push_back(str);
} }
Close(); close();
return content; return content;
} }
std::string File::read() std::string File::read()
{ {
if (!PathExists()) if (!pathExists())
{ {
return {}; return {};
} }
Open(false); if(!open(AccessMode::Read))
{
return {};
}
std::stringstream buffer; std::stringstream buffer;
buffer << mInHandle->rdbuf(); buffer << mInHandle->rdbuf();
Close(); close();
return buffer.str(); return buffer.str();
} }
@ -181,14 +202,24 @@ std::string File::getBaseFilename(const Path& path)
return path.stem().string(); return path.stem().string();
} }
std::string File::ReadText() std::string File::readText()
{ {
if (!pathExists())
{
return {};
}
if(!open(AccessMode::Read))
{
return {};
}
std::string str((std::istreambuf_iterator<char>(*mInHandle)), std::string str((std::istreambuf_iterator<char>(*mInHandle)),
std::istreambuf_iterator<char>()); std::istreambuf_iterator<char>());
return str; return str;
} }
bool File::PathExists() const bool File::pathExists() const
{ {
return std::filesystem::exists(mFullPath); return std::filesystem::exists(mFullPath);
} }

View file

@ -23,42 +23,38 @@ public:
File(std::filesystem::path fullPath); File(std::filesystem::path fullPath);
std::string GetExtension() const; ~File();
FileFormat::Format InferFormat() const; void close();
std::ifstream* GetInHandle() const; std::string dumpBinary();
std::ofstream* GetOutHandle() const; static std::string getBaseFilename(const Path& path);
void WriteText(const std::string& text); std::string getExtension() const;
std::string ReadText(); std::ifstream* getInHandle() const;
std::ofstream* getOutHandle() const;
FileFormat::Format inferFormat() const;
std::string readText();
std::vector<std::string> readLines(); std::vector<std::string> readLines();
std::string read(); std::string read();
static std::string getBaseFilename(const Path& path); bool pathExists() const;
bool PathExists() const; bool open(AccessMode mode);
void SetAccessMode(AccessMode mode);
void Open(bool asBinary = false);
void Close();
std::optional<unsigned char> readNextByte(); std::optional<unsigned char> readNextByte();
std::string dumpBinary(); void writeText(const std::string& text);
private: private:
std::filesystem::path mFullPath; std::filesystem::path mFullPath;
std::unique_ptr<std::ifstream> mInHandle; std::unique_ptr<std::ifstream> mInHandle;
std::unique_ptr<std::ofstream> mOutHandle; std::unique_ptr<std::ofstream> mOutHandle;
AccessMode mAccessMode;
}; };

View file

@ -119,17 +119,15 @@ void TomlReader::processLine(const std::string& line)
if (in_comment) if (in_comment)
{ {
mWorkingTable->addComment({ mLastSectionOffset, working_string }); mWorkingTable->addComment({ mLastSectionOffset, working_string });
} }
else if (in_header) else if (in_header)
{ {
onHeader(working_string); onHeader(working_string);
} }
else if (found_key) else if (found_key)
{ {
std::locale locale; key_string.erase(std::remove_if(key_string.begin(), key_string.end(), [](char c) {return std::isspace(c); }), key_string.end());
key_string.erase(std::remove_if(key_string.begin(), key_string.end(), [locale](unsigned char c) {return std::isspace(c, locale); }), key_string.end()); working_string.erase(std::remove_if(working_string.begin(), working_string.end(), [](char c) {return std::isspace(c); }), working_string.end());
working_string.erase(std::remove_if(working_string.begin(), working_string.end(), [locale](unsigned char c) {return std::isspace(c, locale); }), working_string.end());
if (working_string.size()>2 && working_string[0] == '"' && working_string[working_string.size() - 1] == '"') if (working_string.size()>2 && working_string[0] == '"' && working_string[working_string.size() - 1] == '"')
{ {
working_string = working_string.substr(1, working_string.size() - 2); working_string = working_string.substr(1, working_string.size() - 2);

View file

@ -12,61 +12,61 @@ using Path = std::filesystem::path;
class TomlTable class TomlTable
{ {
public: public:
using Comment = std::pair<unsigned, std::string>; using Comment = std::pair<unsigned, std::string>;
using KeyValuePairs = std::unordered_map<std::string, std::string>; using KeyValuePairs = std::unordered_map<std::string, std::string>;
TomlTable(const std::string& header); TomlTable(const std::string& header);
void addComment(const Comment& comment); void addComment(const Comment& comment);
void addTable(std::unique_ptr<TomlTable> table); void addTable(std::unique_ptr<TomlTable> table);
void addKeyValuePair(const std::string& key, const std::string& value); void addKeyValuePair(const std::string& key, const std::string& value);
std::string getHeader() const; std::string getHeader() const;
TomlTable* getTable(const std::string& path); TomlTable* getTable(const std::string& path);
KeyValuePairs getKeyValuePairs() const; KeyValuePairs getKeyValuePairs() const;
private: private:
unsigned mLineOffset{ 0 }; unsigned mLineOffset{ 0 };
std::string mHeader; std::string mHeader;
std::unordered_map<std::string, std::unique_ptr<TomlTable> > mTables; std::unordered_map<std::string, std::unique_ptr<TomlTable> > mTables;
KeyValuePairs mMap; KeyValuePairs mMap;
std::vector<Comment> mComments; std::vector<Comment> mComments;
}; };
class TomlContent class TomlContent
{ {
public: public:
TomlContent(); TomlContent();
TomlTable* getRootTable() const; TomlTable* getRootTable() const;
TomlTable* getTable(const std::string& path) const; TomlTable* getTable(const std::string& path) const;
private: private:
std::unique_ptr<TomlTable> mRootTable; std::unique_ptr<TomlTable> mRootTable;
}; };
class TomlReader class TomlReader
{ {
public: public:
TomlReader(); TomlReader();
TomlContent* getContent() const; TomlContent* getContent() const;
void read(const Path& input_path); void read(const Path& input_path);
void processLine(const std::string& line); void processLine(const std::string& line);
void onHeader(const std::string& header); void onHeader(const std::string& header);
void onKeyValuePair(const std::string key, const std::string value); void onKeyValuePair(const std::string key, const std::string value);
private: private:
unsigned mLastSectionOffset{ 0 }; unsigned mLastSectionOffset{ 0 };
std::unique_ptr<TomlContent> mContent; std::unique_ptr<TomlContent> mContent;
TomlTable* mWorkingTable{nullptr}; TomlTable* mWorkingTable{nullptr};
}; };

View file

@ -16,12 +16,12 @@ std::unique_ptr<Database> Database::Create()
return std::make_unique<Database>(); return std::make_unique<Database>();
} }
void Database::SetPath(const std::string& path) void Database::setPath(const Path& path)
{ {
mPath = path; mPath = path;
} }
std::string Database::GetPath() const const Path& Database::getPath() const
{ {
return mPath; return mPath;
} }

View file

@ -2,23 +2,25 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include <filesystem>
using Path = std::filesystem::path;
class Database class Database
{ {
std::string mPath;
public: public:
Database(); Database();
~Database(); ~Database();
static std::unique_ptr<Database> Create(); static std::unique_ptr<Database> Create();
void SetPath(const std::string& path); const Path& getPath() const;
std::string GetPath() const; void setPath(const Path& path);
private:
Path mPath;
}; };
using DatabasePtr = std::unique_ptr<Database>; using DatabasePtr = std::unique_ptr<Database>;

View file

@ -18,24 +18,24 @@ std::unique_ptr<DatabaseManager> DatabaseManager::Create()
} }
void DatabaseManager::CreateDatabase(const std::string& path) void DatabaseManager::openDatabase(const Path& path)
{ {
mDatabase = Database::Create(); mDatabase = Database::Create();
mDatabase->SetPath(path); mDatabase->setPath(path);
mDatabaseInterface = SqliteInterface::Create(); mDatabaseInterface = SqliteInterface::Create();
mDatabaseInterface->Open(mDatabase); mDatabaseInterface->open(mDatabase.get());
} }
void DatabaseManager::Run(const std::string& statement) void DatabaseManager::run(const std::string& statement)
{ {
mDatabaseInterface->Run(statement); mDatabaseInterface->run(statement);
} }
void DatabaseManager::OnShutDown() void DatabaseManager::onShutDown()
{ {
if(mDatabaseInterface) if(mDatabaseInterface)
{ {
mDatabaseInterface->Close(); mDatabaseInterface->close();
} }
} }

View file

@ -1,25 +1,27 @@
#pragma once #pragma once
#include <memory>
#include "SqliteInterface.h" #include "SqliteInterface.h"
#include "Database.h" #include "Database.h"
#include <memory>
#include <filesystem>
using Path = std::filesystem::path;
class DatabaseManager class DatabaseManager
{ {
public: public:
DatabaseManager(); DatabaseManager();
~DatabaseManager(); ~DatabaseManager();
static std::unique_ptr<DatabaseManager> Create(); static std::unique_ptr<DatabaseManager> Create();
void CreateDatabase(const std::string& path); void openDatabase(const Path& path);
void Run(const std::string& statement); void run(const std::string& statement);
void OnShutDown(); void onShutDown();
private: private:
DatabasePtr mDatabase; DatabasePtr mDatabase;

View file

@ -18,9 +18,9 @@ std::unique_ptr<SqliteInterface> SqliteInterface::Create()
return std::make_unique<SqliteInterface>(); return std::make_unique<SqliteInterface>();
} }
void SqliteInterface::Open(const DatabasePtr& db) void SqliteInterface::open(Database* db)
{ {
int rc = sqlite3_open(db->GetPath().c_str(), &mSqliteDb); int rc = sqlite3_open(db->getPath().c_str(), &mSqliteDb);
if( rc ) if( rc )
{ {
MLOG_ERROR("Can't open database: %s\n" << sqlite3_errmsg(mSqliteDb)); MLOG_ERROR("Can't open database: %s\n" << sqlite3_errmsg(mSqliteDb));
@ -39,7 +39,7 @@ static int callback(void *NotUsed, int argc, char **argv, char **azColName)
return 0; return 0;
} }
void SqliteInterface::Run(const std::string& statement) void SqliteInterface::run(const std::string& statement)
{ {
char *zErrMsg = 0; char *zErrMsg = 0;
int rc = sqlite3_exec(mSqliteDb, statement.c_str(), callback, 0, &zErrMsg); int rc = sqlite3_exec(mSqliteDb, statement.c_str(), callback, 0, &zErrMsg);
@ -50,7 +50,7 @@ void SqliteInterface::Run(const std::string& statement)
} }
} }
void SqliteInterface::Close() void SqliteInterface::close()
{ {
sqlite3_close(mSqliteDb); sqlite3_close(mSqliteDb);
} }

View file

@ -6,21 +6,21 @@
class SqliteInterface class SqliteInterface
{ {
sqlite3* mSqliteDb;
public: public:
SqliteInterface(); SqliteInterface();
~SqliteInterface(); ~SqliteInterface();
static std::unique_ptr<SqliteInterface> Create(); static std::unique_ptr<SqliteInterface> Create();
void Open(const DatabasePtr& db); void open(Database* db);
void Close(); void close();
void Run(const std::string& statement); void run(const std::string& statement);
private:
sqlite3* mSqliteDb;
}; };
using SqliteInterfacePtr = std::unique_ptr<SqliteInterface>; using SqliteInterfacePtr = std::unique_ptr<SqliteInterface>;

View file

@ -19,19 +19,19 @@ void FontReader::setPath(const std::string& path)
bool FontReader::readOffsetSubtable() bool FontReader::readOffsetSubtable()
{ {
mOffsetSubtable.scaler_type = *BinaryStream::getNextDWord(mFile->GetInHandle()); mOffsetSubtable.scaler_type = *BinaryStream::getNextDWord(mFile->getInHandle());
mCurrentOffset += 4; mCurrentOffset += 4;
mOffsetSubtable.num_tables = *BinaryStream::getNextWord(mFile->GetInHandle()); mOffsetSubtable.num_tables = *BinaryStream::getNextWord(mFile->getInHandle());
mCurrentOffset += 2; mCurrentOffset += 2;
mOffsetSubtable.search_range = *BinaryStream::getNextWord(mFile->GetInHandle()); mOffsetSubtable.search_range = *BinaryStream::getNextWord(mFile->getInHandle());
mCurrentOffset += 2; mCurrentOffset += 2;
mOffsetSubtable.entry_selector = *BinaryStream::getNextWord(mFile->GetInHandle()); mOffsetSubtable.entry_selector = *BinaryStream::getNextWord(mFile->getInHandle());
mCurrentOffset += 2; mCurrentOffset += 2;
mOffsetSubtable.range_shift = *BinaryStream::getNextWord(mFile->GetInHandle()); mOffsetSubtable.range_shift = *BinaryStream::getNextWord(mFile->getInHandle());
mCurrentOffset += 2; mCurrentOffset += 2;
return true; return true;
@ -60,16 +60,16 @@ void FontReader::readTableDirectory()
for (unsigned idx=0; idx<mOffsetSubtable.num_tables; idx++) for (unsigned idx=0; idx<mOffsetSubtable.num_tables; idx++)
{ {
Table table; Table table;
BinaryStream::getNextString(mFile->GetInHandle(), table.name, 4); BinaryStream::getNextString(mFile->getInHandle(), table.name, 4);
mCurrentOffset += 4; mCurrentOffset += 4;
table.checksum = *BinaryStream::getNextDWord(mFile->GetInHandle()); table.checksum = *BinaryStream::getNextDWord(mFile->getInHandle());
mCurrentOffset += 4; mCurrentOffset += 4;
table.offset = *BinaryStream::getNextDWord(mFile->GetInHandle()); table.offset = *BinaryStream::getNextDWord(mFile->getInHandle());
mCurrentOffset += 4; mCurrentOffset += 4;
table.length = *BinaryStream::getNextDWord(mFile->GetInHandle()); table.length = *BinaryStream::getNextDWord(mFile->getInHandle());
mCurrentOffset += 4; mCurrentOffset += 4;
logTable(table); logTable(table);
@ -117,29 +117,29 @@ void FontReader::readHeadTable()
TrueTypeFont::HeadTable table; TrueTypeFont::HeadTable table;
table.version = *BinaryStream::getNextDWord(mFile->GetInHandle()); table.version = *BinaryStream::getNextDWord(mFile->getInHandle());
table.fontRevision = *BinaryStream::getNextDWord(mFile->GetInHandle()); table.fontRevision = *BinaryStream::getNextDWord(mFile->getInHandle());
table.checksumAdjustment = *BinaryStream::getNextDWord(mFile->GetInHandle()); table.checksumAdjustment = *BinaryStream::getNextDWord(mFile->getInHandle());
table.magicNumber = *BinaryStream::getNextDWord(mFile->GetInHandle()); table.magicNumber = *BinaryStream::getNextDWord(mFile->getInHandle());
mCurrentOffset += 16; mCurrentOffset += 16;
table.flags = *BinaryStream::getNextWord(mFile->GetInHandle()); table.flags = *BinaryStream::getNextWord(mFile->getInHandle());
table.unitsPerEm = *BinaryStream::getNextWord(mFile->GetInHandle()); table.unitsPerEm = *BinaryStream::getNextWord(mFile->getInHandle());
mCurrentOffset += 4; mCurrentOffset += 4;
table.created = *BinaryStream::getNextQWord(mFile->GetInHandle()); table.created = *BinaryStream::getNextQWord(mFile->getInHandle());
table.modified = *BinaryStream::getNextQWord(mFile->GetInHandle()); table.modified = *BinaryStream::getNextQWord(mFile->getInHandle());
mCurrentOffset += 16; mCurrentOffset += 16;
table.xMin = *BinaryStream::getNextWord(mFile->GetInHandle()); table.xMin = *BinaryStream::getNextWord(mFile->getInHandle());
table.yMin = *BinaryStream::getNextWord(mFile->GetInHandle()); table.yMin = *BinaryStream::getNextWord(mFile->getInHandle());
table.xMax = *BinaryStream::getNextWord(mFile->GetInHandle()); table.xMax = *BinaryStream::getNextWord(mFile->getInHandle());
table.yMax = *BinaryStream::getNextWord(mFile->GetInHandle()); table.yMax = *BinaryStream::getNextWord(mFile->getInHandle());
table.macStyle = *BinaryStream::getNextWord(mFile->GetInHandle()); table.macStyle = *BinaryStream::getNextWord(mFile->getInHandle());
table.lowestRecPPEM = *BinaryStream::getNextWord(mFile->GetInHandle()); table.lowestRecPPEM = *BinaryStream::getNextWord(mFile->getInHandle());
table.fontDirectionHint = *BinaryStream::getNextWord(mFile->GetInHandle()); table.fontDirectionHint = *BinaryStream::getNextWord(mFile->getInHandle());
table.indexToLocFormat = *BinaryStream::getNextWord(mFile->GetInHandle()); table.indexToLocFormat = *BinaryStream::getNextWord(mFile->getInHandle());
table.glyphDataFormat = *BinaryStream::getNextWord(mFile->GetInHandle()); table.glyphDataFormat = *BinaryStream::getNextWord(mFile->getInHandle());
mCurrentOffset += 18; mCurrentOffset += 18;
@ -154,7 +154,7 @@ std::unique_ptr<IFont> FontReader::read()
mWorkingFont = std::make_unique<TrueTypeFont>(); mWorkingFont = std::make_unique<TrueTypeFont>();
mFile = std::make_unique<File>(mPath); mFile = std::make_unique<File>(mPath);
mFile->Open(true); mFile->open(File::AccessMode::Read);
readOffsetSubtable(); readOffsetSubtable();
//std::cout << "Current offset: " << mCurrentOffset << std::endl; //std::cout << "Current offset: " << mCurrentOffset << std::endl;
@ -171,7 +171,7 @@ std::unique_ptr<IFont> FontReader::read()
break; break;
} }
mFile->Close(); mFile->close();

View file

@ -25,14 +25,14 @@ void PngReader::setPath(const Path& path)
bool PngReader::checkSignature() bool PngReader::checkSignature()
{ {
const int highBitCheck = 0x89; const int highBitCheck = 0x89;
const auto firstPos = mFile->GetInHandle()->get(); const auto firstPos = mFile->getInHandle()->get();
if (firstPos != highBitCheck) if (firstPos != highBitCheck)
{ {
return false; return false;
} }
std::string fileType; std::string fileType;
BinaryStream::getNextString(mFile->GetInHandle(), fileType, 3); BinaryStream::getNextString(mFile->getInHandle(), fileType, 3);
if (fileType != "PNG") if (fileType != "PNG")
{ {
return false; return false;
@ -41,7 +41,7 @@ bool PngReader::checkSignature()
std::vector<char> sequence{13, 10, 26, 10}; std::vector<char> sequence{13, 10, 26, 10};
for (auto c : sequence) for (auto c : sequence)
{ {
if (mFile->GetInHandle()->get() != c) if (mFile->getInHandle()->get() != c)
{ {
return false; return false;
} }
@ -51,10 +51,10 @@ bool PngReader::checkSignature()
bool PngReader::readChunk() bool PngReader::readChunk()
{ {
unsigned length = *BinaryStream::getNextDWord(mFile->GetInHandle()); unsigned length = *BinaryStream::getNextDWord(mFile->getInHandle());
std::string chunkType; std::string chunkType;
BinaryStream::getNextString(mFile->GetInHandle(), chunkType, 4); BinaryStream::getNextString(mFile->getInHandle(), chunkType, 4);
//std::cout << "Got chunk with type: " << chunkType << " and length: " << length << std::endl; //std::cout << "Got chunk with type: " << chunkType << " and length: " << length << std::endl;
bool lastChunk = false; bool lastChunk = false;
@ -72,7 +72,7 @@ bool PngReader::readChunk()
{ {
decodeData(); decodeData();
} }
unsigned crcCheck = *BinaryStream::getNextDWord(mFile->GetInHandle()); unsigned crcCheck = *BinaryStream::getNextDWord(mFile->getInHandle());
} }
else if(chunkType == "IDAT") else if(chunkType == "IDAT")
{ {
@ -91,31 +91,31 @@ bool PngReader::readChunk()
for(unsigned idx=0;idx<length;idx++) for(unsigned idx=0;idx<length;idx++)
{ {
mFile->GetInHandle()->get(); mFile->getInHandle()->get();
} }
unsigned crcCheck = *BinaryStream::getNextDWord(mFile->GetInHandle()); unsigned crcCheck = *BinaryStream::getNextDWord(mFile->getInHandle());
} }
return !lastChunk; return !lastChunk;
} }
bool PngReader::readHeaderChunk() bool PngReader::readHeaderChunk()
{ {
auto width = *BinaryStream::getNextDWord(mFile->GetInHandle()); auto width = *BinaryStream::getNextDWord(mFile->getInHandle());
auto height = *BinaryStream::getNextDWord(mFile->GetInHandle()); auto height = *BinaryStream::getNextDWord(mFile->getInHandle());
auto bitDepth = mFile->GetInHandle()->get(); auto bitDepth = mFile->getInHandle()->get();
mHeader.setImageData(width, height, bitDepth); mHeader.setImageData(width, height, bitDepth);
PngInfo info; PngInfo info;
info.mColorType = static_cast<PngInfo::ColorType>(mFile->GetInHandle()->get()); info.mColorType = static_cast<PngInfo::ColorType>(mFile->getInHandle()->get());
info.mCompressionMethod = static_cast<PngInfo::CompressionMethod>(mFile->GetInHandle()->get()); info.mCompressionMethod = static_cast<PngInfo::CompressionMethod>(mFile->getInHandle()->get());
info.mFilterMethod = static_cast<PngInfo::FilterMethod>(mFile->GetInHandle()->get()); info.mFilterMethod = static_cast<PngInfo::FilterMethod>(mFile->getInHandle()->get());
info.mInterlaceMethod = static_cast<PngInfo::InterlaceMethod>(mFile->GetInHandle()->get()); info.mInterlaceMethod = static_cast<PngInfo::InterlaceMethod>(mFile->getInHandle()->get());
mHeader.setPngInfo(info); mHeader.setPngInfo(info);
mHeader.updateData(); mHeader.updateData();
uint32_t file_crc = *BinaryStream::getNextDWord(mFile->GetInHandle()); uint32_t file_crc = *BinaryStream::getNextDWord(mFile->getInHandle());
auto crc_calc = mHeader.getCrc(); auto crc_calc = mHeader.getCrc();
//std::cout << mHeader.toString() << "*************\n"; //std::cout << mHeader.toString() << "*************\n";
@ -147,7 +147,7 @@ bool PngReader::readIDATChunk(unsigned length)
} }
mInputStream->clearChecksumCalculator(); mInputStream->clearChecksumCalculator();
uint32_t file_crc = *BinaryStream::getNextDWord(mFile->GetInHandle()); uint32_t file_crc = *BinaryStream::getNextDWord(mFile->getInHandle());
auto crc_calc = crc_check->getChecksum(); auto crc_calc = crc_check->getChecksum();
if (file_crc != crc_calc) if (file_crc != crc_calc)
@ -166,7 +166,7 @@ std::unique_ptr<Image<unsigned char> > PngReader::read()
auto image = std::make_unique<Image<unsigned char> >(5, 5); auto image = std::make_unique<Image<unsigned char> >(5, 5);
mFile = std::make_unique<File>(mPath); mFile = std::make_unique<File>(mPath);
mFile->Open(true); mFile->open(File::AccessMode::Read);
if (!checkSignature()) if (!checkSignature())
{ {

View file

@ -161,9 +161,8 @@ void PngWriter::write(const std::unique_ptr<Image<unsigned char> >& image)
if (!mPath.empty()) if (!mPath.empty())
{ {
mWorkingFile = std::make_unique<File>(mPath); mWorkingFile = std::make_unique<File>(mPath);
mWorkingFile->SetAccessMode(File::AccessMode::Write); mWorkingFile->open(File::AccessMode::Write);
mWorkingFile->Open(true); mOutStream = std::make_unique<OutputBitStream>(mWorkingFile->getOutHandle());
mOutStream = std::make_unique<OutputBitStream>(mWorkingFile->GetOutHandle());
} }
else else
{ {
@ -218,6 +217,6 @@ void PngWriter::write(const std::unique_ptr<Image<unsigned char> >& image)
if (mWorkingFile) if (mWorkingFile)
{ {
mWorkingFile->Close(); mWorkingFile->close();
} }
} }

View file

@ -2,6 +2,7 @@
#include "MarkdownParser.h" #include "MarkdownParser.h"
#include "HtmlWriter.h" #include "HtmlWriter.h"
#include "FileLogger.h" #include "FileLogger.h"
#include "File.h"
#include <fstream> #include <fstream>
DocumentConverter::DocumentConverter() DocumentConverter::DocumentConverter()
@ -9,19 +10,19 @@ DocumentConverter::DocumentConverter()
} }
void DocumentConverter::Convert(File* input, File* output) void DocumentConverter::convert(File* input, File* output)
{ {
if(!input || !output) if(!input || !output)
{ {
return; return;
} }
const auto input_format = input->InferFormat(); const auto input_format = input->inferFormat();
switch (input_format) switch (input_format)
{ {
case FileFormat::Format::Markdown: case FileFormat::Format::Markdown:
{ {
ConvertMarkdown(input, output); convertMarkdown(input, output);
break; break;
} }
default: default:
@ -31,14 +32,14 @@ void DocumentConverter::Convert(File* input, File* output)
} }
} }
void DocumentConverter::ConvertMarkdown(File* input, File* output) void DocumentConverter::convertMarkdown(File* input, File* output)
{ {
const auto output_format = output->InferFormat(); const auto output_format = output->inferFormat();
switch (output_format) switch (output_format)
{ {
case FileFormat::Format::Html: case FileFormat::Format::Html:
{ {
MarkdownToHtml(input, output); markdownToHtml(input, output);
break; break;
} }
default: default:
@ -48,29 +49,27 @@ void DocumentConverter::ConvertMarkdown(File* input, File* output)
} }
} }
void DocumentConverter::MarkdownToHtml(File* input, File* output) void DocumentConverter::markdownToHtml(File* input, File* output)
{ {
MLOG_INFO("Converting Markdown to Html"); MLOG_INFO("Converting Markdown to Html");
input->SetAccessMode(File::AccessMode::Read); input->open(File::AccessMode::Read);
input->Open();
MarkdownParser parser; MarkdownParser parser;
auto handle = input->GetInHandle(); auto handle = input->getInHandle();
while(handle->good()) while(handle->good())
{ {
std::string line; std::string line;
std::getline(*handle, line); std::getline(*handle, line);
parser.ProcessLine(line); parser.processLine(line);
}; };
input->Close(); input->close();
auto html_document = parser.GetHtml(); auto html_document = parser.getHtml();
HtmlWriter writer; HtmlWriter writer;
std::string html_string = writer.ToString(html_document); std::string html_string = writer.ToString(html_document);
output->SetAccessMode(File::AccessMode::Write); output->open(File::AccessMode::Write);
output->Open(); *(output->getOutHandle()) << html_string;
*(output->GetOutHandle()) << html_string; output->close();
output->Close();
} }

View file

@ -1,16 +1,17 @@
#pragma once #pragma once
#include <string> #include <string>
#include "File.h"
class File;
class DocumentConverter class DocumentConverter
{ {
public: public:
DocumentConverter(); DocumentConverter();
void Convert(File* input, File* output); void convert(File* input, File* output);
void ConvertMarkdown(File* input, File* output); void convertMarkdown(File* input, File* output);
void MarkdownToHtml(File* input, File* output); void markdownToHtml(File* input, File* output);
}; };

View file

@ -9,22 +9,22 @@ MarkdownParser::MarkdownParser()
} }
void MarkdownParser::ProcessLine(const std::string& line) void MarkdownParser::processLine(const std::string& line)
{ {
} }
void MarkdownParser::Run(const std::string& content) void MarkdownParser::run(const std::string& content)
{ {
std::stringstream ss(content); std::stringstream ss(content);
std::string line; std::string line;
while (std::getline(ss, line, '\n')) while (std::getline(ss, line, '\n'))
{ {
ProcessLine(line); processLine(line);
} }
} }
HtmlDocumentPtr MarkdownParser::GetHtml() HtmlDocumentPtr MarkdownParser::getHtml()
{ {
return mHtmlDocument; return mHtmlDocument;
} }

View file

@ -14,17 +14,16 @@ class MarkdownParser
None None
}; };
DocumentState mDocumentState {DocumentState::None};
HtmlDocumentPtr mHtmlDocument;
public: public:
MarkdownParser(); MarkdownParser();
HtmlDocumentPtr GetHtml(); HtmlDocumentPtr getHtml();
void ProcessLine(const std::string& line); void processLine(const std::string& line);
void Run(const std::string& content); void run(const std::string& content);
private:
DocumentState mDocumentState {DocumentState::None};
HtmlDocumentPtr mHtmlDocument;
}; };

View file

@ -1,5 +1,7 @@
add_subdirectory(test_utils) add_subdirectory(test_utils)
file(COPY data/ DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test_data)
set(TEST_MODULES set(TEST_MODULES
audio audio
compiler compiler
@ -21,7 +23,13 @@ foreach(module ${TEST_MODULES})
string(TOUPPER ${module} MODULE_UPPER) string(TOUPPER ${module} MODULE_UPPER)
list(APPEND UNIT_TEST_FILES ${${MODULE_UPPER}_UNIT_TEST_FILES}) list(APPEND UNIT_TEST_FILES ${${MODULE_UPPER}_UNIT_TEST_FILES})
list(APPEND UNIT_TEST_DEPENDENCIES ${${MODULE_UPPER}_UNIT_TEST_DEPENDENCIES}) list(APPEND UNIT_TEST_DEPENDENCIES ${${MODULE_UPPER}_UNIT_TEST_DEPENDENCIES})
list(APPEND INTEGRATION_TEST_FILES ${${MODULE_UPPER}_INTEGRATION_TEST_FILES})
list(APPEND INTEGRATION_TEST_DEPENDENCIES ${${MODULE_UPPER}_INTEGRATION_TEST_DEPENDENCIES})
endforeach() endforeach()
add_executable(unit_tests test_runner.cpp ${UNIT_TEST_FILES}) add_executable(unit_tests test_runner.cpp ${UNIT_TEST_FILES})
target_link_libraries(unit_tests PUBLIC test_utils ${UNIT_TEST_DEPENDENCIES}) target_link_libraries(unit_tests PUBLIC test_utils ${UNIT_TEST_DEPENDENCIES})
add_executable(integration_tests test_runner.cpp ${INTEGRATION_TEST_FILES})
target_link_libraries(integration_tests PUBLIC test_utils ${INTEGRATION_TEST_DEPENDENCIES})

View file

@ -1,10 +1,22 @@
set(AUDIO_UNIT_TEST_FILES set(MODULE_NAME audio)
audio/TestAudioWriter.cpp
audio/TestMidiReader.cpp set(UNIT_TESTS
PARENT_SCOPE ${MODULE_NAME}/unit/TestAudioWriter.cpp
) ${MODULE_NAME}/unit/TestMidiReader.cpp
)
set(AUDIO_UNIT_TEST_DEPENDENCIES
audio if(UNIX)
PARENT_SCOPE set(INTEGETATION_TESTS
) ${MODULE_NAME}/integration/TestAlsaInterface.cpp
)
else()
set(INTEGETATION_TESTS
${MODULE_NAME}/integration/TestWasapiInterface.cpp
)
endif()
set(AUDIO_UNIT_TEST_FILES ${UNIT_TESTS} PARENT_SCOPE)
set(AUDIO_INTEGRATION_TEST_FILES ${INTEGETATION_TESTS} PARENT_SCOPE)
set(AUDIO_UNIT_TEST_DEPENDENCIES ${MODULE_NAME} PARENT_SCOPE)
set(AUDIO_INTEGRATION_TEST_DEPENDENCIES ${MODULE_NAME} PARENT_SCOPE)

View file

@ -1,34 +0,0 @@
#include "AudioSample.h"
#include "AudioSynth.h"
#include "AudioWriter.h"
#include "WasapiInterface.h"
#include "TestFramework.h"
#include <memory>
#include <string>
#ifdef _WIN32
#include <windows.h>
#endif
#include <iostream>
TEST_CASE(TestWriteWav, "audio")
{
AudioWriter writer;
writer.SetPath("test.wav");
AudioSynth synth;
auto sample = synth.GetSineWave(240, 5);
writer.Write(sample);
};
TEST_CASE(TestAudioRender, "audio")
{
#ifdef _WIN32
WasapiInterface audio_interface;
auto device = AudioDevice::Create();
audio_interface.Play(device);
#endif
};

View file

@ -1,16 +0,0 @@
#include "MidiReader.h"
#include "TestFramework.h"
#include <memory>
#include <string>
#include <iostream>
TEST_CASE(TestReadMidi, "audio")
{
MidiReader reader;
reader.Read("/home/jmsgrogan/Downloads/test.mid");
auto document = reader.GetDocument();
// std::cout << document->Serialize() << std::endl;
};

View file

@ -0,0 +1,13 @@
#include "TestFramework.h"
#include "TestUtils.h"
#include "AudioSample.h"
#include "AudioSynth.h"
#include "WasapiInterface.h"
TEST_CASE(TestWasapiInterface, "audio")
{
WasapiInterface audio_interface;
auto device = AudioDevice::Create();
audio_interface.Play(device);
};

View file

@ -0,0 +1,17 @@
#include "TestFramework.h"
#include "TestUtils.h"
#include "AudioSample.h"
#include "AudioSynth.h"
#include "AudioWriter.h"
TEST_CASE(TestAudioWriterWav, "audio")
{
AudioWriter writer;
writer.setPath(TestUtils::getTestOutputDir() / "TestAudioWriterWav.wav");
AudioSynth synth;
const auto sample = synth.getSineWave(240, 5);
writer.write(sample);
};

View file

@ -0,0 +1,12 @@
#include "MidiReader.h"
#include "TestFramework.h"
#include "TestUtils.h"
TEST_CASE(TestReadMidi, "audio")
{
MidiReader reader;
reader.read(TestUtils::getTestDataDir() / "test.mid");
auto document = reader.getDocument();
};

View file

@ -1,19 +1,16 @@
#include "TemplatingEngine.h" #include "TemplatingEngine.h"
#include "File.h" #include "File.h"
#include "TestFramework.h"
#include <filesystem> #include "TestFramework.h"
#include <iostream> #include "TestUtils.h"
TEST_CASE(TestTemplatingEngine, "compiler") TEST_CASE(TestTemplatingEngine, "compiler")
{ {
const auto data_loc = std::filesystem::path(__FILE__) / "../../data"; auto engine = TemplatingEngine(TestUtils::getTestDataDir());
auto engine = TemplatingEngine(data_loc);
engine.loadTemplateFiles(); engine.loadTemplateFiles();
const auto content = engine.processTemplate("index"); const auto content = engine.processTemplate("index");
File outfile("index.html"); File outfile(TestUtils::getTestOutputDir() / "index.html");
outfile.WriteText(content); outfile.writeText(content);
} }

View file

@ -1,17 +1,12 @@
#include "TomlReader.h" #include "TomlReader.h"
#include "TestFramework.h" #include "TestFramework.h"
#include "TestUtils.h"
#include <filesystem>
#include <iostream>
TEST_CASE(TestTomlReader, "core") TEST_CASE(TestTomlReader, "core")
{ {
const auto data_loc = std::filesystem::path(__FILE__) / "../../data";
const auto sample_toml_file = data_loc / "sample_toml.toml";
auto reader = TomlReader(); auto reader = TomlReader();
reader.read(sample_toml_file); reader.read(TestUtils::getTestDataDir() / "sample_toml.toml");
auto themes_table = reader.getContent()->getTable("themes"); auto themes_table = reader.getContent()->getTable("themes");
@ -19,6 +14,6 @@ TEST_CASE(TestTomlReader, "core")
for (const auto& items : themes_table->getKeyValuePairs()) for (const auto& items : themes_table->getKeyValuePairs())
{ {
std::cout << "Got entry with key: " << items.first << " and val " << items.second << std::endl; //std::cout << "Got entry with key: " << items.first << " and val " << items.second << std::endl;
} }
} }

BIN
test/data/index.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

BIN
test/data/test.mid Normal file

Binary file not shown.

BIN
test/data/test.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

BIN
test/data/test_fixed.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 B

View file

@ -1,12 +1,13 @@
#include "DatabaseManager.h" #include "DatabaseManager.h"
#include "TestFramework.h" #include "TestFramework.h"
#include "TestUtils.h"
TEST_CASE(TestDatabaseManager, "database") TEST_CASE(TestDatabaseManager, "database")
{ {
DatabaseManager db_manager; DatabaseManager db_manager;
db_manager.CreateDatabase("test.db"); db_manager.openDatabase(TestUtils::getTestOutputDir() / "test.db");
std::string statement = "CREATE TABLE corporation;"; std::string statement = "CREATE TABLE corporation;";
db_manager.Run(statement); db_manager.run(statement);
} }

View file

@ -1,8 +1,6 @@
#include "TrueTypeFont.h" #include "TrueTypeFont.h"
#include "FontReader.h" #include "FontReader.h"
#include <iostream>
#include "TestFramework.h" #include "TestFramework.h"
TEST_CASE(TestFontReader, "fonts") TEST_CASE(TestFontReader, "fonts")

View file

@ -1,6 +1,7 @@
#include "PngReader.h" #include "PngReader.h"
#include "BitStream.h" #include "BitStream.h"
#include "TestUtils.h"
#include "Image.h" #include "Image.h"
#include <iostream> #include <iostream>
@ -9,7 +10,7 @@
TEST_CASE(TestThirdPartyPng, "image") TEST_CASE(TestThirdPartyPng, "image")
{ {
const auto path = "/home/jmsgrogan/Downloads/test.png"; const auto path = TestUtils::getTestDataDir() / "test.png";
//const auto path = "/home/jmsgrogan/Downloads/index.png"; //const auto path = "/home/jmsgrogan/Downloads/index.png";
@ -30,7 +31,7 @@ TEST_CASE(TestThirdPartyPng, "image")
TEST_CASE(TestFxedCodePng, "image") TEST_CASE(TestFxedCodePng, "image")
{ {
const auto path = "/home/jmsgrogan/code/MediaTool-build/bin/test_fixed.png"; const auto path = TestUtils::getTestDataDir() / "test_fixed.png";
//File file(path); //File file(path);
//std::cout << file.dumpBinary(); //std::cout << file.dumpBinary();

View file

@ -7,7 +7,7 @@
#include "ImagePrimitives.h" #include "ImagePrimitives.h"
#include "TestFramework.h" #include "TestFramework.h"
#include "TestUtils.h"
#include <iostream> #include <iostream>
TEST_CASE(TestCompressedPng, "image") TEST_CASE(TestCompressedPng, "image")
@ -29,20 +29,18 @@ TEST_CASE(TestCompressedPng, "image")
image->setData(data); image->setData(data);
PngWriter writer; PngWriter writer;
writer.setPath("test_compressed.png"); writer.setPath(TestUtils::getTestOutputDir() / "test_compressed.png");
writer.setCompressionMethod(Deflate::CompressionMethod::NONE); writer.setCompressionMethod(Deflate::CompressionMethod::NONE);
writer.write(image); writer.write(image);
return; return;
File test_file("test_compressed.png"); File test_file(TestUtils::getTestOutputDir() / "test_compressed.png");
test_file.SetAccessMode(File::AccessMode::Read); test_file.open(File::AccessMode::Read);
test_file.Open(true);
while(auto byte = test_file.readNextByte()) while(auto byte = test_file.readNextByte())
{ {
//std::cout << static_cast<unsigned>(*byte) << std::endl; //std::cout << static_cast<unsigned>(*byte) << std::endl;
} }
test_file.Close();
} }
TEST_CASE(TestFixedPng, "image") TEST_CASE(TestFixedPng, "image")
@ -65,12 +63,12 @@ TEST_CASE(TestFixedPng, "image")
image->setData(data); image->setData(data);
PngWriter writer; PngWriter writer;
writer.setPath("test_fixed.png"); writer.setPath(TestUtils::getTestOutputDir() / "test_fixed.png");
writer.setCompressionMethod(Deflate::CompressionMethod::FIXED_HUFFMAN); writer.setCompressionMethod(Deflate::CompressionMethod::FIXED_HUFFMAN);
writer.write(image); writer.write(image);
//return; //return;
File test_file("test_fixed.png"); File test_file(TestUtils::getTestOutputDir() / "test_fixed.png");
//std::cout << test_file.dumpBinary(); //std::cout << test_file.dumpBinary();
} }
@ -95,10 +93,10 @@ TEST_CASE(TestDynamicCompressedPng, "image")
image->setData(data); image->setData(data);
PngWriter writer; PngWriter writer;
writer.setPath("test_dynamic.png"); writer.setPath(TestUtils::getTestOutputDir() / "test_dynamic.png");
writer.write(image); writer.write(image);
//return; //return;
File test_file("test_dynamic.png"); File test_file(TestUtils::getTestOutputDir() / "test_dynamic.png");
//std::cout << test_file.dumpBinary(); //std::cout << test_file.dumpBinary();
} }

View file

@ -4,6 +4,7 @@
#include "File.h" #include "File.h"
#include "TestFramework.h" #include "TestFramework.h"
#include "TestUtils.h"
TEST_CASE(TestPdfWriter, "publishing") TEST_CASE(TestPdfWriter, "publishing")
{ {
@ -12,8 +13,7 @@ TEST_CASE(TestPdfWriter, "publishing")
PdfWriter writer; PdfWriter writer;
const auto output = writer.ToString(document); const auto output = writer.ToString(document);
File pdf_file("TestPdfWriter.pdf"); File pdf_file(TestUtils::getTestOutputDir() / "TestPdfWriter.pdf");
pdf_file.SetAccessMode(File::AccessMode::Write); pdf_file.open(File::AccessMode::Write);
pdf_file.Open(); pdf_file.writeText(output);
pdf_file.WriteText(output);
} }

View file

@ -0,0 +1,19 @@
#pragma once
#include <filesystem>
using Path = std::filesystem::path;
class TestUtils
{
public:
static Path getTestOutputDir()
{
return std::filesystem::current_path() / "test_output";
}
static Path getTestDataDir()
{
return std::filesystem::current_path() / "test_data";
}
};

View file

@ -2,24 +2,22 @@
#include "Image.h" #include "Image.h"
#include "FfmpegInterface.h" #include "FfmpegInterface.h"
#include "PngWriter.h" #include "PngWriter.h"
#include <iostream>
#include "TestFramework.h" #include "TestFramework.h"
TEST_CASE(TestVideoDecoder, "video") TEST_CASE(TestVideoDecoder, "video")
{ {
auto video = Video::Create(); auto video = Video::Create();
video->SetPath("/home/jmsgrogan/test.mp4"); video->SetPath(TestUtils::getTestDataDir() / "test.mp4");
FfmpegInterface decoder; FfmpegInterface decoder;
auto images = decoder.decodeToImages(video, 4); auto images = decoder.decodeToImages(video, 4);
std::cout << "Got " << std::to_string(images.size()) << std::endl;
PngWriter writer; PngWriter writer;
for(unsigned idx=0; idx<20; idx++) for(unsigned idx=0; idx<20; idx++)
{ {
auto filename = "test_out" + std::to_string(idx) + ".png"; auto filename = "test_out" + std::to_string(idx) + ".png";
writer.SetPath(filename); writer.setPath(filename);
writer.Write(images[idx]); writer.write(images[idx]);
} }
} }

View file

@ -3,23 +3,21 @@
#include "HtmlWriter.h" #include "HtmlWriter.h"
#include "TestFramework.h" #include "TestFramework.h"
#include "TestUtils.h"
TEST_CASE(TestMarkdownParser, "web") TEST_CASE(TestMarkdownParser, "web")
{ {
File md_file("/home/jmsgrogan/code/MediaTool/test/data/sample_markdown.md"); File md_file(TestUtils::getTestDataDir() / "sample_markdown.md");
md_file.Open(); const auto md_content = md_file.readText();
const auto md_content = md_file.ReadText();
MarkdownParser parser; MarkdownParser parser;
parser.Run(md_content); parser.run(md_content);
auto html = parser.GetHtml(); auto html = parser.getHtml();
HtmlWriter writer; HtmlWriter writer;
const auto html_string = writer.ToString(html); const auto html_string = writer.ToString(html);
File html_file("TestMarkdownParserOut.html"); File html_file(TestUtils::getTestOutputDir() / "TestMarkdownParserOut.html");
html_file.SetAccessMode(File::AccessMode::Write); html_file.writeText(html_string);
html_file.Open();
html_file.WriteText(html_string);
} }

View file

@ -6,13 +6,14 @@
#include "File.h" #include "File.h"
#include "TestFramework.h" #include "TestFramework.h"
#include "TestUtils.h"
TEST_CASE(TestXmlParser, "web") TEST_CASE(TestXmlParser, "web")
{ {
XmlParser parser; XmlParser parser;
std::ifstream xml_file; std::ifstream xml_file;
xml_file.open("/home/jmsgrogan/test.xml", std::ifstream::in); xml_file.open(TestUtils::getTestDataDir() / "test.xml", std::ifstream::in);
while(xml_file.good()) while(xml_file.good())
{ {
std::string line; std::string line;
@ -21,11 +22,9 @@ TEST_CASE(TestXmlParser, "web")
} }
xml_file.close(); xml_file.close();
auto outFile = std::make_unique<File>("test_out.xml");
outFile->SetAccessMode(File::AccessMode::Write);
outFile->Open();
XmlWriter writer; XmlWriter writer;
auto content = writer.ToString(parser.GetDocument().get()); auto content = writer.ToString(parser.GetDocument().get());
outFile->WriteText(content);
auto outFile = std::make_unique<File>(TestUtils::getTestOutputDir() / "test_out.xml");
outFile->writeText(content);
} }