• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "hcf_parcel.h"
17 #include "securec.h"
18 #include "memory.h"
19 
20 const int PARCEL_DEFAULT_INCREASE_STEP = 16;
21 const uint32_t PARCEL_UINT_MAX = 0xffffffffU;
22 const int HALF_LEN = 2;
23 
CreateParcel(uint32_t size,uint32_t allocUnit)24 HcParcel CreateParcel(uint32_t size, uint32_t allocUnit)
25 {
26     HcParcel parcel;
27     (void)memset_s(&parcel, sizeof(parcel), 0, sizeof(parcel));
28     parcel.allocUnit = allocUnit;
29     if (parcel.allocUnit == 0) {
30         parcel.allocUnit = PARCEL_DEFAULT_INCREASE_STEP;
31     }
32     if (size > 0) {
33         parcel.data = (char *)HcfMalloc(size, 0);
34         if (parcel.data != NULL) {
35             parcel.length = size;
36         }
37     }
38     return parcel;
39 }
40 
DeleteParcel(HcParcel * parcel)41 void DeleteParcel(HcParcel *parcel)
42 {
43     if (parcel == NULL) {
44         return;
45     }
46 
47     if (parcel->data != NULL) {
48         HcfFree(parcel->data);
49         parcel->data = 0;
50     }
51     parcel->length = 0;
52     parcel->beginPos = 0;
53     parcel->endPos = 0;
54 }
55 
GetParcelDataSize(const HcParcel * parcel)56 uint32_t GetParcelDataSize(const HcParcel *parcel)
57 {
58     if (parcel == NULL) {
59         return 0;
60     }
61     if (parcel->endPos >= parcel->beginPos) {
62         return parcel->endPos - parcel->beginPos;
63     }
64     return 0;
65 }
66 
GetParcelData(const HcParcel * parcel)67 const char *GetParcelData(const HcParcel *parcel)
68 {
69     if (parcel == NULL) {
70         return NULL;
71     }
72     return parcel->data + parcel->beginPos;
73 }
74 
ParcelRealloc(HcParcel * parcel,uint32_t size)75 static bool ParcelRealloc(HcParcel *parcel, uint32_t size)
76 {
77     if (parcel->length >= size) {
78         return false;
79     }
80     char *newData = (char *)HcfMalloc(size, 0);
81     if (newData == NULL) {
82         return false;
83     }
84     if (memcpy_s(newData, size, parcel->data, parcel->length) != EOK) {
85         HcfFree(newData);
86         return false;
87     }
88     HcfFree(parcel->data);
89     parcel->data = newData;
90     parcel->length = size;
91     return true;
92 }
93 
ParcelIncrease(HcParcel * parcel,uint32_t size)94 static bool ParcelIncrease(HcParcel *parcel, uint32_t size)
95 {
96     if (parcel == NULL || size == 0) {
97         return false;
98     }
99     if (parcel->data == NULL) {
100         if (parcel->length != 0) {
101             return false;
102         }
103         *parcel = CreateParcel(size, parcel->allocUnit);
104         if (parcel->data == NULL) {
105             return false;
106         } else {
107             return true;
108         }
109     } else {
110         return ParcelRealloc(parcel, size);
111     }
112 }
113 
ParcelRecycle(HcParcel * parcel)114 static void ParcelRecycle(HcParcel *parcel)
115 {
116     if (parcel == NULL) {
117         return;
118     }
119     if (parcel->data == NULL || parcel->beginPos < parcel->allocUnit) {
120         return;
121     }
122 
123     uint32_t contentSize = parcel->endPos - parcel->beginPos;
124     if (contentSize > 0) {
125         if (memmove_s(parcel->data, parcel->endPos - parcel->beginPos,
126             parcel->data + parcel->beginPos, parcel->endPos - parcel->beginPos) != EOK) {
127         }
128     }
129     parcel->beginPos = 0;
130     parcel->endPos = contentSize;
131 }
132 
GetParcelIncreaseSize(HcParcel * parcel,uint32_t newSize)133 static uint32_t GetParcelIncreaseSize(HcParcel *parcel, uint32_t newSize)
134 {
135     if (parcel == NULL || parcel->allocUnit == 0) {
136         return 0;
137     }
138     if (newSize % parcel->allocUnit) {
139         return (newSize / parcel->allocUnit + 1) * parcel->allocUnit;
140     } else {
141         return (newSize / parcel->allocUnit) * parcel->allocUnit;
142     }
143 }
144 
ParcelWrite(HcParcel * parcel,const void * src,uint32_t dataSize)145 bool ParcelWrite(HcParcel *parcel, const void *src, uint32_t dataSize)
146 {
147     errno_t rc;
148     if (parcel == NULL || src == NULL || dataSize == 0) {
149         return false;
150     }
151     if (parcel->endPos > PARCEL_UINT_MAX - dataSize) {
152         return false;
153     }
154     if (parcel->endPos + dataSize > parcel->length) {
155         ParcelRecycle(parcel);
156         if (parcel->endPos + dataSize > parcel->length) {
157             uint32_t newSize = GetParcelIncreaseSize(parcel, parcel->endPos + dataSize);
158             if (!ParcelIncrease(parcel, newSize)) {
159                 return false;
160             }
161         }
162     }
163     rc = memmove_s(parcel->data + parcel->endPos, dataSize, src, dataSize);
164     if (rc != EOK) {
165         return false;
166     }
167     parcel->endPos += dataSize;
168     return true;
169 }
170 
ParcelWriteInt8(HcParcel * parcel,char src)171 bool ParcelWriteInt8(HcParcel *parcel, char src)
172 {
173     return ParcelWrite(parcel, &src, sizeof(src));
174 }
175 
ParcelPopBack(HcParcel * parcel,uint32_t size)176 bool ParcelPopBack(HcParcel *parcel, uint32_t size)
177 {
178     if (parcel != NULL && size > 0 && GetParcelDataSize(parcel) >= size) {
179         parcel->endPos -= size;
180         return true;
181     }
182     return false;
183 }
184