Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2021 Project CHIP Authors
4 : * Copyright (c) 2013-2017 Nest Labs, Inc.
5 : *
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
9 : *
10 : * http://www.apache.org/licenses/LICENSE-2.0
11 : *
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.
17 : */
18 :
19 : /**
20 : * @file
21 : * This file contains an implementation of TLVBackingStore using PacketBuffers.
22 : */
23 :
24 : #include <system/TLVPacketBufferBackingStore.h>
25 :
26 : #include <lib/support/SafeInt.h>
27 :
28 : namespace chip {
29 : namespace System {
30 :
31 96 : CHIP_ERROR TLVPacketBufferBackingStore::OnInit(chip::TLV::TLVReader & reader, const uint8_t *& bufStart, uint32_t & bufLen)
32 : {
33 96 : bufStart = mHeadBuffer->Start();
34 96 : VerifyOrReturnError(CanCastTo<uint32_t>(mHeadBuffer->DataLength()), CHIP_ERROR_INVALID_ARGUMENT);
35 96 : bufLen = static_cast<uint32_t>(mHeadBuffer->DataLength());
36 96 : return CHIP_NO_ERROR;
37 : }
38 :
39 0 : CHIP_ERROR TLVPacketBufferBackingStore::GetNextBuffer(chip::TLV::TLVReader & reader, const uint8_t *& bufStart, uint32_t & bufLen)
40 : {
41 0 : if (mUseChainedBuffers)
42 : {
43 0 : mCurrentBuffer.Advance();
44 : }
45 : else
46 : {
47 0 : mCurrentBuffer = nullptr;
48 : }
49 :
50 0 : if (mCurrentBuffer.IsNull())
51 : {
52 0 : bufStart = nullptr;
53 0 : bufLen = 0;
54 : }
55 : else
56 : {
57 0 : bufStart = mCurrentBuffer->Start();
58 0 : VerifyOrReturnError(CanCastTo<uint32_t>(mCurrentBuffer->DataLength()), CHIP_ERROR_INVALID_ARGUMENT);
59 0 : bufLen = static_cast<uint32_t>(mCurrentBuffer->DataLength());
60 : }
61 :
62 0 : return CHIP_NO_ERROR;
63 : }
64 :
65 19194 : CHIP_ERROR TLVPacketBufferBackingStore::OnInit(chip::TLV::TLVWriter & writer, uint8_t *& bufStart, uint32_t & bufLen)
66 : {
67 19194 : bufStart = mHeadBuffer->Start() + mHeadBuffer->DataLength();
68 19194 : VerifyOrReturnError(CanCastTo<uint32_t>(mHeadBuffer->AvailableDataLength()), CHIP_ERROR_INVALID_ARGUMENT);
69 19194 : bufLen = static_cast<uint32_t>(mHeadBuffer->AvailableDataLength());
70 19194 : return CHIP_NO_ERROR;
71 : }
72 :
73 23252 : CHIP_ERROR TLVPacketBufferBackingStore::FinalizeBuffer(chip::TLV::TLVWriter & writer, uint8_t * bufStart, uint32_t dataLen)
74 : {
75 23252 : uint8_t * endPtr = bufStart + dataLen;
76 :
77 23252 : intptr_t length = endPtr - mCurrentBuffer->Start();
78 23252 : if (!CanCastTo<uint32_t>(length))
79 : {
80 0 : return CHIP_ERROR_INVALID_ARGUMENT;
81 : }
82 23252 : mCurrentBuffer->SetDataLength(static_cast<uint32_t>(length), mHeadBuffer);
83 :
84 23252 : return CHIP_NO_ERROR;
85 : }
86 :
87 2591 : CHIP_ERROR TLVPacketBufferBackingStore::GetNewBuffer(chip::TLV::TLVWriter & writer, uint8_t *& bufStart, uint32_t & bufLen)
88 : {
89 2591 : if (!mUseChainedBuffers)
90 : {
91 2209 : return CHIP_ERROR_NO_MEMORY;
92 : }
93 :
94 382 : mCurrentBuffer.Advance();
95 382 : if (mCurrentBuffer.IsNull())
96 : {
97 382 : mCurrentBuffer = PacketBufferHandle::New(System::PacketBuffer::kMaxSizeWithoutReserve, 0);
98 382 : if (mCurrentBuffer.IsNull())
99 : {
100 0 : return CHIP_ERROR_NO_MEMORY;
101 : }
102 382 : mHeadBuffer->AddToEnd(mCurrentBuffer.Retain());
103 : }
104 :
105 382 : if (mCurrentBuffer.IsNull())
106 : {
107 0 : bufStart = nullptr;
108 0 : bufLen = 0;
109 : }
110 : else
111 : {
112 382 : bufStart = mCurrentBuffer->Start();
113 382 : VerifyOrReturnError(CanCastTo<uint32_t>(mCurrentBuffer->MaxDataLength()), CHIP_ERROR_INVALID_ARGUMENT);
114 382 : bufLen = static_cast<uint32_t>(mCurrentBuffer->MaxDataLength());
115 : }
116 :
117 382 : return CHIP_NO_ERROR;
118 : }
119 :
120 : } // namespace System
121 : } // namespace chip
|