1/*
2 * Copyright (C) 2022-2023 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 "buffer.h"
17
18#include "securec.h"
19
20#include "adaptor_log.h"
21#include "adaptor_memory.h"
22
23#define MAX_BUFFER_SIZE 512000
24
25bool IsBufferValid(const Buffer *buffer)
26{
27    if ((buffer == NULL) || (buffer->buf == NULL) ||
28        (buffer->maxSize == 0) || (buffer->maxSize > MAX_BUFFER_SIZE) ||
29        (buffer->contentSize > buffer->maxSize)) {
30        return false;
31    }
32
33    return true;
34}
35
36Buffer GetTmpBuffer(uint8_t *buf, uint32_t contentSize, uint32_t maxSize)
37{
38    Buffer ret = {
39        .buf = buf,
40        .contentSize = contentSize,
41        .maxSize = maxSize,
42    };
43    return ret;
44}
45
46bool CheckBufferWithSize(const Buffer *buffer, const uint32_t size)
47{
48    if ((!IsBufferValid(buffer)) || (buffer->contentSize != size)) {
49        return false;
50    }
51
52    return true;
53}
54
55Buffer *CreateBufferBySize(const uint32_t size)
56{
57    if ((size == 0) || (size > MAX_BUFFER_SIZE)) {
58        LOG_ERROR("invalid param, size: %u", size);
59        return NULL;
60    }
61
62    Buffer *buffer = (Buffer *)Malloc(sizeof(Buffer));
63    if (buffer == NULL) {
64        LOG_ERROR("malloc buffer struct failed");
65        return NULL;
66    }
67
68    buffer->buf = (uint8_t *)Malloc(size);
69    if (buffer->buf == NULL) {
70        LOG_ERROR("malloc buffer data failed");
71        Free(buffer);
72        return NULL;
73    }
74
75    if (memset_s(buffer->buf, size, 0, size) != EOK) {
76        Free(buffer->buf);
77        Free(buffer);
78        return NULL;
79    }
80    buffer->maxSize = size;
81    buffer->contentSize = 0;
82
83    return buffer;
84}
85
86Buffer *CreateBufferByData(const uint8_t *data, const uint32_t dataSize)
87{
88    if ((data == NULL) || (dataSize == 0) || (dataSize > MAX_BUFFER_SIZE)) {
89        LOG_ERROR("invalid param, dataSize: %u", dataSize);
90        return NULL;
91    }
92
93    Buffer *buffer = (Buffer *)Malloc(sizeof(Buffer));
94    if (buffer == NULL) {
95        LOG_ERROR("malloc buffer struct failed");
96        return NULL;
97    }
98
99    buffer->buf = (uint8_t *)Malloc(dataSize);
100    if (buffer->buf == NULL) {
101        LOG_ERROR("malloc buffer data failed");
102        Free(buffer);
103        return NULL;
104    }
105
106    if (memcpy_s(buffer->buf, dataSize, data, dataSize) != EOK) {
107        LOG_ERROR("copy buffer failed");
108        DestoryBuffer(buffer);
109        return NULL;
110    }
111    buffer->maxSize = dataSize;
112    buffer->contentSize = dataSize;
113
114    return buffer;
115}
116
117void DestoryBuffer(Buffer *buffer)
118{
119    if (buffer != NULL) {
120        if (buffer->buf != NULL) {
121            if (memset_s(buffer->buf, buffer->maxSize, 0, buffer->maxSize) != EOK) {
122                LOG_ERROR("memset_s failed");
123            }
124            Free(buffer->buf);
125            buffer->buf = NULL;
126            buffer->contentSize = 0;
127            buffer->maxSize = 0;
128        }
129        Free(buffer);
130    }
131}
132
133Buffer *CopyBuffer(const Buffer *buffer)
134{
135    if (!IsBufferValid(buffer)) {
136        LOG_ERROR("invalid buffer");
137        return NULL;
138    }
139
140    Buffer *copyBuffer = CreateBufferBySize(buffer->maxSize);
141    if (copyBuffer == NULL) {
142        LOG_ERROR("create buffer failed");
143        return NULL;
144    }
145
146    if (memcpy_s(copyBuffer->buf, copyBuffer->maxSize, buffer->buf, buffer->contentSize) != EOK) {
147        LOG_ERROR("copy buffer failed");
148        goto FAIL;
149    }
150    copyBuffer->contentSize = buffer->contentSize;
151
152    return copyBuffer;
153
154FAIL:
155    DestoryBuffer(copyBuffer);
156    return NULL;
157}
158
159bool CompareBuffer(const Buffer *buffer1, const Buffer *buffer2)
160{
161    if (!IsBufferValid(buffer1) || !IsBufferValid(buffer2) || (buffer1->contentSize != buffer2->contentSize)) {
162        return false;
163    }
164
165    if (memcmp(buffer1->buf, buffer2->buf, buffer1->contentSize) == 0) {
166        return true;
167    }
168
169    return false;
170}
171
172ResultCode GetBufferData(const Buffer *buffer, uint8_t *data, uint32_t *dataSize)
173{
174    if (!IsBufferValid(buffer) || (data == NULL) || (dataSize == NULL)) {
175        LOG_ERROR("invalid params");
176        return RESULT_BAD_PARAM;
177    }
178    if (memcpy_s(data, *dataSize, buffer->buf, buffer->contentSize) != EOK) {
179        LOG_ERROR("copy buffer failed");
180        return RESULT_BAD_COPY;
181    }
182    *dataSize = buffer->contentSize;
183    return RESULT_SUCCESS;
184}
185
186Buffer *MergeBuffers(const Buffer *buffer1, const Buffer *buffer2)
187{
188    if (!IsBufferValid(buffer1) || !IsBufferValid(buffer2)) {
189        LOG_ERROR("invalid params");
190        return NULL;
191    }
192    Buffer *merged = CreateBufferBySize(buffer1->maxSize + buffer2->maxSize);
193    if (!IsBufferValid(merged)) {
194        LOG_ERROR("create buffer failed");
195        return NULL;
196    }
197
198    if (memcpy_s(merged->buf, merged->maxSize, buffer1->buf, buffer1->contentSize) != EOK) {
199        LOG_ERROR("memcpy buffer1 failed");
200        goto FAIL;
201    }
202    if (memcpy_s(merged->buf + buffer1->contentSize, merged->maxSize - buffer1->contentSize,
203        buffer2->buf, buffer2->contentSize) != EOK) {
204        LOG_ERROR("memcpy buffer2 failed");
205        goto FAIL;
206    }
207    merged->contentSize = buffer1->contentSize + buffer2->contentSize;
208    return merged;
209
210FAIL:
211    DestoryBuffer(merged);
212    return NULL;
213}