12bde8e466a4451c7319e3a072d118917957d6554Steve Block/* 22bde8e466a4451c7319e3a072d118917957d6554Steve Block * Copyright (C) 2011 Research In Motion Limited. All rights reserved. 32bde8e466a4451c7319e3a072d118917957d6554Steve Block * 42bde8e466a4451c7319e3a072d118917957d6554Steve Block * This library is free software; you can redistribute it and/or 52bde8e466a4451c7319e3a072d118917957d6554Steve Block * modify it under the terms of the GNU Library General Public 62bde8e466a4451c7319e3a072d118917957d6554Steve Block * License as published by the Free Software Foundation; either 72bde8e466a4451c7319e3a072d118917957d6554Steve Block * version 2 of the License, or (at your option) any later version. 82bde8e466a4451c7319e3a072d118917957d6554Steve Block * 92bde8e466a4451c7319e3a072d118917957d6554Steve Block * This library is distributed in the hope that it will be useful, 102bde8e466a4451c7319e3a072d118917957d6554Steve Block * but WITHOUT ANY WARRANTY; without even the implied warranty of 112bde8e466a4451c7319e3a072d118917957d6554Steve Block * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 122bde8e466a4451c7319e3a072d118917957d6554Steve Block * Library General Public License for more details. 132bde8e466a4451c7319e3a072d118917957d6554Steve Block * 142bde8e466a4451c7319e3a072d118917957d6554Steve Block * You should have received a copy of the GNU Library General Public License 152bde8e466a4451c7319e3a072d118917957d6554Steve Block * along with this library; see the file COPYING.LIB. If not, write to 162bde8e466a4451c7319e3a072d118917957d6554Steve Block * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 172bde8e466a4451c7319e3a072d118917957d6554Steve Block * Boston, MA 02110-1301, USA. 182bde8e466a4451c7319e3a072d118917957d6554Steve Block */ 192bde8e466a4451c7319e3a072d118917957d6554Steve Block 202bde8e466a4451c7319e3a072d118917957d6554Steve Block#ifndef HexNumber_h 212bde8e466a4451c7319e3a072d118917957d6554Steve Block#define HexNumber_h 222bde8e466a4451c7319e3a072d118917957d6554Steve Block 232bde8e466a4451c7319e3a072d118917957d6554Steve Block#include <wtf/text/StringConcatenate.h> 242bde8e466a4451c7319e3a072d118917957d6554Steve Block 252bde8e466a4451c7319e3a072d118917957d6554Steve Blocknamespace WTF { 262bde8e466a4451c7319e3a072d118917957d6554Steve Block 272bde8e466a4451c7319e3a072d118917957d6554Steve Blockenum HexConversionMode { 282bde8e466a4451c7319e3a072d118917957d6554Steve Block Lowercase, 292bde8e466a4451c7319e3a072d118917957d6554Steve Block Uppercase 302bde8e466a4451c7319e3a072d118917957d6554Steve Block}; 312bde8e466a4451c7319e3a072d118917957d6554Steve Block 322bde8e466a4451c7319e3a072d118917957d6554Steve Blocknamespace Internal { 332bde8e466a4451c7319e3a072d118917957d6554Steve Block 342bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic const char* hexDigitsForMode(HexConversionMode mode) 352bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 362bde8e466a4451c7319e3a072d118917957d6554Steve Block static const char lowerHexDigits[17] = "0123456789abcdef"; 372bde8e466a4451c7319e3a072d118917957d6554Steve Block static const char upperHexDigits[17] = "0123456789ABCDEF"; 382bde8e466a4451c7319e3a072d118917957d6554Steve Block return mode == Lowercase ? lowerHexDigits : upperHexDigits; 392bde8e466a4451c7319e3a072d118917957d6554Steve Block} 402bde8e466a4451c7319e3a072d118917957d6554Steve Block 412bde8e466a4451c7319e3a072d118917957d6554Steve Block}; // namespace Internal 422bde8e466a4451c7319e3a072d118917957d6554Steve Block 432bde8e466a4451c7319e3a072d118917957d6554Steve Blocktemplate<typename T> 442bde8e466a4451c7319e3a072d118917957d6554Steve Blockinline void appendByteAsHex(unsigned char byte, T& destination, HexConversionMode mode = Uppercase) 452bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 462bde8e466a4451c7319e3a072d118917957d6554Steve Block const char* hexDigits = Internal::hexDigitsForMode(mode); 472bde8e466a4451c7319e3a072d118917957d6554Steve Block destination.append(hexDigits[byte >> 4]); 482bde8e466a4451c7319e3a072d118917957d6554Steve Block destination.append(hexDigits[byte & 0xF]); 492bde8e466a4451c7319e3a072d118917957d6554Steve Block} 502bde8e466a4451c7319e3a072d118917957d6554Steve Block 512bde8e466a4451c7319e3a072d118917957d6554Steve Blocktemplate<typename T> 522bde8e466a4451c7319e3a072d118917957d6554Steve Blockinline void placeByteAsHexCompressIfPossible(unsigned char byte, T& destination, unsigned& index, HexConversionMode mode = Uppercase) 532bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 542bde8e466a4451c7319e3a072d118917957d6554Steve Block const char* hexDigits = Internal::hexDigitsForMode(mode); 552bde8e466a4451c7319e3a072d118917957d6554Steve Block if (byte >= 0x10) 562bde8e466a4451c7319e3a072d118917957d6554Steve Block destination[index++] = hexDigits[byte >> 4]; 572bde8e466a4451c7319e3a072d118917957d6554Steve Block destination[index++] = hexDigits[byte & 0xF]; 582bde8e466a4451c7319e3a072d118917957d6554Steve Block} 592bde8e466a4451c7319e3a072d118917957d6554Steve Block 602bde8e466a4451c7319e3a072d118917957d6554Steve Blocktemplate<typename T> 612bde8e466a4451c7319e3a072d118917957d6554Steve Blockinline void placeByteAsHex(unsigned char byte, T& destination, HexConversionMode mode = Uppercase) 622bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 632bde8e466a4451c7319e3a072d118917957d6554Steve Block const char* hexDigits = Internal::hexDigitsForMode(mode); 642bde8e466a4451c7319e3a072d118917957d6554Steve Block *destination++ = hexDigits[byte >> 4]; 652bde8e466a4451c7319e3a072d118917957d6554Steve Block *destination++ = hexDigits[byte & 0xF]; 662bde8e466a4451c7319e3a072d118917957d6554Steve Block} 672bde8e466a4451c7319e3a072d118917957d6554Steve Block 682bde8e466a4451c7319e3a072d118917957d6554Steve Blocktemplate<typename T> 692bde8e466a4451c7319e3a072d118917957d6554Steve Blockinline void appendUnsignedAsHex(unsigned number, T& destination, HexConversionMode mode = Uppercase) 702bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 712bde8e466a4451c7319e3a072d118917957d6554Steve Block const char* hexDigits = Internal::hexDigitsForMode(mode); 722bde8e466a4451c7319e3a072d118917957d6554Steve Block Vector<UChar, 8> result; 732bde8e466a4451c7319e3a072d118917957d6554Steve Block do { 742bde8e466a4451c7319e3a072d118917957d6554Steve Block result.prepend(hexDigits[number % 16]); 752bde8e466a4451c7319e3a072d118917957d6554Steve Block number >>= 4; 762bde8e466a4451c7319e3a072d118917957d6554Steve Block } while (number > 0); 772bde8e466a4451c7319e3a072d118917957d6554Steve Block 782bde8e466a4451c7319e3a072d118917957d6554Steve Block destination.append(result.data(), result.size()); 792bde8e466a4451c7319e3a072d118917957d6554Steve Block} 802bde8e466a4451c7319e3a072d118917957d6554Steve Block 812bde8e466a4451c7319e3a072d118917957d6554Steve Block// Same as appendUnsignedAsHex, but using exactly 'desiredDigits' for the conversion. 822bde8e466a4451c7319e3a072d118917957d6554Steve Blocktemplate<typename T> 832bde8e466a4451c7319e3a072d118917957d6554Steve Blockinline void appendUnsignedAsHexFixedSize(unsigned number, T& destination, unsigned desiredDigits, HexConversionMode mode = Uppercase) 842bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 852bde8e466a4451c7319e3a072d118917957d6554Steve Block ASSERT(desiredDigits); 862bde8e466a4451c7319e3a072d118917957d6554Steve Block 872bde8e466a4451c7319e3a072d118917957d6554Steve Block const char* hexDigits = Internal::hexDigitsForMode(mode); 882bde8e466a4451c7319e3a072d118917957d6554Steve Block Vector<UChar, 8> result; 892bde8e466a4451c7319e3a072d118917957d6554Steve Block do { 902bde8e466a4451c7319e3a072d118917957d6554Steve Block result.prepend(hexDigits[number % 16]); 912bde8e466a4451c7319e3a072d118917957d6554Steve Block number >>= 4; 922bde8e466a4451c7319e3a072d118917957d6554Steve Block } while (result.size() < desiredDigits); 932bde8e466a4451c7319e3a072d118917957d6554Steve Block 942bde8e466a4451c7319e3a072d118917957d6554Steve Block ASSERT(result.size() == desiredDigits); 952bde8e466a4451c7319e3a072d118917957d6554Steve Block destination.append(result.data(), result.size()); 962bde8e466a4451c7319e3a072d118917957d6554Steve Block} 972bde8e466a4451c7319e3a072d118917957d6554Steve Block 982bde8e466a4451c7319e3a072d118917957d6554Steve Block} // namespace WTF 992bde8e466a4451c7319e3a072d118917957d6554Steve Block 1002bde8e466a4451c7319e3a072d118917957d6554Steve Blockusing WTF::appendByteAsHex; 1012bde8e466a4451c7319e3a072d118917957d6554Steve Blockusing WTF::appendUnsignedAsHex; 1022bde8e466a4451c7319e3a072d118917957d6554Steve Blockusing WTF::appendUnsignedAsHexFixedSize; 1032bde8e466a4451c7319e3a072d118917957d6554Steve Blockusing WTF::placeByteAsHex; 1042bde8e466a4451c7319e3a072d118917957d6554Steve Blockusing WTF::placeByteAsHexCompressIfPossible; 1052bde8e466a4451c7319e3a072d118917957d6554Steve Blockusing WTF::Lowercase; 1062bde8e466a4451c7319e3a072d118917957d6554Steve Block 1072bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif // HexNumber_h 108