1 // Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef CHROMIUMOS_WIDE_PROFILING_BINARY_DATA_UTILS_H_
6 #define CHROMIUMOS_WIDE_PROFILING_BINARY_DATA_UTILS_H_
7
8 #include <byteswap.h>
9 #include <limits.h>
10 #include <stdint.h>
11
12 #include <bitset>
13 #include <type_traits>
14 #include <vector>
15
16 #include "base/logging.h"
17
18 #include "compat/string.h"
19 #include "kernel/perf_internals.h"
20
21 namespace quipper {
22
23 // Swaps the byte order of 16-bit, 32-bit, and 64-bit unsigned integers.
24 template <class T>
ByteSwap(T * input)25 void ByteSwap(T* input) {
26 switch (sizeof(T)) {
27 case sizeof(uint8_t):
28 LOG(WARNING) << "Attempting to byte swap on a single byte.";
29 break;
30 case sizeof(uint16_t):
31 *input = bswap_16(*input);
32 break;
33 case sizeof(uint32_t):
34 *input = bswap_32(*input);
35 break;
36 case sizeof(uint64_t):
37 *input = bswap_64(*input);
38 break;
39 default:
40 LOG(FATAL) << "Invalid size for byte swap: " << sizeof(T) << " bytes";
41 break;
42 }
43 }
44
45 // Swaps byte order of |value| if the |swap| flag is set. This function is
46 // trivial but it avoids filling code with "if (swap) { ... } " statements.
47 template <typename T>
MaybeSwap(T value,bool swap)48 T MaybeSwap(T value, bool swap) {
49 if (swap) ByteSwap(&value);
50 return value;
51 }
52
53 // Returns the number of bits in a numerical value.
54 template <typename T>
GetNumBits(const T & value)55 size_t GetNumBits(const T& value) {
56 return std::bitset<sizeof(T) * CHAR_BIT>(value).count();
57 }
58
59 // Returns the leading 64 bits of the MD5 digest of |input|.
60 uint64_t Md5Prefix(const string& input);
61 uint64_t Md5Prefix(const std::vector<char>& input);
62
63 // Returns a string that represents |array| in hexadecimal.
64 string RawDataToHexString(const u8* array, size_t length);
65
66 // Given raw data in |str|, returns a string that represents the binary data as
67 // hexadecimal.
68 string RawDataToHexString(const string& str);
69
70 // Given a string |str| containing data represented in hexadecimal, converts to
71 // to raw bytes stored in |array|. Returns true on success. Only stores up to
72 // |length| bytes - if there are more characters in the string, they are
73 // ignored (but the function may still return true).
74 bool HexStringToRawData(const string& str, u8* array, size_t length);
75
76 // Round |value| up to the next |alignment|. I.e. returns the smallest multiple
77 // of |alignment| less than or equal to |value|. |alignment| must be a power
78 // of 2 (compile-time enforced).
79 // clang-format off
80 template<unsigned int alignment,
81 typename std::enable_if<
82 alignment != 0 && (alignment&(alignment-1)) == 0
83 >::type* = nullptr>
84 // clang-format on
Align(uint64_t value)85 inline uint64_t Align(uint64_t value) {
86 constexpr uint64_t mask = alignment - 1;
87 return (value + mask) & ~mask;
88 }
89
90 // Allows passing a type parameter instead of a size.
91 template <typename T>
Align(uint64_t value)92 inline uint64_t Align(uint64_t value) {
93 return Align<sizeof(T)>(value);
94 }
95
96 } // namespace quipper
97
98 #endif // CHROMIUMOS_WIDE_PROFILING_BINARY_DATA_UTILS_H_
99