joy
Dependencies: mbed USBDevice USBJoystick_
buffer_builder.hpp@2:d9f806076779, 2021-08-01 (annotated)
- Committer:
- gagarinlg
- Date:
- Sun Aug 01 17:36:27 2021 +0000
- Revision:
- 2:d9f806076779
done
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
gagarinlg | 2:d9f806076779 | 1 | /* |
gagarinlg | 2:d9f806076779 | 2 | * buffer_builder.hpp |
gagarinlg | 2:d9f806076779 | 3 | * |
gagarinlg | 2:d9f806076779 | 4 | * Created on: Nov 25, 2011 |
gagarinlg | 2:d9f806076779 | 5 | * Author: premmers |
gagarinlg | 2:d9f806076779 | 6 | */ |
gagarinlg | 2:d9f806076779 | 7 | |
gagarinlg | 2:d9f806076779 | 8 | #ifndef BUFFER_BUILDER_HPP_ |
gagarinlg | 2:d9f806076779 | 9 | #define BUFFER_BUILDER_HPP_ |
gagarinlg | 2:d9f806076779 | 10 | |
gagarinlg | 2:d9f806076779 | 11 | #include <vector> |
gagarinlg | 2:d9f806076779 | 12 | #include <assert.h> |
gagarinlg | 2:d9f806076779 | 13 | #include <stdint.h> |
gagarinlg | 2:d9f806076779 | 14 | #include <string.h> |
gagarinlg | 2:d9f806076779 | 15 | |
gagarinlg | 2:d9f806076779 | 16 | //#include "utilities.h" |
gagarinlg | 2:d9f806076779 | 17 | |
gagarinlg | 2:d9f806076779 | 18 | class buffer_builder |
gagarinlg | 2:d9f806076779 | 19 | { |
gagarinlg | 2:d9f806076779 | 20 | public: |
gagarinlg | 2:d9f806076779 | 21 | static inline void put(uint8_t *&p, uint8_t &bitoffset, uint8_t fieldlen, uint32_t value) { |
gagarinlg | 2:d9f806076779 | 22 | |
gagarinlg | 2:d9f806076779 | 23 | assert(bitoffset < 8); |
gagarinlg | 2:d9f806076779 | 24 | assert(fieldlen <= 32); |
gagarinlg | 2:d9f806076779 | 25 | |
gagarinlg | 2:d9f806076779 | 26 | uint32_t mask = (1U<<fieldlen)-1; |
gagarinlg | 2:d9f806076779 | 27 | value &= mask; |
gagarinlg | 2:d9f806076779 | 28 | |
gagarinlg | 2:d9f806076779 | 29 | uint8_t b; |
gagarinlg | 2:d9f806076779 | 30 | |
gagarinlg | 2:d9f806076779 | 31 | // first byte |
gagarinlg | 2:d9f806076779 | 32 | if (bitoffset > 0) |
gagarinlg | 2:d9f806076779 | 33 | { |
gagarinlg | 2:d9f806076779 | 34 | uint8_t remaining_bits = 8-bitoffset; |
gagarinlg | 2:d9f806076779 | 35 | int8_t unused_bits = int8_t(remaining_bits - fieldlen); |
gagarinlg | 2:d9f806076779 | 36 | if (unused_bits > 0) |
gagarinlg | 2:d9f806076779 | 37 | { |
gagarinlg | 2:d9f806076779 | 38 | b = *p; |
gagarinlg | 2:d9f806076779 | 39 | b &= ~(mask << unused_bits); |
gagarinlg | 2:d9f806076779 | 40 | b |= value << unused_bits; |
gagarinlg | 2:d9f806076779 | 41 | *p = b; |
gagarinlg | 2:d9f806076779 | 42 | bitoffset += fieldlen; |
gagarinlg | 2:d9f806076779 | 43 | return; |
gagarinlg | 2:d9f806076779 | 44 | } |
gagarinlg | 2:d9f806076779 | 45 | |
gagarinlg | 2:d9f806076779 | 46 | // all the remaining bits in first byte are in use |
gagarinlg | 2:d9f806076779 | 47 | fieldlen -= remaining_bits; |
gagarinlg | 2:d9f806076779 | 48 | b = *p; |
gagarinlg | 2:d9f806076779 | 49 | b &= ~(mask >> fieldlen); |
gagarinlg | 2:d9f806076779 | 50 | b |= value >> fieldlen; |
gagarinlg | 2:d9f806076779 | 51 | *p++ = b; |
gagarinlg | 2:d9f806076779 | 52 | bitoffset = 0; |
gagarinlg | 2:d9f806076779 | 53 | } |
gagarinlg | 2:d9f806076779 | 54 | |
gagarinlg | 2:d9f806076779 | 55 | // middle section (whole bytes) |
gagarinlg | 2:d9f806076779 | 56 | while (fieldlen >= 8) |
gagarinlg | 2:d9f806076779 | 57 | { |
gagarinlg | 2:d9f806076779 | 58 | fieldlen -= 8; |
gagarinlg | 2:d9f806076779 | 59 | *p++ = (value >> fieldlen) & 0xFF; |
gagarinlg | 2:d9f806076779 | 60 | } |
gagarinlg | 2:d9f806076779 | 61 | |
gagarinlg | 2:d9f806076779 | 62 | // last byte |
gagarinlg | 2:d9f806076779 | 63 | if (fieldlen > 0) |
gagarinlg | 2:d9f806076779 | 64 | { |
gagarinlg | 2:d9f806076779 | 65 | b = *p; |
gagarinlg | 2:d9f806076779 | 66 | b &= 0xFFU >> fieldlen; |
gagarinlg | 2:d9f806076779 | 67 | b |= value << (8-fieldlen); |
gagarinlg | 2:d9f806076779 | 68 | *p = b; |
gagarinlg | 2:d9f806076779 | 69 | bitoffset = fieldlen; |
gagarinlg | 2:d9f806076779 | 70 | } |
gagarinlg | 2:d9f806076779 | 71 | } |
gagarinlg | 2:d9f806076779 | 72 | |
gagarinlg | 2:d9f806076779 | 73 | static inline void put_u8(uint8_t *&p, uint8_t b) |
gagarinlg | 2:d9f806076779 | 74 | { |
gagarinlg | 2:d9f806076779 | 75 | *p++ = b; |
gagarinlg | 2:d9f806076779 | 76 | } |
gagarinlg | 2:d9f806076779 | 77 | static inline void put_u16(uint8_t *&p, uint16_t w) |
gagarinlg | 2:d9f806076779 | 78 | { |
gagarinlg | 2:d9f806076779 | 79 | *p++ = (uint8_t)(w>> 8); |
gagarinlg | 2:d9f806076779 | 80 | *p++ = (uint8_t)(w); |
gagarinlg | 2:d9f806076779 | 81 | } |
gagarinlg | 2:d9f806076779 | 82 | static inline void put_u16le(uint8_t *&p, uint16_t w) |
gagarinlg | 2:d9f806076779 | 83 | { |
gagarinlg | 2:d9f806076779 | 84 | *p++ = (uint8_t)(w); |
gagarinlg | 2:d9f806076779 | 85 | *p++ = (uint8_t)(w>> 8); |
gagarinlg | 2:d9f806076779 | 86 | } |
gagarinlg | 2:d9f806076779 | 87 | static inline void put_u32(uint8_t *&p, uint32_t d) |
gagarinlg | 2:d9f806076779 | 88 | { |
gagarinlg | 2:d9f806076779 | 89 | *p++ = (uint8_t)(d>>24); |
gagarinlg | 2:d9f806076779 | 90 | *p++ = (uint8_t)(d>>16); |
gagarinlg | 2:d9f806076779 | 91 | *p++ = (uint8_t)(d>> 8); |
gagarinlg | 2:d9f806076779 | 92 | *p++ = (uint8_t)(d); |
gagarinlg | 2:d9f806076779 | 93 | } |
gagarinlg | 2:d9f806076779 | 94 | static inline void put_u32le(uint8_t *&p, uint32_t d) |
gagarinlg | 2:d9f806076779 | 95 | { |
gagarinlg | 2:d9f806076779 | 96 | *p++ = (uint8_t)(d); |
gagarinlg | 2:d9f806076779 | 97 | *p++ = (uint8_t)(d>> 8); |
gagarinlg | 2:d9f806076779 | 98 | *p++ = (uint8_t)(d>>16); |
gagarinlg | 2:d9f806076779 | 99 | *p++ = (uint8_t)(d>>24); |
gagarinlg | 2:d9f806076779 | 100 | } |
gagarinlg | 2:d9f806076779 | 101 | static inline void put_u64(uint8_t *&p, uint64_t d) |
gagarinlg | 2:d9f806076779 | 102 | { |
gagarinlg | 2:d9f806076779 | 103 | *p++ = (uint8_t)(d>>56); |
gagarinlg | 2:d9f806076779 | 104 | *p++ = (uint8_t)(d>>48); |
gagarinlg | 2:d9f806076779 | 105 | *p++ = (uint8_t)(d>>40); |
gagarinlg | 2:d9f806076779 | 106 | *p++ = (uint8_t)(d>>32); |
gagarinlg | 2:d9f806076779 | 107 | *p++ = (uint8_t)(d>>24); |
gagarinlg | 2:d9f806076779 | 108 | *p++ = (uint8_t)(d>>16); |
gagarinlg | 2:d9f806076779 | 109 | *p++ = (uint8_t)(d>> 8); |
gagarinlg | 2:d9f806076779 | 110 | *p++ = (uint8_t)(d); |
gagarinlg | 2:d9f806076779 | 111 | } |
gagarinlg | 2:d9f806076779 | 112 | static inline void put_u64le(uint8_t *&p, uint64_t d) |
gagarinlg | 2:d9f806076779 | 113 | { |
gagarinlg | 2:d9f806076779 | 114 | *p++ = (uint8_t)(d); |
gagarinlg | 2:d9f806076779 | 115 | *p++ = (uint8_t)(d>> 8); |
gagarinlg | 2:d9f806076779 | 116 | *p++ = (uint8_t)(d>>16); |
gagarinlg | 2:d9f806076779 | 117 | *p++ = (uint8_t)(d>>24); |
gagarinlg | 2:d9f806076779 | 118 | *p++ = (uint8_t)(d>>32); |
gagarinlg | 2:d9f806076779 | 119 | *p++ = (uint8_t)(d>>40); |
gagarinlg | 2:d9f806076779 | 120 | *p++ = (uint8_t)(d>>48); |
gagarinlg | 2:d9f806076779 | 121 | *p++ = (uint8_t)(d>>56); |
gagarinlg | 2:d9f806076779 | 122 | } |
gagarinlg | 2:d9f806076779 | 123 | static inline void put(uint8_t *&p, const uint8_t *data, size_t len) |
gagarinlg | 2:d9f806076779 | 124 | { |
gagarinlg | 2:d9f806076779 | 125 | memcpy(p, data, len); |
gagarinlg | 2:d9f806076779 | 126 | p += len; |
gagarinlg | 2:d9f806076779 | 127 | } |
gagarinlg | 2:d9f806076779 | 128 | |
gagarinlg | 2:d9f806076779 | 129 | static inline void put_u8(std::vector<uint8_t> &v, uint8_t b) |
gagarinlg | 2:d9f806076779 | 130 | { |
gagarinlg | 2:d9f806076779 | 131 | v.push_back(b); |
gagarinlg | 2:d9f806076779 | 132 | } |
gagarinlg | 2:d9f806076779 | 133 | static inline void put_u16(std::vector<uint8_t> &v, uint16_t w) |
gagarinlg | 2:d9f806076779 | 134 | { |
gagarinlg | 2:d9f806076779 | 135 | v.push_back((uint8_t)(w>> 8)); |
gagarinlg | 2:d9f806076779 | 136 | v.push_back((uint8_t)(w)); |
gagarinlg | 2:d9f806076779 | 137 | } |
gagarinlg | 2:d9f806076779 | 138 | static inline void put_u16le(std::vector<uint8_t> &v, uint16_t w) |
gagarinlg | 2:d9f806076779 | 139 | { |
gagarinlg | 2:d9f806076779 | 140 | v.push_back((uint8_t)(w)); |
gagarinlg | 2:d9f806076779 | 141 | v.push_back((uint8_t)(w>> 8)); |
gagarinlg | 2:d9f806076779 | 142 | } |
gagarinlg | 2:d9f806076779 | 143 | static inline void put_u32(std::vector<uint8_t> &v, uint32_t d) |
gagarinlg | 2:d9f806076779 | 144 | { |
gagarinlg | 2:d9f806076779 | 145 | v.push_back((uint8_t)(d>>24)); |
gagarinlg | 2:d9f806076779 | 146 | v.push_back((uint8_t)(d>>16)); |
gagarinlg | 2:d9f806076779 | 147 | v.push_back((uint8_t)(d>> 8)); |
gagarinlg | 2:d9f806076779 | 148 | v.push_back((uint8_t)(d)); |
gagarinlg | 2:d9f806076779 | 149 | } |
gagarinlg | 2:d9f806076779 | 150 | static inline void put_u32le(std::vector<uint8_t> &v, uint32_t d) |
gagarinlg | 2:d9f806076779 | 151 | { |
gagarinlg | 2:d9f806076779 | 152 | v.push_back((uint8_t)(d)); |
gagarinlg | 2:d9f806076779 | 153 | v.push_back((uint8_t)(d>> 8)); |
gagarinlg | 2:d9f806076779 | 154 | v.push_back((uint8_t)(d>>16)); |
gagarinlg | 2:d9f806076779 | 155 | v.push_back((uint8_t)(d>>24)); |
gagarinlg | 2:d9f806076779 | 156 | } |
gagarinlg | 2:d9f806076779 | 157 | static inline void put_u64(std::vector<uint8_t> &v, uint64_t d) |
gagarinlg | 2:d9f806076779 | 158 | { |
gagarinlg | 2:d9f806076779 | 159 | v.push_back((uint8_t)(d>>56)); |
gagarinlg | 2:d9f806076779 | 160 | v.push_back((uint8_t)(d>>48)); |
gagarinlg | 2:d9f806076779 | 161 | v.push_back((uint8_t)(d>>40)); |
gagarinlg | 2:d9f806076779 | 162 | v.push_back((uint8_t)(d>>32)); |
gagarinlg | 2:d9f806076779 | 163 | v.push_back((uint8_t)(d>>24)); |
gagarinlg | 2:d9f806076779 | 164 | v.push_back((uint8_t)(d>>16)); |
gagarinlg | 2:d9f806076779 | 165 | v.push_back((uint8_t)(d>> 8)); |
gagarinlg | 2:d9f806076779 | 166 | v.push_back((uint8_t)(d)); |
gagarinlg | 2:d9f806076779 | 167 | } |
gagarinlg | 2:d9f806076779 | 168 | static inline void put_u64le(std::vector<uint8_t> &v, uint64_t d) |
gagarinlg | 2:d9f806076779 | 169 | { |
gagarinlg | 2:d9f806076779 | 170 | v.push_back((uint8_t)(d)); |
gagarinlg | 2:d9f806076779 | 171 | v.push_back((uint8_t)(d>> 8)); |
gagarinlg | 2:d9f806076779 | 172 | v.push_back((uint8_t)(d>>16)); |
gagarinlg | 2:d9f806076779 | 173 | v.push_back((uint8_t)(d>>24)); |
gagarinlg | 2:d9f806076779 | 174 | v.push_back((uint8_t)(d>>32)); |
gagarinlg | 2:d9f806076779 | 175 | v.push_back((uint8_t)(d>>40)); |
gagarinlg | 2:d9f806076779 | 176 | v.push_back((uint8_t)(d>>48)); |
gagarinlg | 2:d9f806076779 | 177 | v.push_back((uint8_t)(d>>56)); |
gagarinlg | 2:d9f806076779 | 178 | } |
gagarinlg | 2:d9f806076779 | 179 | static inline void put(std::vector<uint8_t> &v, const uint8_t *data, size_t len) |
gagarinlg | 2:d9f806076779 | 180 | { |
gagarinlg | 2:d9f806076779 | 181 | v.insert(v.end(), data, data+len); |
gagarinlg | 2:d9f806076779 | 182 | } |
gagarinlg | 2:d9f806076779 | 183 | |
gagarinlg | 2:d9f806076779 | 184 | static inline void fill(std::vector<uint8_t> &v, uint8_t value, size_t len) |
gagarinlg | 2:d9f806076779 | 185 | { |
gagarinlg | 2:d9f806076779 | 186 | v.resize(v.size()+len, value); |
gagarinlg | 2:d9f806076779 | 187 | } |
gagarinlg | 2:d9f806076779 | 188 | |
gagarinlg | 2:d9f806076779 | 189 | explicit buffer_builder(std::vector<uint8_t> &v) : data(v), initial_size(v.size()) {} |
gagarinlg | 2:d9f806076779 | 190 | buffer_builder(const buffer_builder& rhs) : data(rhs.data), initial_size(rhs.data.size()) {} |
gagarinlg | 2:d9f806076779 | 191 | |
gagarinlg | 2:d9f806076779 | 192 | size_t written() const |
gagarinlg | 2:d9f806076779 | 193 | { |
gagarinlg | 2:d9f806076779 | 194 | return data.size() - initial_size; |
gagarinlg | 2:d9f806076779 | 195 | } |
gagarinlg | 2:d9f806076779 | 196 | void put_u8(uint8_t b) { put_u8(data, b); } |
gagarinlg | 2:d9f806076779 | 197 | void put_u16(uint16_t w) { put_u16(data, w); } |
gagarinlg | 2:d9f806076779 | 198 | void put_u16le(uint16_t w) { put_u16le(data, w); } |
gagarinlg | 2:d9f806076779 | 199 | void put_u32(uint32_t w) { put_u32(data, w); } |
gagarinlg | 2:d9f806076779 | 200 | void put_u32le(uint32_t w) { put_u32le(data, w); } |
gagarinlg | 2:d9f806076779 | 201 | void put_u64(uint64_t w) { put_u64(data,w); } |
gagarinlg | 2:d9f806076779 | 202 | void put_u64le(uint64_t w) { put_u64le(data,w); } |
gagarinlg | 2:d9f806076779 | 203 | #ifdef __ADSPBLACKFIN__ |
gagarinlg | 2:d9f806076779 | 204 | void put_float(float f) { put_u32(*(uint32_t*)&f); } |
gagarinlg | 2:d9f806076779 | 205 | void put_floatle(float f) { put_u32le(*(uint32_t*)&f); } |
gagarinlg | 2:d9f806076779 | 206 | void put_double(double d) { put_u64(*(uint64_t*)&d); } |
gagarinlg | 2:d9f806076779 | 207 | void put_doublele(double d) { put_u64le(*(uint64_t*)&d); } |
gagarinlg | 2:d9f806076779 | 208 | COMPILETIME_ASSERT(sizeof(double)==8); |
gagarinlg | 2:d9f806076779 | 209 | COMPILETIME_ASSERT(sizeof(float)==4); |
gagarinlg | 2:d9f806076779 | 210 | #endif |
gagarinlg | 2:d9f806076779 | 211 | void put(const uint8_t *p, size_t len) { put(data, p, len); } |
gagarinlg | 2:d9f806076779 | 212 | void put(const void *p, size_t len) { put(data, (const uint8_t*)p, len); } |
gagarinlg | 2:d9f806076779 | 213 | void fill(uint8_t v, size_t len) { fill(data, v, len); } |
gagarinlg | 2:d9f806076779 | 214 | uint8_t* putptr(size_t len) |
gagarinlg | 2:d9f806076779 | 215 | { |
gagarinlg | 2:d9f806076779 | 216 | size_t s = data.size(); |
gagarinlg | 2:d9f806076779 | 217 | data.insert(data.end(), len, uint8_t()); |
gagarinlg | 2:d9f806076779 | 218 | return &data[s]; |
gagarinlg | 2:d9f806076779 | 219 | } |
gagarinlg | 2:d9f806076779 | 220 | |
gagarinlg | 2:d9f806076779 | 221 | template<typename T, void (*F)(uint8_t *&, T)> |
gagarinlg | 2:d9f806076779 | 222 | class ref |
gagarinlg | 2:d9f806076779 | 223 | { |
gagarinlg | 2:d9f806076779 | 224 | public: |
gagarinlg | 2:d9f806076779 | 225 | void operator=(T d) |
gagarinlg | 2:d9f806076779 | 226 | { |
gagarinlg | 2:d9f806076779 | 227 | uint8_t* p = &data[index]; |
gagarinlg | 2:d9f806076779 | 228 | F(p, d); |
gagarinlg | 2:d9f806076779 | 229 | } |
gagarinlg | 2:d9f806076779 | 230 | private: |
gagarinlg | 2:d9f806076779 | 231 | friend class buffer_builder; |
gagarinlg | 2:d9f806076779 | 232 | ref(std::vector<uint8_t> &data, size_t index) : data(data), index(index) {} |
gagarinlg | 2:d9f806076779 | 233 | std::vector<uint8_t> &data; |
gagarinlg | 2:d9f806076779 | 234 | size_t index; |
gagarinlg | 2:d9f806076779 | 235 | }; |
gagarinlg | 2:d9f806076779 | 236 | |
gagarinlg | 2:d9f806076779 | 237 | typedef ref<uint8_t, &buffer_builder::put_u8> ref_u8; |
gagarinlg | 2:d9f806076779 | 238 | typedef ref<uint16_t, &buffer_builder::put_u16> ref_u16; |
gagarinlg | 2:d9f806076779 | 239 | typedef ref<uint16_t, &buffer_builder::put_u16le> ref_u16le; |
gagarinlg | 2:d9f806076779 | 240 | typedef ref<uint32_t, &buffer_builder::put_u32> ref_u32; |
gagarinlg | 2:d9f806076779 | 241 | typedef ref<uint32_t, &buffer_builder::put_u32le> ref_u32le; |
gagarinlg | 2:d9f806076779 | 242 | typedef ref<uint64_t, &buffer_builder::put_u64> ref_u64; |
gagarinlg | 2:d9f806076779 | 243 | typedef ref<uint64_t, &buffer_builder::put_u64le> ref_u64le; |
gagarinlg | 2:d9f806076779 | 244 | |
gagarinlg | 2:d9f806076779 | 245 | ref_u8 put_ref_u8() { ref_u8 r(data, data.size()); put_u8(0); return r; } |
gagarinlg | 2:d9f806076779 | 246 | ref_u16 put_ref_u16() { ref_u16 r(data, data.size()); put_u16(0); return r; } |
gagarinlg | 2:d9f806076779 | 247 | ref_u16le put_ref_u16le() { ref_u16le r(data, data.size()); put_u16le(0); return r; } |
gagarinlg | 2:d9f806076779 | 248 | ref_u32 put_ref_u32() { ref_u32 r(data, data.size()); put_u32(0); return r; } |
gagarinlg | 2:d9f806076779 | 249 | ref_u32le put_ref_u32le() { ref_u32le r(data, data.size()); put_u32le(0); return r; } |
gagarinlg | 2:d9f806076779 | 250 | ref_u64 put_ref_u64() { ref_u64 r(data, data.size()); put_u64(0); return r; } |
gagarinlg | 2:d9f806076779 | 251 | ref_u64le put_ref_u64le() { ref_u64le r(data, data.size()); put_u64le(0); return r; } |
gagarinlg | 2:d9f806076779 | 252 | |
gagarinlg | 2:d9f806076779 | 253 | std::vector<uint8_t> &getData() { return data; } |
gagarinlg | 2:d9f806076779 | 254 | private: |
gagarinlg | 2:d9f806076779 | 255 | buffer_builder(); |
gagarinlg | 2:d9f806076779 | 256 | std::vector<uint8_t> &data; |
gagarinlg | 2:d9f806076779 | 257 | size_t initial_size; |
gagarinlg | 2:d9f806076779 | 258 | }; |
gagarinlg | 2:d9f806076779 | 259 | |
gagarinlg | 2:d9f806076779 | 260 | |
gagarinlg | 2:d9f806076779 | 261 | |
gagarinlg | 2:d9f806076779 | 262 | #endif /* BUFFER_BUILDER_HPP_ */ |