X-Git-Url: http://git.code-monkey.de/?p=pulseview.git;a=blobdiff_plain;f=pv%2Fdevices%2Finputfile.cpp;h=94fb9c82cb6d4df2e2a47d261ff8220bb471ad3e;hp=13af3db9cd85c791935da6c80bf1a14220d492a0;hb=f4ab4b5c657e5613caba82feaa81a8a400e4f331;hpb=4d6c6ea3e6b069787c270d4911083dae05eae4c6 diff --git a/pv/devices/inputfile.cpp b/pv/devices/inputfile.cpp index 13af3db..94fb9c8 100644 --- a/pv/devices/inputfile.cpp +++ b/pv/devices/inputfile.cpp @@ -14,85 +14,184 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * along with this program; if not, see . */ #include #include +#include +#include #include +#include + #include "inputfile.hpp" +using sigrok::InputFormat; + +using std::map; +using std::out_of_range; +using std::pair; +using std::shared_ptr; +using std::streamsize; +using std::string; +using std::ifstream; +using std::ios; +using std::vector; + namespace pv { namespace devices { -const std::streamsize InputFile::BufferSize = 16384; +// Use a 4MB chunk size for reading a file into memory. Larger values don't +// seem to provide any substancial performance improvements, but can cause +// UI lag and a visually "stuttering" display of the data currently loading. +const streamsize InputFile::BufferSize = (4 * 1024 * 1024); -InputFile::InputFile(const std::shared_ptr &context, - const std::string &file_name, - std::shared_ptr format, - const std::map &options) : +InputFile::InputFile(const shared_ptr &context, + const string &file_name, + shared_ptr format, + const map &options) : File(file_name), context_(context), - input_(format->create_input(options)), - interrupt_(false) { - if (!input_) - throw QString("Failed to create input"); + format_(format), + options_(options), + interrupt_(false) +{ } -void InputFile::open() { +InputFile::InputFile(const shared_ptr &context, + QSettings &settings): + File(""), + context_(context), + interrupt_(false) +{ + file_name_ = settings.value("filename").toString().toStdString(); + + QString format_name = settings.value("format").toString(); + + // Find matching format + const map > formats = context->input_formats(); + + try { + format_ = formats.at(format_name.toStdString()); + + // Restore all saved options + int options = settings.value("options").toInt(); + + for (int i = 0; i < options; i++) { + settings.beginGroup("option" + QString::number(i)); + QString name = settings.value("name").toString(); + options_[name.toStdString()] = GlobalSettings::restore_variantbase(settings); + settings.endGroup(); + } + + } catch (out_of_range&) { + qWarning() << "Could not find input format" << format_name << + "needed to restore session input file"; + } +} + +void InputFile::save_meta_to_settings(QSettings &settings) +{ + settings.setValue("filename", QString::fromStdString(file_name_)); + + settings.setValue("format", QString::fromStdString(format_->name())); + + settings.setValue("options", (int)options_.size()); + + int i = 0; + for (const pair& option : options_) { + settings.beginGroup("option" + QString::number(i)); + settings.setValue("name", QString::fromStdString(option.first)); + GlobalSettings::store_variantbase(settings, option.second); + settings.endGroup(); + i++; + } +} + +void InputFile::open() +{ if (session_) close(); + else + session_ = context_->create_session(); + + if (!format_) + return; + + 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 ifstream(file_name_, ios::binary); + + vector buffer(BufferSize); + + f->read(buffer.data(), BufferSize); + const streamsize size = f->gcount(); + + if (size == 0) + throw QString("Failed to read file"); - session_ = context_->create_session(); + input_->send(buffer.data(), size); + + try { + device_ = input_->device(); + } catch (sigrok::Error& e) { + throw e; + } + + session_->add_device(device_); } -void InputFile::close() { +void InputFile::close() +{ if (session_) session_->remove_devices(); } -void InputFile::start() { +void InputFile::start() +{ } -void InputFile::run() { - char buffer[BufferSize]; - bool need_device = true; +void InputFile::run() +{ + if (!input_) + return; + + if (!f) { + // Previous call to run() processed the entire file already + f = new ifstream(file_name_, ios::binary); + input_->reset(); + } - assert(session_); - assert(input_); + vector buffer(BufferSize); interrupt_ = false; - std::ifstream f(file_name_); - while (!interrupt_ && f) { - f.read(buffer, BufferSize); - const std::streamsize size = f.gcount(); + while (!interrupt_ && !f->eof()) { + f->read(buffer.data(), BufferSize); + const streamsize size = f->gcount(); if (size == 0) break; - input_->send(buffer, size); - - if (need_device) { - try { - device_ = input_->device(); - } catch (sigrok::Error) { - break; - } - - session_->add_device(device_); - need_device = false; - } + input_->send(buffer.data(), size); if (size != BufferSize) break; } input_->end(); + + delete f; + f = nullptr; } -void InputFile::stop() { +void InputFile::stop() +{ interrupt_ = true; }