CatapultServer  v0.5.0.1 (Elephant)
PacketPayloadBuilder.h
Go to the documentation of this file.
1 
21 #pragma once
22 #include "PacketPayload.h"
25 
26 namespace catapult { namespace ionet {
27 
30  public:
32  explicit PacketPayloadBuilder(PacketType type) : PacketPayloadBuilder(type, std::numeric_limits<uint32_t>::max())
33  {}
34 
36  explicit PacketPayloadBuilder(PacketType type, uint32_t maxPacketDataSize)
37  : m_maxPacketDataSize(maxPacketDataSize)
38  , m_payload(type)
39  , m_hasError(false)
40  {}
41 
42  public:
44  template<typename TEntity>
45  bool appendEntity(const std::shared_ptr<TEntity>& pEntity) {
46  if (!increaseSize(pEntity->Size))
47  return false;
48 
49  m_payload.m_buffers.push_back({ reinterpret_cast<const uint8_t*>(pEntity.get()), pEntity->Size });
50  m_payload.m_entities.push_back(pEntity);
51  return true;
52  }
53 
55  template<typename TEntity>
56  bool appendEntities(const std::vector<std::shared_ptr<TEntity>>& entities) {
57  for (const auto& pEntity : entities) {
58  if (!appendEntity(pEntity))
59  return false;
60  }
61 
62  return true;
63  }
64 
66  template<typename TEntityGenerator>
67  bool appendGeneratedEntities(TEntityGenerator&& generator) {
68  for (;;) {
69  auto pEntity = generator();
70  if (!pEntity)
71  return true;
72 
73  if (!appendEntity(pEntity))
74  return false;
75  }
76  }
77 
79  template<typename TEntity>
81  auto rangeSize = static_cast<uint32_t>(sizeof(TEntity) * range.size());
82  if (!increaseSize(rangeSize))
83  return false;
84 
85  if (!range.empty()) {
86  m_payload.m_buffers.push_back({ reinterpret_cast<const uint8_t*>(range.data()), rangeSize });
87  m_payload.m_entities.push_back(std::make_shared<model::EntityRange<TEntity>>(std::move(range)));
88  }
89 
90  return true;
91  }
92 
94  template<typename TValue>
95  bool appendValue(const TValue& value) {
96  if (!increaseSize(sizeof(TValue)))
97  return false;
98 
99  auto pValue = std::make_shared<TValue>(value);
100  m_payload.m_buffers.push_back({ reinterpret_cast<const uint8_t*>(pValue.get()), sizeof(TValue) });
101  m_payload.m_entities.push_back(pValue);
102  return true;
103  }
104 
106  template<typename TValue>
107  bool appendValues(const std::vector<TValue>& values) {
108  auto valuesSize = static_cast<uint32_t>(sizeof(TValue) * values.size());
109  if (!increaseSize(valuesSize))
110  return false;
111 
112  if (!values.empty()) {
113  auto pValues = utils::MakeSharedWithSize<uint8_t>(valuesSize);
114  std::memcpy(pValues.get(), values.data(), valuesSize);
115  m_payload.m_buffers.push_back({ pValues.get(), valuesSize });
116  m_payload.m_entities.push_back(pValues);
117  }
118 
119  return true;
120  }
121 
124  template<typename TValueGenerator>
125  bool appendGeneratedValues(TValueGenerator&& generator) {
126  using ValueType = std::remove_const_t<std::remove_reference_t<decltype(*generator())>>;
127  std::vector<ValueType> values;
128  for (;;) {
129  auto pValue = generator();
130  if (!pValue)
131  break;
132 
133  values.push_back(*pValue);
134  }
135 
136  return appendValues(values);
137  }
138 
139  public:
142  return m_hasError ? PacketPayload() : std::move(m_payload);
143  }
144 
145  private:
146  bool increaseSize(uint32_t numBytes) {
147  // check for overflow and against m_maxPacketDataSize
148  auto& header = m_payload.m_header;
149  if (m_hasError || !utils::CheckedAdd(header.Size, numBytes) || !IsPacketDataSizeValid(header, m_maxPacketDataSize)) {
150  m_hasError = true;
151  return false;
152  }
153 
154  return true;
155  }
156 
157  private:
161  };
162 }}
catapult::ionet::PacketPayloadBuilder::appendGeneratedValues
bool appendGeneratedValues(TValueGenerator &&generator)
Definition: PacketPayloadBuilder.h:125
catapult::ionet::PacketPayload::m_buffers
std::vector< RawBuffer > m_buffers
Definition: PacketPayload.h:56
IntegerMath.h
catapult::ionet::PacketPayload::m_entities
std::vector< std::shared_ptr< const void > > m_entities
Definition: PacketPayload.h:59
catapult::model::EntityRange
Represents a range of entities.
Definition: EntityRange.h:31
catapult::ionet::PacketPayloadBuilder::appendEntity
bool appendEntity(const std::shared_ptr< TEntity > &pEntity)
Appends a single entity (pEntity) to the payload.
Definition: PacketPayloadBuilder.h:45
catapult::ionet::PacketPayloadBuilder::appendValue
bool appendValue(const TValue &value)
Appends a fixed size value to the payload.
Definition: PacketPayloadBuilder.h:95
catapult::ionet::PacketType
PacketType
An enumeration of known packet types.
Definition: PacketType.h:171
catapult::ionet::PacketPayloadBuilder
A packet payload builder for creating payloads composed of heterogeneous data.
Definition: PacketPayloadBuilder.h:29
catapult::ionet::PacketPayloadBuilder::m_maxPacketDataSize
uint32_t m_maxPacketDataSize
Definition: PacketPayloadBuilder.h:158
catapult::ionet::IsPacketDataSizeValid
constexpr bool IsPacketDataSizeValid(const PacketHeader &header, size_t maxPacketDataSize)
Determines if header indicates a valid packet data size no greater than maxPacketDataSize.
Definition: PacketHeader.h:41
catapult::ionet::PacketPayloadBuilder::appendValues
bool appendValues(const std::vector< TValue > &values)
Appends fixed size values to the payload.
Definition: PacketPayloadBuilder.h:107
catapult::ionet::PacketPayloadBuilder::appendGeneratedEntities
bool appendGeneratedEntities(TEntityGenerator &&generator)
Appends all entities produced by generator to the payload.
Definition: PacketPayloadBuilder.h:67
catapult::ionet::PacketPayload::m_header
PacketHeader m_header
Definition: PacketPayload.h:55
catapult::ionet::PacketPayloadBuilder::PacketPayloadBuilder
PacketPayloadBuilder(PacketType type, uint32_t maxPacketDataSize)
Creates builder for a packet with the specified type and max packet data size (maxPacketDataSize).
Definition: PacketPayloadBuilder.h:36
PacketPayload.h
EntityRange.h
catapult::ionet::PacketPayloadBuilder::m_payload
PacketPayload m_payload
Definition: PacketPayloadBuilder.h:159
catapult::ionet::PacketPayloadBuilder::build
PacketPayload build()
Builds the packet payload.
Definition: PacketPayloadBuilder.h:141
catapult::ionet::PacketPayload
A packet payload that can be written.
Definition: PacketPayload.h:29
catapult
Definition: AddressExtractionExtension.cpp:28
catapult::ionet::PacketPayloadBuilder::PacketPayloadBuilder
PacketPayloadBuilder(PacketType type)
Creates builder for a packet with the specified type.
Definition: PacketPayloadBuilder.h:32
catapult::ionet::PacketPayloadBuilder::m_hasError
bool m_hasError
Definition: PacketPayloadBuilder.h:160
catapult::ionet::PacketPayloadBuilder::increaseSize
bool increaseSize(uint32_t numBytes)
Definition: PacketPayloadBuilder.h:146
catapult::ionet::PacketPayloadBuilder::appendRange
bool appendRange(model::EntityRange< TEntity > &&range)
Appends a fixed size range to the payload.
Definition: PacketPayloadBuilder.h:80
catapult::utils::CheckedAdd
bool CheckedAdd(T &value, T delta)
Adds delta to value if and only if there is no overflow.
Definition: IntegerMath.h:30
catapult::ionet::PacketPayloadBuilder::appendEntities
bool appendEntities(const std::vector< std::shared_ptr< TEntity >> &entities)
Appends all entities to the payload.
Definition: PacketPayloadBuilder.h:56