1 /*
2  * Copyright (c) 2024 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 #include "easy_event_encoder.h"
17 
18 #include <string.h>
19 
20 #include "easy_def.h"
21 #include "easy_util.h"
22 
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26 
27 static const unsigned int TAG_BYTE_OFFSET = 5;
28 static const unsigned int TAG_BYTE_BOUND = (1 << TAG_BYTE_OFFSET);
29 static const unsigned int TAG_BYTE_MASK = (TAG_BYTE_BOUND - 1);
30 static const unsigned int NON_TAG_BYTE_OFFSET = 7;
31 static const unsigned int NON_TAG_BYTE_BOUND = (1 << NON_TAG_BYTE_OFFSET);
32 static const unsigned int NON_TAG_BYTE_MASK = (NON_TAG_BYTE_BOUND - 1);
33 static uint8_t LENGTH_DELIMITED_ENCODE_TYPE = 1;
34 static const int VAR_INT_ENCODE_SUCCESS = 0;
35 static const int VAR_INT_ENCODE_FAIL = 1;
36 
EncodeTag(uint8_t encodeType)37 static uint8_t EncodeTag(uint8_t encodeType)
38 {
39     return (encodeType << (TAG_BYTE_OFFSET + 1));
40 }
41 
EncodeUnsignedVarint(uint8_t* data, const size_t dataLen, size_t* offset, uint8_t encodeType, uint64_t u64Val)42 static int EncodeUnsignedVarint(uint8_t* data, const size_t dataLen, size_t* offset, uint8_t encodeType,
43     uint64_t u64Val)
44 {
45     uint8_t cpyVal = EncodeTag(encodeType) | ((u64Val < TAG_BYTE_BOUND) ? 0 : TAG_BYTE_BOUND) |
46         (uint8_t)(u64Val & TAG_BYTE_MASK);
47     if ((dataLen < *offset) || ((dataLen - *offset) < sizeof(uint8_t))) {
48         return VAR_INT_ENCODE_FAIL;
49     }
50     *(data + *offset) = cpyVal;
51     *offset += sizeof(uint8_t);
52     u64Val >>= TAG_BYTE_OFFSET;
53     while (u64Val > 0) {
54         cpyVal = ((u64Val < NON_TAG_BYTE_BOUND) ? 0 : NON_TAG_BYTE_BOUND) | (uint8_t)(u64Val & NON_TAG_BYTE_MASK);
55         if ((dataLen < *offset) || ((dataLen - *offset) < sizeof(uint8_t))) {
56             return VAR_INT_ENCODE_FAIL;
57         }
58         *(data + *offset) = cpyVal;
59         *offset += sizeof(uint8_t);
60         u64Val >>= NON_TAG_BYTE_OFFSET;
61     }
62     return VAR_INT_ENCODE_SUCCESS;
63 }
64 
EncodeValueType(uint8_t* data, const size_t dataLen, size_t* offset, const struct HiSysEventEasyParamValueType* valueType)65 int EncodeValueType(uint8_t* data, const size_t dataLen, size_t* offset,
66     const struct HiSysEventEasyParamValueType* valueType)
67 {
68     if ((data == NULL) || (offset == NULL) || (valueType == NULL)) {
69         return ERR_EVENT_BUF_INVALID;
70     }
71     if ((dataLen < *offset) || ((dataLen - *offset) < sizeof(struct HiSysEventEasyParamValueType))) {
72         return ERR_ENCODE_VALUE_TYPE_FAILED;
73     }
74     *((struct HiSysEventEasyParamValueType*)(data + *offset)) = *valueType;
75     *offset += sizeof(struct HiSysEventEasyParamValueType);
76     return SUCCESS;
77 }
78 
EncodeStringValue(uint8_t* data, const size_t dataLen, size_t* offset, const char* content)79 int EncodeStringValue(uint8_t* data, const size_t dataLen, size_t* offset, const char* content)
80 {
81     if ((data == NULL) || (offset == NULL) || (content == NULL)) {
82         return ERR_EVENT_BUF_INVALID;
83     }
84     size_t contentLen = strlen(content);
85     if (EncodeUnsignedVarint(data, dataLen, offset, LENGTH_DELIMITED_ENCODE_TYPE, contentLen) !=
86         VAR_INT_ENCODE_SUCCESS) {
87         return ERR_ENCODE_STR_FAILED;
88     }
89     if ((dataLen < *offset) || ((dataLen - *offset) < contentLen)) {
90         return ERR_ENCODE_STR_FAILED;
91     }
92     int cpyRet = MemoryCopy(data + *offset, dataLen - *offset, (uint8_t*)content, contentLen);
93     if (cpyRet != SUCCESS) {
94         return cpyRet;
95     }
96     *offset += contentLen;
97     return SUCCESS;
98 }
99 
100 #ifdef __cplusplus
101 }
102 #endif