ESPHome  2024.9.0
bytebuffer.cpp
Go to the documentation of this file.
1 #include "bytebuffer.h"
2 #include <cassert>
3 #include "esphome/core/helpers.h"
4 
5 #include <list>
6 #include <vector>
7 
8 namespace esphome {
9 
10 ByteBuffer ByteBuffer::wrap(const uint8_t *ptr, size_t len, Endian endianness) {
11  // there is a double copy happening here, could be optimized but at cost of clarity.
12  std::vector<uint8_t> data(ptr, ptr + len);
13  ByteBuffer buffer = {data};
14  buffer.endianness_ = endianness;
15  return buffer;
16 }
17 
18 ByteBuffer ByteBuffer::wrap(std::vector<uint8_t> const &data, Endian endianness) {
19  ByteBuffer buffer = {data};
20  buffer.endianness_ = endianness;
21  return buffer;
22 }
23 
24 ByteBuffer ByteBuffer::wrap(uint8_t value) {
25  ByteBuffer buffer = ByteBuffer(1);
26  buffer.put_uint8(value);
27  buffer.flip();
28  return buffer;
29 }
30 
31 ByteBuffer ByteBuffer::wrap(uint16_t value, Endian endianness) {
32  ByteBuffer buffer = ByteBuffer(2, endianness);
33  buffer.put_uint16(value);
34  buffer.flip();
35  return buffer;
36 }
37 
38 ByteBuffer ByteBuffer::wrap(uint32_t value, Endian endianness) {
39  ByteBuffer buffer = ByteBuffer(4, endianness);
40  buffer.put_uint32(value);
41  buffer.flip();
42  return buffer;
43 }
44 
45 ByteBuffer ByteBuffer::wrap(uint64_t value, Endian endianness) {
46  ByteBuffer buffer = ByteBuffer(8, endianness);
47  buffer.put_uint64(value);
48  buffer.flip();
49  return buffer;
50 }
51 
52 ByteBuffer ByteBuffer::wrap(float value, Endian endianness) {
53  ByteBuffer buffer = ByteBuffer(sizeof(float), endianness);
54  buffer.put_float(value);
55  buffer.flip();
56  return buffer;
57 }
58 
59 ByteBuffer ByteBuffer::wrap(double value, Endian endianness) {
60  ByteBuffer buffer = ByteBuffer(sizeof(double), endianness);
61  buffer.put_double(value);
62  buffer.flip();
63  return buffer;
64 }
65 
66 void ByteBuffer::set_limit(size_t limit) {
67  assert(limit <= this->get_capacity());
68  this->limit_ = limit;
69 }
71  assert(position <= this->get_limit());
72  this->position_ = position;
73 }
75  this->limit_ = this->get_capacity();
76  this->position_ = 0;
77 }
79  this->limit_ = this->position_;
80  this->position_ = 0;
81 }
82 
85  assert(this->get_remaining() >= 1);
86  return this->data_[this->position_++];
87 }
88 uint64_t ByteBuffer::get_uint(size_t length) {
89  assert(this->get_remaining() >= length);
90  uint64_t value = 0;
91  if (this->endianness_ == LITTLE) {
92  this->position_ += length;
93  auto index = this->position_;
94  while (length-- != 0) {
95  value <<= 8;
96  value |= this->data_[--index];
97  }
98  } else {
99  while (length-- != 0) {
100  value <<= 8;
101  value |= this->data_[this->position_++];
102  }
103  }
104  return value;
105 }
106 
108  auto value = this->get_uint24();
109  uint32_t mask = (~static_cast<uint32_t>(0)) << 23;
110  if ((value & mask) != 0)
111  value |= mask;
112  return value;
113 }
115  assert(this->get_remaining() >= sizeof(float));
116  return bit_cast<float>(this->get_uint32());
117 }
119  assert(this->get_remaining() >= sizeof(double));
120  return bit_cast<double>(this->get_uint64());
121 }
122 
123 std::vector<uint8_t> ByteBuffer::get_vector(size_t length) {
124  assert(this->get_remaining() >= length);
125  auto start = this->data_.begin() + this->position_;
126  this->position_ += length;
127  return {start, start + length};
128 }
129 
131 void ByteBuffer::put_uint8(uint8_t value) {
132  assert(this->get_remaining() >= 1);
133  this->data_[this->position_++] = value;
134 }
135 
136 void ByteBuffer::put_uint(uint64_t value, size_t length) {
137  assert(this->get_remaining() >= length);
138  if (this->endianness_ == LITTLE) {
139  while (length-- != 0) {
140  this->data_[this->position_++] = static_cast<uint8_t>(value);
141  value >>= 8;
142  }
143  } else {
144  this->position_ += length;
145  auto index = this->position_;
146  while (length-- != 0) {
147  this->data_[--index] = static_cast<uint8_t>(value);
148  value >>= 8;
149  }
150  }
151 }
152 void ByteBuffer::put_float(float value) {
153  static_assert(sizeof(float) == sizeof(uint32_t), "Float sizes other than 32 bit not supported");
154  assert(this->get_remaining() >= sizeof(float));
155  this->put_uint32(bit_cast<uint32_t>(value));
156 }
157 void ByteBuffer::put_double(double value) {
158  static_assert(sizeof(double) == sizeof(uint64_t), "Double sizes other than 64 bit not supported");
159  assert(this->get_remaining() >= sizeof(double));
160  this->put_uint64(bit_cast<uint64_t>(value));
161 }
162 void ByteBuffer::put_vector(const std::vector<uint8_t> &value) {
163  assert(this->get_remaining() >= value.size());
164  std::copy(value.begin(), value.end(), this->data_.begin() + this->position_);
165  this->position_ += value.size();
166 }
167 } // namespace esphome
void put_uint32(uint32_t value)
Definition: bytebuffer.h:102
size_t get_limit() const
Definition: bytebuffer.h:118
void set_limit(size_t limit)
Definition: bytebuffer.cpp:66
void put_uint64(uint64_t value)
Definition: bytebuffer.h:103
std::vector< uint8_t > data_
Definition: bytebuffer.h:137
uint32_t get_uint32()
Definition: bytebuffer.h:78
static ByteBuffer wrap(std::vector< uint8_t > const &data, Endian endianness=LITTLE)
Wrap an existing vector in a ByteBufffer.
Definition: bytebuffer.cpp:18
std::vector< uint8_t > get_vector(size_t length)
Definition: bytebuffer.cpp:123
void put_uint8(uint8_t value)
Putters.
Definition: bytebuffer.cpp:131
uint8_t get_uint8()
Getters.
Definition: bytebuffer.cpp:84
void put_uint(uint64_t value, size_t length)
Definition: bytebuffer.cpp:136
uint32_t get_int24()
Definition: bytebuffer.cpp:107
void put_double(double value)
Definition: bytebuffer.cpp:157
uint64_t get_uint(size_t length)
Definition: bytebuffer.cpp:88
void put_uint16(uint16_t value)
Definition: bytebuffer.h:100
size_t get_capacity() const
Definition: bytebuffer.h:116
void put_float(float value)
Definition: bytebuffer.cpp:152
size_t get_remaining() const
Definition: bytebuffer.h:119
std::string size_t len
Definition: helpers.h:292
To bit_cast(const From &src)
Convert data between types, without aliasing issues or undefined behaviour.
Definition: helpers.h:121
void set_position(size_t position)
Definition: bytebuffer.cpp:70
uint16_t length
Definition: tt21100.cpp:12
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
float position
Definition: cover.h:14
A class modelled on the Java ByteBuffer class.
Definition: bytebuffer.h:33
uint64_t get_uint64()
Definition: bytebuffer.h:80
void put_vector(const std::vector< uint8_t > &value)
Definition: bytebuffer.cpp:162
uint32_t get_uint24()
Definition: bytebuffer.h:76