1/*
2 * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development 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 "data_buffer.h"
17#include <cstring>
18#include <unistd.h>
19#include <securec.h>
20
21namespace OHOS {
22namespace Sharing {
23
24DataBuffer::DataBuffer(int size)
25{
26    data_ = new uint8_t[size + 1];
27    data_[size] = '\0';
28    capacity_ = size;
29    size_ = 0;
30}
31
32DataBuffer::DataBuffer(const DataBuffer &other) noexcept
33{
34    if (other.data_ && other.size_) {
35        capacity_ = other.size_;
36        data_ = new uint8_t[capacity_ + 1];
37        memcpy_s(data_, capacity_ + 1, other.data_, other.size_);
38        size_ = other.size_;
39    }
40}
41
42DataBuffer &DataBuffer::operator=(const DataBuffer &other) noexcept
43{
44    if (this != &other) {
45        if (other.data_ && other.size_) {
46            capacity_ = other.size_;
47            delete[] data_;
48            data_ = new uint8_t[capacity_ + 1];
49            memcpy_s(data_, capacity_ + 1, other.data_, other.size_);
50            size_ = other.size_;
51        }
52    }
53
54    return *this;
55}
56
57DataBuffer::DataBuffer(DataBuffer &&other) noexcept
58{
59    data_ = other.data_;
60    size_ = other.size_;
61    capacity_ = other.capacity_;
62    other.data_ = nullptr;
63    other.size_ = 0;
64    other.capacity_ = 0;
65}
66
67DataBuffer &DataBuffer::operator=(DataBuffer &&other) noexcept
68{
69    if (this != &other) {
70        if (data_) {
71            delete[] data_;
72        }
73        data_ = other.data_;
74        size_ = other.size_;
75        capacity_ = other.capacity_;
76        other.data_ = nullptr;
77        other.size_ = 0;
78        other.capacity_ = 0;
79    }
80
81    return *this;
82}
83
84DataBuffer::~DataBuffer()
85{
86    delete[] data_;
87    capacity_ = 0;
88    size_ = 0;
89}
90
91void DataBuffer::Resize(int size)
92{
93    if (size > capacity_) {
94        capacity_ = size;
95        auto data2 = new uint8_t[capacity_];
96        if (data_ && size_ > 0) {
97            auto ret = memcpy_s(data2, capacity_, data_, size_);
98            if (ret != EOK) {
99                return;
100            }
101            delete[] data_;
102        }
103        data_ = data2;
104    } else if (size < capacity_) {
105        if (data_) {
106            delete[] data_;
107        }
108        capacity_ = size;
109        data_ = new uint8_t[capacity_];
110        size_ = 0;
111    }
112}
113
114void DataBuffer::PushData(const char *data, int dataLen)
115{
116    if (!data) {
117        return;
118    }
119
120    if (dataLen + size_ <= capacity_) {
121        auto ret = memcpy_s(data_ + size_, capacity_, data, dataLen);
122        if (ret != EOK) {
123            return;
124        }
125        size_ += dataLen;
126    } else {
127        capacity_ = size_ + dataLen;
128        auto newBuffer = new (std::nothrow) uint8_t[capacity_];
129        if (!newBuffer) {
130            return;
131        }
132        if (data_) {
133            auto ret = memcpy_s(newBuffer, capacity_, data_, size_);
134            if (ret != EOK) {
135                return;
136            }
137        }
138        auto ret = memcpy_s(newBuffer + size_, capacity_, data, dataLen);
139        if (ret != EOK) {
140            return;
141        }
142        delete[] data_;
143        data_ = newBuffer;
144        size_ = capacity_;
145    }
146}
147
148void DataBuffer::ReplaceData(const char *data, int dataLen)
149{
150    if (!data) {
151        return;
152    }
153
154    if (dataLen > capacity_) {
155        if (data_)
156            delete[] data_;
157        capacity_ = dataLen;
158        data_ = new uint8_t[capacity_];
159    }
160
161    auto ret = memcpy_s(data_, capacity_, data, dataLen);
162    if (ret != EOK) {
163        return;
164    }
165    size_ = dataLen;
166}
167
168void DataBuffer::SetCapacity(int capacity)
169{
170    if (data_) {
171        delete[] data_;
172    }
173
174    if (capacity == 0) {
175        return;
176    }
177    if (capacity > 0) {
178        data_ = new uint8_t[capacity];
179    }
180    capacity_ = capacity;
181}
182
183} // namespace Sharing
184} // namespace OHOS