15d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 25d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Use of this source code is governed by a BSD-style license that can be 35d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// found in the LICENSE file. 45d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana 55d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#ifndef CHROMIUMOS_WIDE_PROFILING_BINARY_DATA_UTILS_H_ 65d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#define CHROMIUMOS_WIDE_PROFILING_BINARY_DATA_UTILS_H_ 75d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana 85d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#include <byteswap.h> 95d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#include <limits.h> 105d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#include <stdint.h> 115d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana 125d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#include <bitset> 135d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#include <type_traits> 145d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#include <vector> 155d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana 165d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#include "base/logging.h" 175d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana 185d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#include "compat/string.h" 195d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#include "kernel/perf_internals.h" 205d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana 215d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmananamespace quipper { 225d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana 235d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Swaps the byte order of 16-bit, 32-bit, and 64-bit unsigned integers. 245d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanatemplate <class T> 255d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanavoid ByteSwap(T* input) { 265d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana switch (sizeof(T)) { 273fa0a5f4b88119fac65f86971738ea0202797b6elakshmana case sizeof(uint8_t): 283fa0a5f4b88119fac65f86971738ea0202797b6elakshmana LOG(WARNING) << "Attempting to byte swap on a single byte."; 293fa0a5f4b88119fac65f86971738ea0202797b6elakshmana break; 303fa0a5f4b88119fac65f86971738ea0202797b6elakshmana case sizeof(uint16_t): 313fa0a5f4b88119fac65f86971738ea0202797b6elakshmana *input = bswap_16(*input); 323fa0a5f4b88119fac65f86971738ea0202797b6elakshmana break; 333fa0a5f4b88119fac65f86971738ea0202797b6elakshmana case sizeof(uint32_t): 343fa0a5f4b88119fac65f86971738ea0202797b6elakshmana *input = bswap_32(*input); 353fa0a5f4b88119fac65f86971738ea0202797b6elakshmana break; 363fa0a5f4b88119fac65f86971738ea0202797b6elakshmana case sizeof(uint64_t): 373fa0a5f4b88119fac65f86971738ea0202797b6elakshmana *input = bswap_64(*input); 383fa0a5f4b88119fac65f86971738ea0202797b6elakshmana break; 393fa0a5f4b88119fac65f86971738ea0202797b6elakshmana default: 403fa0a5f4b88119fac65f86971738ea0202797b6elakshmana LOG(FATAL) << "Invalid size for byte swap: " << sizeof(T) << " bytes"; 413fa0a5f4b88119fac65f86971738ea0202797b6elakshmana break; 425d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana } 435d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana} 445d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana 455d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Swaps byte order of |value| if the |swap| flag is set. This function is 465d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// trivial but it avoids filling code with "if (swap) { ... } " statements. 475d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanatemplate <typename T> 485d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanaT MaybeSwap(T value, bool swap) { 493fa0a5f4b88119fac65f86971738ea0202797b6elakshmana if (swap) ByteSwap(&value); 505d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana return value; 515d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana} 525d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana 535d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Returns the number of bits in a numerical value. 545d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanatemplate <typename T> 555d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanasize_t GetNumBits(const T& value) { 565d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana return std::bitset<sizeof(T) * CHAR_BIT>(value).count(); 575d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana} 585d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana 595d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Returns the leading 64 bits of the MD5 digest of |input|. 605d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanauint64_t Md5Prefix(const string& input); 615d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanauint64_t Md5Prefix(const std::vector<char>& input); 625d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana 635d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Returns a string that represents |array| in hexadecimal. 645d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanastring RawDataToHexString(const u8* array, size_t length); 655d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana 665d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Given raw data in |str|, returns a string that represents the binary data as 675d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// hexadecimal. 685d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanastring RawDataToHexString(const string& str); 695d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana 705d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Given a string |str| containing data represented in hexadecimal, converts to 715d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// to raw bytes stored in |array|. Returns true on success. Only stores up to 725d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// |length| bytes - if there are more characters in the string, they are 735d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// ignored (but the function may still return true). 745d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanabool HexStringToRawData(const string& str, u8* array, size_t length); 755d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana 765d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Round |value| up to the next |alignment|. I.e. returns the smallest multiple 775d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// of |alignment| less than or equal to |value|. |alignment| must be a power 785d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// of 2 (compile-time enforced). 793fa0a5f4b88119fac65f86971738ea0202797b6elakshmana// clang-format off 805d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanatemplate<unsigned int alignment, 815d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana typename std::enable_if< 825d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana alignment != 0 && (alignment&(alignment-1)) == 0 835d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana >::type* = nullptr> 843fa0a5f4b88119fac65f86971738ea0202797b6elakshmana// clang-format on 855d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanainline uint64_t Align(uint64_t value) { 865d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana constexpr uint64_t mask = alignment - 1; 875d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana return (value + mask) & ~mask; 885d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana} 895d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana 905d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Allows passing a type parameter instead of a size. 913fa0a5f4b88119fac65f86971738ea0202797b6elakshmanatemplate <typename T> 925d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanainline uint64_t Align(uint64_t value) { 935d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana return Align<sizeof(T)>(value); 945d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana} 955d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana 965d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana} // namespace quipper 975d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana 985d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#endif // CHROMIUMOS_WIDE_PROFILING_BINARY_DATA_UTILS_H_ 99