1 /* 2 * Copyright (C) 2011 Research In Motion Limited. All rights reserved. 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Library General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Library General Public License for more details. 13 * 14 * You should have received a copy of the GNU Library General Public License 15 * along with this library; see the file COPYING.LIB. If not, write to 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 * Boston, MA 02110-1301, USA. 18 */ 19 20 #ifndef HexNumber_h 21 #define HexNumber_h 22 23 #include <wtf/text/StringConcatenate.h> 24 25 namespace WTF { 26 27 enum HexConversionMode { 28 Lowercase, 29 Uppercase 30 }; 31 32 namespace Internal { 33 34 static const char* hexDigitsForMode(HexConversionMode mode) 35 { 36 static const char lowerHexDigits[17] = "0123456789abcdef"; 37 static const char upperHexDigits[17] = "0123456789ABCDEF"; 38 return mode == Lowercase ? lowerHexDigits : upperHexDigits; 39 } 40 41 }; // namespace Internal 42 43 template<typename T> 44 inline void appendByteAsHex(unsigned char byte, T& destination, HexConversionMode mode = Uppercase) 45 { 46 const char* hexDigits = Internal::hexDigitsForMode(mode); 47 destination.append(hexDigits[byte >> 4]); 48 destination.append(hexDigits[byte & 0xF]); 49 } 50 51 template<typename T> 52 inline void placeByteAsHexCompressIfPossible(unsigned char byte, T& destination, unsigned& index, HexConversionMode mode = Uppercase) 53 { 54 const char* hexDigits = Internal::hexDigitsForMode(mode); 55 if (byte >= 0x10) 56 destination[index++] = hexDigits[byte >> 4]; 57 destination[index++] = hexDigits[byte & 0xF]; 58 } 59 60 template<typename T> 61 inline void placeByteAsHex(unsigned char byte, T& destination, HexConversionMode mode = Uppercase) 62 { 63 const char* hexDigits = Internal::hexDigitsForMode(mode); 64 *destination++ = hexDigits[byte >> 4]; 65 *destination++ = hexDigits[byte & 0xF]; 66 } 67 68 template<typename T> 69 inline void appendUnsignedAsHex(unsigned number, T& destination, HexConversionMode mode = Uppercase) 70 { 71 const char* hexDigits = Internal::hexDigitsForMode(mode); 72 Vector<UChar, 8> result; 73 do { 74 result.prepend(hexDigits[number % 16]); 75 number >>= 4; 76 } while (number > 0); 77 78 destination.append(result.data(), result.size()); 79 } 80 81 // Same as appendUnsignedAsHex, but using exactly 'desiredDigits' for the conversion. 82 template<typename T> 83 inline void appendUnsignedAsHexFixedSize(unsigned number, T& destination, unsigned desiredDigits, HexConversionMode mode = Uppercase) 84 { 85 ASSERT(desiredDigits); 86 87 const char* hexDigits = Internal::hexDigitsForMode(mode); 88 Vector<UChar, 8> result; 89 do { 90 result.prepend(hexDigits[number % 16]); 91 number >>= 4; 92 } while (result.size() < desiredDigits); 93 94 ASSERT(result.size() == desiredDigits); 95 destination.append(result.data(), result.size()); 96 } 97 98 } // namespace WTF 99 100 using WTF::appendByteAsHex; 101 using WTF::appendUnsignedAsHex; 102 using WTF::appendUnsignedAsHexFixedSize; 103 using WTF::placeByteAsHex; 104 using WTF::placeByteAsHexCompressIfPossible; 105 using WTF::Lowercase; 106 107 #endif // HexNumber_h 108