3 * Copyright (c) 2020-2021 Project CHIP Authors
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
30 BufferWriter(uint8_t * buf, size_t len) : mBuf(buf), mSize(len), mNeeded(0) {}
31 BufferWriter(const BufferWriter & other) = default;
32 BufferWriter & operator=(const BufferWriter & other) = default;
34 /// Append a null terminated string, exclude the null terminator
35 BufferWriter & Put(const char * s);
37 /// Raw append a buffer, regardless of endianess
38 BufferWriter & Put(const void * buf, size_t len);
40 /// Append a single byte
41 BufferWriter & Put(uint8_t c);
43 BufferWriter & Skip(size_t len)
49 /// Number of bytes required to satisfy all calls to Put() so far
50 size_t Needed() const { return mNeeded; }
52 /// Number of bytes still available for writing
53 size_t Available() const { return mSize < mNeeded ? 0 : mSize - mNeeded; }
55 /// Whether the input fit in the buffer
62 /// Returns whether the input fit in the buffer, outputs what was actually written
63 bool Fit(size_t & actuallyWritten) const
65 actuallyWritten = mSize >= mNeeded ? mNeeded : mSize;
66 return mSize >= mNeeded;
69 /// Size of the output buffer
70 size_t Size() const { return mSize; }
72 uint8_t * Buffer() { return mBuf; }
73 const uint8_t * Buffer() const { return mBuf; }
81 template <class Derived>
82 class EndianBufferWriterBase : public BufferWriter
85 // typed BufferWriter forwards
87 Derived & Put(const char * s) { return static_cast<Derived &>(BufferWriter::Put(s)); }
88 Derived & Put(const void * buf, size_t len) { return static_cast<Derived &>(BufferWriter::Put(buf, len)); }
89 Derived & Put(uint8_t c) { return static_cast<Derived &>(BufferWriter::Put(c)); }
90 Derived & Skip(size_t len) { return static_cast<Derived &>(BufferWriter::Skip(len)); }
92 // write an integer into a buffer, in an endian specific way
94 Derived & Put8(uint8_t c) { return static_cast<Derived *>(this)->Put(c); }
95 Derived & Put16(uint16_t x) { return static_cast<Derived *>(this)->EndianPut(x, sizeof(x)); }
96 Derived & Put32(uint32_t x) { return static_cast<Derived *>(this)->EndianPut(x, sizeof(x)); }
97 Derived & Put64(uint64_t x) { return static_cast<Derived *>(this)->EndianPut(x, sizeof(x)); }
100 EndianBufferWriterBase(uint8_t * buf, size_t len) : BufferWriter(buf, len) {}
101 EndianBufferWriterBase(const EndianBufferWriterBase & other) = default;
102 EndianBufferWriterBase & operator=(const EndianBufferWriterBase & other) = default;
105 namespace LittleEndian {
107 class BufferWriter : public EndianBufferWriterBase<BufferWriter>
110 BufferWriter(uint8_t * buf, size_t len) : EndianBufferWriterBase<BufferWriter>(buf, len) {}
111 BufferWriter(const BufferWriter & other) = default;
112 BufferWriter & operator=(const BufferWriter & other) = default;
113 BufferWriter & EndianPut(uint64_t x, size_t size);
116 } // namespace LittleEndian
118 namespace BigEndian {
120 class BufferWriter : public EndianBufferWriterBase<BufferWriter>
123 BufferWriter(uint8_t * buf, size_t len) : EndianBufferWriterBase<BufferWriter>(buf, len) {}
124 BufferWriter(const BufferWriter & other) = default;
125 BufferWriter & operator=(const BufferWriter & other) = default;
126 BufferWriter & EndianPut(uint64_t x, size_t size);
129 } // namespace BigEndian
131 } // namespace Encoding