1/* 2 * Copyright (C) 2013 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#ifndef StringHashDumpContext_h 27#define StringHashDumpContext_h 28 29#include <wtf/HashMap.h> 30#include <wtf/SixCharacterHash.h> 31#include <wtf/StdLibExtras.h> 32#include <wtf/StringPrintStream.h> 33#include <wtf/text/CString.h> 34 35namespace WTF { 36 37template<typename T> 38class StringHashDumpContext { 39public: 40 StringHashDumpContext() { } 41 42 CString getID(const T* value) 43 { 44 typename HashMap<const T*, CString>::iterator iter = m_forwardMap.find(value); 45 if (iter != m_forwardMap.end()) 46 return iter->value; 47 48 for (unsigned hashValue = toCString(*value).hash(); ; hashValue++) { 49 CString fullHash = integerToSixCharacterHashString(hashValue).data(); 50 51 for (unsigned length = 2; length < 6; ++length) { 52 CString shortHash = CString(fullHash.data(), length); 53 if (!m_backwardMap.contains(shortHash)) { 54 m_forwardMap.add(value, shortHash); 55 m_backwardMap.add(shortHash, value); 56 return shortHash; 57 } 58 } 59 } 60 } 61 62 void dumpBrief(const T* value, PrintStream& out) 63 { 64 value->dumpBrief(out, getID(value)); 65 } 66 67 CString brief(const T* value) 68 { 69 StringPrintStream out; 70 dumpBrief(value, out); 71 return out.toCString(); 72 } 73 74 bool isEmpty() const { return m_forwardMap.isEmpty(); } 75 76 void dump(PrintStream& out, const char* prefix = "") const 77 { 78 out.print(prefix); 79 T::dumpContextHeader(out); 80 out.print("\n"); 81 82 Vector<CString> keys; 83 unsigned maxKeySize = 0; 84 for ( 85 typename HashMap<CString, const T*>::const_iterator iter = m_backwardMap.begin(); 86 iter != m_backwardMap.end(); 87 ++iter) { 88 keys.append(iter->key); 89 maxKeySize = std::max(maxKeySize, static_cast<unsigned>(brief(iter->value, iter->key).length())); 90 } 91 92 std::sort(keys.begin(), keys.end()); 93 94 for (unsigned i = 0; i < keys.size(); ++i) { 95 const T* value = m_backwardMap.get(keys[i]); 96 out.print(prefix, " "); 97 CString briefString = brief(value, keys[i]); 98 out.print(briefString); 99 for (unsigned n = briefString.length(); n < maxKeySize; ++n) 100 out.print(" "); 101 out.print(" = ", *value, "\n"); 102 } 103 } 104 105public: 106 static CString brief(const T* value, const CString& string) 107 { 108 StringPrintStream out; 109 value->dumpBrief(out, string); 110 return out.toCString(); 111 } 112 113 HashMap<const T*, CString> m_forwardMap; 114 HashMap<CString, const T*> m_backwardMap; 115}; 116 117} // namespace WTF 118 119using WTF::StringHashDumpContext; 120 121#endif // StringHashDumpContext_h 122 123