Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(700)

Side by Side Diff: src/utils/SkHashDigest.h

Issue 14265010: Make SkSHA1 and SkM5 use common SkDigestHash result type (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: sync_to_r8826 Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/utils/SkBitmapTransformer.cpp ('k') | tests/BitmapHasherTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #ifndef SkHashDigest_DEFINED
9 #define SkHashDigest_DEFINED
10
11 #include "SkData.h"
12 #include "SkRefCnt.h"
13 #include "SkString.h"
14
15 /**
16 * A mutable hash digest; it can be filled with a bytearray of any
17 * length, anytime.
18 */
19 class SkHashDigest {
20 public:
21 SkHashDigest() : fSkDataRef(SkData::NewEmpty()) {}
22 SkHashDigest(const void *data, size_t length) : fSkDataRef(SkData::NewWithCo py(data, length)) {}
23
24 /**
25 * Destructor: if this object is the only one with a reference to the data
26 * that makes up the hash digest, then that data will be freed.
27 */
28 ~SkHashDigest() {
29 }
30
31 /**
32 * Replace the hash digest data held by this object with a copy of the
33 * data from this pointer/length.
34 */
35 void copyFrom(const void *data, size_t length) {
36 fSkDataRef = SkData::NewWithCopy(data, length);
37 }
38
39 /**
40 * Convert a single hexadecimal character [0-9a-fA-F] into its integer value
41 *
42 * @param c the hexadecimal character to convert
43 * @param result where the integer value will be written
44 * Returns true if the conversion succeeded.
45 */
46 static bool hexCharValue(const char c, uint8_t *result) {
47 if ((c >= '0') && (c <= '9')) {
48 *result = c - '0';
49 } else if ((c >= 'a') && (c <= 'f')) {
50 *result = c - ('a' - 10);
51 } else if ((c >= 'A') && (c <= 'F')) {
52 *result = c - ('A' - 10);
53 } else {
54 // EPOGER: add unittest that exercises this
55 SkDEBUGF(("unrecognized hexChar '%c'\n", c));
56 return false;
57 }
58 return true;
59 }
60
61 /**
62 * Fill in the hash digest data from a null-terminated hexadecimal string.
63 *
64 * Returns true if it was able to properly parse the hexadecimal string.
65 */
66 bool copyFromHexString(const char *hexString) {
67 const int stringLen = strlen(hexString);
68 if (0 != stringLen % 2) {
69 // EPOGER: add unittest that exercises this
70 SkDEBUGF(("hexString '%s' has odd length %d\n", hexString, stringLen ));
71 return false;
72 }
73 const int digestLen = stringLen / 2;
74
75 // EPOGER: rewrite in a way that doesn't need this temporary array and m emcpy?
76 uint8_t digest[digestLen];
77 uint8_t *digestPtr = digest;
78 uint8_t *pastDigestEnd = digest + digestLen;
79 const char *hexStringPtr = hexString;
80 while (digestPtr < pastDigestEnd) {
81 uint8_t nybble1, nybble2;
82 if (!hexCharValue(*hexStringPtr++, &nybble1)) {
83 return false;
84 }
85 if (!hexCharValue(*hexStringPtr++, &nybble2)) {
86 return false;
87 }
88 *digestPtr++ = (nybble1 << 4) + nybble2;
89 }
90
91 this->copyFrom(digest, digestLen);
92 return true;
93 }
94
95 /**
96 * Return a pointer to the SkData object holding the hash digest data.
97 *
98 * The SkData object's reference counter will be bumped to account for this call,
99 * so the caller must call unref() on it once it is no longer needed!
100 *
101 * For example:
102 * {
103 * SkData *skDataPtr = digest.skDataPtr();
104 * const uint8_t* bytes = skDataPtr->bytes();
105 * ...
106 * skDataPtr->unref();
107 * }
108 */
109 // EPOGER: try to set it up so that this is never needed, and the caller wou ld just ask for a string representation instead???
110 SkData *skDataPtr() const {
111 return fSkDataRef.get();
112 }
113
114 size_t size() const {
115 return fSkDataRef->size();
116 }
117
118 bool equals(const SkHashDigest &other) const {
119 return fSkDataRef->equals(other.fSkDataRef.get());
120 }
121 friend bool operator==(const SkHashDigest& a, const SkHashDigest& b) {
122 return a.equals(b);
123 }
124
125 /**
126 * Returns a printable SkString representation of the hash digest
127 * (the bytes in hexadecimal, e.g. "deadbeef49")
128 */
129 SkString toHexString() const {
130 SkString retval;
131 const uint8_t *start = fSkDataRef->bytes();
132 const uint8_t *pastTheEnd = start + fSkDataRef->size();
133 for (const uint8_t *b = start; b < pastTheEnd; b++) {
134 // EPOGER: faster implementation that doesn't use appendf()?
135 retval.appendf("%02x", *b);
136 }
137 return retval;
138 }
139
140 private:
141
142 // The SkData pointer within fSkDataRef may change over the
143 // lifetime of the SkHashDigest object, but it will never be set
144 // to NULL. (Every SkHashDigest constructor initializes it to
145 // point at *some* SkData object.)
146 SkRefPtr<SkData> fSkDataRef;
147 };
148
149 #endif
OLDNEW
« no previous file with comments | « src/utils/SkBitmapTransformer.cpp ('k') | tests/BitmapHasherTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698