Statistics
| Branch: | Revision:

root / include / chasher.h @ master

History | View | Annotate | Download (3.18 KB)

1
//==========================================================================
2
//   CHASHER.H  - part of
3
//                     OMNeT++/OMNEST
4
//            Discrete System Simulation in C++
5
//
6
//  Author: Andras Varga
7
//
8
//==========================================================================
9

    
10
/*--------------------------------------------------------------*
11
  Copyright (C) 1992-2008 Andras Varga
12
  Copyright (C) 2006-2008 OpenSim Ltd.
13

14
  This file is distributed WITHOUT ANY WARRANTY. See the file
15
  `license' for details on this and other legal matters.
16
*--------------------------------------------------------------*/
17

    
18
#ifndef __CHASHER_H
19
#define __CHASHER_H
20

    
21
#include <string.h>
22
#include <stdlib.h>
23
#include "simkerneldefs.h"
24
#include "cobject.h"
25
#include "cexception.h"
26
#include "platdep/intxtypes.h"
27

    
28
NAMESPACE_BEGIN
29

    
30

    
31
/**
32
 * Utility class to calculate the "fingerprint" of a simulation.
33
 *
34
 * We are trying to achieve that the same simulation gives the same fingerprint
35
 * on a 32-bit machine and on a 64-bit machine. Longs can be either 32-bit or
36
 * 64-bit, so we always convert them to 64 bits. We do not try to convert
37
 * endianness, it would be too costly.
38
 */
39
class SIM_API cHasher : noncopyable
40
{
41
  private:
42
    uint32 value;
43

    
44
    void merge(uint32 x) {
45
        // rotate value left by one bit, and xor with new data
46
        uint32 carry = (value & 0x80000000U) >> 31;
47
        value = ((value<<1)|carry) ^ x;
48
    }
49

    
50
    void merge2(uint64 x) {
51
        merge((uint32)x);
52
        merge((uint32)(x>>32));
53
    }
54

    
55
  public:
56
    /**
57
     * Constructor.
58
     */
59
    cHasher() {ASSERT(sizeof(uint32)==4); ASSERT(sizeof(double)==8); value = 0;}
60

    
61
    /** @name Updating the hash */
62
    //@{
63
    void reset() {value = 0;}
64
    void add(const char *p, size_t length);
65
    void add(char d)           {merge((uint32)d);}
66
    void add(short d)          {merge((uint32)d);}
67
    void add(int d)            {merge((uint32)d);}
68
    void add(long d)           {int64 tmp=d; merge2((uint64)tmp);}
69
    void add(opp_long_long d)   {merge2((uint64)d);}
70
    void add(unsigned char d)  {merge((uint32)d);}
71
    void add(unsigned short d) {merge((uint32)d);}
72
    void add(unsigned int d)   {merge((uint32)d);}
73
    void add(unsigned long d)  {uint64 tmp=d; merge2(tmp);}
74
    void add(opp_unsigned_long_long d)  {merge2(d);}
75
    // note: safe(r) type punning, see http://cocoawithlove.decenturl.com/type-punning
76
    void add(double d)         {union _ {double d; uint64 i;}; merge2(((union _ *)&d)->i);}
77
    void add(const char *s)    {if (s) add(s, strlen(s)+1); else add(0);}
78
    //@}
79

    
80
    /** @name Obtaining the result */
81
    //@{
82
    /**
83
     * Returns the hash value.
84
     */
85
    uint32 getHash() const {return value;}
86

    
87
    /**
88
     * Converts the given string to a numeric fingerprint value. The object is
89
     * not changed. Throws an error if the string does not contain a valid
90
     * fingerprint.
91
     */
92
    uint32 parse(const char *fingerprint) const;
93

    
94
    /**
95
     * Parses the given fingerprint string, and compares it to the stored hash.
96
     */
97
    bool equals(const char *fingerprint) const;
98

    
99
    /**
100
     * Returns the textual representation (hex string) of the stored hash.
101
     */
102
    std::string str() const;
103
    //@}
104
};
105

    
106
NAMESPACE_END
107

    
108
#endif
109

    
110