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