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