File indexing completed on 2025-08-06 08:17:18
0001
0002
0003
0004
0005
0006
0007 #ifndef MVTXDECODER_PAYLOADCONT_H
0008 #define MVTXDECODER_PAYLOADCONT_H
0009
0010 #include <cstring>
0011 #include <vector>
0012 #include <functional>
0013 #include <cstdint>
0014
0015 namespace mvtx
0016 {
0017
0018 class PayLoadCont
0019 {
0020
0021
0022
0023 public:
0024 static constexpr size_t MinCapacity = 16;
0025
0026
0027 PayLoadCont() = default;
0028 PayLoadCont(size_t sz) { expand(sz); }
0029 ~PayLoadCont() = default;
0030
0031 PayLoadCont(const PayLoadCont& src);
0032
0033 PayLoadCont& operator=(const PayLoadCont& src);
0034
0035 const uint8_t *data() const { return mBuffer.data(); }
0036
0037
0038 void expand(size_t sz);
0039
0040 bool isEmpty() const { return mPtr >= mEnd; }
0041
0042
0043 void clear()
0044 {
0045 mPtr = mBuffer.data();
0046 mEnd = mPtr;
0047 }
0048
0049
0050 size_t getUnusedSize() const { return mEnd > mPtr ? mEnd - mPtr : 0; }
0051
0052
0053 size_t getSize() const { return mEnd - mBuffer.data(); }
0054
0055
0056 size_t getOffset() const { return mPtr - mBuffer.data(); }
0057
0058
0059 size_t getCapacity() const { return mBuffer.size(); }
0060
0061
0062 size_t getFreeCapacity() const { return mBuffer.size() - getSize(); }
0063
0064
0065 void ensureFreeCapacity(size_t n)
0066 {
0067 if (getFreeCapacity() < n) {
0068 expand(getCapacity() + 2 * n);
0069 }
0070 }
0071
0072
0073 void fillFast(const uint8_t c, size_t n)
0074 {
0075 std::memset(mEnd, c, n);
0076 mEnd += n;
0077 }
0078
0079
0080 void addFast(const uint8_t* ptr, size_t n)
0081 {
0082 std::memcpy(mEnd, ptr, n);
0083 mEnd += n;
0084 }
0085
0086
0087 void addFast(uint8_t val) { *mEnd++ = val; }
0088
0089
0090 void addFast(uint16_t val)
0091 {
0092 *mEnd++ = val >> 8;
0093 *mEnd++ = 0xff & val;
0094 }
0095
0096
0097 void eraseFast(size_t n) { mEnd -= n; }
0098
0099
0100 void erase(size_t n)
0101 {
0102 if (n > getSize()) {
0103 clear();
0104 } else {
0105 eraseFast(n);
0106 }
0107 }
0108
0109
0110 void fill(const uint8_t c, size_t n)
0111 {
0112 ensureFreeCapacity(n);
0113 fillFast(c, n);
0114 }
0115
0116
0117 void add(const uint8_t* ptr, size_t n)
0118 {
0119 ensureFreeCapacity(n);
0120 addFast(ptr, n);
0121 }
0122
0123
0124 void add(uint8_t val)
0125 {
0126 ensureFreeCapacity(sizeof(val));
0127 addFast(val);
0128 }
0129
0130
0131 void add(uint16_t val)
0132 {
0133 ensureFreeCapacity(sizeof(val));
0134 addFast(val);
0135 }
0136
0137
0138 void shrinkToSize(size_t sz)
0139 {
0140 mEnd = mPtr + sz;
0141 }
0142
0143
0144 uint8_t operator[](size_t i) const { return mBuffer[i]; }
0145
0146
0147 uint8_t& operator[](size_t i) { return mBuffer[i]; }
0148
0149
0150 bool current(uint8_t& v) const
0151 {
0152 if (mPtr < mEnd) {
0153 v = *mPtr;
0154 return true;
0155 }
0156 return false;
0157 }
0158
0159
0160 bool next(uint8_t& v)
0161 {
0162 if (mPtr < mEnd) {
0163 v = *mPtr++;
0164 return true;
0165 }
0166 return false;
0167 }
0168
0169
0170 bool next(uint16_t& v)
0171 {
0172 if (mPtr < mEnd - (sizeof(uint16_t) - 1)) {
0173 v = (*mPtr++) << 8;
0174 v |= (*mPtr++);
0175 return true;
0176 }
0177 return false;
0178 }
0179
0180
0181 void rewind() { mPtr = mBuffer.data(); }
0182
0183
0184 void moveUnusedToHead()
0185 {
0186 auto left = getUnusedSize();
0187 if (left < getOffset()) {
0188 std::memcpy(mBuffer.data(), mPtr, left);
0189 } else {
0190 std::memmove(mBuffer.data(), mPtr, left);
0191 }
0192 mPtr = mBuffer.data();
0193 mEnd = mPtr + left;
0194 }
0195
0196
0197
0198 size_t append(std::function<size_t(uint8_t*, size_t)> getNext)
0199 {
0200 moveUnusedToHead();
0201 auto nRead = getNext(mEnd, getFreeCapacity());
0202 mEnd += nRead;
0203 return nRead;
0204 }
0205
0206
0207 uint8_t* getPtr() { return mPtr; }
0208 void setPtr(uint8_t* ptr) { mPtr = ptr; }
0209 void movePtr(size_t step) { mPtr += step; }
0210
0211 uint8_t* getEnd() { return mEnd; }
0212 void setEnd(uint8_t* ptr) { mEnd = ptr; }
0213
0214 private:
0215 std::vector<uint8_t> mBuffer;
0216 uint8_t* mPtr = nullptr;
0217 uint8_t* mEnd = nullptr;
0218
0219
0220 };
0221
0222 }
0223
0224 #endif