1 /*
2 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "hdf_block_buffer.h"
10 #include "osal_mem.h"
11 #include "securec.h"
12
13 static const unsigned int OFFSET = 8;
14
HdfHdfBlockBufferNew(const uint8_t * data,uint16_t size)15 struct HdfHdfBlockBuffer *HdfHdfBlockBufferNew(const uint8_t *data, uint16_t size)
16 {
17 uint16_t wantedSize;
18 struct HdfBlockBuffer *buffer = NULL;
19 if (size == 0) {
20 return NULL;
21 }
22 wantedSize = sizeof(struct HdfBlockBuffer) + size;
23 buffer = (struct HdfBlockBuffer *)OsalMemAlloc(wantedSize);
24 if (buffer == NULL) {
25 return NULL;
26 }
27 buffer->dataSize = size;
28 buffer->position = 0;
29 if (data != NULL) {
30 if (memcpy_s(buffer->data, buffer->dataSize, data, size) != EOK) {
31 OsalMemFree(buffer);
32 return NULL;
33 }
34 }
35 return buffer;
36 }
37
HdfBlockBufferFree(const struct HdfBlockBuffer * buffer)38 void HdfBlockBufferFree(const struct HdfBlockBuffer *buffer)
39 {
40 if (buffer != NULL) {
41 OsalMemFree(buffer);
42 }
43 }
44
HdfBlockBufferGetDataSize(struct HdfBlockBuffer * buffer)45 uint16_t HdfBlockBufferGetDataSize(struct HdfBlockBuffer *buffer)
46 {
47 return (buffer == NULL) ? 0 : buffer->dataSize;
48 }
49
HdfBlockBufferGetAvailableSize(struct HdfBlockBuffer * buffer)50 uint16_t HdfBlockBufferGetAvailableSize(struct HdfBlockBuffer *buffer)
51 {
52 return (buffer == NULL) ? 0 : (buffer->dataSize - buffer->position);
53 }
54
HdfBlockBufferRead(struct HdfBlockBuffer * buffer,uint16_t size)55 uint8_t *HdfBlockBufferRead(struct HdfBlockBuffer *buffer, uint16_t size)
56 {
57 uint8_t *dataPtr = NULL;
58 if ((buffer == NULL) || (buffer->dataSize - buffer->position < size)) {
59 return NULL;
60 }
61 dataPtr = &buffer->data[buffer->position];
62 buffer->position += size;
63 return dataPtr;
64 }
65
HdfBlockBufferGetData(struct HdfBlockBuffer * buffer)66 uint8_t *HdfBlockBufferGetData(struct HdfBlockBuffer *buffer)
67 {
68 return (buffer == NULL) ? NULL : &buffer->data[0];
69 }
70
HdfBlockBufferGetPoistion(struct HdfBlockBuffer * buffer)71 uint16_t HdfBlockBufferGetPoistion(struct HdfBlockBuffer *buffer)
72 {
73 return (buffer == NULL) ? 0 : buffer->position;
74 }
75
76
HdfBlockBufferSkipBytes(struct HdfBlockBuffer * buffer,uint16_t bytes)77 uint16_t HdfBlockBufferSkipBytes(struct HdfBlockBuffer *buffer, uint16_t bytes)
78 {
79 if (buffer == NULL) {
80 return 0;
81 }
82 if (buffer->position + bytes <= buffer->dataSize) {
83 buffer->position += bytes;
84 return buffer->dataSize - buffer->position;
85 } else {
86 buffer->position = buffer->dataSize;
87 return 0;
88 }
89 }
90
HdfBlockBufferReadUint8(struct HdfBlockBuffer * buffer,uint8_t * outValue)91 bool HdfBlockBufferReadUint8(struct HdfBlockBuffer *buffer, uint8_t *outValue)
92 {
93 if (buffer == NULL) {
94 return false;
95 }
96 if (buffer->position + BYTES_UINT8 <= buffer->dataSize) {
97 *outValue = buffer->data[buffer->position++];
98 return true;
99 }
100 return false;
101 }
102
HdfBlockBufferReadUint8At(struct HdfBlockBuffer * buffer,uint16_t idx,uint8_t * outValue)103 bool HdfBlockBufferReadUint8At(struct HdfBlockBuffer *buffer, uint16_t idx, uint8_t *outValue)
104 {
105 if (buffer == NULL) {
106 return false;
107 }
108 if (idx + BYTES_UINT8 <= buffer->dataSize) {
109 *outValue = buffer->data[idx];
110 return true;
111 }
112 return false;
113 }
114
HdfBlockBufferReadUint16(struct HdfBlockBuffer * buffer,uint16_t * outValue)115 bool HdfBlockBufferReadUint16(struct HdfBlockBuffer *buffer, uint16_t *outValue)
116 {
117 if (buffer == NULL) {
118 return false;
119 }
120 if (buffer->position + BYTES_UINT16 <= buffer->dataSize) {
121 *outValue = read_be16(buffer->data, buffer->position);
122 buffer->position += BYTES_UINT16;
123 return true;
124 }
125 return false;
126 }
127
HdfBlockBufferReadUint16At(struct HdfBlockBuffer * buffer,size_t idx,uint16_t * outValue)128 bool HdfBlockBufferReadUint16At(struct HdfBlockBuffer *buffer, size_t idx, uint16_t *outValue)
129 {
130 if (buffer == NULL) {
131 return false;
132 }
133 if (idx + BYTES_UINT16 <= buffer->dataSize) {
134 *outValue = read_be16(buffer->data, idx);
135 return true;
136 }
137 return false;
138 }
139
HdfBlockBufferRewind(struct HdfBlockBuffer * buffer)140 void HdfBlockBufferRewind(struct HdfBlockBuffer *buffer)
141 {
142 if (buffer != NULL) {
143 buffer->position = 0;
144 }
145 }
146
HdfBlockBufferWriteUint8(struct HdfBlockBuffer * buffer,uint8_t value)147 bool HdfBlockBufferWriteUint8(struct HdfBlockBuffer *buffer, uint8_t value)
148 {
149 if (buffer == NULL) {
150 return false;
151 }
152 if (buffer->position + sizeof(uint8_t) <= buffer->dataSize) {
153 buffer->data[buffer->position++] = value;
154 return true;
155 }
156 return false;
157 }
158
HdfBlockBufferWriteUint16(struct HdfBlockBuffer * buffer,uint16_t inValue)159 bool HdfBlockBufferWriteUint16(struct HdfBlockBuffer *buffer, uint16_t inValue)
160 {
161 if (buffer == NULL) {
162 return false;
163 }
164 if (buffer->position + BYTES_UINT16 <= buffer->dataSize) {
165 buffer->data[buffer->position++] = (uint8_t) (inValue >> OFFSET);
166 buffer->data[buffer->position++] = (uint8_t) (inValue & 0xFF);
167 return true;
168 }
169 return false;
170 }
171
HdfBlockBufferWriteData(struct HdfBlockBuffer * buffer,uint8_t * data,size_t length)172 bool HdfBlockBufferWriteData(struct HdfBlockBuffer *buffer, uint8_t *data, size_t length)
173 {
174 uint16_t residualSize;
175 if (buffer == NULL) {
176 return false;
177 }
178 residualSize = buffer->dataSize - buffer->position;
179 if (memcpy_s(buffer->data + buffer->position, residualSize, data, length) != EOK) {
180 return false;
181 }
182 buffer->position += length;
183 return true;
184 }
185
HdfBlockBufferDuplicate(const struct HdfBlockBuffer * buffer,uint16_t start,uint16_t end)186 struct HdfBlockBuffer *HdfBlockBufferDuplicate(const struct HdfBlockBuffer *buffer, uint16_t start, uint16_t end)
187 {
188 uint16_t bufferSize = HdfBlockBufferGetDataSize(buffer);
189 uint16_t newBufferSize;
190 struct HdfBlockBuffer *newBuffer = NULL;
191 if ((buffer == NULL) || (start > end)) {
192 return NULL;
193 }
194 if ((end > bufferSize) || (start > bufferSize)) {
195 return NULL;
196 }
197 newBufferSize = end - start + 1;
198 newBuffer = HdfBlockBufferNew(newBufferSize);
199 if (newBuffer == NULL) {
200 return NULL;
201 }
202 if (memcpy_s(newBuffer->data, newBufferSize, buffer->data + start, newBufferSize) != EOK) {
203 OsalMemFree(newBuffer);
204 return NULL;
205 }
206
207 return newBuffer;
208 }
209
HdfBlockBufferWriteBuff(struct HdfBlockBuffer * dst,struct HdfBlockBuffer * src)210 bool HdfBlockBufferWriteBuff(struct HdfBlockBuffer *dst, struct HdfBlockBuffer *src)
211 {
212 if (memcpy_s(&dst->data[dst->position], dst->dataSize - dst->position, src->data, src->dataSize) != EOK) {
213 return false;
214 }
215 dst->position += src->dataSize;
216 return true;
217 }
218
219