[BLEREFACTOR]:Refactor byte_utils global functions

PiperOrigin-RevId: 831134984
This commit is contained in:
Edwin Wu
2025-11-11 17:40:12 -08:00
committed by Copybara-Service
parent decf2acbd9
commit 2695dd4089
6 changed files with 121 additions and 48 deletions
@@ -31,6 +31,7 @@
#include "connections/implementation/offline_frames.h"
#include "internal/flags/nearby_flags.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/byte_utils.h"
#include "internal/platform/exception.h"
#include "internal/platform/implementation/system_clock.h"
#include "internal/platform/input_stream.h"
@@ -49,38 +50,17 @@ using ::location::nearby::proto::connections::Medium::BLE_L2CAP;
using DisconnectionReason =
::location::nearby::proto::connections::DisconnectionReason;
std::int32_t BytesToInt(const ByteArray& bytes) {
const char* int_bytes = bytes.data();
std::int32_t result = 0;
result |= (static_cast<std::int32_t>(int_bytes[0]) & 0x0FF) << 24;
result |= (static_cast<std::int32_t>(int_bytes[1]) & 0x0FF) << 16;
result |= (static_cast<std::int32_t>(int_bytes[2]) & 0x0FF) << 8;
result |= (static_cast<std::int32_t>(int_bytes[3]) & 0x0FF);
return result;
}
ByteArray IntToBytes(std::int32_t value) {
char int_bytes[sizeof(std::int32_t)];
int_bytes[0] = static_cast<char>((value >> 24) & 0x0FF);
int_bytes[1] = static_cast<char>((value >> 16) & 0x0FF);
int_bytes[2] = static_cast<char>((value >> 8) & 0x0FF);
int_bytes[3] = static_cast<char>((value) & 0x0FF);
return ByteArray(int_bytes, sizeof(int_bytes));
}
ExceptionOr<std::int32_t> ReadInt(InputStream* reader) {
ExceptionOr<ByteArray> read_bytes = reader->ReadExactly(sizeof(std::int32_t));
if (!read_bytes.ok()) {
return ExceptionOr<std::int32_t>(read_bytes.exception());
}
return ExceptionOr<std::int32_t>(BytesToInt(std::move(read_bytes.result())));
return ExceptionOr<std::int32_t>(
byte_utils::BytesToInt(std::move(read_bytes.result())));
}
Exception WriteInt(OutputStream* writer, std::int32_t value) {
return writer->Write(IntToBytes(value));
return writer->Write(byte_utils::IntToBytes(value));
}
} // namespace
+1 -1
View File
@@ -49,7 +49,7 @@ using ResultCallback = absl::AnyInvocable<void(Status)>;
struct ConnectionResponseInfo {
std::string GetAuthenticationDigits() {
return ByteUtils::ToFourDigitString(raw_authentication_token);
return byte_utils::ToFourDigitString(raw_authentication_token);
}
ByteArray remote_endpoint_info;
+4 -3
View File
@@ -14,13 +14,14 @@
#include "connections/listeners.h"
#include <memory>
#include <string>
#include <utility>
#include "gmock/gmock.h"
#include "protobuf-matchers/protocol-buffer-matchers.h"
#include "gtest/gtest.h"
#include "absl/strings/string_view.h"
#include "connections/medium_selector.h"
#include "connections/payload.h"
#include "connections/status.h"
#include "internal/platform/byte_array.h"
namespace nearby {
+33 -1
View File
@@ -14,6 +14,7 @@
#include "internal/platform/byte_utils.h"
#include <cstdint>
#include <cstdlib>
#include <string>
@@ -22,8 +23,18 @@
#include "internal/platform/stream_reader.h"
namespace nearby {
namespace byte_utils {
std::string ByteUtils::ToFourDigitString(ByteArray& bytes) {
namespace {
// The biggest prime number under 10000, used as a mod base to trim integers
// into 4 digits.
constexpr int kHashBasePrime = 9973;
// The hash multiplier.
constexpr int kHashBaseMultiplier = 31;
} // namespace
std::string ToFourDigitString(const ByteArray& bytes) {
int multiplier = 1;
int hashCode = 0;
@@ -36,4 +47,25 @@ std::string ByteUtils::ToFourDigitString(ByteArray& bytes) {
return absl::StrFormat("%04d", abs(hashCode));
}
int32_t BytesToInt(const ByteArray& bytes) {
const char* int_bytes = bytes.data();
int32_t result = 0;
for (int i = 0; i < bytes.size() && i < 4; ++i) {
result <<= 8;
result |= static_cast<int32_t>(int_bytes[i]) & 0x0FF;
}
return result;
}
ByteArray IntToBytes(int32_t value) {
ByteArray result(sizeof(int32_t));
char* buffer = result.data();
buffer[0] = static_cast<char>((value >> 24) & 0x0FF);
buffer[1] = static_cast<char>((value >> 16) & 0x0FF);
buffer[2] = static_cast<char>((value >> 8) & 0x0FF);
buffer[3] = static_cast<char>(value & 0x0FF);
return result;
}
} // namespace byte_utils
} // namespace nearby
+17 -12
View File
@@ -15,23 +15,28 @@
#ifndef PLATFORM_BASE_BYTE_UTILS_H_
#define PLATFORM_BASE_BYTE_UTILS_H_
#include <cstdint>
#include <string>
#include "internal/platform/byte_array.h"
namespace nearby {
// TODO(edwinwu): Remove this namespace and move all the functions into
// ByteArray class.
namespace nearby::byte_utils {
class ByteUtils {
public:
static std::string ToFourDigitString(ByteArray& bytes);
// Generates a four-digit numeric string representation of a byte array.
std::string ToFourDigitString(const ByteArray& bytes);
private:
// The biggest prime number under 10000, used as a mod base to trim integers
// into 4 digits.
static constexpr int kHashBasePrime = 9973;
// The hash multiplier.
static constexpr int kHashBaseMultiplier = 31;
};
// Converts a ByteArray to a 32-bit integer in big-endian format.
// It reads min(4, bytes.size()) bytes from input ByteArray; bytes[0] is
// read as MSB, bytes[1] as second byte, and so on. If bytes.size() < 4,
// bytes will be read to high order bytes of result and low order bytes
// will be 0.
int32_t BytesToInt(const ByteArray& bytes);
} // namespace nearby
// Converts a 32-bit integer to a 4-byte ByteArray in big-endian format.
ByteArray IntToBytes(int32_t value);
} // namespace nearby::byte_utils
#endif // PLATFORM_BASE_BYTE_UTILS_H_
+62 -7
View File
@@ -14,7 +14,9 @@
#include "internal/platform/byte_utils.h"
#include <cstdint>
#include <string>
#include <limits>
#include "gtest/gtest.h"
#include "absl/strings/string_view.h"
@@ -26,12 +28,12 @@ constexpr absl::string_view kFooBytes{"rawABCDE"};
constexpr absl::string_view kFooFourDigitsToken{"0392"};
constexpr absl::string_view kEmptyFourDigitsToken{"0000"};
constexpr absl::string_view kNegativeBytes{"raw\xd5\x01\xe4\x03\x81"};
constexpr absl::string_view kNegativeFourDigitsToken{"9084"};
constexpr absl::string_view kNegativeFourDigitsToken{"6251"};
TEST(ByteUtilsTest, ToFourDigitStringCorrect) {
ByteArray bytes{std::string(kFooBytes)};
auto four_digit_string = ByteUtils::ToFourDigitString(bytes);
auto four_digit_string = byte_utils::ToFourDigitString(bytes);
EXPECT_EQ(std::string(kFooFourDigitsToken), four_digit_string);
}
@@ -39,17 +41,70 @@ TEST(ByteUtilsTest, ToFourDigitStringCorrect) {
TEST(ByteUtilsTest, ToFourDigitStringNegativeCorrect) {
ByteArray bytes{std::string(kNegativeBytes)};
auto four_digit_string = ByteUtils::ToFourDigitString(bytes);
auto four_digit_string = byte_utils::ToFourDigitString(bytes);
EXPECT_EQ(std::string(kNegativeFourDigitsToken), kNegativeFourDigitsToken);
EXPECT_EQ(std::string(kNegativeFourDigitsToken), four_digit_string);
}
TEST(ByteUtilsTest, TestEmptyByteArrayCorrect) {
ByteArray bytes;
TEST(ByteUtilsTest, ToFourDigitStringHandlesEmptyInput) {
ByteArray bytes{};
auto four_digit_string = ByteUtils::ToFourDigitString(bytes);
auto four_digit_string = byte_utils::ToFourDigitString(bytes);
EXPECT_EQ(std::string(kEmptyFourDigitsToken), four_digit_string);
}
TEST(ByteUtilsTest, IntToBytesThenBytesToIntIsSymmetric) {
constexpr std::int32_t kTestValue = 123456789;
ByteArray bytes = byte_utils::IntToBytes(kTestValue);
EXPECT_EQ(kTestValue, byte_utils::BytesToInt(bytes));
}
TEST(ByteUtilsTest, IntToBytesThenBytesToIntIsSymmetricNegative) {
constexpr std::int32_t kTestValue = -123456789;
ByteArray bytes = byte_utils::IntToBytes(kTestValue);
EXPECT_EQ(kTestValue, byte_utils::BytesToInt(bytes));
}
TEST(ByteUtilsTest, BytesToIntHandlesZero) {
ByteArray bytes({'\0', '\0', '\0', '\0'});
EXPECT_EQ(0, byte_utils::BytesToInt(bytes));
}
TEST(ByteUtilsTest, BytesToIntHandlesNegative) {
ByteArray bytes({'\xff', '\xff', '\xff', '\xff'});
EXPECT_EQ(-1, byte_utils::BytesToInt(bytes));
}
TEST(ByteUtilsTest, BytesToIntHandlesNegativeLarge) {
ByteArray bytes({'\x80', '\x00', '\x00', '\x00'});
EXPECT_EQ(std::numeric_limits<std::int32_t>::min(),
byte_utils::BytesToInt(bytes));
}
TEST(ByteUtilsTest, IntToBytesHandlesZero) {
ByteArray expected_bytes({'\0', '\0', '\0', '\0'});
EXPECT_EQ(expected_bytes, byte_utils::IntToBytes(0));
}
TEST(ByteUtilsTest, HandlesInt32Max) {
constexpr std::int32_t kMaxValue = std::numeric_limits<std::int32_t>::max();
ByteArray bytes = byte_utils::IntToBytes(kMaxValue);
EXPECT_EQ(kMaxValue, byte_utils::BytesToInt(bytes));
}
TEST(ByteUtilsTest, HandlesInt32Min) {
constexpr std::int32_t kMinValue = std::numeric_limits<std::int32_t>::min();
ByteArray bytes = byte_utils::IntToBytes(kMinValue);
EXPECT_EQ(kMinValue, byte_utils::BytesToInt(bytes));
}
} // namespace nearby