From cda515676ce6c2fa81e1cecacba3ea26ec2ee50e Mon Sep 17 00:00:00 2001 From: Soeren Apel Date: Mon, 2 May 2016 22:22:39 +0200 Subject: [PATCH] InputFile: Use new reset() function to allow re-reading file Commit 519d0ccbe67d005a9c442795ce3b8255e78ca46d tried to solve the problem of being unable to re-read an opened file by clicking the "run" button. However, the solution is insufficient. PV expects the session device to be updated after the open() call. If it is not, the device settings popup will show the settings of the previously used device. This patch fixes this and also makes use of the new reset() method to allow re-reading of the file contents. The method is necessary because otherwise we have to destroy the input module and create a new instance. This however also means setting a new session device, which is highly undesirable. So reset() it is. --- pv/devices/inputfile.cpp | 59 ++++++++++++++++++++++++---------------- pv/devices/inputfile.hpp | 1 + 2 files changed, 37 insertions(+), 23 deletions(-) diff --git a/pv/devices/inputfile.cpp b/pv/devices/inputfile.cpp index 935b0c47..c30bcd33 100644 --- a/pv/devices/inputfile.cpp +++ b/pv/devices/inputfile.cpp @@ -48,6 +48,31 @@ void InputFile::open() close(); else session_ = context_->create_session(); + + input_ = format_->create_input(options_); + + if (!input_) + throw QString("Failed to create input"); + + // open() should add the input device to the session but + // we can't open the device without sending some data first + f = new std::ifstream(file_name_, std::ios::binary); + + char buffer[BufferSize]; + f->read(buffer, BufferSize); + const std::streamsize size = f->gcount(); + if (size == 0) + return; + + input_->send(buffer, size); + + try { + device_ = input_->device(); + } catch (sigrok::Error) { + return; + } + + session_->add_device(device_); } void InputFile::close() @@ -63,42 +88,30 @@ void InputFile::start() void InputFile::run() { char buffer[BufferSize]; - bool need_device = true; - - assert(session_); - input_ = format_->create_input(options_); - - if (!input_) - throw QString("Failed to create input"); + if (!f) { + // Previous call to run() processed the entire file already + f = new std::ifstream(file_name_, std::ios::binary); + input_->reset(); + } interrupt_ = false; - std::ifstream f(file_name_, std::ios::binary); - while (!interrupt_ && f) { - f.read(buffer, BufferSize); - const std::streamsize size = f.gcount(); + while (!interrupt_ && !f->eof()) { + f->read(buffer, BufferSize); + const std::streamsize size = f->gcount(); if (size == 0) break; input_->send(buffer, size); - if (need_device) { - try { - device_ = input_->device(); - } catch (sigrok::Error) { - break; - } - - session_->remove_devices(); // Remove instance from previous run - session_->add_device(device_); - need_device = false; - } - if (size != BufferSize) break; } input_->end(); + + delete f; + f = nullptr; } void InputFile::stop() diff --git a/pv/devices/inputfile.hpp b/pv/devices/inputfile.hpp index 02d4417c..e6b57033 100644 --- a/pv/devices/inputfile.hpp +++ b/pv/devices/inputfile.hpp @@ -57,6 +57,7 @@ private: const std::map options_; std::shared_ptr input_; + std::ifstream *f; std::atomic interrupt_; }; -- 2.30.2