Line data Source code
1 : /*
2 : * Copyright (c) 2025 Project CHIP Authors
3 : *
4 : * Licensed under the Apache License, Version 2.0 (the "License");
5 : * you may not use this file except in compliance with the License.
6 : * You may obtain a copy of the License at
7 : *
8 : * http://www.apache.org/licenses/LICENSE-2.0
9 : *
10 : * Unless required by applicable law or agreed to in writing, software
11 : * distributed under the License is distributed on an "AS IS" BASIS,
12 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : * See the License for the specific language governing permissions and
14 : * limitations under the License.
15 : */
16 : #include <app/persistence/AttributePersistence.h>
17 :
18 : #include <app/ConcreteAttributePath.h>
19 : #include <app/data-model/Nullable.h>
20 : #include <app/persistence/AttributePersistenceProvider.h>
21 : #include <app/persistence/String.h>
22 : #include <lib/core/CHIPError.h>
23 : #include <lib/support/Span.h>
24 :
25 : namespace chip::app {
26 :
27 : namespace {
28 :
29 13 : bool VerifySuccessLogOnFailure(const ConcreteAttributePath & path, CHIP_ERROR err)
30 : {
31 13 : VerifyOrReturnValue(err != CHIP_NO_ERROR, true);
32 :
33 : // Value not found is typical. Not an error worth logging.
34 6 : VerifyOrReturnValue(err != CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND, false);
35 :
36 3 : ChipLogError(Zcl, "Failed to load attribute %u/" ChipLogFormatMEI "/" ChipLogFormatMEI ": %" CHIP_ERROR_FORMAT,
37 : path.mEndpointId, ChipLogValueMEI(path.mClusterId), ChipLogValueMEI(path.mAttributeId), err.Format());
38 3 : return false;
39 : }
40 :
41 : } // namespace
42 :
43 6 : bool AttributePersistence::InternalRawLoadNativeEndianValue(const ConcreteAttributePath & path, void * data,
44 : const void * valueOnLoadFailure, size_t size)
45 : {
46 6 : MutableByteSpan rawBytes(reinterpret_cast<uint8_t *>(data), size);
47 6 : if (!VerifySuccessLogOnFailure(path, mProvider.ReadValue(path, rawBytes)))
48 : {
49 : // in case of failure, set the default value
50 3 : memcpy(data, valueOnLoadFailure, size);
51 3 : return false;
52 : }
53 :
54 3 : if (rawBytes.size() != size)
55 : {
56 : // short read: the value is not valid
57 1 : memcpy(data, valueOnLoadFailure, size);
58 1 : return false;
59 : }
60 :
61 2 : return true;
62 : }
63 :
64 7 : bool AttributePersistence::LoadString(const ConcreteAttributePath & path, Storage::Internal::ShortString & value)
65 : {
66 7 : Storage::Internal::ShortStringInputAdapter io(value);
67 7 : MutableByteSpan rawBytes = io.ReadBuffer();
68 :
69 7 : if (!VerifySuccessLogOnFailure(path, mProvider.ReadValue(path, rawBytes)))
70 : {
71 3 : value.SetContent(""_span);
72 3 : return false;
73 : }
74 4 : return io.FinalizeRead(rawBytes);
75 : }
76 :
77 2 : CHIP_ERROR AttributePersistence::StoreString(const ConcreteAttributePath & path, const Storage::Internal::ShortString & value)
78 : {
79 2 : Storage::Internal::ShortStringOutputAdapter io(value);
80 2 : return mProvider.WriteValue(path, io.ContentWithPrefix());
81 : }
82 :
83 : } // namespace chip::app
|