/* * * Copyright (c) 2020-2021 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include #include #include #include #include #include #include namespace chip { namespace app { namespace Clusters { static auto __attribute__((unused)) EnsureKnownEnumValue(chip::VendorId val) { return val; } } // namespace Clusters namespace DataModel { // // Decode // template ::value, int> = 0> CHIP_ERROR Decode(TLV::TLVReader & reader, X & x) { return reader.Get(x); } template ::value, int> = 0> CHIP_ERROR Decode(TLV::TLVReader & reader, X & x) { return reader.Get(x); } template ::value, int> = 0> CHIP_ERROR Decode(TLV::TLVReader & reader, X & x) { ReturnErrorOnFailure(reader.Get(x)); x = Clusters::EnsureKnownEnumValue(x); return CHIP_NO_ERROR; } template CHIP_ERROR Decode(TLV::TLVReader & reader, BitFlags & x) { return reader.Get(x); } // // @brief // // Decodes an octet string that is expected at the positioned reader. // // The passed in ByteSpan is ignored and updated to point directly into // the buffer backing the reader. // inline CHIP_ERROR Decode(TLV::TLVReader & reader, ByteSpan & x) { VerifyOrReturnError(reader.GetType() == TLV::kTLVType_ByteString, CHIP_ERROR_UNEXPECTED_TLV_ELEMENT); return reader.Get(x); } // // @brief // // Decodes a UTF-8 string that is expected at the positioned reader. // // The passed in char Span is ignored and updated to point directly into // the buffer backing the reader. // inline CHIP_ERROR Decode(TLV::TLVReader & reader, Span & x) { return reader.Get(x); } /* * @brief * * This specific variant that decodes cluster objects (like structs, commands, events) from TLV * depends on the presence of a Decode method on the object to present. The signature of that method * is as follows: * * CHIP_ERROR ::Decode(TLVReader &reader); * */ template ::value && std::is_same().Decode(std::declval())), CHIP_ERROR>::value, X> * = nullptr> CHIP_ERROR Decode(TLV::TLVReader & reader, X & x) { return x.Decode(reader); } /* * @brief * * This specific variant decodes from TLV a cluster object that contains all attributes encapsulated within a single, monolithic * cluster object. * * Each attribute in the cluster is decoded based on the provided ConcreteAttributePath. The TLVReader is to be positioned right on * the data value for the specified attribute. * * This API depends on the presence of a Decode method on the object. The signature of that method * is as follows: * * CHIP_ERROR ::Decode(TLVReader &reader, ConcreteAttributePath &path); * */ template < typename X, typename std::enable_if_t::value && std::is_same().Decode(std::declval(), std::declval())), CHIP_ERROR>::value, X> * = nullptr> CHIP_ERROR Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path, X & x) { return x.Decode(reader, path); } /* * @brief * * Decodes an optional value (struct field, command field, event field). */ template CHIP_ERROR Decode(TLV::TLVReader & reader, Optional & x) { // If we are calling this, it means we found the right tag, so just decode // the item. return Decode(reader, x.Emplace()); } /* * @brief * * Decodes a nullable value. */ template CHIP_ERROR Decode(TLV::TLVReader & reader, Nullable & x) { if (reader.GetType() == TLV::kTLVType_Null) { x.SetNull(); return CHIP_NO_ERROR; } // We have a value; decode it. ReturnErrorOnFailure(Decode(reader, x.SetNonNull())); if (!x.ExistingValueInEncodableRange()) { return CHIP_IM_GLOBAL_STATUS(ConstraintError); } return CHIP_NO_ERROR; } } // namespace DataModel } // namespace app } // namespace chip