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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/utils/SkBitmapTransformer.cpp ('k') | tests/BitmapHasherTest.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/utils/SkHashDigest.h
===================================================================
--- src/utils/SkHashDigest.h (revision 0)
+++ src/utils/SkHashDigest.h (revision 0)
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkHashDigest_DEFINED
+#define SkHashDigest_DEFINED
+
+#include "SkData.h"
+#include "SkRefCnt.h"
+#include "SkString.h"
+
+/**
+ * A mutable hash digest; it can be filled with a bytearray of any
+ * length, anytime.
+ */
+class SkHashDigest {
+public:
+ SkHashDigest() : fSkDataRef(SkData::NewEmpty()) {}
+ SkHashDigest(const void *data, size_t length) : fSkDataRef(SkData::NewWithCopy(data, length)) {}
+
+ /**
+ * Destructor: if this object is the only one with a reference to the data
+ * that makes up the hash digest, then that data will be freed.
+ */
+ ~SkHashDigest() {
+ }
+
+ /**
+ * Replace the hash digest data held by this object with a copy of the
+ * data from this pointer/length.
+ */
+ void copyFrom(const void *data, size_t length) {
+ fSkDataRef = SkData::NewWithCopy(data, length);
+ }
+
+ /**
+ * Convert a single hexadecimal character [0-9a-fA-F] into its integer value
+ *
+ * @param c the hexadecimal character to convert
+ * @param result where the integer value will be written
+ * Returns true if the conversion succeeded.
+ */
+ static bool hexCharValue(const char c, uint8_t *result) {
+ if ((c >= '0') && (c <= '9')) {
+ *result = c - '0';
+ } else if ((c >= 'a') && (c <= 'f')) {
+ *result = c - ('a' - 10);
+ } else if ((c >= 'A') && (c <= 'F')) {
+ *result = c - ('A' - 10);
+ } else {
+ // EPOGER: add unittest that exercises this
+ SkDEBUGF(("unrecognized hexChar '%c'\n", c));
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Fill in the hash digest data from a null-terminated hexadecimal string.
+ *
+ * Returns true if it was able to properly parse the hexadecimal string.
+ */
+ bool copyFromHexString(const char *hexString) {
+ const int stringLen = strlen(hexString);
+ if (0 != stringLen % 2) {
+ // EPOGER: add unittest that exercises this
+ SkDEBUGF(("hexString '%s' has odd length %d\n", hexString, stringLen));
+ return false;
+ }
+ const int digestLen = stringLen / 2;
+
+ // EPOGER: rewrite in a way that doesn't need this temporary array and memcpy?
+ uint8_t digest[digestLen];
+ uint8_t *digestPtr = digest;
+ uint8_t *pastDigestEnd = digest + digestLen;
+ const char *hexStringPtr = hexString;
+ while (digestPtr < pastDigestEnd) {
+ uint8_t nybble1, nybble2;
+ if (!hexCharValue(*hexStringPtr++, &nybble1)) {
+ return false;
+ }
+ if (!hexCharValue(*hexStringPtr++, &nybble2)) {
+ return false;
+ }
+ *digestPtr++ = (nybble1 << 4) + nybble2;
+ }
+
+ this->copyFrom(digest, digestLen);
+ return true;
+ }
+
+ /**
+ * Return a pointer to the SkData object holding the hash digest data.
+ *
+ * The SkData object's reference counter will be bumped to account for this call,
+ * so the caller must call unref() on it once it is no longer needed!
+ *
+ * For example:
+ * {
+ * SkData *skDataPtr = digest.skDataPtr();
+ * const uint8_t* bytes = skDataPtr->bytes();
+ * ...
+ * skDataPtr->unref();
+ * }
+ */
+ // EPOGER: try to set it up so that this is never needed, and the caller would just ask for a string representation instead???
+ SkData *skDataPtr() const {
+ return fSkDataRef.get();
+ }
+
+ size_t size() const {
+ return fSkDataRef->size();
+ }
+
+ bool equals(const SkHashDigest &other) const {
+ return fSkDataRef->equals(other.fSkDataRef.get());
+ }
+ friend bool operator==(const SkHashDigest& a, const SkHashDigest& b) {
+ return a.equals(b);
+ }
+
+ /**
+ * Returns a printable SkString representation of the hash digest
+ * (the bytes in hexadecimal, e.g. "deadbeef49")
+ */
+ SkString toHexString() const {
+ SkString retval;
+ const uint8_t *start = fSkDataRef->bytes();
+ const uint8_t *pastTheEnd = start + fSkDataRef->size();
+ for (const uint8_t *b = start; b < pastTheEnd; b++) {
+ // EPOGER: faster implementation that doesn't use appendf()?
+ retval.appendf("%02x", *b);
+ }
+ return retval;
+ }
+
+private:
+
+ // The SkData pointer within fSkDataRef may change over the
+ // lifetime of the SkHashDigest object, but it will never be set
+ // to NULL. (Every SkHashDigest constructor initializes it to
+ // point at *some* SkData object.)
+ SkRefPtr<SkData> fSkDataRef;
+};
+
+#endif
« 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