mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-16 07:36:10 -04:00
Create a help class to generate data
PiperOrigin-RevId: 726714013
This commit is contained in:
committed by
Copybara-Service
parent
788984f182
commit
3de3a9479d
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
@@ -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_
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user