vega
tag_mask.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "vega/vega.h"
4 #include "vega/tag.h"
5 #include "vega/math.h"
6 
7 #include <tuple>
8 #include <algorithm>
9 
10 namespace vega {
11  class TagMask {
12  private:
13  Tag m_value_tag;
14  Tag m_mask_tag;
15 
16  public:
17  // Format (40xx,xxab)
18  // => group_value = 0x4000, group_mask = 0xFF00
19  // => element_value = 0x00ab, element_mask = 0x00FF
20  explicit TagMask(const std::string& group_, const std::string& element_)
21  :
22  m_value_tag(0),
23  m_mask_tag(0)
24  {
25  if (group_.size() != 4 || element_.size() != 4) {
26  throw vega::Exception("Invalid group/element in TagMask: " + group_ + ", " + element_);
27  }
28 
29  std::string group(group_);
30  std::transform(group.begin(), group.end(), group.begin(), ::tolower);
31  std::string element(element_);
32  std::transform(element.begin(), element.end(), element.begin(), ::tolower);
33 
34  char c;
35  uint8_t digit;
36 
37  // Group
38  for (int i = 0; i < 4; ++i) {
39  c = group[3-i];
40  if (c != 'x') {
41  m_mask_tag.group() |= (0xF << 4*i);
42 
43  if (c >= '0' && c <= '9') {
44  digit = (c - '0');
45  }
46  else {
47  digit = 10 + (c - 'a');
48  }
49 
50  m_value_tag.group() |= (digit << 4*i);
51  }
52  }
53 
54  // Element
55  for (int i = 0; i < 4; ++i) {
56  c = element[3-i];
57  if (c != 'x') {
58  m_mask_tag.element() |= (0xF << 4*i);
59 
60  if (c >= '0' && c <= '9') {
61  digit = (c - '0');
62  }
63  else {
64  digit = 10 + (c - 'a');
65  }
66 
67  m_value_tag.element() |= (digit << 4*i);
68  }
69  }
70  }
71 
72  explicit constexpr TagMask(const Tag::group_type& group_value, const Tag::group_type& group_mask, const Tag::element_type& element_value, const Tag::element_type& element_mask)
73  :
74  m_value_tag(group_value, element_value),
75  m_mask_tag(group_mask, element_mask)
76  {}
77 
78  const Tag& value_tag() const { return m_value_tag; }
79  const Tag& mask_tag() const { return m_mask_tag; }
80 
81  bool is_single() const { return m_mask_tag.tag() == 0xFFFFFFFF; }
82  const Tag& singular_tag() const {
83  if (!this->is_single()) throw vega::Exception("Cannot get singular tag from TagMask with value and mask of " + this->value_tag().str() + " and " + this->mask_tag().str());
84  return this->value_tag();
85  }
86 
87  unsigned mask_popcount() const { return math::popcount(this->mask_tag().tag()); }
88 
89  bool operator==(const TagMask& other) const { return this->value_tag() == other.value_tag() && this->mask_tag() == other.mask_tag(); }
90  bool operator!=(const TagMask& other) const { return !(*this == other); }
91  bool operator<(const TagMask& other) const {
92  return std::tie(this->value_tag(), this->mask_tag()) < std::tie(other.value_tag(), other.mask_tag());
93  }
94 
95  // Group = 28xx =>
96  // group_value = 2800
97  // group_mask = FF00
98  //
99  // So a group of 28ab would pass the check in this case because
100  // 28ab & FF00 == 2800 which is the same as group_value
101  //
102  // Group = 1234 =>
103  // group_value = 1234
104  // group_mask = FFFF
105  //
106  // Group = xxx0 =>
107  // group_value = 0000
108  // group_mask = 000F
109  bool contains(const Tag& tag) const {
110  return (tag.tag() & this->mask_tag().tag()) == this->value_tag().tag();
111  }
112  };
113 }
uint16_t element_type
Definition: tag.h:18
bool operator!=(const TagMask &other) const
Definition: tag_mask.h:90
const Tag & value_tag() const
Definition: tag_mask.h:78
tag_type tag() const
bool operator==(const TagMask &other) const
Definition: tag_mask.h:89
bool is_single() const
Definition: tag_mask.h:81
bool operator<(const TagMask &other) const
Definition: tag_mask.h:91
constexpr TagMask(const Tag::group_type &group_value, const Tag::group_type &group_mask, const Tag::element_type &element_value, const Tag::element_type &element_mask)
Definition: tag_mask.h:72
const group_type & group() const
const Tag & singular_tag() const
Definition: tag_mask.h:82
The base class for exceptions that are raised by the vega library.
Definition: vega.h:11
bool contains(const Tag &tag) const
Definition: tag_mask.h:109
TagMask(const std::string &group_, const std::string &element_)
Definition: tag_mask.h:20
unsigned popcount(uint64_t x)
Definition: tag_mask.h:11
Definition: age.h:6
const element_type & element() const
uint16_t group_type
Definition: tag.h:17
Class for working with DICOM data element tags.
Definition: tag.h:15
const Tag & mask_tag() const
Definition: tag_mask.h:79
unsigned mask_popcount() const
Definition: tag_mask.h:87