3 * Copyright (c) 2021 Project CHIP Authors
4 * Copyright (c) 2013-2017 Nest Labs, Inc.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
21 * This file contains an implementation of TLVBackingStore using PacketBuffers.
26 #include <core/CHIPTLV.h>
27 #include <system/SystemPacketBuffer.h>
35 * An implementation of TLVBackingStore using PacketBuffers.
37 class TLVPacketBufferBackingStore : public chip::TLV::TLVBackingStore
40 TLVPacketBufferBackingStore() : mHeadBuffer(nullptr), mCurrentBuffer(nullptr), mUseChainedBuffers(false) {}
41 TLVPacketBufferBackingStore(chip::System::PacketBufferHandle && buffer, bool useChainedBuffers = false)
43 Init(std::move(buffer), useChainedBuffers);
45 virtual ~TLVPacketBufferBackingStore() {}
48 * Take ownership of a backing packet buffer.
50 * @param[in] buffer A handle to a packet buffer, to be used as backing store for a TLV class.
51 * @param[in] useChainedBuffers
52 * If true, advance to the next buffer in the chain once all data or space
53 * in the current buffer has been consumed; a write will allocate new
54 * packet buffers if necessary.
56 * @note This must take place before initializing a TLV class with this backing store.
58 void Init(chip::System::PacketBufferHandle && buffer, bool useChainedBuffers = false)
60 mHeadBuffer = std::move(buffer);
61 mCurrentBuffer = mHeadBuffer.Retain();
62 mUseChainedBuffers = useChainedBuffers;
64 void Adopt(chip::System::PacketBufferHandle && buffer) { Init(std::move(buffer), mUseChainedBuffers); }
67 * Release ownership of the backing packet buffer.
69 * @note TLV operations must no longer be performed on this store.
71 CHECK_RETURN_VALUE chip::System::PacketBufferHandle Release()
73 mCurrentBuffer = nullptr;
74 return std::move(mHeadBuffer);
77 // TLVBackingStore overrides:
78 CHIP_ERROR OnInit(chip::TLV::TLVReader & reader, const uint8_t *& bufStart, uint32_t & bufLen) override;
79 CHIP_ERROR GetNextBuffer(chip::TLV::TLVReader & reader, const uint8_t *& bufStart, uint32_t & bufLen) override;
80 CHIP_ERROR OnInit(chip::TLV::TLVWriter & writer, uint8_t *& bufStart, uint32_t & bufLen) override;
81 CHIP_ERROR GetNewBuffer(chip::TLV::TLVWriter & writer, uint8_t *& bufStart, uint32_t & bufLen) override;
82 CHIP_ERROR FinalizeBuffer(chip::TLV::TLVWriter & writer, uint8_t * bufStart, uint32_t bufLen) override;
85 chip::System::PacketBufferHandle mHeadBuffer;
86 chip::System::PacketBufferHandle mCurrentBuffer;
87 bool mUseChainedBuffers;
90 class DLL_EXPORT PacketBufferTLVReader : public chip::TLV::TLVReader
94 * Initializes a TLVReader object to read from a PacketBuffer.
96 * @param[in] buffer A handle to PacketBuffer, to be used as backing store for a TLV class.
97 * @param[in] useChainedBuffers
98 * If true, advance to the next buffer in the chain once all data
99 * in the current buffer has been consumed.
101 void Init(chip::System::PacketBufferHandle && buffer, bool useChainedBuffers = false)
103 mBackingStore.Init(std::move(buffer), useChainedBuffers);
104 chip::TLV::TLVReader::Init(mBackingStore);
108 TLVPacketBufferBackingStore mBackingStore;
111 class DLL_EXPORT PacketBufferTLVWriter : public chip::TLV::TLVWriter
115 * Initializes a TLVWriter object to write to a PacketBuffer.
117 * @param[in] buffer A handle to PacketBuffer, to be used as backing store for a TLV class.
118 * @param[in] useChainedBuffers
119 * If true, advance to the next buffer in the chain once all space
120 * in the current buffer has been consumed. Once all existing buffers
121 * have been used, new PacketBuffers will be allocated as necessary.
123 void Init(chip::System::PacketBufferHandle && buffer, bool useChainedBuffers = false)
125 mBackingStore.Init(std::move(buffer), useChainedBuffers);
126 chip::TLV::TLVWriter::Init(mBackingStore);
129 * Finish the writing of a TLV encoding and release ownership of the underlying PacketBuffer.
131 * @param[in,out] outBuffer The backing packet buffer.
133 * @retval #CHIP_NO_ERROR If the encoding was finalized successfully.
134 * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN
135 * If a container writer has been opened on the current writer and not
137 * @retval #CHIP_ERROR_INVALID_ARGUMENT
138 * If the apparent data length does not fit in uint16_t.
140 * @note No further TLV operations may be performed, unless or until this PacketBufferTLVWriter is re-initialized.
142 CHIP_ERROR Finalize(chip::System::PacketBufferHandle * outBuffer)
144 CHIP_ERROR err = Finalize();
145 *outBuffer = mBackingStore.Release();
149 * Free the underlying PacketBuffer.
151 * @note No further TLV operations may be performed, unless or until this PacketBufferTLVWriter is re-initialized.
153 void Reset() { static_cast<void>(mBackingStore.Release()); }
156 CHIP_ERROR Finalize() { return chip::TLV::TLVWriter::Finalize(); }
157 TLVPacketBufferBackingStore mBackingStore;
160 } // namespace System