LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
Hash.h
Go to the documentation of this file.
1 #ifndef canvas_Persistency_Provenance_Hash_h
2 #define canvas_Persistency_Provenance_Hash_h
3 
4 // ======================================================================
5 //
6 // Hash:
7 //
8 // Note: The call to 'fixup' in every member function is a temporary
9 // measure for backwards compatibility. It is necessary in every function
10 // because Root creates instances of the class *without* using the
11 // interface of the class, thus making it insufficient to assure that all
12 // constructors make corrected instances.
13 //
14 // ======================================================================
15 
17 #include "cetlib/MD5Digest.h"
18 #include "cetlib/container_algorithms.h"
19 #include <ostream>
20 #include <string>
21 
22 // ----------------------------------------------------------------------
23 
24 namespace art {
25 
26  namespace detail {
27  // This string is the 16-byte, non-printable version.
28  std::string const& InvalidHash();
29  }
30 
31  template <int I>
32  class Hash {
33  public:
34  typedef std::string value_type;
35 
36  Hash();
37  explicit Hash(value_type const& v);
38 
39  Hash(Hash<I> const&);
40  // We can't ref-qualify assignment because of GCC_XML
41  Hash<I> const& operator=(Hash<I> const& iRHS);
42 
43  // For now, just check the most basic: a default constructed
44  // ParameterSetID is not valid. This is very crude: we are
45  // assuming that nobody created a ParameterSetID from an empty
46  // string, nor from any string that is not a valid string
47  // representation of an MD5 checksum.
48  bool isValid() const;
49 
50  bool operator<(Hash<I> const& other) const;
51  bool operator>(Hash<I> const& other) const;
52  bool operator==(Hash<I> const& other) const;
53  bool operator!=(Hash<I> const& other) const;
54  std::ostream& print(std::ostream& os) const;
55  void swap(Hash<I>& other);
56 
57  // Return the 16-byte (non-printable) string form.
58  value_type compactForm() const;
59 
60  bool isCompactForm() const;
61 
62  // MUST UPDATE WHEN CLASS IS CHANGED!
63  static short
65  {
66  return 10;
67  }
68 
69  private:
70  // Hexified version of data *must* contain a multiple of 2
71  // bytes. If it does not, throw an exception.
72  void throwIfIllFormed() const;
73 
74  // 'Fix' the string data member of this Hash, i.e., if it is in
75  // the hexified (32 byte) representation, make it be in the
76  // 16-byte (unhexified) representation.
77  void fixup();
78 
79  template <typename Op>
80  bool
81  compareUsing(Hash<I> const& iOther, Op op) const
82  {
83  if (this->isCompactForm() == iOther.isCompactForm()) {
84  return op(this->hash_, iOther.hash_);
85  }
86  Hash<I> tMe(*this);
87  Hash<I> tOther(iOther);
88  return op(tMe.hash_, tOther.hash_);
89  }
90 
91  value_type hash_;
92  };
93 
94  //--------------------------------------------------------------------
95  //
96  // Implementation details follow...
97  //--------------------------------------------------------------------
98 
99  template <int I>
100  inline Hash<I>::Hash() : hash_()
101  {
102  fixup();
103  }
104 
105  template <int I>
106  inline Hash<I>::Hash(typename Hash<I>::value_type const& v) : hash_(v)
107  {
108  fixup();
109  }
110 
111  template <int I>
112  inline Hash<I>::Hash(Hash<I> const& iOther) : hash_(iOther.hash_)
113  {
114  fixup();
115  }
116 
117  template <int I>
118  inline Hash<I> const&
120  {
121  hash_ = iRHS.hash_;
122  fixup();
123  return *this;
124  }
125 
126  template <int I>
127  inline bool
129  {
130  return isCompactForm() ? (hash_ != art::detail::InvalidHash()) :
131  (hash_.size() != 0);
132  }
133 
134  template <int I>
135  inline bool
137  {
138  return this->compareUsing(other, std::less<std::string>());
139  }
140 
141  template <int I>
142  inline bool
144  {
145  return this->compareUsing(other, std::greater<std::string>());
146  }
147 
148  template <int I>
149  inline bool
151  {
152  return this->compareUsing(other, std::equal_to<std::string>());
153  }
154 
155  template <int I>
156  inline bool
158  {
159  return this->compareUsing(other, std::not_equal_to<std::string>());
160  }
161 
162  template <int I>
163  inline std::ostream&
164  Hash<I>::print(std::ostream& os) const
165  {
166  Hash<I> tMe(*this);
167  cet::MD5Result temp;
168  cet::copy_all(tMe.hash_, temp.bytes);
169  os << temp.toString();
170  return os;
171  }
172 
173  template <int I>
174  inline void
176  {
177  fixup();
178  hash_.swap(other.hash_);
179  fixup();
180  }
181 
182  template <int I>
183  inline typename Hash<I>::value_type
185  {
186  if (this->isCompactForm()) {
187  return hash_;
188  }
189  Hash<I> tMe(*this);
190  return tMe.compactForm();
191  }
192 
193  template <int I>
194  inline void
196  {
197  // Fixup not needed here.
198  if (hash_.size() % 2 == 1) {
200  << "Ill-formed Hash instance. "
201  << "Please report this to the core framework developers";
202  }
203  }
204 
205  // Note: this template is not declared 'inline' because of the
206  // switch statement.
207 
208  template <int I>
209  void
211  {
212  switch (hash_.size()) {
213  case 0: {
215  }
216  case 16: {
217  break;
218  }
219  case 32: {
220  cet::MD5Result temp;
221  temp.fromHexifiedString(hash_);
222  hash_ = temp.compactForm();
223  break;
224  }
225  default: {
227  << "art::Hash<> instance with data in illegal state:\n"
228  << hash_ << "\nPlease report this to the core framework developers";
229  }
230  }
231  }
232 
233  template <int I>
234  inline bool
236  {
237  return 16 == hash_.size();
238  }
239 
240  // Free swap function
241  template <int I>
242  inline void
244  {
245  a.swap(b);
246  }
247 
248  template <int I>
249  inline std::ostream&
250  operator<<(std::ostream& os, Hash<I> const& h)
251  {
252  return h.print(os);
253  }
254 
255 } // art
256 
257  // ======================================================================
258 
259 #endif /* canvas_Persistency_Provenance_Hash_h */
260 
261 // Local Variables:
262 // mode: c++
263 // End:
std::string const & InvalidHash()
Definition: Hash.cc:7
Hash< I > const & operator=(Hash< I > const &iRHS)
Definition: Hash.h:119
void fixup()
Definition: Hash.h:210
bool operator!=(Hash< I > const &other) const
Definition: Hash.h:157
bool operator>(Hash< I > const &other) const
Definition: Hash.h:143
Hash()
Definition: Hash.h:100
bool operator!=(debugging_allocator< X > const &, debugging_allocator< Y > const &)
bool operator>(ScheduleID left, ScheduleID right)
Definition: ScheduleID.h:136
void throwIfIllFormed() const
Definition: Hash.h:195
std::string value_type
Definition: Hash.h:34
value_type compactForm() const
Definition: Hash.h:184
void swap(Handle< T > &a, Handle< T > &b)
bool operator==(Hash< I > const &other) const
Definition: Hash.h:150
bool isCompactForm() const
Definition: Hash.h:235
bool isValid() const
Definition: Hash.h:128
bool compareUsing(Hash< I > const &iOther, Op op) const
Definition: Hash.h:81
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
static short Class_Version()
Definition: Hash.h:64
bool operator<(Hash< I > const &other) const
Definition: Hash.h:136
HLT enums.
std::ostream & print(std::ostream &os) const
Definition: Hash.h:164
value_type hash_
Definition: Hash.h:91
bool operator==(Provenance const &a, Provenance const &b)
Definition: Provenance.h:168
void swap(Hash< I > &other)
Definition: Hash.h:175
Definition: Hash.h:32