Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
digest.h
Go to the documentation of this file.
1 /*! \file xstream/digest.h
2  *
3  * \brief C++ objects to calculate digests of data
4  */
5 
6 #ifndef __XSTREAM_DIGEST_H
7 #define __XSTREAM_DIGEST_H
8 
9 #include <xstream/config.h>
10 #include <xstream/common.h>
11 
12 #include <streambuf>
13 
14 #if HAVE_INTTYPES_H
15 # include<inttypes.h>
16 #else
17 # if HAVE_STDINT_H
18 # include <stdint.h>
19 # endif
20 # error "I need inttypes.h or stdint.h to exist"
21 #endif
22 
23 #include <iosfwd>
24 
25 
26 namespace xstream{
27 /*!
28  * \brief digest objects
29  */
30 namespace digest{
31 
32 /*
33  * \brief streambuf class for stream digests
34  *
35  */
37 {
38  protected: // changed to protected to avoif clang compiler error when
39  // sync() is called from class "common" below. 10/23/2013 DL
40  /*!
41  * \brief update digest with as much data as possible (overloaded from streambuf)
42  *
43  * */
44  int sync();
45  private: // change back to private (see note above) 10/23/2013 DL
46  /*!
47  * \brief write a character that surpasses buffer end (overloaded from streambuf)
48  *
49  */
50  int overflow(int c);
51 
52  /*!
53  * \brief add an entire buffer to digest calculation (overloaded from streambuf)
54  *
55  */
56  std::streamsize xsputn(const char *buffer, std::streamsize n);
57 
58  protected:
59  xstream::buffer buf; /*!<buffer data to calculate digest */
60  uint64_t length; /*!< number of bytes read so far */
61 
62  /*!
63  * \brief default constructor
64  *
65  * allocates the buffer
66  *
67  * \parameter len length of buffer
68  *
69  * */
70  stream(size_t len);
71 
72  /*!
73  * \brief updates the digest
74  * must be inplemented by classes that implement this interface
75  *
76  */
77  virtual void calculate_digest()=0;
78 
79  /*!
80  * \brief resets digest to it's initial value
81  *
82  */
83  virtual void reset_digest()=0;
84 
85  /*! destructor
86  *
87  * frees the buffer
88  *
89  * */
90 
91  ~stream();
92 };
93 
94 /*!
95  * \brief Digest base class
96  *
97  * general interface for digest functions
98  *
99  */
100 
101 template <typename digest_type>
102 class common: public stream{
103  public:
104 
105  /*
106  * \brief constructor
107  *
108  * \param s size of the buffer
109  *
110  */
111  common(size_t s)
112  :stream(s)
113  {}
114 
115  /*!
116  * \brief return the digest value
117  *
118  */
119  virtual digest_type digest()=0;
120 
121  /*!
122  * \brief resets the digest calculation
123  *
124  * returns the digest of data so far and for future calculations only considers data entered from now on
125  *
126  */
127 
128  digest_type reset()
129  {
130  sync();
131  digest_type d = digest();
132  reset_digest();
133  return d;
134  }
135 };
136 
137 
138 #if HAVE_LIBZ
139 
140 /*!
141  * \internal
142  * \brief zlib's digest classes base
143  *
144  * zlib implements \c adler32 and \c crc32 digests
145  *
146  */
147 
148 class z_common : public common<unsigned long int> {
149  protected:
150  unsigned long int _digest; /*!< digest value */
151 
152  virtual void reset_digest();
153 
154  z_common();
155 
156  public:
157  virtual unsigned long int digest();
158 };
159 
160 /*!
161  * \brief adler32 digest class
162  *
163  */
164 
165 class adler32 : public z_common {
166  private:
167  void calculate_digest();
168 };
169 
170 /*!
171  * \brief crc32 digest class
172  *
173  */
174 
175 class crc32 : public z_common {
176  private:
177  void calculate_digest();
178 };
179 
180 /*!
181  * \brief base class for digest that work on fixed sized chunks of data
182  */
183 
184 class block_stream: public stream{
185  private:
186  const size_t chunk_size; /*!< size of the chunk used to calculate the digest */
187 
188  /*!
189  * \brief update digest with as much data as possible (overloaded from streambuf)
190  *
191  * */
192  int sync();
193 
194  /*!
195  * \brief write a character that surpasses buffer end (overloaded from streambuf)
196  *
197  */
198  int overflow(int c);
199 
200  /*!
201  * \brief add an entire buffer to digest calculation (overloaded from streambuf)
202  *
203  */
204  std::streamsize xsputn(const char *buffer, std::streamsize n);
205 
206  public:
207 
208  /*!
209  * \brief constructor
210  *
211  * \param chunk size in bytes of the chunk \c digest uses to update it's value
212  * \param blocks number of blocks of size chunk that fit in the buffer size
213  *
214  * */
215  block_stream(size_t chunk, unsigned int blocks);
216 
217 };
218 
219 
220 /*!
221  * \brief md5 digest class
222  *
223  * return digest as 4 32bit words ( ABCD as defined in the RFC 1321, 128bits total) un a simple wrapping structure
224  *
225  */
226 
227 class md5 : public block_stream {
228 
229  public:
230 
231  /*
232  * \brief result of an \c md5 digest
233  *
234  */
235 
236  struct result {
237  uint32_t a;
238  uint32_t b;
239  uint32_t c;
240  uint32_t d;
241 
242  bool operator==(const result& r) const{
243  return (a==r.a && b==r.b && c==r.c && d==r.d);
244  }
245  };
246 
247  /*!
248  * \brief returns the digest of the data as an \c result structure
249  *
250  */
251  result digest();
252 
253  /*!
254  * \brief resets digest value
255  *
256  * returns the digest of data so far and for future calculations only considers data entered from now on
257  */
258 
259  result reset();
260 
261  /*!
262  * \brief default constructor
263  *
264  */
265  md5();
266 
267  private:
268  result result;
269  virtual void reset_digest();
270 
271  virtual void calculate_digest();
272 
273 
274 };
275 
276 #endif //have zlib
277 
278 /*
279  * \brief dump md5 value to a stream
280  */
281 
282 std::ostream& operator<<(std::ostream& o, const struct md5::result& m);
283 
284 }//namespace digest
285 }//namespace xstream
286 
287 
288 /*!
289  * \example adler.cpp
290  *
291  * Calculates adler32 checksum of data
292  *
293  */
294 
295 /*!
296  * \example crc.cpp
297  *
298  * Calculates crc32 checksum of data
299  *
300  */
301 
302 /*!
303  * \example md5.cpp
304  *
305  * Calculates md5 checksum of data
306  *
307  */
308 #endif
int overflow(int c)
write a character that surpasses buffer end (overloaded from streambuf)
Definition: digest.cpp:37
int sync()
update digest with as much data as possible (overloaded from streambuf)
Definition: digest.cpp:26
stream(size_t len)
default constructor
Definition: digest.cpp:14
#define c
digest_type reset()
resets the digest calculation
Definition: digest.h:128
virtual digest_type digest()=0
return the digest value
xstream::buffer buf
Definition: digest.h:59
std::ostream & operator<<(std::ostream &o, const struct md5::result &m)
Definition: src/md5.cpp:278
Digest base class.
Definition: digest.h:102
virtual void reset_digest()=0
resets digest to it&#39;s initial value
buffer management
Definition: common.h:46
virtual void calculate_digest()=0
updates the digest must be inplemented by classes that implement this interface
common objects
std::streamsize xsputn(const char *buffer, std::streamsize n)
add an entire buffer to digest calculation (overloaded from streambuf)
Definition: digest.cpp:52