• 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 "hc_parcel.h"
17 #include "securec.h"
18 #include "hc_types.h"
19 
20 const int PARCEL_DEFAULT_INCREASE_STEP = 16;
21 const uint32_t PARCEL_UINT_MAX = 0xffffffffU;
22 
CreateParcel(uint32_t size,uint32_t allocUnit)23 HcParcel CreateParcel(uint32_t size, uint32_t allocUnit)
24 {
25     HcParcel parcel;
26     (void)memset_s(&parcel, sizeof(parcel), 0, sizeof(parcel));
27     parcel.allocUnit = allocUnit;
28     if (parcel.allocUnit == 0) {
29         parcel.allocUnit = PARCEL_DEFAULT_INCREASE_STEP;
30     }
31     if (size > 0) {
32         parcel.data = (char *)HcMalloc(size, 0);
33         if (parcel.data != NULL) {
34             parcel.length = size;
35         }
36     }
37     return parcel;
38 }
39 
DeleteParcel(HcParcel * parcel)40 void DeleteParcel(HcParcel *parcel)
41 {
42     if (parcel == NULL) {
43         return;
44     }
45 
46     if (parcel->data != NULL) {
47         HcFree(parcel->data);
48         parcel->data = 0;
49     }
50     parcel->length = 0;
51     parcel->beginPos = 0;
52     parcel->endPos = 0;
53 }
54 
ClearParcel(HcParcel * parcel)55 void ClearParcel(HcParcel *parcel)
56 {
57     if (parcel != NULL) {
58         parcel->beginPos = 0;
59         parcel->endPos = 0;
60     }
61 }
62 
ResetParcel(HcParcel * parcel,uint32_t size,uint32_t allocUnit)63 void ResetParcel(HcParcel *parcel, uint32_t size, uint32_t allocUnit)
64 {
65     if (parcel != NULL) {
66         DeleteParcel(parcel);
67         HcParcel newParcel = CreateParcel(size, allocUnit);
68         (void)memcpy_s(parcel, sizeof(HcParcel), &newParcel, sizeof(HcParcel));
69     }
70 }
71 
GetParcelDataSize(const HcParcel * parcel)72 uint32_t GetParcelDataSize(const HcParcel *parcel)
73 {
74     if (parcel == NULL) {
75         return 0;
76     }
77     if (parcel->endPos >= parcel->beginPos) {
78         return parcel->endPos - parcel->beginPos;
79     }
80     return 0;
81 }
82 
GetParcelData(const HcParcel * parcel)83 const char *GetParcelData(const HcParcel *parcel)
84 {
85     if (parcel == NULL) {
86         return NULL;
87     }
88     return parcel->data + parcel->beginPos;
89 }
90 
GetParcelLastChar(const HcParcel * parcel)91 const char *GetParcelLastChar(const HcParcel *parcel)
92 {
93     if (parcel == NULL || GetParcelDataSize(parcel) == 0) {
94         return NULL;
95     }
96     return parcel->data + parcel->endPos - 1;
97 }
98 
ParcelReadWithoutPopData(HcParcel * parcel,void * dst,uint32_t dataSize)99 HcBool ParcelReadWithoutPopData(HcParcel *parcel, void *dst, uint32_t dataSize)
100 {
101 #ifdef IS_BIG_ENDIAN
102     HcBool ret = ParcelReadRevert(parcel, dst, dataSize);
103 #else
104     HcBool ret = ParcelRead(parcel, dst, dataSize);
105 #endif
106     if (ret == HC_TRUE) {
107         parcel->beginPos -= dataSize;
108     }
109     return ret;
110 }
111 
ParcelRead(HcParcel * parcel,void * dst,uint32_t dataSize)112 HcBool ParcelRead(HcParcel *parcel, void *dst, uint32_t dataSize)
113 {
114     errno_t rc;
115     if (parcel == NULL || dst == NULL || dataSize == 0) {
116         return HC_FALSE;
117     }
118     if (parcel->beginPos > PARCEL_UINT_MAX - dataSize) {
119         return HC_FALSE;
120     }
121     if (parcel->beginPos + dataSize > parcel->endPos) {
122         return HC_FALSE;
123     }
124     rc = memmove_s(dst, dataSize, parcel->data + parcel->beginPos, dataSize);
125     if (rc != EOK) {
126         return HC_FALSE;
127     }
128     parcel->beginPos += dataSize;
129     return HC_TRUE;
130 }
131 
ParcelEraseBlock(HcParcel * parcel,uint32_t start,uint32_t dataSize,void * dst)132 HcBool ParcelEraseBlock(HcParcel *parcel, uint32_t start, uint32_t dataSize, void *dst)
133 {
134     errno_t rc;
135     if (parcel == NULL || dst == NULL || dataSize == 0) {
136         return HC_FALSE;
137     }
138     if (start > PARCEL_UINT_MAX - dataSize) {
139         return HC_FALSE;
140     }
141     uint32_t parcelSizeOrg = GetParcelDataSize(parcel);
142     if (parcelSizeOrg < start + dataSize) {
143         return HC_FALSE;
144     }
145     char *beginCopy = parcel->data + parcel->beginPos + start;
146     uint32_t copySize = parcelSizeOrg - start - dataSize;
147 
148     rc = memmove_s(dst, dataSize, beginCopy, dataSize);
149     if (rc != EOK) {
150         return HC_FALSE;
151     }
152     if (copySize != 0) {
153         rc = memmove_s(beginCopy, copySize, beginCopy + dataSize, copySize);
154         if (rc != EOK) {
155             return HC_FALSE;
156         }
157     }
158     parcel->endPos -= dataSize;
159     return HC_TRUE;
160 }
161 
ParcelReadRevert(HcParcel * parcel,void * dst,uint32_t dataSize)162 HcBool ParcelReadRevert(HcParcel *parcel, void *dst, uint32_t dataSize)
163 {
164     if (ParcelRead(parcel, dst, dataSize)) {
165         DataRevert(dst, dataSize);
166         return HC_TRUE;
167     } else {
168         return HC_FALSE;
169     }
170 }
171 
ParcelWriteRevert(HcParcel * parcel,const void * src,uint32_t dataSize)172 HcBool ParcelWriteRevert(HcParcel *parcel, const void *src, uint32_t dataSize)
173 {
174     errno_t rc;
175     void *srcCopy = HcMalloc(dataSize, 0);
176     if (srcCopy == NULL) {
177         return HC_FALSE;
178     }
179     rc = memmove_s(srcCopy, dataSize, src, dataSize);
180     if (rc != EOK) {
181         HcFree(srcCopy);
182         return HC_FALSE;
183     }
184     DataRevert(srcCopy, dataSize);
185     HcBool ret = ParcelWrite(parcel, srcCopy, dataSize);
186     HcFree(srcCopy);
187     return ret;
188 }
189 
ParcelReadInt32(HcParcel * parcel,int * dst)190 HcBool ParcelReadInt32(HcParcel *parcel, int *dst)
191 {
192     return ParcelRead(parcel, dst, sizeof(int));
193 }
194 
ParcelReadUint32(HcParcel * parcel,uint32_t * dst)195 HcBool ParcelReadUint32(HcParcel *parcel, uint32_t *dst)
196 {
197     return ParcelRead(parcel, dst, sizeof(uint32_t));
198 }
199 
ParcelReadInt16(HcParcel * parcel,short * dst)200 HcBool ParcelReadInt16(HcParcel *parcel, short *dst)
201 {
202     return ParcelRead(parcel, dst, sizeof(short));
203 }
204 
ParcelReadUint16(HcParcel * parcel,uint16_t * dst)205 HcBool ParcelReadUint16(HcParcel *parcel, uint16_t *dst)
206 {
207     return ParcelRead(parcel, dst, sizeof(uint16_t));
208 }
209 
ParcelReadInt8(HcParcel * parcel,char * dst)210 HcBool ParcelReadInt8(HcParcel *parcel, char *dst)
211 {
212     return ParcelRead(parcel, dst, sizeof(char));
213 }
214 
ParcelReadUint8(HcParcel * parcel,uint8_t * dst)215 HcBool ParcelReadUint8(HcParcel *parcel, uint8_t *dst)
216 {
217     return ParcelRead(parcel, dst, sizeof(uint8_t));
218 }
219 
ParcelReadUint64(HcParcel * parcel,uint64_t * dst)220 HcBool ParcelReadUint64(HcParcel *parcel, uint64_t *dst)
221 {
222     return ParcelRead(parcel, dst, sizeof(uint64_t));
223 }
224 
ParcelReadInt64(HcParcel * parcel,int64_t * dst)225 HcBool ParcelReadInt64(HcParcel *parcel, int64_t *dst)
226 {
227     return ParcelRead(parcel, dst, sizeof(int64_t));
228 }
229 
ParcelRealloc(HcParcel * parcel,uint32_t size)230 static HcBool ParcelRealloc(HcParcel *parcel, uint32_t size)
231 {
232     if (parcel->length >= size) {
233         return HC_FALSE;
234     }
235     char *newData = (char *)HcMalloc(size, 0);
236     if (newData == NULL) {
237         return HC_FALSE;
238     }
239     if (memcpy_s(newData, size, parcel->data, parcel->length) != EOK) {
240         HcFree(newData);
241         return HC_FALSE;
242     }
243     HcFree(parcel->data);
244     parcel->data = newData;
245     parcel->length = size;
246     return HC_TRUE;
247 }
248 
ParcelIncrease(HcParcel * parcel,uint32_t size)249 static HcBool ParcelIncrease(HcParcel *parcel, uint32_t size)
250 {
251     if (parcel == NULL || size == 0) {
252         return HC_FALSE;
253     }
254     if (parcel->data == NULL) {
255         if (parcel->length != 0) {
256             return HC_FALSE;
257         }
258         *parcel = CreateParcel(size, parcel->allocUnit);
259         if (parcel->data == NULL) {
260             return HC_FALSE;
261         } else {
262             return HC_TRUE;
263         }
264     } else {
265         return ParcelRealloc(parcel, size);
266     }
267 }
268 
ParcelRecycle(HcParcel * parcel)269 static void ParcelRecycle(HcParcel *parcel)
270 {
271     if (parcel == NULL) {
272         return;
273     }
274     if (parcel->data == NULL || parcel->beginPos < parcel->allocUnit) {
275         return;
276     }
277 
278     uint32_t contentSize = parcel->endPos - parcel->beginPos;
279     if (contentSize > 0) {
280         if (memmove_s(parcel->data, parcel->endPos - parcel->beginPos,
281             parcel->data + parcel->beginPos, parcel->endPos - parcel->beginPos) != EOK) {
282         }
283     }
284     parcel->beginPos = 0;
285     parcel->endPos = contentSize;
286 }
287 
GetParcelIncreaseSize(HcParcel * parcel,uint32_t newSize)288 static uint32_t GetParcelIncreaseSize(HcParcel *parcel, uint32_t newSize)
289 {
290     if (parcel == NULL || parcel->allocUnit == 0) {
291         return 0;
292     }
293     if (newSize % parcel->allocUnit) {
294         return (newSize / parcel->allocUnit + 1) * parcel->allocUnit;
295     } else {
296         return (newSize / parcel->allocUnit) * parcel->allocUnit;
297     }
298 }
299 
ParcelWrite(HcParcel * parcel,const void * src,uint32_t dataSize)300 HcBool ParcelWrite(HcParcel *parcel, const void *src, uint32_t dataSize)
301 {
302     errno_t rc;
303     if (parcel == NULL || src == NULL || dataSize == 0) {
304         return HC_FALSE;
305     }
306     if (parcel->endPos > PARCEL_UINT_MAX - dataSize) {
307         return HC_FALSE;
308     }
309     if (parcel->endPos + dataSize > parcel->length) {
310         ParcelRecycle(parcel);
311         if (parcel->endPos + dataSize > parcel->length) {
312             uint32_t newSize = GetParcelIncreaseSize(parcel, parcel->endPos + dataSize);
313             if (!ParcelIncrease(parcel, newSize)) {
314                 return HC_FALSE;
315             }
316         }
317     }
318     rc = memmove_s(parcel->data + parcel->endPos, dataSize, src, dataSize);
319     if (rc != EOK) {
320         return HC_FALSE;
321     }
322     parcel->endPos += dataSize;
323     return HC_TRUE;
324 }
325 
ParcelWriteInt32(HcParcel * parcel,int src)326 HcBool ParcelWriteInt32(HcParcel *parcel, int src)
327 {
328     return ParcelWrite(parcel, &src, sizeof(src));
329 }
330 
ParcelWriteUint32(HcParcel * parcel,uint32_t src)331 HcBool ParcelWriteUint32(HcParcel *parcel, uint32_t src)
332 {
333     return ParcelWrite(parcel, &src, sizeof(src));
334 }
335 
ParcelWriteInt16(HcParcel * parcel,short src)336 HcBool ParcelWriteInt16(HcParcel *parcel, short src)
337 {
338     return ParcelWrite(parcel, &src, sizeof(src));
339 }
340 
ParcelWriteUint16(HcParcel * parcel,uint16_t src)341 HcBool ParcelWriteUint16(HcParcel *parcel, uint16_t src)
342 {
343     return ParcelWrite(parcel, &src, sizeof(src));
344 }
345 
ParcelWriteInt8(HcParcel * parcel,char src)346 HcBool ParcelWriteInt8(HcParcel *parcel, char src)
347 {
348     return ParcelWrite(parcel, &src, sizeof(src));
349 }
350 
ParcelWriteUint8(HcParcel * parcel,uint8_t src)351 HcBool ParcelWriteUint8(HcParcel *parcel, uint8_t src)
352 {
353     return ParcelWrite(parcel, &src, sizeof(src));
354 }
355 
ParcelWriteUint64(HcParcel * parcel,uint64_t src)356 HcBool ParcelWriteUint64(HcParcel *parcel, uint64_t src)
357 {
358     return ParcelWrite(parcel, &src, sizeof(src));
359 }
360 
ParcelWriteInt64(HcParcel * parcel,int64_t src)361 HcBool ParcelWriteInt64(HcParcel *parcel, int64_t src)
362 {
363     return ParcelWrite(parcel, &src, sizeof(src));
364 }
365 
ParcelReadParcel(HcParcel * src,HcParcel * dst,uint32_t size,HcBool copy)366 HcBool ParcelReadParcel(HcParcel *src, HcParcel *dst, uint32_t size, HcBool copy)
367 {
368     if (src == NULL || dst == NULL) {
369         return HC_FALSE;
370     }
371     if (GetParcelDataSize(src) < size) {
372         return HC_FALSE;
373     }
374     if (!ParcelWrite(dst, (void *)GetParcelData(src), size)) {
375         return HC_FALSE;
376     }
377 
378     if (!copy) {
379         src->beginPos += size;
380     }
381     return HC_TRUE;
382 }
383 
ParcelCopy(HcParcel * src,HcParcel * dst)384 HcBool ParcelCopy(HcParcel *src, HcParcel *dst)
385 {
386     if (src == NULL || dst == NULL) {
387         return HC_FALSE;
388     }
389     if (GetParcelDataSize(src) == 0) {
390         return HC_TRUE;
391     }
392     return ParcelReadParcel(src, dst, GetParcelDataSize(src), HC_TRUE);
393 }
394 
DataRevert(void * data,uint32_t length)395 void DataRevert(void *data, uint32_t length)
396 {
397     if (data != NULL) {
398         uint8_t *pc = (uint8_t *) data;
399         uint32_t i = 0;
400         for (; i < length / 2; ++i) { /* half of the length */
401             /* swap p[i] and p[length-i-1] */
402             pc[i] ^= pc[length - i - 1];
403             pc[length - i - 1] ^= pc[i];
404             pc[i] ^= pc[length - i - 1];
405         }
406     }
407 }
408 
ParcelReadInt32Revert(HcParcel * parcel,int32_t * dst)409 HcBool ParcelReadInt32Revert(HcParcel *parcel, int32_t *dst)
410 {
411     HcBool ret = ParcelRead(parcel, dst, sizeof(int));
412     if (ret) {
413         DataRevert(dst, sizeof(int));
414     }
415     return ret;
416 }
417 
ParcelReadUint32Revert(HcParcel * parcel,uint32_t * dst)418 HcBool ParcelReadUint32Revert(HcParcel *parcel, uint32_t *dst)
419 {
420     HcBool ret = ParcelRead(parcel, dst, sizeof(uint32_t));
421     if (ret) {
422         DataRevert(dst, sizeof(uint32_t));
423     }
424     return ret;
425 }
426 
ParcelReadInt16Revert(HcParcel * parcel,short * dst)427 HcBool ParcelReadInt16Revert(HcParcel *parcel, short *dst)
428 {
429     HcBool ret = ParcelRead(parcel, dst, sizeof(short));
430     if (ret) {
431         DataRevert(dst, sizeof(short));
432     }
433     return ret;
434 }
435 
ParcelReadUint16Revert(HcParcel * parcel,uint16_t * dst)436 HcBool ParcelReadUint16Revert(HcParcel *parcel, uint16_t *dst)
437 {
438     if (parcel == NULL || dst == NULL) {
439         return HC_FALSE;
440     }
441     HcBool ret = ParcelRead(parcel, dst, sizeof(uint16_t));
442     if (ret) {
443         DataRevert(dst, sizeof(uint16_t));
444     }
445     return ret;
446 }
447 
ParcelReadInt8Revert(HcParcel * parcel,char * dst)448 HcBool ParcelReadInt8Revert(HcParcel *parcel, char *dst)
449 {
450     return ParcelRead(parcel, dst, sizeof(char));
451 }
452 
ParcelReadUint8Revert(HcParcel * parcel,uint8_t * dst)453 HcBool ParcelReadUint8Revert(HcParcel *parcel, uint8_t *dst)
454 {
455     return ParcelRead(parcel, dst, sizeof(uint8_t));
456 }
457 
ParcelReadUint64Revert(HcParcel * parcel,uint64_t * dst)458 HcBool ParcelReadUint64Revert(HcParcel *parcel, uint64_t *dst)
459 {
460     HcBool ret = ParcelRead(parcel, dst, sizeof(uint64_t));
461     if (ret) {
462         DataRevert(dst, sizeof(uint64_t));
463     }
464     return ret;
465 }
466 
ParcelReadInt64Revert(HcParcel * parcel,int64_t * dst)467 HcBool ParcelReadInt64Revert(HcParcel *parcel, int64_t *dst)
468 {
469     HcBool ret = ParcelRead(parcel, dst, sizeof(int64_t));
470     if (ret) {
471         DataRevert(dst, sizeof(int64_t));
472     }
473     return ret;
474 }
475 
ParcelWriteInt32Revert(HcParcel * parcel,int src)476 HcBool ParcelWriteInt32Revert(HcParcel *parcel, int src)
477 {
478     DataRevert(&src, sizeof(src));
479     return ParcelWriteInt32(parcel, src);
480 }
481 
ParcelWriteUint32Revert(HcParcel * parcel,uint32_t src)482 HcBool ParcelWriteUint32Revert(HcParcel *parcel, uint32_t src)
483 {
484     DataRevert(&src, sizeof(src));
485     return ParcelWriteUint32(parcel, src);
486 }
487 
ParcelWriteInt16Revert(HcParcel * parcel,short src)488 HcBool ParcelWriteInt16Revert(HcParcel *parcel, short src)
489 {
490     DataRevert(&src, sizeof(src));
491     return ParcelWriteInt16(parcel, src);
492 }
493 
ParcelWriteUint16Revert(HcParcel * parcel,uint16_t src)494 HcBool ParcelWriteUint16Revert(HcParcel *parcel, uint16_t src)
495 {
496     DataRevert(&src, sizeof(src));
497     return ParcelWriteUint16(parcel, src);
498 }
499 
ParcelWriteInt8Revert(HcParcel * parcel,char src)500 HcBool ParcelWriteInt8Revert(HcParcel *parcel, char src)
501 {
502     return ParcelWriteInt8(parcel, src);
503 }
504 
ParcelWriteUint8Revert(HcParcel * parcel,uint8_t src)505 HcBool ParcelWriteUint8Revert(HcParcel *parcel, uint8_t src)
506 {
507     return ParcelWriteUint8(parcel, src);
508 }
509 
ParcelWriteUint64Revert(HcParcel * parcel,uint64_t src)510 HcBool ParcelWriteUint64Revert(HcParcel *parcel, uint64_t src)
511 {
512     DataRevert(&src, sizeof(src));
513     return ParcelWriteUint64(parcel, src);
514 }
515 
ParcelWriteInt64Revert(HcParcel * parcel,int64_t src)516 HcBool ParcelWriteInt64Revert(HcParcel *parcel, int64_t src)
517 {
518     DataRevert(&src, sizeof(src));
519     return ParcelWriteInt64(parcel, src);
520 }
521 
ParcelPopBack(HcParcel * parcel,uint32_t size)522 HcBool ParcelPopBack(HcParcel *parcel, uint32_t size)
523 {
524     if (parcel != NULL && size > 0 && GetParcelDataSize(parcel) >= size) {
525         parcel->endPos -= size;
526         return HC_TRUE;
527     }
528     return HC_FALSE;
529 }
530 
ParcelPopFront(HcParcel * parcel,uint32_t size)531 HcBool ParcelPopFront(HcParcel *parcel, uint32_t size)
532 {
533     if ((parcel != NULL) && (size > 0) && (GetParcelDataSize(parcel) >= size)) {
534         parcel->beginPos += size;
535         return HC_TRUE;
536     }
537     return HC_FALSE;
538 }
539