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