From 8f67ca3213488cba5d9d33e5999d3b36c89d8f32 Mon Sep 17 00:00:00 2001 From: Yunhan Wang Date: Fri, 29 Oct 2021 09:36:10 -0700 Subject: [PATCH] Add ListBuilder/Parser and StructBuilder/Parser --Fix ListBuilder naming, which should be ArrayBuilder --Add ListBuilder/Parser and StructBuilder/Praser, the enablement for them would be follow-up PR --- src/app/BUILD.gn | 6 +- src/app/MessageDef/ArrayBuilder.cpp | 41 +++++ src/app/MessageDef/ArrayBuilder.h | 56 +++++++ src/app/MessageDef/ArrayParser.cpp | 31 ++++ src/app/MessageDef/ArrayParser.h | 38 +++++ src/app/MessageDef/AttributeDataList.h | 8 +- src/app/MessageDef/AttributeDataVersionList.h | 8 +- src/app/MessageDef/AttributePathList.h | 8 +- src/app/MessageDef/AttributeStatusList.h | 8 +- src/app/MessageDef/Builder.h | 4 +- src/app/MessageDef/CommandDataIB.cpp | 20 --- src/app/MessageDef/CommandDataIB.h | 22 +-- src/app/MessageDef/CommandList.h | 8 +- src/app/MessageDef/CommandPathIB.cpp | 36 ----- src/app/MessageDef/CommandPathIB.h | 40 +---- src/app/MessageDef/EventList.h | 8 +- src/app/MessageDef/EventPathList.h | 8 +- src/app/MessageDef/ListBuilder.cpp | 18 +-- src/app/MessageDef/ListBuilder.h | 14 +- src/app/MessageDef/ListParser.cpp | 56 +------ src/app/MessageDef/ListParser.h | 38 +---- src/app/MessageDef/Parser.cpp | 12 +- src/app/MessageDef/Parser.h | 7 + src/app/MessageDef/StatusIB.cpp | 12 -- src/app/MessageDef/StatusIB.h | 28 +--- src/app/MessageDef/StructBuilder.cpp | 39 +++++ src/app/MessageDef/StructBuilder.h | 56 +++++++ src/app/MessageDef/StructParser.cpp | 29 ++++ src/app/MessageDef/StructParser.h | 38 +++++ src/app/tests/BUILD.gn | 1 + src/app/tests/TestBuilderParser.cpp | 145 ++++++++++++++++++ 31 files changed, 547 insertions(+), 296 deletions(-) create mode 100644 src/app/MessageDef/ArrayBuilder.cpp create mode 100644 src/app/MessageDef/ArrayBuilder.h create mode 100644 src/app/MessageDef/ArrayParser.cpp create mode 100644 src/app/MessageDef/ArrayParser.h create mode 100644 src/app/MessageDef/StructBuilder.cpp create mode 100644 src/app/MessageDef/StructBuilder.h create mode 100644 src/app/MessageDef/StructParser.cpp create mode 100644 src/app/MessageDef/StructParser.h create mode 100644 src/app/tests/TestBuilderParser.cpp diff --git a/src/app/BUILD.gn b/src/app/BUILD.gn index 27a18093ad83d4..397e4d3c0e2a18 100644 --- a/src/app/BUILD.gn +++ b/src/app/BUILD.gn @@ -41,6 +41,8 @@ static_library("app") { "CommandSender.cpp", "EventManagement.cpp", "InteractionModelEngine.cpp", + "MessageDef/ArrayBuilder.cpp", + "MessageDef/ArrayParser.cpp", "MessageDef/AttributeDataElement.cpp", "MessageDef/AttributeDataElement.h", "MessageDef/AttributeDataList.cpp", @@ -74,9 +76,7 @@ static_library("app") { "MessageDef/InvokeCommand.cpp", "MessageDef/InvokeCommand.h", "MessageDef/ListBuilder.cpp", - "MessageDef/ListBuilder.h", "MessageDef/ListParser.cpp", - "MessageDef/ListParser.h", "MessageDef/MessageDefHelper.cpp", "MessageDef/MessageDefHelper.h", "MessageDef/Parser.cpp", @@ -88,6 +88,8 @@ static_library("app") { "MessageDef/StatusIB.cpp", "MessageDef/StatusIB.h", "MessageDef/StatusResponse.cpp", + "MessageDef/StructBuilder.cpp", + "MessageDef/StructParser.cpp", "MessageDef/SubscribeRequest.cpp", "MessageDef/SubscribeResponse.cpp", "MessageDef/TimedRequestMessage.cpp", diff --git a/src/app/MessageDef/ArrayBuilder.cpp b/src/app/MessageDef/ArrayBuilder.cpp new file mode 100644 index 00000000000000..202adbe415b3d8 --- /dev/null +++ b/src/app/MessageDef/ArrayBuilder.cpp @@ -0,0 +1,41 @@ +/** + * + * Copyright (c) 2021 Project CHIP Authors + * 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. + */ + +#include "ArrayBuilder.h" + +#include +#include +#include + +namespace chip { +namespace app { +CHIP_ERROR ArrayBuilder::Init(TLV::TLVWriter * const apWriter, const uint8_t aContextTagToUse) +{ + mpWriter = apWriter; + mError = mpWriter->StartContainer(TLV::ContextTag(aContextTagToUse), chip::TLV::kTLVType_Array, mOuterContainerType); + + return mError; +} + +CHIP_ERROR ArrayBuilder::Init(TLV::TLVWriter * const apWriter) +{ + mpWriter = apWriter; + mError = mpWriter->StartContainer(TLV::AnonymousTag, chip::TLV::kTLVType_Array, mOuterContainerType); + + return mError; +} +}; // namespace app +}; // namespace chip diff --git a/src/app/MessageDef/ArrayBuilder.h b/src/app/MessageDef/ArrayBuilder.h new file mode 100644 index 00000000000000..1b5b67efd7a957 --- /dev/null +++ b/src/app/MessageDef/ArrayBuilder.h @@ -0,0 +1,56 @@ +/** + * + * Copyright (c) 2021 Project CHIP Authors + * + * 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 "Builder.h" +#include "Parser.h" +#include +#include +#include +#include +#include + +namespace chip { +namespace app { +class ArrayBuilder : public Builder +{ +public: + /** + * Init the TLV array container with an particular context tag. + * Required to implement arrays of arrays, and to test ArrayBuilder. + * + * @param[in] apWriter Pointer to the TLVWriter that is encoding the message. + * @param[in] aContextTagToUse A contextTag to use. + * + * @return CHIP_ERROR codes returned by chip::TLV objects. + */ + + CHIP_ERROR Init(TLV::TLVWriter * const apWriter, const uint8_t aContextTagToUse); + /** + * Init the TLV array container with an anonymous tag. + * Required to implement arrays of arrays, and to test ArrayBuilder. + * + * @param[in] apWriter Pointer to the TLVWriter that is encoding the message. + * + * @return CHIP_ERROR codes returned by chip::TLV objects. + */ + CHIP_ERROR Init(TLV::TLVWriter * const apWriter); +}; + +}; // namespace app +}; // namespace chip diff --git a/src/app/MessageDef/ArrayParser.cpp b/src/app/MessageDef/ArrayParser.cpp new file mode 100644 index 00000000000000..bd53d024386223 --- /dev/null +++ b/src/app/MessageDef/ArrayParser.cpp @@ -0,0 +1,31 @@ +/** + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2018 Google LLC. + * Copyright (c) 2016-2017 Nest Labs, Inc. + * 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. + */ + +#include "ArrayParser.h" + +namespace chip { +namespace app { +CHIP_ERROR ArrayParser::Init(const TLV::TLVReader & aReader) +{ + mReader.Init(aReader); + VerifyOrReturnError(TLV::kTLVType_Array == mReader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE); + ReturnLogErrorOnFailure(mReader.EnterContainer(mOuterContainerType)); + return CHIP_NO_ERROR; +} +}; // namespace app +}; // namespace chip diff --git a/src/app/MessageDef/ArrayParser.h b/src/app/MessageDef/ArrayParser.h new file mode 100644 index 00000000000000..1cfa4900d46eed --- /dev/null +++ b/src/app/MessageDef/ArrayParser.h @@ -0,0 +1,38 @@ +/** + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2016-2017 Nest Labs, Inc. + * + * 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 "Parser.h" + +namespace chip { +namespace app { +class ArrayParser : public Parser +{ +public: + /** + * @brief Initialize the parser object with TLVReader + * + * @param [in] aReader A pointer to a TLVReader, which should be on the element of the array element + * + * @return #CHIP_NO_ERROR on success + */ + CHIP_ERROR Init(const TLV::TLVReader & aReader); +}; +}; // namespace app +}; // namespace chip diff --git a/src/app/MessageDef/AttributeDataList.h b/src/app/MessageDef/AttributeDataList.h index 9f38ab3c46c397..20949a064fd45d 100644 --- a/src/app/MessageDef/AttributeDataList.h +++ b/src/app/MessageDef/AttributeDataList.h @@ -23,9 +23,9 @@ #pragma once +#include "ArrayBuilder.h" +#include "ArrayParser.h" #include "AttributeDataElement.h" -#include "ListBuilder.h" -#include "ListParser.h" #include #include @@ -37,7 +37,7 @@ namespace chip { namespace app { namespace AttributeDataList { -class Parser : public ListParser +class Parser : public ArrayParser { public: #if CHIP_CONFIG_IM_ENABLE_SCHEMA_CHECK @@ -58,7 +58,7 @@ class Parser : public ListParser #endif }; -class Builder : public ListBuilder +class Builder : public ArrayBuilder { public: /** diff --git a/src/app/MessageDef/AttributeDataVersionList.h b/src/app/MessageDef/AttributeDataVersionList.h index 29b7095def62b7..cb079e18e470e6 100644 --- a/src/app/MessageDef/AttributeDataVersionList.h +++ b/src/app/MessageDef/AttributeDataVersionList.h @@ -23,9 +23,9 @@ #pragma once +#include "ArrayBuilder.h" +#include "ArrayParser.h" #include "AttributeDataElement.h" -#include "ListBuilder.h" -#include "ListParser.h" #include #include @@ -37,7 +37,7 @@ namespace chip { namespace app { namespace AttributeDataVersionList { -class Parser : public ListParser +class Parser : public ArrayParser { public: #if CHIP_CONFIG_IM_ENABLE_SCHEMA_CHECK @@ -83,7 +83,7 @@ class Parser : public ListParser CHIP_ERROR GetVersion(chip::DataVersion * const apVersion); }; -class Builder : public ListBuilder +class Builder : public ArrayBuilder { public: /** diff --git a/src/app/MessageDef/AttributePathList.h b/src/app/MessageDef/AttributePathList.h index f28d378465f269..11b475596a228b 100644 --- a/src/app/MessageDef/AttributePathList.h +++ b/src/app/MessageDef/AttributePathList.h @@ -23,9 +23,9 @@ #pragma once +#include "ArrayBuilder.h" +#include "ArrayParser.h" #include "AttributePath.h" -#include "ListBuilder.h" -#include "ListParser.h" #include #include @@ -37,7 +37,7 @@ namespace chip { namespace app { namespace AttributePathList { -class Parser : public ListParser +class Parser : public ArrayParser { public: #if CHIP_CONFIG_IM_ENABLE_SCHEMA_CHECK @@ -58,7 +58,7 @@ class Parser : public ListParser #endif }; -class Builder : public ListBuilder +class Builder : public ArrayBuilder { public: /** diff --git a/src/app/MessageDef/AttributeStatusList.h b/src/app/MessageDef/AttributeStatusList.h index 6ee48d9851a00a..78774a7fea11ee 100644 --- a/src/app/MessageDef/AttributeStatusList.h +++ b/src/app/MessageDef/AttributeStatusList.h @@ -23,9 +23,9 @@ #pragma once +#include "ArrayBuilder.h" +#include "ArrayParser.h" #include "AttributeStatusIB.h" -#include "ListBuilder.h" -#include "ListParser.h" #include #include @@ -37,7 +37,7 @@ namespace chip { namespace app { namespace AttributeStatusList { -class Builder : public ListBuilder +class Builder : public ArrayBuilder { public: /** @@ -58,7 +58,7 @@ class Builder : public ListBuilder AttributeStatusIB::Builder mAttributeStatusBuilder; }; -class Parser : public ListParser +class Parser : public ArrayParser { public: #if CHIP_CONFIG_IM_ENABLE_SCHEMA_CHECK diff --git a/src/app/MessageDef/Builder.h b/src/app/MessageDef/Builder.h index 347a67318fcde3..3aaef32803ca7c 100644 --- a/src/app/MessageDef/Builder.h +++ b/src/app/MessageDef/Builder.h @@ -85,14 +85,14 @@ class Builder */ void Rollback(const chip::TLV::TLVWriter & aPoint) { *mpWriter = aPoint; } + void EndOfContainer(); + protected: CHIP_ERROR mError; chip::TLV::TLVWriter * mpWriter; chip::TLV::TLVType mOuterContainerType; Builder(); - void EndOfContainer(); - CHIP_ERROR InitAnonymousStructure(chip::TLV::TLVWriter * const apWriter); }; }; // namespace app diff --git a/src/app/MessageDef/CommandDataIB.cpp b/src/app/MessageDef/CommandDataIB.cpp index e42fe57ce85bab..c590fdc463bfdc 100644 --- a/src/app/MessageDef/CommandDataIB.cpp +++ b/src/app/MessageDef/CommandDataIB.cpp @@ -36,21 +36,6 @@ using namespace chip::TLV; namespace chip { namespace app { -CHIP_ERROR CommandDataIB::Parser::Init(const chip::TLV::TLVReader & aReader) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - - // make a copy of the reader here - mReader.Init(aReader); - - VerifyOrExit(chip::TLV::kTLVType_Structure == mReader.GetType(), err = CHIP_ERROR_WRONG_TLV_TYPE); - - err = mReader.EnterContainer(mOuterContainerType); - -exit: - return err; -} - CHIP_ERROR CommandDataIB::Parser::ParseData(chip::TLV::TLVReader & aReader, int aDepth) const { @@ -370,11 +355,6 @@ CHIP_ERROR CommandDataIB::Parser::GetStatusIB(StatusIB::Parser * const apStatusI return err; } -CHIP_ERROR CommandDataIB::Builder::Init(chip::TLV::TLVWriter * const apWriter) -{ - return InitAnonymousStructure(apWriter); -} - CommandPathIB::Builder & CommandDataIB::Builder::CreateCommandPathBuilder() { // skip if error has already been set diff --git a/src/app/MessageDef/CommandDataIB.h b/src/app/MessageDef/CommandDataIB.h index f3175caef54b16..fa6476e504dd4f 100644 --- a/src/app/MessageDef/CommandDataIB.h +++ b/src/app/MessageDef/CommandDataIB.h @@ -46,18 +46,9 @@ enum kCsTag_StatusIB = 2, }; -class Parser : public chip::app::Parser +class Parser : public StructParser { public: - /** - * @brief Initialize the parser object with TLVReader - * - * @param [in] aReader A pointer to a TLVReader, which should point to the beginning of this CommandDataIB - * - * @return #CHIP_NO_ERROR on success - */ - CHIP_ERROR Init(const chip::TLV::TLVReader & aReader); - #if CHIP_CONFIG_IM_ENABLE_SCHEMA_CHECK /** * @brief Roughly verify the message is correctly formed @@ -112,18 +103,9 @@ class Parser : public chip::app::Parser CHIP_ERROR ParseData(chip::TLV::TLVReader & aReader, int aDepth) const; }; -class Builder : public chip::app::Builder +class Builder : public StructBuilder { public: - /** - * @brief Initialize a AttributeDataList::Builder for writing into a TLV stream - * - * @param [in] apWriter A pointer to TLVWriter - * - * @return #CHIP_NO_ERROR on success - */ - CHIP_ERROR Init(chip::TLV::TLVWriter * const apWriter); - /** * @brief Initialize a CommandPathIB::Builder for writing into the TLV stream * diff --git a/src/app/MessageDef/CommandList.h b/src/app/MessageDef/CommandList.h index 3422ffe43eccde..ebf193a1da85d6 100644 --- a/src/app/MessageDef/CommandList.h +++ b/src/app/MessageDef/CommandList.h @@ -23,9 +23,9 @@ #pragma once +#include "ArrayBuilder.h" +#include "ArrayParser.h" #include "CommandDataIB.h" -#include "ListBuilder.h" -#include "ListParser.h" #include #include @@ -37,7 +37,7 @@ namespace chip { namespace app { namespace CommandList { -class Parser : public ListParser +class Parser : public ArrayParser { public: #if CHIP_CONFIG_IM_ENABLE_SCHEMA_CHECK @@ -58,7 +58,7 @@ class Parser : public ListParser #endif }; -class Builder : public ListBuilder +class Builder : public ArrayBuilder { public: /** diff --git a/src/app/MessageDef/CommandPathIB.cpp b/src/app/MessageDef/CommandPathIB.cpp index 70ae23be0f066e..fbda9de0b33507 100644 --- a/src/app/MessageDef/CommandPathIB.cpp +++ b/src/app/MessageDef/CommandPathIB.cpp @@ -36,22 +36,6 @@ using namespace chip::TLV; namespace chip { namespace app { -CHIP_ERROR CommandPathIB::Parser::Init(const chip::TLV::TLVReader & aReader) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - - // make a copy of the reader here - mReader.Init(aReader); - - VerifyOrExit(chip::TLV::kTLVType_List == mReader.GetType(), err = CHIP_ERROR_WRONG_TLV_TYPE); - - err = mReader.EnterContainer(mOuterContainerType); - -exit: - - return err; -} - #if CHIP_CONFIG_IM_ENABLE_SCHEMA_CHECK CHIP_ERROR CommandPathIB::Parser::CheckSchemaValidity() const { @@ -154,26 +138,6 @@ CHIP_ERROR CommandPathIB::Parser::GetCommandId(chip::CommandId * const apCommand return GetUnsignedInteger(kCsTag_CommandId, apCommandId); } -CHIP_ERROR CommandPathIB::Builder::_Init(chip::TLV::TLVWriter * const apWriter, const Tag aTag) -{ - mpWriter = apWriter; - mError = mpWriter->StartContainer(aTag, chip::TLV::kTLVType_List, mOuterContainerType); - SuccessOrExit(mError); - -exit: - return mError; -} - -CHIP_ERROR CommandPathIB::Builder::Init(chip::TLV::TLVWriter * const apWriter) -{ - return _Init(apWriter, chip::TLV::AnonymousTag); -} - -CHIP_ERROR CommandPathIB::Builder::Init(chip::TLV::TLVWriter * const apWriter, const uint8_t aContextTagToUse) -{ - return _Init(apWriter, chip::TLV::ContextTag(aContextTagToUse)); -} - CommandPathIB::Builder & CommandPathIB::Builder::EndpointId(const chip::EndpointId aEndpointId) { // skip if error has already been set diff --git a/src/app/MessageDef/CommandPathIB.h b/src/app/MessageDef/CommandPathIB.h index 0867c91f757e65..3450ac31efeb0a 100644 --- a/src/app/MessageDef/CommandPathIB.h +++ b/src/app/MessageDef/CommandPathIB.h @@ -23,8 +23,8 @@ #pragma once -#include "Builder.h" -#include "Parser.h" +#include "ListBuilder.h" +#include "ListParser.h" #include #include @@ -43,18 +43,9 @@ enum kCsTag_CommandId = 2, }; -class Parser : public chip::app::Parser +class Parser : public ListParser { public: - /** - * @brief Initialize the parser object with TLVReader - * - * @param [in] aReader A pointer to a TLVReader, which should point to the beginning of this CommandPathIB - * - * @return #CHIP_NO_ERROR on success - */ - CHIP_ERROR Init(const chip::TLV::TLVReader & aReader); - #if CHIP_CONFIG_IM_ENABLE_SCHEMA_CHECK /** * @brief Roughly verify the message is correctly formed @@ -106,29 +97,9 @@ class Parser : public chip::app::Parser CHIP_ERROR GetCommandId(chip::CommandId * const apCommandId) const; }; -class Builder : public chip::app::Builder +class Builder : public ListBuilder { public: - /** - * @brief Initialize a CommandPathIB::Builder for writing into a TLV stream - * - * @param [in] apWriter A pointer to TLVWriter - * - * @return #CHIP_NO_ERROR on success - */ - CHIP_ERROR Init(chip::TLV::TLVWriter * const apWriter); - - /** - * Init the CommandPathIB container with an particular context tag. - * Required to implement arrays of arrays, and to test ListBuilder. - * - * @param[in] apWriter Pointer to the TLVWriter that is encoding the message. - * @param[in] aContextTagToUse A contextTag to use. - * - * @return CHIP_ERROR codes returned by chip::TLV objects. - */ - CHIP_ERROR Init(chip::TLV::TLVWriter * const apWriter, const uint8_t aContextTagToUse); - /** * @brief Inject EndpointId into the TLV stream to indicate the endpointId referenced by the path. * @@ -162,9 +133,6 @@ class Builder : public chip::app::Builder * @return A reference to *this */ CommandPathIB::Builder & EndOfCommandPath(); - -private: - CHIP_ERROR _Init(TLV::TLVWriter * const apWriter, const TLV::Tag aTag); }; }; // namespace CommandPathIB diff --git a/src/app/MessageDef/EventList.h b/src/app/MessageDef/EventList.h index b90db97c122f32..c3550a24d5a276 100644 --- a/src/app/MessageDef/EventList.h +++ b/src/app/MessageDef/EventList.h @@ -23,9 +23,9 @@ #pragma once +#include "ArrayBuilder.h" +#include "ArrayParser.h" #include "EventDataElement.h" -#include "ListBuilder.h" -#include "ListParser.h" #include #include @@ -37,7 +37,7 @@ namespace chip { namespace app { namespace EventList { -class Parser : public ListParser +class Parser : public ArrayParser { public: #if CHIP_CONFIG_IM_ENABLE_SCHEMA_CHECK @@ -58,7 +58,7 @@ class Parser : public ListParser #endif }; -class Builder : public ListBuilder +class Builder : public ArrayBuilder { public: /** diff --git a/src/app/MessageDef/EventPathList.h b/src/app/MessageDef/EventPathList.h index 1ef4987f61f182..f236a04ceb3c8f 100644 --- a/src/app/MessageDef/EventPathList.h +++ b/src/app/MessageDef/EventPathList.h @@ -23,10 +23,10 @@ #pragma once +#include "ArrayBuilder.h" +#include "ArrayParser.h" #include "EventPath.h" #include "EventPathList.h" -#include "ListBuilder.h" -#include "ListParser.h" #include #include @@ -38,7 +38,7 @@ namespace chip { namespace app { namespace EventPathList { -class Parser : public ListParser +class Parser : public ArrayParser { public: #if CHIP_CONFIG_IM_ENABLE_SCHEMA_CHECK @@ -59,7 +59,7 @@ class Parser : public ListParser #endif }; -class Builder : public ListBuilder +class Builder : public ArrayBuilder { public: /** diff --git a/src/app/MessageDef/ListBuilder.cpp b/src/app/MessageDef/ListBuilder.cpp index 5ba483951d879f..c383747bc280e8 100644 --- a/src/app/MessageDef/ListBuilder.cpp +++ b/src/app/MessageDef/ListBuilder.cpp @@ -15,11 +15,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/** - * @file - * This file defines List builder in CHIP interaction model - * - */ #include "ListBuilder.h" @@ -27,25 +22,20 @@ #include #include -using namespace chip; -using namespace chip::TLV; - namespace chip { namespace app { -ListBuilder::ListBuilder() {} - -CHIP_ERROR ListBuilder::Init(chip::TLV::TLVWriter * const apWriter, const uint8_t aContextTagToUse) +CHIP_ERROR ListBuilder::Init(TLV::TLVWriter * const apWriter, const uint8_t aContextTagToUse) { mpWriter = apWriter; - mError = mpWriter->StartContainer(chip::TLV::ContextTag(aContextTagToUse), chip::TLV::kTLVType_Array, mOuterContainerType); + mError = mpWriter->StartContainer(TLV::ContextTag(aContextTagToUse), TLV::kTLVType_List, mOuterContainerType); return mError; } -CHIP_ERROR ListBuilder::Init(chip::TLV::TLVWriter * const apWriter) +CHIP_ERROR ListBuilder::Init(TLV::TLVWriter * const apWriter) { mpWriter = apWriter; - mError = mpWriter->StartContainer(chip::TLV::AnonymousTag, chip::TLV::kTLVType_Array, mOuterContainerType); + mError = mpWriter->StartContainer(TLV::AnonymousTag, TLV::kTLVType_List, mOuterContainerType); return mError; } diff --git a/src/app/MessageDef/ListBuilder.h b/src/app/MessageDef/ListBuilder.h index b0a27380d3dfab..deeeb0af3472aa 100644 --- a/src/app/MessageDef/ListBuilder.h +++ b/src/app/MessageDef/ListBuilder.h @@ -15,11 +15,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/** - * @file - * This file defines List builder in CHIP interaction model - * - */ #pragma once @@ -33,11 +28,8 @@ namespace chip { namespace app { -class ListBuilder : public chip::app::Builder +class ListBuilder : public Builder { -protected: - ListBuilder(); - public: /** * Init the TLV array container with an particular context tag. @@ -49,7 +41,7 @@ class ListBuilder : public chip::app::Builder * @return CHIP_ERROR codes returned by chip::TLV objects. */ - CHIP_ERROR Init(chip::TLV::TLVWriter * const apWriter, const uint8_t aContextTagToUse); + CHIP_ERROR Init(TLV::TLVWriter * const apWriter, const uint8_t aContextTagToUse); /** * Init the TLV array container with an anonymous tag. * Required to implement arrays of arrays, and to test ListBuilder. @@ -58,7 +50,7 @@ class ListBuilder : public chip::app::Builder * * @return CHIP_ERROR codes returned by chip::TLV objects. */ - CHIP_ERROR Init(chip::TLV::TLVWriter * const apWriter); + CHIP_ERROR Init(TLV::TLVWriter * const apWriter); }; }; // namespace app diff --git a/src/app/MessageDef/ListParser.cpp b/src/app/MessageDef/ListParser.cpp index cc3811e2aa3371..21b6b7bff3e6b1 100644 --- a/src/app/MessageDef/ListParser.cpp +++ b/src/app/MessageDef/ListParser.cpp @@ -15,65 +15,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/** - * @file - * This file defines List parser in CHIP interaction model - * - */ #include "ListParser.h" -#include -#include -#include - -using namespace chip; -using namespace chip::TLV; - namespace chip { namespace app { -ListParser::ListParser() {} - -CHIP_ERROR ListParser::Init(const chip::TLV::TLVReader & aReader) +CHIP_ERROR ListParser::Init(const TLV::TLVReader & aReader) { - CHIP_ERROR err = CHIP_NO_ERROR; - - // make a copy of the reader here mReader.Init(aReader); - - VerifyOrExit(chip::TLV::kTLVType_Array == mReader.GetType(), err = CHIP_ERROR_WRONG_TLV_TYPE); - - err = mReader.EnterContainer(mOuterContainerType); - -exit: - - return err; -} - -CHIP_ERROR ListParser::InitIfPresent(const chip::TLV::TLVReader & aReader, const uint8_t aContextTagToFind) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - chip::TLV::TLVReader reader; - - err = mReader.FindElementWithTag(chip::TLV::ContextTag(aContextTagToFind), reader); - SuccessOrExit(err); - - err = Init(reader); - SuccessOrExit(err); - -exit: - ChipLogIfFalse((CHIP_NO_ERROR == err) || (CHIP_END_OF_TLV == err)); - - return err; -} - -CHIP_ERROR ListParser::Next() -{ - CHIP_ERROR err = mReader.Next(); - - ChipLogIfFalse((CHIP_NO_ERROR == err) || (CHIP_END_OF_TLV == err)); - - return err; + VerifyOrReturnError(TLV::kTLVType_List == mReader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE); + ReturnLogErrorOnFailure(mReader.EnterContainer(mOuterContainerType)); + return CHIP_NO_ERROR; } }; // namespace app }; // namespace chip diff --git a/src/app/MessageDef/ListParser.h b/src/app/MessageDef/ListParser.h index dc33ba271b0a4c..0f0359faf9a8b7 100644 --- a/src/app/MessageDef/ListParser.h +++ b/src/app/MessageDef/ListParser.h @@ -15,56 +15,24 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/** - * @file - * This file defines List parser in CHIP interaction model - * - */ #pragma once -#include "Builder.h" #include "Parser.h" -#include -#include -#include -#include -#include namespace chip { namespace app { -class ListParser : public chip::app::Parser +class ListParser : public Parser { -protected: - ListParser(); - public: /** * @brief Initialize the parser object with TLVReader * - * @param [in] aReader A pointer to a TLVReader, which should be on the element of the array element - * - * @return #CHIP_NO_ERROR on success - */ - CHIP_ERROR Init(const chip::TLV::TLVReader & aReader); - - /** - * @brief Initialize the parser object with TLVReader if context tag exists - * - * @param [in] aReader A pointer to a TLVReader, which should be on the element of the array element - * @param [in] aContextTagToFind A context tag it tries to find - * - * @return #CHIP_NO_ERROR on success - */ - CHIP_ERROR InitIfPresent(const chip::TLV::TLVReader & aReader, const uint8_t aContextTagToFind); - - /** - * @brief Iterate to next element + * @param [in] aReader A pointer to a TLVReader, which should be on the element of the list element * * @return #CHIP_NO_ERROR on success */ - CHIP_ERROR Next(); + CHIP_ERROR Init(const TLV::TLVReader & aReader); }; - }; // namespace app }; // namespace chip diff --git a/src/app/MessageDef/Parser.cpp b/src/app/MessageDef/Parser.cpp index 98b30f6ed38660..1303a6ac440603 100644 --- a/src/app/MessageDef/Parser.cpp +++ b/src/app/MessageDef/Parser.cpp @@ -27,9 +27,6 @@ #include #include -using namespace chip; -using namespace chip::TLV; - namespace chip { namespace app { @@ -41,7 +38,7 @@ void Parser::Init(const chip::TLV::TLVReader & aReader, chip::TLV::TLVType aOute mOuterContainerType = aOuterContainerType; } -CHIP_ERROR Parser::GetReaderOnTag(const Tag aTagToFind, chip::TLV::TLVReader * const apReader) const +CHIP_ERROR Parser::GetReaderOnTag(const TLV::Tag aTagToFind, chip::TLV::TLVReader * const apReader) const { return mReader.FindElementWithTag(aTagToFind, *apReader); } @@ -50,5 +47,12 @@ void Parser::GetReader(chip::TLV::TLVReader * const apReader) { apReader->Init(mReader); } + +CHIP_ERROR Parser::Next() +{ + CHIP_ERROR err = mReader.Next(); + ChipLogIfFalse((CHIP_NO_ERROR == err) || (CHIP_END_OF_TLV == err)); + return err; +} }; // namespace app }; // namespace chip diff --git a/src/app/MessageDef/Parser.h b/src/app/MessageDef/Parser.h index 0b027a93002474..7030a73e0b36a0 100644 --- a/src/app/MessageDef/Parser.h +++ b/src/app/MessageDef/Parser.h @@ -62,6 +62,13 @@ class Parser */ void GetReader(chip::TLV::TLVReader * const apReader); + /** + * @brief Iterate to next element + * + * @return #CHIP_NO_ERROR on success + */ + CHIP_ERROR Next(); + protected: chip::TLV::TLVReader mReader; chip::TLV::TLVType mOuterContainerType; diff --git a/src/app/MessageDef/StatusIB.cpp b/src/app/MessageDef/StatusIB.cpp index eb71ab8bfbd412..77f72c5e388005 100644 --- a/src/app/MessageDef/StatusIB.cpp +++ b/src/app/MessageDef/StatusIB.cpp @@ -135,18 +135,6 @@ CHIP_ERROR StatusIB::Parser::CheckSchemaValidity() const } #endif // CHIP_CONFIG_IM_ENABLE_SCHEMA_CHECK -CHIP_ERROR StatusIB::Builder::Init(TLV::TLVWriter * const apWriter) -{ - return InitAnonymousStructure(apWriter); -} - -CHIP_ERROR StatusIB::Builder::Init(TLV::TLVWriter * const apWriter, const uint8_t aContextTagToUse) -{ - mpWriter = apWriter; - mError = mpWriter->StartContainer(TLV::ContextTag(aContextTagToUse), TLV::kTLVType_Structure, mOuterContainerType); - return mError; -} - StatusIB::Builder & StatusIB::Builder::EncodeStatusIB(const StatusIB & aStatusIB) { mError = mpWriter->Put(TLV::ContextTag(to_underlying(Tag::kStatus)), aStatusIB.mStatus); diff --git a/src/app/MessageDef/StatusIB.h b/src/app/MessageDef/StatusIB.h index 80b7bfff9256c2..679680815714b8 100644 --- a/src/app/MessageDef/StatusIB.h +++ b/src/app/MessageDef/StatusIB.h @@ -23,8 +23,8 @@ #pragma once -#include "ListBuilder.h" -#include "ListParser.h" +#include "StructBuilder.h" +#include "StructParser.h" #include #include @@ -52,7 +52,7 @@ struct StatusIB kClusterStatus = 1, }; - class Parser : public chip::app::Parser + class Parser : public StructParser { public: /** @@ -91,29 +91,9 @@ struct StatusIB CHIP_ERROR DecodeStatusIB(StatusIB & aStatusIB) const; }; - class Builder : public chip::app::Builder + class Builder : public StructBuilder { public: - /** - * @brief Initialize a StatusIB::Builder for writing into a TLV stream - * - * @param [in] apWriter A pointer to TLVWriter - * - * @return #CHIP_NO_ERROR on success - */ - CHIP_ERROR Init(TLV::TLVWriter * const apWriter); - - /** - * Init the StatusIB container with an particular context tag. - * Required to implement arrays of arrays, and to test ListBuilder. - * - * @param[in] apWriter Pointer to the TLVWriter that is encoding the message. - * @param[in] aContextTagToUse A contextTag to use. - * - * @return CHIP_ERROR codes returned by chip::TLV objects. - */ - CHIP_ERROR Init(TLV::TLVWriter * const apWriter, const uint8_t aContextTagToUse); - /** * Write the StatusIB into TLV and close the container * diff --git a/src/app/MessageDef/StructBuilder.cpp b/src/app/MessageDef/StructBuilder.cpp new file mode 100644 index 00000000000000..b891db7316392d --- /dev/null +++ b/src/app/MessageDef/StructBuilder.cpp @@ -0,0 +1,39 @@ +/** + * + * Copyright (c) 2021 Project CHIP Authors + * 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. + */ + +#include "StructBuilder.h" + +#include +#include +#include + +namespace chip { +namespace app { +CHIP_ERROR StructBuilder::Init(TLV::TLVWriter * const apWriter, const uint8_t aContextTagToUse) +{ + mpWriter = apWriter; + mError = mpWriter->StartContainer(TLV::ContextTag(aContextTagToUse), TLV::kTLVType_Structure, mOuterContainerType); + return mError; +} + +CHIP_ERROR StructBuilder::Init(TLV::TLVWriter * const apWriter) +{ + mpWriter = apWriter; + mError = mpWriter->StartContainer(TLV::AnonymousTag, TLV::kTLVType_Structure, mOuterContainerType); + return mError; +} +}; // namespace app +}; // namespace chip diff --git a/src/app/MessageDef/StructBuilder.h b/src/app/MessageDef/StructBuilder.h new file mode 100644 index 00000000000000..7851306e05b86e --- /dev/null +++ b/src/app/MessageDef/StructBuilder.h @@ -0,0 +1,56 @@ +/** + * + * Copyright (c) 2021 Project CHIP Authors + * + * 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 "Builder.h" +#include "Parser.h" +#include +#include +#include +#include +#include + +namespace chip { +namespace app { +class StructBuilder : public Builder +{ +public: + /** + * Init the TLV array container with an particular context tag. + * Required to implement arrays of arrays, and to test StructBuilder. + * + * @param[in] apWriter Pointer to the TLVWriter that is encoding the message. + * @param[in] aContextTagToUse A contextTag to use. + * + * @return CHIP_ERROR codes returned by chip::TLV objects. + */ + + CHIP_ERROR Init(TLV::TLVWriter * const apWriter, const uint8_t aContextTagToUse); + /** + * Init the TLV array container with an anonymous tag. + * Required to implement arrays of arrays, and to test StructBuilder. + * + * @param[in] apWriter Pointer to the TLVWriter that is encoding the message. + * + * @return CHIP_ERROR codes returned by chip::TLV objects. + */ + CHIP_ERROR Init(TLV::TLVWriter * const apWriter); +}; + +}; // namespace app +}; // namespace chip diff --git a/src/app/MessageDef/StructParser.cpp b/src/app/MessageDef/StructParser.cpp new file mode 100644 index 00000000000000..58a265db520976 --- /dev/null +++ b/src/app/MessageDef/StructParser.cpp @@ -0,0 +1,29 @@ +/** + * + * Copyright (c) 2021 Project CHIP Authors + * 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. + */ + +#include "StructParser.h" + +namespace chip { +namespace app { +CHIP_ERROR StructParser::Init(const TLV::TLVReader & aReader) +{ + mReader.Init(aReader); + VerifyOrReturnError(TLV::kTLVType_Structure == mReader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE); + ReturnLogErrorOnFailure(mReader.EnterContainer(mOuterContainerType)); + return CHIP_NO_ERROR; +} +}; // namespace app +}; // namespace chip diff --git a/src/app/MessageDef/StructParser.h b/src/app/MessageDef/StructParser.h new file mode 100644 index 00000000000000..fdf4ffa081ce8e --- /dev/null +++ b/src/app/MessageDef/StructParser.h @@ -0,0 +1,38 @@ +/** + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2016-2017 Nest Labs, Inc. + * + * 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 "Parser.h" + +namespace chip { +namespace app { +class StructParser : public Parser +{ +public: + /** + * @brief Initialize the parser object with TLVReader + * + * @param [in] aReader A pointer to a TLVReader, which should be on the element of the struct element + * + * @return #CHIP_NO_ERROR on success + */ + CHIP_ERROR Init(const TLV::TLVReader & aReader); +}; +}; // namespace app +}; // namespace chip diff --git a/src/app/tests/BUILD.gn b/src/app/tests/BUILD.gn index 9bfd53e0622530..ba9d9115b8c3fa 100644 --- a/src/app/tests/BUILD.gn +++ b/src/app/tests/BUILD.gn @@ -51,6 +51,7 @@ chip_test_suite("tests") { "TestInteractionModelEngine.cpp", "TestMessageDef.cpp", "TestStatusResponse.cpp", + "TestBuilderParser.cpp", ] if (chip_device_platform != "efr32") { diff --git a/src/app/tests/TestBuilderParser.cpp b/src/app/tests/TestBuilderParser.cpp new file mode 100644 index 00000000000000..4959d2a4a2e8b5 --- /dev/null +++ b/src/app/tests/TestBuilderParser.cpp @@ -0,0 +1,145 @@ +/* + * + * Copyright (c) 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace { + +using namespace chip::app; + +void ListTest(nlTestSuite * apSuite, void * apContext) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + chip::System::PacketBufferTLVWriter writer; + chip::System::PacketBufferTLVReader reader; + writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); + ListBuilder listBuilder; + NL_TEST_ASSERT(apSuite, listBuilder.Init(&writer) == CHIP_NO_ERROR); + listBuilder.EndOfContainer(); + + chip::System::PacketBufferHandle buf; + err = writer.Finalize(&buf); + + ListParser listParser; + reader.Init(std::move(buf)); + err = reader.Next(); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + NL_TEST_ASSERT(apSuite, listParser.Init(reader) == CHIP_NO_ERROR); +} + +void StructTest(nlTestSuite * apSuite, void * apContext) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + chip::System::PacketBufferTLVWriter writer; + chip::System::PacketBufferTLVReader reader; + writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); + StructBuilder structBuilder; + NL_TEST_ASSERT(apSuite, structBuilder.Init(&writer) == CHIP_NO_ERROR); + structBuilder.EndOfContainer(); + + chip::System::PacketBufferHandle buf; + err = writer.Finalize(&buf); + + StructParser structParser; + reader.Init(std::move(buf)); + err = reader.Next(); + + NL_TEST_ASSERT(apSuite, structParser.Init(reader) == CHIP_NO_ERROR); +} + +void ArrayTest(nlTestSuite * apSuite, void * apContext) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + chip::System::PacketBufferTLVWriter writer; + chip::System::PacketBufferTLVReader reader; + writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); + ArrayBuilder arrayBuilder; + NL_TEST_ASSERT(apSuite, arrayBuilder.Init(&writer) == CHIP_NO_ERROR); + arrayBuilder.EndOfContainer(); + + chip::System::PacketBufferHandle buf; + err = writer.Finalize(&buf); + + ArrayParser arrayParser; + reader.Init(std::move(buf)); + err = reader.Next(); + + NL_TEST_ASSERT(apSuite, arrayParser.Init(reader) == CHIP_NO_ERROR); +} + +// clang-format off +const nlTest sTests[] = + { + NL_TEST_DEF("ListTest", ListTest), + NL_TEST_DEF("StructTest", StructTest), + NL_TEST_DEF("ArrayTest", ArrayTest), + NL_TEST_SENTINEL() + }; +// clang-format on +} // namespace + +/** + * Set up the test suite. + */ +static int TestSetup(void * inContext) +{ + CHIP_ERROR error = chip::Platform::MemoryInit(); + if (error != CHIP_NO_ERROR) + return FAILURE; + return SUCCESS; +} + +/** + * Tear down the test suite. + */ +static int TestTeardown(void * inContext) +{ + chip::Platform::MemoryShutdown(); + return SUCCESS; +} + +int TestBuilderParser() +{ + // clang-format off + nlTestSuite theSuite = + { + "TestBuilderParser", + &sTests[0], + TestSetup, + TestTeardown, + }; + // clang-format on + + nlTestRunner(&theSuite, nullptr); + + return (nlTestRunnerStats(&theSuite)); +} + +CHIP_REGISTER_TEST_SUITE(TestBuilderParser)