PulseView  unreleased development snapshot
A Qt-based sigrok GUI
inputfile.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the PulseView project.
3  *
4  * Copyright (C) 2015 Joel Holdsworth <joel@airwebreathe.org.uk>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include <cassert>
21 #include <fstream>
22 #include <vector>
23 
24 #include <QDebug>
25 #include <QString>
26 
27 #include <pv/globalsettings.hpp>
28 
29 #include "inputfile.hpp"
30 
31 using sigrok::InputFormat;
32 
33 using std::map;
34 using std::out_of_range;
35 using std::pair;
36 using std::shared_ptr;
37 using std::streamsize;
38 using std::string;
39 using std::ifstream;
40 using std::ios;
41 using std::vector;
42 
43 namespace pv {
44 namespace devices {
45 
46 // Use a 4MB chunk size for reading a file into memory. Larger values don't
47 // seem to provide any substancial performance improvements, but can cause
48 // UI lag and a visually "stuttering" display of the data currently loading.
49 const streamsize InputFile::BufferSize = (4 * 1024 * 1024);
50 
51 InputFile::InputFile(const shared_ptr<sigrok::Context> &context,
52  const string &file_name,
53  shared_ptr<sigrok::InputFormat> format,
54  const map<string, Glib::VariantBase> &options) :
55  File(file_name),
56  context_(context),
57  format_(format),
58  options_(options),
59  interrupt_(false)
60 {
61 }
62 
63 InputFile::InputFile(const shared_ptr<sigrok::Context> &context,
64  QSettings &settings):
65  File(""),
66  context_(context),
67  interrupt_(false)
68 {
69  file_name_ = settings.value("filename").toString().toStdString();
70 
71  QString format_name = settings.value("format").toString();
72 
73  // Find matching format
74  const map<string, shared_ptr<InputFormat> > formats = context->input_formats();
75 
76  try {
77  format_ = formats.at(format_name.toStdString());
78 
79  // Restore all saved options
80  int options = settings.value("options").toInt();
81 
82  for (int i = 0; i < options; i++) {
83  settings.beginGroup("option" + QString::number(i));
84  QString name = settings.value("name").toString();
85  options_[name.toStdString()] = GlobalSettings::restore_variantbase(settings);
86  settings.endGroup();
87  }
88 
89  } catch (out_of_range&) {
90  qWarning() << "Could not find input format" << format_name <<
91  "needed to restore session input file";
92  }
93 }
94 
96 {
97  settings.setValue("filename", QString::fromStdString(file_name_));
98 
99  settings.setValue("format", QString::fromStdString(format_->name()));
100 
101  settings.setValue("options", (int)options_.size());
102 
103  int i = 0;
104  for (const pair<const string, Glib::VariantBase>& option : options_) {
105  settings.beginGroup("option" + QString::number(i));
106  settings.setValue("name", QString::fromStdString(option.first));
107  GlobalSettings::store_variantbase(settings, option.second);
108  settings.endGroup();
109  i++;
110  }
111 }
112 
114 {
115  if (session_)
116  close();
117  else
118  session_ = context_->create_session();
119 
120  if (!format_)
121  return;
122 
123  input_ = format_->create_input(options_);
124 
125  if (!input_)
126  throw QString("Failed to create input");
127 
128  // open() should add the input device to the session but
129  // we can't open the device without sending some data first
130  f = new ifstream(file_name_, ios::binary);
131 
132  vector<char> buffer(BufferSize);
133 
134  f->read(buffer.data(), BufferSize);
135  const streamsize size = f->gcount();
136 
137  if (size == 0)
138  throw QString("Failed to read file");
139 
140  input_->send(buffer.data(), size);
141 
142  try {
143  device_ = input_->device();
144  } catch (sigrok::Error& e) {
145  throw e;
146  }
147 
148  session_->add_device(device_);
149 }
150 
152 {
153  if (session_)
154  session_->remove_devices();
155 }
156 
158 {
159 }
160 
162 {
163  if (!input_)
164  return;
165 
166  if (!f) {
167  // Previous call to run() processed the entire file already
168  f = new ifstream(file_name_, ios::binary);
169  input_->reset();
170  }
171 
172  vector<char> buffer(BufferSize);
173 
174  interrupt_ = false;
175  while (!interrupt_ && !f->eof()) {
176  f->read(buffer.data(), BufferSize);
177  const streamsize size = f->gcount();
178  if (size == 0)
179  break;
180 
181  input_->send(buffer.data(), size);
182 
183  if (size != BufferSize)
184  break;
185  }
186 
187  input_->end();
188 
189  delete f;
190  f = nullptr;
191 }
192 
194 {
195  interrupt_ = true;
196 }
197 
198 } // namespace devices
199 } // namespace pv
libsigrok allows users to import and export data from files in various formats some of them as generic as others very specific For a list and make sure to check not so common and outright exotic ways to represent data and sigrok tries to suit as many needs as it can To see which formats your version of PulseView just click on the small arrow next to the _Open_ PulseView will ask for the file name to open Once you picked the you may be asked to specify the details of the format
map< string, Glib::VariantBase > options_
Definition: inputfile.hpp:74
InputFile(const shared_ptr< sigrok::Context > &context, const string &file_name, shared_ptr< sigrok::InputFormat > format, const map< string, Glib::VariantBase > &options)
Definition: inputfile.cpp:51
CMake option(DISABLE_WERROR"Build without -Werror"TRUE) option(ENABLE_SIGNALS"Build with UNIX signals"TRUE) option(ENABLE_STACKTRACE"Enable stack trace when crashing"FALSE) option(ENABLE_DECODE"Build with libsigrokdecode"TRUE) option(ENABLE_FLOW"Build with libsigrokflow"FALSE) option(ENABLE_TESTS"Enable unit tests"FALSE) option(STATIC_PKGDEPS_LIBS"Statically link to (pkg-config) libraries"FALSE) option(ENABLE_TS_UPDATE"Update .ts source files (Qt l10n)"FALSE) if(WIN32) set(STATIC_PKGDEPS_LIBS TRUE) set(ENABLE_SIGNALS FALSE) endif() if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING"Choose the type of build (None
shared_ptr< sigrok::Input > input_
Definition: inputfile.hpp:75
void save_meta_to_settings(QSettings &settings)
Definition: inputfile.cpp:95
Mac OS X or Android For some we provide binary for others we provide installers and for others we provide AppImage containers that you can run without the need to install anything Check the the usual way to install PulseView is to install the packages provided by your distro s package manager sometimes only outdated packages are made available to you In that you have two options
Definition: installation.txt:2
shared_ptr< sigrok::Session > session_
Definition: device.hpp:80
shared_ptr< sigrok::InputFormat > format_
Definition: inputfile.hpp:73
static Glib::VariantBase restore_variantbase(QSettings &settings)
shared_ptr< sigrok::Device > device_
Definition: device.hpp:81
string file_name_
Definition: file.hpp:49
static const streamsize BufferSize
Definition: inputfile.hpp:44
atomic< bool > interrupt_
Definition: inputfile.hpp:78
static void store_variantbase(QSettings &settings, Glib::VariantBase v)
const shared_ptr< sigrok::Context > context_
Definition: inputfile.hpp:72