Create a help class to generate data

PiperOrigin-RevId: 726714013
This commit is contained in:
Guogang Li
2025-02-13 18:25:07 -08:00
committed by Copybara-Service
parent 788984f182
commit 3de3a9479d
6 changed files with 273 additions and 1 deletions
+1
View File
@@ -521,6 +521,7 @@ let package = Package(
"internal/platform/input_stream_test.cc",
"internal/platform/single_thread_executor_test.cc",
"internal/platform/scheduled_executor_test.cc",
"internal/platform/stream_writer_test.cc",
"internal/platform/count_down_latch_test.cc",
"internal/platform/pipe_test.cc",
"internal/platform/timer_impl_test.cc",
+3
View File
@@ -84,10 +84,12 @@ cc_library(
srcs = [
"base_input_stream.cc",
"byte_utils.cc",
"stream_writer.cc",
],
hdrs = [
"base_input_stream.h",
"byte_utils.h",
"stream_writer.h",
],
visibility = [
"//connections:__subpackages__",
@@ -399,6 +401,7 @@ cc_test(
srcs = [
"base_input_stream_test.cc",
"byte_utils_test.cc",
"stream_writer_test.cc",
],
deps = [
":base",
+1 -1
View File
@@ -39,7 +39,7 @@ ExceptionOr<ByteArray> BaseInputStream::Read(std::int64_t size) {
}
std::optional<std::uint8_t> BaseInputStream::ReadBits(int bits) {
if (bits > 8) {
if (bits > 8 || bits <= 0) {
return std::nullopt;
}
if (bits_unused_ == 0) {
+126
View File
@@ -0,0 +1,126 @@
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "internal/platform/stream_writer.h"
#include <cstdint>
#include <string>
#include "internal/platform/exception.h"
namespace nearby {
std::string StreamWriter::GetData() {
if (bits_used_ != 0) {
return buffer_ + std::string(1, bits_buffer_);
}
return buffer_;
}
Exception StreamWriter::WriteBits(uint8_t value, int bits) {
if (bits >= 8 || bits <= 0 || 8 - bits < bits_used_) {
return Exception{Exception::kInvalidProtocolBuffer};
}
bits_buffer_ |= (value & ((1 << bits) - 1)) << (8 - bits - bits_used_);
bits_used_ += bits;
if (bits_used_ == 8) {
buffer_.push_back(bits_buffer_);
bits_used_ = 0;
bits_buffer_ = 0;
}
return Exception{Exception::kSuccess};
}
Exception StreamWriter::WriteUint8(uint8_t value) {
if (bits_used_ != 0) {
return Exception{Exception::kInvalidProtocolBuffer};
}
buffer_.push_back(value);
return Exception{Exception::kSuccess};
}
Exception StreamWriter::WriteInt8(int8_t value) {
return WriteUint8(static_cast<uint8_t>(value));
}
Exception StreamWriter::WriteUint16(uint16_t value) {
if (bits_used_ != 0) {
return Exception{Exception::kInvalidProtocolBuffer};
}
char bytes[2];
bytes[0] = (value >> 8) & 0xff;
bytes[1] = value & 0xff;
buffer_.append(bytes, 2);
return Exception{Exception::kSuccess};
}
Exception StreamWriter::WriteInt16(int16_t value) {
return WriteUint16(static_cast<uint16_t>(value));
}
Exception StreamWriter::WriteUint32(uint32_t value) {
if (bits_used_ != 0) {
return Exception{Exception::kInvalidProtocolBuffer};
}
char bytes[4];
bytes[0] = (value >> 24) & 0xff;
bytes[1] = (value >> 16) & 0xff;
bytes[2] = (value >> 8) & 0xff;
bytes[3] = value & 0xff;
buffer_.append(bytes, 4);
return Exception{Exception::kSuccess};
}
Exception StreamWriter::WriteInt32(int32_t value) {
return WriteUint32(static_cast<uint32_t>(value));
}
Exception StreamWriter::WriteUint64(uint64_t value) {
if (bits_used_ != 0) {
return Exception{Exception::kInvalidProtocolBuffer};
}
char bytes[8];
bytes[0] = (value >> 56) & 0xff;
bytes[1] = (value >> 48) & 0xff;
bytes[2] = (value >> 40) & 0xff;
bytes[3] = (value >> 32) & 0xff;
bytes[4] = (value >> 24) & 0xff;
bytes[5] = (value >> 16) & 0xff;
bytes[6] = (value >> 8) & 0xff;
bytes[7] = value & 0xff;
buffer_.append(bytes, 8);
return Exception{Exception::kSuccess};
}
Exception StreamWriter::WriteInt64(int64_t value) {
return WriteUint64(static_cast<uint64_t>(value));
}
Exception StreamWriter::WriteBytes(const std::string& data) {
if (bits_used_ != 0) {
return Exception{Exception::kInvalidProtocolBuffer};
}
buffer_.append(data);
return Exception{Exception::kSuccess};
}
} // namespace nearby
+55
View File
@@ -0,0 +1,55 @@
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_STREAM_WRITER_H_
#define THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_STREAM_WRITER_H_
#include <cstdint>
#include <string>
#include "internal/platform/exception.h"
namespace nearby {
// A base {@link StreamWriter } for writing the contents of a byte array.
// All internal data is stored in network order.
class StreamWriter {
public:
StreamWriter() = default;
~StreamWriter() = default;
std::string GetData();
// Writes less than 8 bits to the stream. The written bits cannot across a
// byte boundary.
Exception WriteBits(uint8_t value, int bits);
Exception WriteUint8(uint8_t value);
Exception WriteInt8(int8_t value);
Exception WriteUint16(uint16_t value);
Exception WriteInt16(int16_t value);
Exception WriteUint32(uint32_t value);
Exception WriteInt32(int32_t value);
Exception WriteUint64(uint64_t value);
Exception WriteInt64(int64_t value);
Exception WriteBytes(const std::string& data);
private:
uint8_t bits_used_{0};
uint8_t bits_buffer_{0};
std::string buffer_;
};
} // namespace nearby
#endif // THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_STREAM_WRITER_H_
+87
View File
@@ -0,0 +1,87 @@
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "internal/platform/stream_writer.h"
#include <string>
#include "gtest/gtest.h"
#include "internal/platform/exception.h"
namespace nearby {
namespace {
TEST(StreamWriterTest, WriteBits) {
StreamWriter writer;
EXPECT_EQ(writer.WriteBits(0x01, 1), Exception{Exception::kSuccess});
EXPECT_EQ(writer.WriteBits(0x01, 1), Exception{Exception::kSuccess});
EXPECT_EQ(writer.WriteBits(0x01, 1), Exception{Exception::kSuccess});
EXPECT_EQ(writer.WriteBits(0x00, 1), Exception{Exception::kSuccess});
EXPECT_EQ(writer.GetData(), std::string("\xe0"));
EXPECT_EQ(writer.WriteBits(0x01, 1), Exception{Exception::kSuccess});
EXPECT_EQ(writer.WriteBits(0x01, 1), Exception{Exception::kSuccess});
EXPECT_EQ(writer.WriteBits(0x01, 1), Exception{Exception::kSuccess});
EXPECT_EQ(writer.WriteBits(0x01, 1), Exception{Exception::kSuccess});
EXPECT_EQ(writer.GetData(), std::string("\xef"));
}
TEST(StreamWriterTest, WriteInvalidBits) {
StreamWriter writer;
EXPECT_EQ(writer.WriteBits(0x01, 1), Exception{Exception::kSuccess});
EXPECT_EQ(writer.WriteBits(0x01, 9),
Exception{Exception::kInvalidProtocolBuffer});
EXPECT_EQ(writer.WriteBits(0x03, 4), Exception{Exception::kSuccess});
EXPECT_EQ(writer.WriteBits(0x01, 5),
Exception{Exception::kInvalidProtocolBuffer});
}
TEST(StreamWriterTest, WriteIntegerValues) {
StreamWriter writer;
EXPECT_EQ(writer.WriteUint8(0x01), Exception{Exception::kSuccess});
EXPECT_EQ(writer.WriteInt8(0xf1), Exception{Exception::kSuccess});
EXPECT_EQ(writer.WriteUint16(0x0102), Exception{Exception::kSuccess});
EXPECT_EQ(writer.WriteInt16(0xf102), Exception{Exception::kSuccess});
EXPECT_EQ(writer.GetData(), "\x01\xF1\x01\x02\xF1\x02");
EXPECT_EQ(writer.WriteUint32(0x01020304), Exception{Exception::kSuccess});
EXPECT_EQ(writer.WriteInt32(0xf1020304), Exception{Exception::kSuccess});
writer = {};
EXPECT_EQ(writer.WriteUint64(0x0102030405060708),
Exception{Exception::kSuccess});
EXPECT_EQ(writer.WriteInt64(0xf102030405060708),
Exception{Exception::kSuccess});
EXPECT_EQ(writer.GetData(),
"\x01\x02\x03\x04\x05\x06\x07\x08\xF1\x02\x03\x04\x05\x06\x07\x08");
}
TEST(StreamWriterTest, InvalidWriteIntegerValues) {
StreamWriter writer;
EXPECT_EQ(writer.WriteBits(0x01, 1), Exception{Exception::kSuccess});
EXPECT_EQ(writer.WriteUint8(0x01),
Exception{Exception::kInvalidProtocolBuffer});
EXPECT_EQ(writer.WriteUint16(0x0102),
Exception{Exception::kInvalidProtocolBuffer});
EXPECT_EQ(writer.WriteUint32(0x01020304),
Exception{Exception::kInvalidProtocolBuffer});
EXPECT_EQ(writer.WriteUint64(0x0102030405060708),
Exception{Exception::kInvalidProtocolBuffer});
}
TEST(StreamWriterTest, WriteBytes) {
StreamWriter writer;
EXPECT_EQ(writer.WriteBytes("test"), Exception{Exception::kSuccess});
EXPECT_EQ(writer.GetData(), std::string("test"));
}
} // namespace
} // namespace nearby