Home | History | Annotate | Download | only in wtf
      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