]> sigrok.org Git - pulseview.git/blobdiff - pv/data/decode/rowdata.cpp
Fix compile issues with some compiler versions
[pulseview.git] / pv / data / decode / rowdata.cpp
index a06af6169a9803997dd2e2b4d130f3c85e471b3c..3d250f49472eb03194d1001c6dd693c2ef644ae2 100644 (file)
  * 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 <http://www.gnu.org/licenses/>.
  */
 
-#include <boost/bind.hpp>
+#include <cassert>
 
-#include <assert.h>
-
-#include "rowdata.h"
+#include <pv/data/decode/decoder.hpp>
+#include <pv/data/decode/row.hpp>
+#include <pv/data/decode/rowdata.hpp>
 
 using std::vector;
 
@@ -30,89 +29,131 @@ namespace pv {
 namespace data {
 namespace decode {
 
-RowData::RowData()
+RowData::RowData(Row* row) :
+       row_(row),
+       prev_ann_start_sample_(0)
 {
+       assert(row);
 }
 
-uint64_t RowData::get_max_sample() const
+const Row* RowData::row() const
 {
-       if (_annotations.empty())
-               return 0;
-       return _annotations.back().end_sample();
+       return row_;
 }
 
-void RowData::get_annotation_subset(
-       std::vector<pv::data::decode::Annotation> &dest,
-       uint64_t start_sample, uint64_t end_sample) const
+uint64_t RowData::get_max_sample() const
 {
-       const vector<size_t>::const_iterator start_iter =
-               lower_bound(_ann_end_index.begin(),
-                       _ann_end_index.end(), start_sample,
-                       bind(&RowData::index_entry_end_sample_lt,
-                               this, _1, _2));
-
-       const vector<size_t>::const_iterator end_iter =
-               upper_bound(_ann_start_index.begin(),
-                       _ann_start_index.end(), end_sample,
-                       bind(&RowData::index_entry_start_sample_gt,
-                               this, _1, _2));
-
-       for (vector<size_t>::const_iterator i = start_iter;
-               i != _ann_end_index.end() && *i != *end_iter; i++)
-               dest.push_back(_annotations[*i]);
+       if (annotations_.empty())
+               return 0;
+       return annotations_.back().end_sample();
 }
 
-void RowData::push_annotation(const Annotation &a)
+uint64_t RowData::get_annotation_count() const
 {
-       const size_t offset = _annotations.size();
-       _annotations.push_back(a);
-
-       // Insert the annotation into the start index
-       vector<size_t>::iterator i = _ann_start_index.end();
-       if (!_ann_start_index.empty() &&
-               _annotations[_ann_start_index.back()].start_sample() >
-                       a.start_sample())
-               i = upper_bound(_ann_start_index.begin(),
-                       _ann_start_index.end(), a.start_sample(),
-                       bind(&RowData::index_entry_start_sample_gt,
-                               this, _1, _2));
-
-       _ann_start_index.insert(i, offset);
-
-       // Insert the annotation into the end index
-       vector<size_t>::iterator j = _ann_end_index.end();
-       if (!_ann_end_index.empty() &&
-               _annotations[_ann_end_index.back()].end_sample() <
-                       a.end_sample())
-               j = upper_bound(_ann_end_index.begin(),
-                       _ann_end_index.end(), a.end_sample(),
-                       bind(&RowData::index_entry_end_sample_gt,
-                               this, _1, _2));
-
-       _ann_end_index.insert(j, offset);
+       return annotations_.size();
 }
 
-bool RowData::index_entry_start_sample_gt(
-       const uint64_t sample, const size_t index) const
+void RowData::get_annotation_subset(
+       deque<const pv::data::decode::Annotation*> &dest,
+       uint64_t start_sample, uint64_t end_sample) const
 {
-       assert(index < _annotations.size());
-       return _annotations[index].start_sample() > sample;
+       // Determine whether we must apply per-class filtering or not
+       bool all_ann_classes_enabled = true;
+       bool all_ann_classes_disabled = true;
+
+       uint32_t max_ann_class_id = 0;
+       for (AnnotationClass* c : row_->ann_classes()) {
+               if (!c->visible())
+                       all_ann_classes_enabled = false;
+               else
+                       all_ann_classes_disabled = false;
+               if (c->id > max_ann_class_id)
+                       max_ann_class_id = c->id;
+       }
+
+       if (all_ann_classes_enabled) {
+               // No filtering, send everyting out as-is
+               for (const auto& annotation : annotations_)
+                       if ((annotation.end_sample() > start_sample) &&
+                               (annotation.start_sample() <= end_sample))
+                               dest.push_back(&annotation);
+       } else {
+               if (!all_ann_classes_disabled) {
+                       // Filter out invisible annotation classes
+                       vector<size_t> class_visible;
+                       class_visible.resize(max_ann_class_id + 1, 0);
+                       for (AnnotationClass* c : row_->ann_classes())
+                               if (c->visible())
+                                       class_visible[c->id] = 1;
+
+                       for (const auto& annotation : annotations_)
+                               if ((class_visible[annotation.ann_class_id()]) &&
+                                       (annotation.end_sample() > start_sample) &&
+                                       (annotation.start_sample() <= end_sample))
+                                       dest.push_back(&annotation);
+               }
+       }
 }
 
-bool RowData::index_entry_end_sample_lt(
-       const size_t index, const uint64_t sample) const
+const deque<Annotation>& RowData::annotations() const
 {
-       assert(index < _annotations.size());
-       return _annotations[index].end_sample() < sample;
+       return annotations_;
 }
 
-bool RowData::index_entry_end_sample_gt(
-       const uint64_t sample, const size_t index) const
+const Annotation* RowData::emplace_annotation(srd_proto_data *pdata)
 {
-       assert(index < _annotations.size());
-       return _annotations[index].end_sample() > sample;
+       const srd_proto_data_annotation *const pda = (const srd_proto_data_annotation*)pdata->data;
+
+       uint32_t ann_class_id = pda->ann_class;
+
+       // Look up the longest annotation text to see if we have it in storage.
+       // This implies that if the longest text is the same, the shorter texts
+       // are expected to be the same, too. PDs that violate this assumption
+       // should be considered broken.
+       const char* const* ann_texts = (char**)pda->ann_text;
+       const QString ann0 = QString::fromUtf8(ann_texts[0]);
+       vector<QString>* storage_entry = &(ann_texts_[ann0]);
+
+       if (storage_entry->empty()) {
+               while (*ann_texts) {
+                       storage_entry->emplace_back(QString::fromUtf8(*ann_texts));
+                       ann_texts++;
+               }
+               storage_entry->shrink_to_fit();
+       }
+
+
+       const Annotation* result = nullptr;
+
+       // We insert the annotation in a way so that the annotation list
+       // is sorted by start sample. Otherwise, we'd have to sort when
+       // painting, which is expensive
+
+       if (pdata->start_sample < prev_ann_start_sample_) {
+               // Find location to insert the annotation at
+
+               auto it = annotations_.end();
+               do {
+                       it--;
+               } while ((it->start_sample() > pdata->start_sample) && (it != annotations_.begin()));
+
+               // Allow inserting at the front
+               if (it != annotations_.begin())
+                       it++;
+
+               it = annotations_.emplace(it, pdata->start_sample, pdata->end_sample,
+                       storage_entry, ann_class_id, this);
+               result = &(*it);
+       } else {
+               annotations_.emplace_back(pdata->start_sample, pdata->end_sample,
+                       storage_entry, ann_class_id, this);
+               result = &(annotations_.back());
+               prev_ann_start_sample_ = pdata->start_sample;
+       }
+
+       return result;
 }
 
-} // decode
-} // data
-} // pv
+}  // namespace decode
+}  // namespace data
+}  // namespace pv