joy

Dependencies:   mbed USBDevice USBJoystick_

Committer:
gagarinlg
Date:
Sun Aug 01 17:36:27 2021 +0000
Revision:
2:d9f806076779
done

Who changed what in which revision?

UserRevisionLine numberNew 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_ */