普通文本  |  248行  |  7.67 KB

/*
 * Copyright 2019 The Android Open Source Project
 *
 * 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
 *
 *      http://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 "packet/packet_builder.h"

#include <gtest/gtest.h>
#include <forward_list>
#include <memory>

using bluetooth::packet::BasePacketBuilder;
using bluetooth::packet::BitInserter;
using bluetooth::packet::PacketBuilder;
using std::vector;

namespace {
vector<uint8_t> count_all = {
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
};

vector<uint8_t> count_1 = {
    0x00,
    0x01,
    0x02,
};

vector<uint8_t> count_2 = {
    0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
};

vector<uint8_t> count_3 = {
    0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
};
}  // namespace

namespace bluetooth {
namespace packet {

template <bool little_endian>
class EndianBuilder : public PacketBuilder<little_endian> {
 public:
  EndianBuilder(uint8_t byte, uint16_t two_bytes, uint32_t four_bytes, uint64_t eight_bytes)
      : byte_(byte), two_bytes_(two_bytes), four_bytes_(four_bytes), eight_bytes_(eight_bytes) {}
  ~EndianBuilder() = default;

  virtual size_t size() const override {
    return sizeof(signature_) + sizeof(byte_) + sizeof(two_bytes_) + sizeof(four_bytes_) + sizeof(eight_bytes_);
  }

  virtual const std::unique_ptr<std::vector<uint8_t>> FinalPacket() {
    std::unique_ptr<std::vector<uint8_t>> packet = std::make_unique<std::vector<uint8_t>>();
    packet->reserve(size());
    BitInserter it(*packet);
    Serialize(it);
    return packet;
  }

  virtual void Serialize(BitInserter& it) const override {
    PacketBuilder<little_endian>::insert(signature_, it);
    PacketBuilder<little_endian>::insert(byte_, it);
    PacketBuilder<little_endian>::insert(two_bytes_, it);
    PacketBuilder<little_endian>::insert(four_bytes_, it);
    PacketBuilder<little_endian>::insert(eight_bytes_, it);
  }

 private:
  uint32_t signature_{(little_endian ? 0x03020100 : 0x00010203)};
  uint8_t byte_;
  uint16_t two_bytes_;
  uint32_t four_bytes_;
  uint64_t eight_bytes_;
};

class PacketBuilderEndianTest : public ::testing::Test {
 public:
  PacketBuilderEndianTest() = default;
  ~PacketBuilderEndianTest() = default;
};

TEST(PacketBuilderEndianTest, insertTest) {
  EndianBuilder<true> little(0x04, 0x0605, 0x0a090807, 0x1211100f0e0d0c0b);
  EndianBuilder<false> big(0x04, 0x0506, 0x0708090a, 0x0b0c0d0e0f101112);
  ASSERT_EQ(*big.FinalPacket(), *little.FinalPacket());
}

template <typename T>
class VectorBuilder : public PacketBuilder<true> {
 public:
  VectorBuilder(std::vector<uint64_t> vect) {
    for (uint64_t element : vect) {
      vect.push_back(static_cast<T>(element));
    }
  }
  ~VectorBuilder() = default;

  virtual size_t size() const override {
    return vect_.size() * sizeof(T);
  }

  virtual const std::unique_ptr<std::vector<uint8_t>> FinalPacket() {
    std::unique_ptr<std::vector<uint8_t>> packet = std::make_unique<std::vector<uint8_t>>();
    packet->reserve(size());
    BitInserter it(*packet);
    Serialize(it);
    return packet;
  }

  virtual void Serialize(BitInserter& it) const override {
    PacketBuilder<true>::insert_vector(vect_, it);
  }

 private:
  std::vector<T> vect_;
};

template <typename T>
class InsertElementsBuilder : public PacketBuilder<true> {
 public:
  InsertElementsBuilder(std::vector<uint64_t> vect) {
    for (uint64_t element : vect) {
      vect.push_back(static_cast<T>(element));
    }
  }
  virtual ~InsertElementsBuilder() = default;

  virtual size_t size() const override {
    return vect_.size() * sizeof(T);
  }

  virtual const std::unique_ptr<std::vector<uint8_t>> FinalPacket() {
    std::unique_ptr<std::vector<uint8_t>> packet = std::make_unique<std::vector<uint8_t>>();
    packet->reserve(size());
    BitInserter it(*packet);
    Serialize(it);
    return packet;
  }

  virtual void Serialize(BitInserter& it) const override {
    for (T elem : vect_) {
      PacketBuilder<true>::insert(elem, it);
    }
  }

 private:
  std::vector<T> vect_;
};

std::vector<uint64_t> vector_data{
    0x7060504030201000, 0x7161514131211101, 0x7262524232221202, 0x7363534333231303, 0x7464544434241404,
    0x7565554535251505, 0x7666564636261606, 0x7767574737271707, 0x7868584838281808,
};

template <typename T>
class VectorBuilderTest : public ::testing::Test {
 public:
  VectorBuilderTest() = default;
  ~VectorBuilderTest() = default;

  void SetUp() {
    packet_1_ = std::shared_ptr<VectorBuilder<T>>(new VectorBuilder<T>(vector_data));
    packet_2_ = std::shared_ptr<InsertElementsBuilder<T>>(new InsertElementsBuilder<T>(vector_data));
  }

  void TearDown() {
    packet_1_.reset();
    packet_2_.reset();
  }

  std::shared_ptr<VectorBuilder<T>> packet_1_;
  std::shared_ptr<InsertElementsBuilder<T>> packet_2_;
};

using VectorBaseTypes = ::testing::Types<uint8_t, uint16_t, uint32_t, uint64_t, int8_t, int16_t, int32_t, int64_t>;
TYPED_TEST_CASE(VectorBuilderTest, VectorBaseTypes);

TYPED_TEST(VectorBuilderTest, insertVectorTest) {
  ASSERT_EQ(*(this->packet_1_->FinalPacket()), *(this->packet_2_->FinalPacket()));
}

class NestedBuilder : public PacketBuilder<true> {
 public:
  ~NestedBuilder() = default;

  virtual size_t size() const override {
    size_t payload_size = (payload_ ? payload_->size() : 0);
    return 1 + payload_size;
  }

  static std::unique_ptr<NestedBuilder> Create(uint8_t level) {
    return std::unique_ptr<NestedBuilder>(new NestedBuilder(level));
  }

  static std::unique_ptr<NestedBuilder> CreateNested(std::unique_ptr<BasePacketBuilder> payload, uint8_t level) {
    return std::unique_ptr<NestedBuilder>(new NestedBuilder(std::move(payload), level));
  }

  virtual const std::unique_ptr<std::vector<uint8_t>> FinalPacket() {
    std::unique_ptr<std::vector<uint8_t>> packet = std::make_unique<std::vector<uint8_t>>();
    packet->reserve(size());
    BitInserter it(*packet);
    Serialize(it);
    return packet;
  }

  virtual void Serialize(BitInserter& it) const override {
    PacketBuilder<true>::insert(level_, it);
    if (payload_) {
      payload_->Serialize(it);
    }
  }

 private:
  std::unique_ptr<BasePacketBuilder> payload_;
  uint8_t level_;

  NestedBuilder(std::unique_ptr<BasePacketBuilder> inner, uint8_t level) : payload_(std::move(inner)), level_(level) {}
  NestedBuilder(uint8_t level) : level_(level) {}
};

class BuilderBuilderTest : public ::testing::Test {};

TEST(BuilderBuilderTest, nestingTest) {
  std::unique_ptr<BasePacketBuilder> innermost = NestedBuilder::Create(0);
  std::unique_ptr<BasePacketBuilder> number_1 = NestedBuilder::CreateNested(std::move(innermost), 1);
  std::unique_ptr<BasePacketBuilder> number_2 = NestedBuilder::CreateNested(std::move(number_1), 2);
  std::unique_ptr<BasePacketBuilder> number_3 = NestedBuilder::CreateNested(std::move(number_2), 3);
  std::unique_ptr<BasePacketBuilder> number_4 = NestedBuilder::CreateNested(std::move(number_3), 4);
  std::unique_ptr<NestedBuilder> number_5 = NestedBuilder::CreateNested(std::move(number_4), 5);

  std::vector<uint8_t> count_down{5, 4, 3, 2, 1, 0};
  ASSERT_EQ(*number_5->FinalPacket(), count_down);
}
}  // namespace packet
}  // namespace bluetooth