diff --git a/inputsource.cpp b/inputsource.cpp index 1fea732..24d182b 100644 --- a/inputsource.cpp +++ b/inputsource.cpp @@ -27,31 +27,60 @@ #include -InputSource::InputSource(const char *filename) +InputSource::InputSource() { - m_file = fopen(filename, "rb"); - if (m_file == nullptr) - throw std::runtime_error("Error opening file"); - - struct stat sb; - if (fstat(fileno(m_file), &sb) != 0) - throw std::runtime_error("Error fstating file"); - m_file_size = sb.st_size; - sampleCount = m_file_size / sizeof(std::complex); - - m_data = (std::complex*)mmap(NULL, m_file_size, PROT_READ, MAP_SHARED, fileno(m_file), 0); - if (m_data == 0) - throw std::runtime_error("Error mmapping file"); } InputSource::~InputSource() { - munmap(m_data, m_file_size); - fclose(m_file); + cleanup(); +} + +void InputSource::cleanup() +{ + if (mmapData != nullptr) { + munmap(mmapData, fileSize); + mmapData = nullptr; + fileSize = 0; + } + + if (inputFile != nullptr) { + fclose(inputFile); + inputFile = nullptr; + } +} + +void InputSource::openFile(const char *filename) +{ + FILE *file = fopen(filename, "rb"); + if (file == nullptr) + throw std::runtime_error("Error opening file"); + + struct stat sb; + if (fstat(fileno(file), &sb) != 0) + throw std::runtime_error("Error fstating file"); + off_t size = sb.st_size; + sampleCount = size / sizeof(std::complex); + + auto data = (std::complex*)mmap(NULL, size, PROT_READ, MAP_SHARED, fileno(file), 0); + if (data == nullptr) + throw std::runtime_error("Error mmapping file"); + + cleanup(); + + inputFile = file; + fileSize = size; + mmapData = data; } std::unique_ptr[]> InputSource::getSamples(off_t start, off_t length) { + if (inputFile == nullptr) + return nullptr; + + if (mmapData == nullptr) + return nullptr; + if(start < 0 || length < 0) return nullptr; @@ -59,6 +88,6 @@ std::unique_ptr[]> InputSource::getSamples(off_t start, off_ return nullptr; std::unique_ptr[]> dest(new std::complex[length]); - memcpy(dest.get(), &m_data[start], length * sizeof(std::complex)); + memcpy(dest.get(), &mmapData[start], length * sizeof(std::complex)); return dest; } diff --git a/inputsource.h b/inputsource.h index ea31e1e..75feeac 100644 --- a/inputsource.h +++ b/inputsource.h @@ -25,15 +25,16 @@ class InputSource : public SampleSource> { private: - FILE *m_file; - off_t m_file_size; - off_t sampleCount; - std::complex *m_data; + FILE *inputFile = nullptr; + off_t fileSize = 0; + off_t sampleCount = 0; + std::complex *mmapData = nullptr; public: - InputSource(const char *filename); + InputSource(); ~InputSource(); - + void cleanup(); + void openFile(const char *filename); std::unique_ptr[]> getSamples(off_t start, off_t length); off_t count() { return sampleCount; diff --git a/mainwindow.cpp b/mainwindow.cpp index f7eda87..7535212 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -31,7 +31,9 @@ MainWindow::MainWindow() dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); addDockWidget(Qt::LeftDockWidgetArea, dock); - plots = new PlotView(); + InputSource *input = new InputSource(); + + plots = new PlotView(input); setCentralWidget(plots); connect(dock, SIGNAL(fftSizeChanged(int)), plots, SLOT(setFFTSize(int))); @@ -43,6 +45,5 @@ void MainWindow::openFile(QString fileName) { QString title="%1: %2"; this->setWindowTitle(title.arg(QApplication::applicationName(),fileName.section('/',-1,-1))); - // TODO: error check, ownership - plots->inputSourceChanged(new InputSource(fileName.toUtf8().constData())); + // TODO: open a file again } diff --git a/plotview.cpp b/plotview.cpp index cabad05..a0a0582 100644 --- a/plotview.cpp +++ b/plotview.cpp @@ -31,8 +31,9 @@ #include "memory_source.h" #include "traceplot.h" -PlotView::PlotView() : cursors(this), viewRange({0, 0}) +PlotView::PlotView(InputSource *input) : cursors(this), viewRange({0, 0}) { + mainSampleSource = input; setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); enableCursors(false); } diff --git a/plotview.h b/plotview.h index 3c0e3a6..6f6a6c0 100644 --- a/plotview.h +++ b/plotview.h @@ -32,7 +32,7 @@ class PlotView : public QAbstractScrollArea Q_OBJECT public: - PlotView(); + PlotView(InputSource *input); public slots: void enableCursors(bool enable);