Matter SDK Coverage Report
Current view: top level - lib/support - BufferWriter.h (source / functions) Coverage Total Hit
Test: SHA:b879ecb8e99e175eea0a293a888bda853da2b19c Lines: 100.0 % 35 35
Test Date: 2025-01-17 19:00:11 Functions: 100.0 % 31 31

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2020-2021 Project CHIP Authors
       4              :  *
       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
       8              :  *
       9              :  *        http://www.apache.org/licenses/LICENSE-2.0
      10              :  *
      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.
      16              :  */
      17              : 
      18              : #pragma once
      19              : 
      20              : #include <climits>
      21              : #include <stdint.h>
      22              : #include <string.h>
      23              : 
      24              : #include <lib/support/Span.h>
      25              : 
      26              : namespace chip {
      27              : namespace Encoding {
      28              : 
      29              : class BufferWriter
      30              : {
      31              : public:
      32       390212 :     BufferWriter(uint8_t * buf, size_t len) : mBuf(buf), mSize(len), mNeeded(0)
      33              :     {
      34       390212 :         if (buf == nullptr)
      35              :         {
      36          123 :             mSize = 0;
      37              :         }
      38       390212 :     }
      39          224 :     BufferWriter(MutableByteSpan buf) : BufferWriter(buf.data(), buf.size()) {}
      40              :     BufferWriter(const BufferWriter & other)             = default;
      41              :     BufferWriter & operator=(const BufferWriter & other) = default;
      42              : 
      43              :     /// Append a null terminated string, exclude the null terminator
      44              :     BufferWriter & Put(const char * s);
      45              : 
      46              :     /// Raw append a buffer, regardless of endianess.
      47              :     /// This is memmove-safe: if `buf` points to the underlying buffer, where output
      48              :     /// will be written, and the overlap is legal for a memmove to have worked properly,
      49              :     /// then this method will properly copy data.
      50              :     BufferWriter & Put(const void * buf, size_t len);
      51              : 
      52              :     /// Append a single byte
      53              :     BufferWriter & Put(uint8_t c);
      54              : 
      55         1871 :     BufferWriter & Skip(size_t len)
      56              :     {
      57         1871 :         mNeeded += len;
      58         1871 :         return *this;
      59              :     }
      60              : 
      61              :     /// Number of bytes required to satisfy all calls to Put() so far
      62        10274 :     inline size_t Needed() const { return mNeeded; }
      63              : 
      64              :     /// Alias to Needed() for code clarity: current writing position for the buffer.
      65         7726 :     inline size_t WritePos() const { return Needed(); }
      66              : 
      67              :     /// Number of bytes still available for writing
      68        11250 :     size_t Available() const { return mSize < mNeeded ? 0 : mSize - mNeeded; }
      69              : 
      70              :     /// Whether the input fit in the buffer
      71        27259 :     bool Fit() const
      72              :     {
      73              :         size_t _;
      74        27259 :         return Fit(_);
      75              :     }
      76              : 
      77              :     /// Returns whether the input fit in the buffer, outputs what was actually written
      78       395155 :     bool Fit(size_t & actuallyWritten) const
      79              :     {
      80       395155 :         actuallyWritten = mSize >= mNeeded ? mNeeded : mSize;
      81       395155 :         return mSize >= mNeeded;
      82              :     }
      83              : 
      84              :     /// Size of the output buffer
      85           26 :     size_t Size() const { return mSize; }
      86              : 
      87        23654 :     uint8_t * Buffer() { return mBuf; }
      88          704 :     const uint8_t * Buffer() const { return mBuf; }
      89              : 
      90          341 :     void Reset() { mNeeded = 0; }
      91              : 
      92              : protected:
      93              :     uint8_t * mBuf;
      94              :     size_t mSize;
      95              :     size_t mNeeded;
      96              : };
      97              : 
      98              : template <class Derived>
      99              : class EndianBufferWriterBase : public BufferWriter
     100              : {
     101              : public:
     102              :     // typed BufferWriter forwards
     103              : 
     104          737 :     Derived & Put(const char * s) { return static_cast<Derived &>(BufferWriter::Put(s)); }
     105          507 :     Derived & Put(const void * buf, size_t len) { return static_cast<Derived &>(BufferWriter::Put(buf, len)); }
     106      1099250 :     Derived & Put(uint8_t c) { return static_cast<Derived &>(BufferWriter::Put(c)); }
     107          104 :     Derived & Skip(size_t len) { return static_cast<Derived &>(BufferWriter::Skip(len)); }
     108              : 
     109              :     // write an integer into a buffer, in an endian-specific way
     110              : 
     111       579619 :     Derived & Put8(uint8_t c) { return static_cast<Derived *>(this)->Put(c); }
     112         8865 :     Derived & Put16(uint16_t x) { return static_cast<Derived *>(this)->EndianPut(x, sizeof(x)); }
     113        21909 :     Derived & Put32(uint32_t x) { return static_cast<Derived *>(this)->EndianPut(x, sizeof(x)); }
     114        19421 :     Derived & Put64(uint64_t x) { return static_cast<Derived *>(this)->EndianPut(x, sizeof(x)); }
     115              : 
     116              :     Derived & PutSigned8(int8_t x) { return static_cast<Derived *>(this)->EndianPutSigned(x, sizeof(x)); }
     117              :     Derived & PutSigned16(int16_t x) { return static_cast<Derived *>(this)->EndianPutSigned(x, sizeof(x)); }
     118              :     Derived & PutSigned32(int32_t x) { return static_cast<Derived *>(this)->EndianPutSigned(x, sizeof(x)); }
     119              :     Derived & PutSigned64(int64_t x) { return static_cast<Derived *>(this)->EndianPutSigned(x, sizeof(x)); }
     120              : 
     121              : protected:
     122       387343 :     EndianBufferWriterBase(uint8_t * buf, size_t len) : BufferWriter(buf, len) {}
     123           66 :     EndianBufferWriterBase(MutableByteSpan buf) : BufferWriter(buf.data(), buf.size()) {}
     124              :     EndianBufferWriterBase(const EndianBufferWriterBase & other)             = default;
     125              :     EndianBufferWriterBase & operator=(const EndianBufferWriterBase & other) = default;
     126              : };
     127              : 
     128              : namespace LittleEndian {
     129              : 
     130              : class BufferWriter : public EndianBufferWriterBase<BufferWriter>
     131              : {
     132              : public:
     133       387271 :     BufferWriter(uint8_t * buf, size_t len) : EndianBufferWriterBase<BufferWriter>(buf, len)
     134              :     {
     135              :         static_assert((-1 & 3) == 3, "LittleEndian::BufferWriter only works with 2's complement architectures.");
     136       387271 :     }
     137           66 :     BufferWriter(MutableByteSpan buf) : EndianBufferWriterBase<BufferWriter>(buf) {}
     138              :     BufferWriter(const BufferWriter & other)             = default;
     139              :     BufferWriter & operator=(const BufferWriter & other) = default;
     140              :     BufferWriter & EndianPut(uint64_t x, size_t size);
     141              :     BufferWriter & EndianPutSigned(int64_t x, size_t size);
     142              : };
     143              : 
     144              : } // namespace LittleEndian
     145              : 
     146              : namespace BigEndian {
     147              : 
     148              : class BufferWriter : public EndianBufferWriterBase<BufferWriter>
     149              : {
     150              : public:
     151           72 :     BufferWriter(uint8_t * buf, size_t len) : EndianBufferWriterBase<BufferWriter>(buf, len)
     152              :     {
     153              :         static_assert((-1 & 3) == 3, "BigEndian::BufferWriter only works with 2's complement architectures.");
     154           72 :     }
     155              :     BufferWriter(MutableByteSpan buf) : EndianBufferWriterBase<BufferWriter>(buf) {}
     156              :     BufferWriter(const BufferWriter & other)             = default;
     157              :     BufferWriter & operator=(const BufferWriter & other) = default;
     158              :     BufferWriter & EndianPut(uint64_t x, size_t size);
     159              :     BufferWriter & EndianPutSigned(int64_t x, size_t size);
     160              : };
     161              : 
     162              : } // namespace BigEndian
     163              : 
     164              : } // namespace Encoding
     165              : } // namespace chip
        

Generated by: LCOV version 2.0-1