joy
Dependencies: mbed USBDevice USBJoystick_
buffer_builder.hpp
- Committer:
- gagarinlg
- Date:
- 2021-08-01
- Revision:
- 2:d9f806076779
File content as of revision 2:d9f806076779:
/* * buffer_builder.hpp * * Created on: Nov 25, 2011 * Author: premmers */ #ifndef BUFFER_BUILDER_HPP_ #define BUFFER_BUILDER_HPP_ #include <vector> #include <assert.h> #include <stdint.h> #include <string.h> //#include "utilities.h" class buffer_builder { public: static inline void put(uint8_t *&p, uint8_t &bitoffset, uint8_t fieldlen, uint32_t value) { assert(bitoffset < 8); assert(fieldlen <= 32); uint32_t mask = (1U<<fieldlen)-1; value &= mask; uint8_t b; // first byte if (bitoffset > 0) { uint8_t remaining_bits = 8-bitoffset; int8_t unused_bits = int8_t(remaining_bits - fieldlen); if (unused_bits > 0) { b = *p; b &= ~(mask << unused_bits); b |= value << unused_bits; *p = b; bitoffset += fieldlen; return; } // all the remaining bits in first byte are in use fieldlen -= remaining_bits; b = *p; b &= ~(mask >> fieldlen); b |= value >> fieldlen; *p++ = b; bitoffset = 0; } // middle section (whole bytes) while (fieldlen >= 8) { fieldlen -= 8; *p++ = (value >> fieldlen) & 0xFF; } // last byte if (fieldlen > 0) { b = *p; b &= 0xFFU >> fieldlen; b |= value << (8-fieldlen); *p = b; bitoffset = fieldlen; } } static inline void put_u8(uint8_t *&p, uint8_t b) { *p++ = b; } static inline void put_u16(uint8_t *&p, uint16_t w) { *p++ = (uint8_t)(w>> 8); *p++ = (uint8_t)(w); } static inline void put_u16le(uint8_t *&p, uint16_t w) { *p++ = (uint8_t)(w); *p++ = (uint8_t)(w>> 8); } static inline void put_u32(uint8_t *&p, uint32_t d) { *p++ = (uint8_t)(d>>24); *p++ = (uint8_t)(d>>16); *p++ = (uint8_t)(d>> 8); *p++ = (uint8_t)(d); } static inline void put_u32le(uint8_t *&p, uint32_t d) { *p++ = (uint8_t)(d); *p++ = (uint8_t)(d>> 8); *p++ = (uint8_t)(d>>16); *p++ = (uint8_t)(d>>24); } static inline void put_u64(uint8_t *&p, uint64_t d) { *p++ = (uint8_t)(d>>56); *p++ = (uint8_t)(d>>48); *p++ = (uint8_t)(d>>40); *p++ = (uint8_t)(d>>32); *p++ = (uint8_t)(d>>24); *p++ = (uint8_t)(d>>16); *p++ = (uint8_t)(d>> 8); *p++ = (uint8_t)(d); } static inline void put_u64le(uint8_t *&p, uint64_t d) { *p++ = (uint8_t)(d); *p++ = (uint8_t)(d>> 8); *p++ = (uint8_t)(d>>16); *p++ = (uint8_t)(d>>24); *p++ = (uint8_t)(d>>32); *p++ = (uint8_t)(d>>40); *p++ = (uint8_t)(d>>48); *p++ = (uint8_t)(d>>56); } static inline void put(uint8_t *&p, const uint8_t *data, size_t len) { memcpy(p, data, len); p += len; } static inline void put_u8(std::vector<uint8_t> &v, uint8_t b) { v.push_back(b); } static inline void put_u16(std::vector<uint8_t> &v, uint16_t w) { v.push_back((uint8_t)(w>> 8)); v.push_back((uint8_t)(w)); } static inline void put_u16le(std::vector<uint8_t> &v, uint16_t w) { v.push_back((uint8_t)(w)); v.push_back((uint8_t)(w>> 8)); } static inline void put_u32(std::vector<uint8_t> &v, uint32_t d) { v.push_back((uint8_t)(d>>24)); v.push_back((uint8_t)(d>>16)); v.push_back((uint8_t)(d>> 8)); v.push_back((uint8_t)(d)); } static inline void put_u32le(std::vector<uint8_t> &v, uint32_t d) { v.push_back((uint8_t)(d)); v.push_back((uint8_t)(d>> 8)); v.push_back((uint8_t)(d>>16)); v.push_back((uint8_t)(d>>24)); } static inline void put_u64(std::vector<uint8_t> &v, uint64_t d) { v.push_back((uint8_t)(d>>56)); v.push_back((uint8_t)(d>>48)); v.push_back((uint8_t)(d>>40)); v.push_back((uint8_t)(d>>32)); v.push_back((uint8_t)(d>>24)); v.push_back((uint8_t)(d>>16)); v.push_back((uint8_t)(d>> 8)); v.push_back((uint8_t)(d)); } static inline void put_u64le(std::vector<uint8_t> &v, uint64_t d) { v.push_back((uint8_t)(d)); v.push_back((uint8_t)(d>> 8)); v.push_back((uint8_t)(d>>16)); v.push_back((uint8_t)(d>>24)); v.push_back((uint8_t)(d>>32)); v.push_back((uint8_t)(d>>40)); v.push_back((uint8_t)(d>>48)); v.push_back((uint8_t)(d>>56)); } static inline void put(std::vector<uint8_t> &v, const uint8_t *data, size_t len) { v.insert(v.end(), data, data+len); } static inline void fill(std::vector<uint8_t> &v, uint8_t value, size_t len) { v.resize(v.size()+len, value); } explicit buffer_builder(std::vector<uint8_t> &v) : data(v), initial_size(v.size()) {} buffer_builder(const buffer_builder& rhs) : data(rhs.data), initial_size(rhs.data.size()) {} size_t written() const { return data.size() - initial_size; } void put_u8(uint8_t b) { put_u8(data, b); } void put_u16(uint16_t w) { put_u16(data, w); } void put_u16le(uint16_t w) { put_u16le(data, w); } void put_u32(uint32_t w) { put_u32(data, w); } void put_u32le(uint32_t w) { put_u32le(data, w); } void put_u64(uint64_t w) { put_u64(data,w); } void put_u64le(uint64_t w) { put_u64le(data,w); } #ifdef __ADSPBLACKFIN__ void put_float(float f) { put_u32(*(uint32_t*)&f); } void put_floatle(float f) { put_u32le(*(uint32_t*)&f); } void put_double(double d) { put_u64(*(uint64_t*)&d); } void put_doublele(double d) { put_u64le(*(uint64_t*)&d); } COMPILETIME_ASSERT(sizeof(double)==8); COMPILETIME_ASSERT(sizeof(float)==4); #endif void put(const uint8_t *p, size_t len) { put(data, p, len); } void put(const void *p, size_t len) { put(data, (const uint8_t*)p, len); } void fill(uint8_t v, size_t len) { fill(data, v, len); } uint8_t* putptr(size_t len) { size_t s = data.size(); data.insert(data.end(), len, uint8_t()); return &data[s]; } template<typename T, void (*F)(uint8_t *&, T)> class ref { public: void operator=(T d) { uint8_t* p = &data[index]; F(p, d); } private: friend class buffer_builder; ref(std::vector<uint8_t> &data, size_t index) : data(data), index(index) {} std::vector<uint8_t> &data; size_t index; }; typedef ref<uint8_t, &buffer_builder::put_u8> ref_u8; typedef ref<uint16_t, &buffer_builder::put_u16> ref_u16; typedef ref<uint16_t, &buffer_builder::put_u16le> ref_u16le; typedef ref<uint32_t, &buffer_builder::put_u32> ref_u32; typedef ref<uint32_t, &buffer_builder::put_u32le> ref_u32le; typedef ref<uint64_t, &buffer_builder::put_u64> ref_u64; typedef ref<uint64_t, &buffer_builder::put_u64le> ref_u64le; ref_u8 put_ref_u8() { ref_u8 r(data, data.size()); put_u8(0); return r; } ref_u16 put_ref_u16() { ref_u16 r(data, data.size()); put_u16(0); return r; } ref_u16le put_ref_u16le() { ref_u16le r(data, data.size()); put_u16le(0); return r; } ref_u32 put_ref_u32() { ref_u32 r(data, data.size()); put_u32(0); return r; } ref_u32le put_ref_u32le() { ref_u32le r(data, data.size()); put_u32le(0); return r; } ref_u64 put_ref_u64() { ref_u64 r(data, data.size()); put_u64(0); return r; } ref_u64le put_ref_u64le() { ref_u64le r(data, data.size()); put_u64le(0); return r; } std::vector<uint8_t> &getData() { return data; } private: buffer_builder(); std::vector<uint8_t> &data; size_t initial_size; }; #endif /* BUFFER_BUILDER_HPP_ */