Line data Source code
1 : /*
2 : * Copyright (c) 2021-2024 Project CHIP Authors
3 : * All rights reserved.
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 : #pragma once
18 :
19 : #include <lib/core/DataModelTypes.h>
20 :
21 : namespace chip {
22 : namespace app {
23 :
24 : /// Maintains the internal state of list encoding
25 : ///
26 : /// List encoding is generally assumed incremental and chunkable (i.e.
27 : /// partial encoding is ok.). For this purpose the class maintains two
28 : /// pieces of data:
29 : /// - AllowPartialData tracks if partial encoding is acceptable in the
30 : /// current encoding state (to be used for atomic/non-atomic list item writes)
31 : /// - CurrentEncodingListIndex representing the list index that is next
32 : /// to be encoded in the output. kInvalidListIndex means that a new list
33 : /// encoding has been started.
34 : class AttributeEncodeState
35 : {
36 : public:
37 4535 : AttributeEncodeState() = default;
38 :
39 : /// Allows the encode state to be initialized from an OPTIONAL
40 : /// other encoding state
41 : ///
42 : /// if other is nullptr, this is the same as the default initializer.
43 2471 : AttributeEncodeState(const AttributeEncodeState * other)
44 2471 : {
45 2471 : if (other != nullptr)
46 : {
47 2471 : *this = *other;
48 : }
49 : else
50 : {
51 0 : mCurrentEncodingListIndex = kInvalidListIndex;
52 0 : mAllowPartialData = false;
53 : }
54 2471 : }
55 :
56 393 : bool AllowPartialData() const { return mAllowPartialData; }
57 5780 : ListIndex CurrentEncodingListIndex() const { return mCurrentEncodingListIndex; }
58 :
59 3186 : AttributeEncodeState & SetAllowPartialData(bool allow)
60 : {
61 3186 : mAllowPartialData = allow;
62 3186 : return *this;
63 : }
64 :
65 5042 : AttributeEncodeState & SetCurrentEncodingListIndex(ListIndex idx)
66 : {
67 5042 : mCurrentEncodingListIndex = idx;
68 5042 : return *this;
69 : }
70 :
71 2287 : void Reset()
72 : {
73 2287 : mCurrentEncodingListIndex = kInvalidListIndex;
74 2287 : mAllowPartialData = false;
75 2287 : }
76 :
77 : private:
78 : /**
79 : * If set to kInvalidListIndex, indicates that we have not encoded any data for the list yet and
80 : * need to start by encoding an empty list before we start encoding any list items.
81 : *
82 : * When set to a valid ListIndex value, indicates the index of the next list item that needs to be
83 : * encoded (i.e. the count of items encoded so far).
84 : */
85 : ListIndex mCurrentEncodingListIndex = kInvalidListIndex;
86 :
87 : /**
88 : * When an attempt to encode an attribute returns an error, the buffer may contain tailing dirty data
89 : * (since the put was aborted). The report engine normally rolls back the buffer to right before encoding
90 : * of the attribute started on errors.
91 : *
92 : * When chunking a list, EncodeListItem will atomically encode list items, ensuring that the
93 : * state of the buffer is valid to send (i.e. contains no trailing garbage), and return an error
94 : * if the list doesn't entirely fit. In this situation, mAllowPartialData is set to communicate to the
95 : * report engine that it should not roll back the list items.
96 : *
97 : * TODO: There might be a better name for this variable.
98 : */
99 : bool mAllowPartialData = false;
100 : };
101 :
102 : } // namespace app
103 : } // namespace chip
|