Hash.h
Go to the documentation of this file.
1 #ifndef canvas_Persistency_Provenance_Hash_h
2 #define canvas_Persistency_Provenance_Hash_h
3 // vim: set sw=2 expandtab :
4 
5 // ======================================================================
6 //
7 // Hash:
8 //
9 // Note: The call to 'fixup' in every member function is a temporary
10 // measure for backwards compatibility. It is necessary in every function
11 // because Root creates instances of the class *without* using the
12 // interface of the class, thus making it insufficient to assure that all
13 // constructors make corrected instances.
14 //
15 // ======================================================================
16 
18 #include "cetlib/MD5Digest.h"
20 
21 #include <ostream>
22 #include <string>
23 
24 namespace art {
25 
26  namespace detail {
27  // This string is in the 16 byte (non-printable) representation.
28  std::string const& InvalidHash();
29  } // namespace detail
30 
31  template <int I>
32  class Hash {
33  public:
35 
36  Hash();
37  explicit Hash(std::string const&);
38  Hash(Hash<I> const&);
39  Hash(Hash<I>&&);
40  Hash<I>& operator=(Hash<I> const&);
41  Hash<I>& operator=(Hash<I>&&);
42 
43  // For ROOT
44  static short Class_Version() noexcept;
45 
46  // For now, just check the most basic: a default constructed
47  // ParameterSetID is not valid. This is very crude: we are
48  // assuming that nobody created a ParameterSetID from an empty
49  // string, nor from any string that is not a valid string
50  // representation of an MD5 checksum.
51  bool isValid() const;
52  bool isCompactForm() const noexcept;
53  // Return the 16 byte (non-printable) string form.
54  std::string compactForm() const;
55  bool operator<(Hash<I> const&) const;
56  bool operator>(Hash<I> const&) const;
57  bool operator==(Hash<I> const&) const;
58  bool operator!=(Hash<I> const&) const;
59  std::ostream& print(std::ostream&) const;
60  void swap(Hash<I>&);
61 
62  private:
63  // If hash_ is in the hexified 32 byte representation,
64  // make it be in the 16 byte unhexified representation.
65  void fixup();
66  std::string hash_{};
67  };
68 
69  // MUST UPDATE WHEN CLASS IS CHANGED!
70  template <int I>
71  short
73  {
74  return 10;
75  }
76 
77  template <int I>
79  {
80  fixup();
81  }
82 
83  template <int I>
84  Hash<I>::Hash(std::string const& s) : hash_{s}
85  {
86  fixup();
87  }
88 
89  template <int I>
90  Hash<I>::Hash(Hash<I> const& rhs) : hash_{rhs.hash_}
91  {
92  fixup();
93  }
94 
95  template <int I>
96  Hash<I>::Hash(Hash<I>&& rhs) : hash_{std::move(rhs.hash_)}
97  {
98  fixup();
99  }
100 
101  template <int I>
102  Hash<I>&
104  {
105  if (this != &rhs) {
106  hash_ = rhs.hash_;
107  fixup();
108  }
109  return *this;
110  }
111 
112  template <int I>
113  Hash<I>&
115  {
116  hash_ = std::move(rhs.hash_);
117  fixup();
118  return *this;
119  }
120 
121  template <int I>
122  bool
124  {
125  if (isCompactForm()) {
126  return hash_ != art::detail::InvalidHash();
127  }
128  return !hash_.empty();
129  }
130 
131  template <int I>
132  bool
133  Hash<I>::operator<(Hash<I> const& rhs) const
134  {
135  if (isCompactForm() == rhs.isCompactForm()) {
136  return hash_ < rhs.hash_;
137  }
138  // Force both into compact form.
139  return Hash<I>{*this} < Hash<I>{rhs};
140  }
141 
142  template <int I>
143  bool
144  Hash<I>::operator>(Hash<I> const& rhs) const
145  {
146  if (isCompactForm() == rhs.isCompactForm()) {
147  return hash_ > rhs.hash_;
148  }
149  // Force both into compact form.
150  return Hash<I>{*this} > Hash<I>{rhs};
151  }
152 
153  template <int I>
154  bool
155  Hash<I>::operator==(Hash<I> const& rhs) const
156  {
157  if (isCompactForm() == rhs.isCompactForm()) {
158  return hash_ == rhs.hash_;
159  }
160  // Force both into compact form.
161  return Hash<I>{*this} == Hash<I>{rhs};
162  }
163 
164  template <int I>
165  bool
166  Hash<I>::operator!=(Hash<I> const& rhs) const
167  {
168  if (isCompactForm() == rhs.isCompactForm()) {
169  return hash_ != rhs.hash_;
170  }
171  // Force both into compact form.
172  return Hash<I>{*this} != Hash<I>{rhs};
173  }
174 
175  template <int I>
176  std::ostream&
177  Hash<I>::print(std::ostream& os) const
178  {
179  Hash<I> tMe{*this};
181  cet::copy_all(tMe.hash_, temp.bytes);
182  os << temp.toString();
183  return os;
184  }
185 
186  template <int I>
187  void
189  {
190  fixup();
191  hash_.swap(rhs.hash_);
192  fixup();
193  }
194 
195  template <int I>
198  {
199  if (isCompactForm()) {
200  return hash_;
201  }
202  Hash<I> tMe(*this);
203  return tMe.compactForm();
204  }
205 
206  template <int I>
207  void
209  {
210  if (hash_.size() == 16) {
211  // Already in compact form.
212  return;
213  }
214  if (hash_.size() == 0) {
216  return;
217  }
218  if (hash_.size() == 32) {
219  cet::MD5Result md5;
221  hash_ = md5.compactForm();
222  return;
223  }
225  << "art::Hash<> instance with data in illegal state:\n"
226  << hash_ << "\nPlease report this to the core framework developers";
227  }
228 
229  template <int I>
230  bool
232  {
233  return hash_.size() == 16;
234  }
235 
236  template <int I>
237  void
239  {
240  a.swap(b);
241  }
242 
243  template <int I>
244  std::ostream&
245  operator<<(std::ostream& os, Hash<I> const& h)
246  {
247  return h.print(os);
248  }
249 
250 } // namespace art
251 
252 #endif /* canvas_Persistency_Provenance_Hash_h */
253 
254 // Local Variables:
255 // mode: c++
256 // End:
std::string const & InvalidHash()
Definition: Hash.cc:7
void fixup()
Definition: Hash.h:208
std::string string
Definition: nybbler.cc:12
std::string toString() const
Definition: MD5Digest.cc:45
std::string value_type
Definition: Hash.h:34
static short Class_Version() noexcept
Definition: Hash.h:72
STL namespace.
std::ostream & print(std::ostream &) const
Definition: Hash.h:177
Hash()
Definition: Hash.h:78
void fromHexifiedString(std::string const &s)
Definition: MD5Digest.cc:78
bool operator>(Hash< I > const &) const
Definition: Hash.h:144
void swap(Hash< I > &)
Definition: Hash.h:188
void swap(Handle< T > &a, Handle< T > &b)
std::string hash_
Definition: Hash.h:66
const double a
def move(depos, offset)
Definition: depos.py:107
bool operator==(Hash< I > const &) const
Definition: Hash.h:155
unsigned char bytes[16]
Definition: MD5Digest.h:24
bool isValid() const
Definition: Hash.h:123
bool operator<(Hash< I > const &) const
Definition: Hash.h:133
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
auto copy_all(FwdCont &, FwdIter)
Hash< I > & operator=(Hash< I > const &)
Definition: Hash.h:103
bool isCompactForm() const noexcept
Definition: Hash.h:231
static bool * b
Definition: config.cpp:1043
std::string compactForm() const
Definition: MD5Digest.cc:68
static QCString * s
Definition: config.cpp:1042
std::string compactForm() const
Definition: Hash.h:197
Definition: Hash.h:32
bool operator!=(Hash< I > const &) const
Definition: Hash.h:166