1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef ENCDEC_FACADE_H
17 #define ENCDEC_FACADE_H
18 
19 #include "utils/encdec/include/data_encoder.h"
20 #include "utils/encdec/include/data_decoder.h"
21 
22 namespace OHOS {
23 namespace AI {
24 /**
25  * Facade pattern for DataEncoder and DataDecoder.
26  */
27 class EncdecFacade {
28 public:
29 /**
30  * @brief encode arbitrary number args.
31  *
32  * Please note,
33  *
34  * 1. the memory in dataInfo should be released manually by the caller,
35  *    recommend to use guard macro immediately after ProcessEncode.
36  *    e.g.
37  *         MallocPointerGuard<unsigned char> dataInfoGuard(dataInfo.data);
38  *
39  * 2. the allowed input args contains:
40  *      - basic data types(int, double, boolean etc.), fix length arrays and structs containing them only.
41  *      - std::string
42  *
43  *    otherwise you should implement your own version of encoding/decoding
44  *    for pointers or struct containing pointers.
45  *    Specifically, you should instantiate template function (@link DataEncoder::EncodeOneParameter)
46  *    and (@link DataDecoder::DecodeOneParameter) for your own data type.
47  *
48  * 3. class and container are not supported or tested.
49  *
50  * @param [in] arg argument need to be serialized. Receive any number of input.
51  * @return Return 0 if encode successfully, returns a non-zero value otherwise.
52  */
53 template<typename Type, typename... Types>
ProcessEncode(DataInfo & dataInfo,const Type & arg,const Types &...args)54 static int ProcessEncode(DataInfo &dataInfo, const Type &arg, const Types &...args)
55 {
56     DataEncoder dataEncoder;
57     int retCode = dataEncoder.Init();
58     if (retCode != RETCODE_SUCCESS) {
59         HILOGE("[Encdec]Init encoder failed!");
60         return retCode;
61     }
62     retCode = dataEncoder.RecursiveEncode(arg, args...);
63     if (retCode != RETCODE_SUCCESS) {
64         HILOGE("[Encdec]Serialize failed.");
65         return retCode;
66     }
67     retCode = dataEncoder.GetSerializedData(dataInfo);
68     if (retCode != RETCODE_SUCCESS) {
69         HILOGE("[Encdec]Memory error when GetSerializedData.");
70         return retCode;
71     }
72 
73     if (dataInfo.length <= 0 || dataInfo.data == nullptr) {
74         HILOGE("[Encdec]dataInfo is invalid.");
75         return RETCODE_FAILURE;
76     }
77 
78     return RETCODE_SUCCESS;
79 }
80 
81 /**
82  * @brief decode arbitrary number args.
83  *
84  * Please note,
85  * 1. the encode and decode order should be matched strictly.
86  *
87  * @param [out] arg argument need to be unserialized. Receive any number of input.
88  * @return Return 0 if decode successfully, returns a non-zero value otherwise.
89  */
90 template<typename Type, typename... Types>
ProcessDecode(const DataInfo & dataInfo,Type & arg,Types &...args)91 static int ProcessDecode(const DataInfo &dataInfo, Type &arg, Types &...args)
92 {
93     if (dataInfo.data == nullptr || dataInfo.length <= 0) {
94         HILOGE("[Encdec]dataInfo is invalid.");
95         return RETCODE_FAILURE;
96     }
97 
98     DataDecoder dataDecoder(dataInfo);
99     int retCode = dataDecoder.RecursiveDecode(arg, args...);
100     if (retCode != RETCODE_SUCCESS) {
101         HILOGE("[Encdec]Unserialize Argument failed.");
102         return RETCODE_FAILURE;
103     }
104 
105     if (!dataDecoder.CheckDataEnd()) {
106         HILOGE("[Encdec]The size of decode data does not equal to the original one.");
107         return RETCODE_FAILURE;
108     }
109     return RETCODE_SUCCESS;
110 }
111 };
112 } // namespace AI
113 } // namespace OHOS
114 
115 #endif // ENCDEC_FACADE_H
116