106f6ba60Sopenharmony_ci/*
206f6ba60Sopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
306f6ba60Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
406f6ba60Sopenharmony_ci * you may not use this file except in compliance with the License.
506f6ba60Sopenharmony_ci * You may obtain a copy of the License at
606f6ba60Sopenharmony_ci *
706f6ba60Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
806f6ba60Sopenharmony_ci *
906f6ba60Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1006f6ba60Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1106f6ba60Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1206f6ba60Sopenharmony_ci * See the License for the specific language governing permissions and
1306f6ba60Sopenharmony_ci * limitations under the License.
1406f6ba60Sopenharmony_ci */
1506f6ba60Sopenharmony_ci
1606f6ba60Sopenharmony_ci#include "ringbuffer.h"
1706f6ba60Sopenharmony_ci
1806f6ba60Sopenharmony_ci#include <memory>
1906f6ba60Sopenharmony_ci#include <sys/uio.h>
2006f6ba60Sopenharmony_ci#include <securec.h>
2106f6ba60Sopenharmony_ci#include <cstring>
2206f6ba60Sopenharmony_ci#include <iostream>
2306f6ba60Sopenharmony_ciRingBuffer::RingBuffer(const std::size_t bufSize, const enum MemAlignShift shift)
2406f6ba60Sopenharmony_ci    : bufSize_ {bufSize},
2506f6ba60Sopenharmony_ci      alignShift_ {shift}
2606f6ba60Sopenharmony_ci{
2706f6ba60Sopenharmony_ci    if (bufSize_ <= DEFAULT_SIZE) {
2806f6ba60Sopenharmony_ci        bufSize_ = DEFAULT_SIZE;
2906f6ba60Sopenharmony_ci    }
3006f6ba60Sopenharmony_ci    switch (shift) {
3106f6ba60Sopenharmony_ci        case B_ALIGN_SHIFT: {
3206f6ba60Sopenharmony_ci            bufSize_ = (bufSize_ >> B_ALIGN_SHIFT);
3306f6ba60Sopenharmony_ci            uint16_t *temp = new(std::nothrow) uint16_t[bufSize_];
3406f6ba60Sopenharmony_ci            if (temp != nullptr) {
3506f6ba60Sopenharmony_ci                buffer_ = reinterpret_cast<char *>(temp);
3606f6ba60Sopenharmony_ci            }
3706f6ba60Sopenharmony_ci            bufSize_ = (bufSize_ << B_ALIGN_SHIFT);
3806f6ba60Sopenharmony_ci            break;
3906f6ba60Sopenharmony_ci        }
4006f6ba60Sopenharmony_ci        case H_ALIGN_SHIFT: {
4106f6ba60Sopenharmony_ci            bufSize_ = (bufSize_ >> H_ALIGN_SHIFT);
4206f6ba60Sopenharmony_ci            uint16_t *temp = new(std::nothrow) uint16_t[bufSize_];
4306f6ba60Sopenharmony_ci            if (temp != nullptr) {
4406f6ba60Sopenharmony_ci                buffer_ = reinterpret_cast<char *>(temp);
4506f6ba60Sopenharmony_ci            }
4606f6ba60Sopenharmony_ci            bufSize_ = (bufSize_ << H_ALIGN_SHIFT);
4706f6ba60Sopenharmony_ci            break;
4806f6ba60Sopenharmony_ci        }
4906f6ba60Sopenharmony_ci        case W_ALIGN_SHIFT: {
5006f6ba60Sopenharmony_ci            bufSize_ = (bufSize_ >> W_ALIGN_SHIFT);
5106f6ba60Sopenharmony_ci            uint32_t *temp = new(std::nothrow) uint32_t[bufSize_];
5206f6ba60Sopenharmony_ci            if (temp != nullptr) {
5306f6ba60Sopenharmony_ci                buffer_ = reinterpret_cast<char *>(temp);
5406f6ba60Sopenharmony_ci            }
5506f6ba60Sopenharmony_ci            bufSize_ = (bufSize_ << W_ALIGN_SHIFT);
5606f6ba60Sopenharmony_ci            break;
5706f6ba60Sopenharmony_ci        }
5806f6ba60Sopenharmony_ci        case D_ALIGN_SHIFT: {
5906f6ba60Sopenharmony_ci            bufSize_ = (bufSize_ >> D_ALIGN_SHIFT);
6006f6ba60Sopenharmony_ci            uint64_t *temp = new(std::nothrow) uint64_t[bufSize_];
6106f6ba60Sopenharmony_ci            if (temp != nullptr) {
6206f6ba60Sopenharmony_ci                buffer_ = reinterpret_cast<char *>(temp);
6306f6ba60Sopenharmony_ci            }
6406f6ba60Sopenharmony_ci            bufSize_ = (bufSize_ << D_ALIGN_SHIFT);
6506f6ba60Sopenharmony_ci            break;
6606f6ba60Sopenharmony_ci        }
6706f6ba60Sopenharmony_ci    }
6806f6ba60Sopenharmony_ci}
6906f6ba60Sopenharmony_ci
7006f6ba60Sopenharmony_cissize_t RingBuffer::Read(const int fd, const std::size_t len)
7106f6ba60Sopenharmony_ci{
7206f6ba60Sopenharmony_ci    if (fd < 0) {
7306f6ba60Sopenharmony_ci        return -1;
7406f6ba60Sopenharmony_ci    }
7506f6ba60Sopenharmony_ci    if (len == 0) {
7606f6ba60Sopenharmony_ci        return 0;
7706f6ba60Sopenharmony_ci    }
7806f6ba60Sopenharmony_ci    constexpr std::size_t numDests {2};
7906f6ba60Sopenharmony_ci    struct iovec destBufs[numDests];
8006f6ba60Sopenharmony_ci    // resize if free space is not big enough
8106f6ba60Sopenharmony_ci    std::lock_guard<std::mutex> lk {mtx_};
8206f6ba60Sopenharmony_ci    while (len >= FreeSize()) {
8306f6ba60Sopenharmony_ci        // the equal sign makes sure the buffer will not be fully filled
8406f6ba60Sopenharmony_ci        if (Resize() != 0) {
8506f6ba60Sopenharmony_ci            return -1;
8606f6ba60Sopenharmony_ci        }
8706f6ba60Sopenharmony_ci    }
8806f6ba60Sopenharmony_ci    if (buffer_ == nullptr) {
8906f6ba60Sopenharmony_ci        return -1;
9006f6ba60Sopenharmony_ci    }
9106f6ba60Sopenharmony_ci    // now we have enough free space to read in from fd
9206f6ba60Sopenharmony_ci    destBufs[0].iov_base = buffer_ + tail_;
9306f6ba60Sopenharmony_ci    if (tail_ + len < bufSize_) {
9406f6ba60Sopenharmony_ci        // continuous free space
9506f6ba60Sopenharmony_ci        destBufs[0].iov_len = len;
9606f6ba60Sopenharmony_ci        destBufs[1].iov_base = buffer_ + tail_ + len;
9706f6ba60Sopenharmony_ci        destBufs[1].iov_len = 0;
9806f6ba60Sopenharmony_ci    } else {
9906f6ba60Sopenharmony_ci        // free space splitted
10006f6ba60Sopenharmony_ci        destBufs[0].iov_len = bufSize_ - tail_;
10106f6ba60Sopenharmony_ci        destBufs[1].iov_base = buffer_;
10206f6ba60Sopenharmony_ci        destBufs[1].iov_len = len + tail_ - bufSize_;
10306f6ba60Sopenharmony_ci    }
10406f6ba60Sopenharmony_ci    ssize_t ret = readv(fd, destBufs, numDests);
10506f6ba60Sopenharmony_ci    if (ret != -1) {
10606f6ba60Sopenharmony_ci        // update buffer status
10706f6ba60Sopenharmony_ci        tail_ += static_cast<std::size_t>(ret);
10806f6ba60Sopenharmony_ci        while (tail_ >= bufSize_) {
10906f6ba60Sopenharmony_ci            tail_ -= bufSize_;
11006f6ba60Sopenharmony_ci        }
11106f6ba60Sopenharmony_ci    }
11206f6ba60Sopenharmony_ci    return ret;
11306f6ba60Sopenharmony_ci}
11406f6ba60Sopenharmony_ci
11506f6ba60Sopenharmony_cissize_t RingBuffer::Write(const int fd, std::size_t len)
11606f6ba60Sopenharmony_ci{
11706f6ba60Sopenharmony_ci    if (fd < 0) {
11806f6ba60Sopenharmony_ci        return -1;
11906f6ba60Sopenharmony_ci    }
12006f6ba60Sopenharmony_ci    constexpr std::size_t numSrcs {2};
12106f6ba60Sopenharmony_ci    struct iovec srcBufs[numSrcs];
12206f6ba60Sopenharmony_ci    std::lock_guard<std::mutex> lk {mtx_};
12306f6ba60Sopenharmony_ci    std::size_t dataSize = DataSize();
12406f6ba60Sopenharmony_ci    if (dataSize < len) {
12506f6ba60Sopenharmony_ci        len = dataSize;
12606f6ba60Sopenharmony_ci    }
12706f6ba60Sopenharmony_ci    if (len == 0) {
12806f6ba60Sopenharmony_ci        return 0;
12906f6ba60Sopenharmony_ci    }
13006f6ba60Sopenharmony_ci    if (buffer_ == nullptr) {
13106f6ba60Sopenharmony_ci        return -1;
13206f6ba60Sopenharmony_ci    }
13306f6ba60Sopenharmony_ci    // now we are sure there is at least 'len' bytes data in the buffer
13406f6ba60Sopenharmony_ci    srcBufs[0].iov_base = buffer_ + head_;
13506f6ba60Sopenharmony_ci    if (head_ + len > bufSize_) {
13606f6ba60Sopenharmony_ci        // data splitted
13706f6ba60Sopenharmony_ci        srcBufs[0].iov_len = bufSize_ - head_;
13806f6ba60Sopenharmony_ci        srcBufs[1].iov_base = buffer_;
13906f6ba60Sopenharmony_ci        srcBufs[1].iov_len = len + head_- bufSize_;
14006f6ba60Sopenharmony_ci    } else {
14106f6ba60Sopenharmony_ci        // continuous data
14206f6ba60Sopenharmony_ci        srcBufs[0].iov_len = len;
14306f6ba60Sopenharmony_ci        srcBufs[1].iov_base = buffer_ + head_ + len;
14406f6ba60Sopenharmony_ci        srcBufs[1].iov_len = 0;
14506f6ba60Sopenharmony_ci    }
14606f6ba60Sopenharmony_ci    ssize_t ret = writev(fd, srcBufs, numSrcs);
14706f6ba60Sopenharmony_ci    if (ret != -1) {
14806f6ba60Sopenharmony_ci        // update buffer status
14906f6ba60Sopenharmony_ci        head_ += static_cast<std::size_t>(ret);
15006f6ba60Sopenharmony_ci        while (head_ >= bufSize_) {
15106f6ba60Sopenharmony_ci            head_ -= bufSize_;
15206f6ba60Sopenharmony_ci        }
15306f6ba60Sopenharmony_ci    }
15406f6ba60Sopenharmony_ci    return ret;
15506f6ba60Sopenharmony_ci}
15606f6ba60Sopenharmony_ci
15706f6ba60Sopenharmony_cistd::size_t RingBuffer::Get(char* dest, const std::size_t len)
15806f6ba60Sopenharmony_ci{
15906f6ba60Sopenharmony_ci    if (dest == nullptr) {
16006f6ba60Sopenharmony_ci        return 0;
16106f6ba60Sopenharmony_ci    }
16206f6ba60Sopenharmony_ci    if (len == 0) {
16306f6ba60Sopenharmony_ci        return 0;
16406f6ba60Sopenharmony_ci    }
16506f6ba60Sopenharmony_ci    std::lock_guard<std::mutex> lk {mtx_};
16606f6ba60Sopenharmony_ci    auto dataSize = DataSize();
16706f6ba60Sopenharmony_ci    if (len > dataSize) {
16806f6ba60Sopenharmony_ci        return 0;
16906f6ba60Sopenharmony_ci    }
17006f6ba60Sopenharmony_ci    if (buffer_ == nullptr) {
17106f6ba60Sopenharmony_ci        return -1;
17206f6ba60Sopenharmony_ci    }
17306f6ba60Sopenharmony_ci    if (head_ + len > bufSize_) {
17406f6ba60Sopenharmony_ci        // data splitted
17506f6ba60Sopenharmony_ci        if (memcpy_s(dest, len, buffer_ + head_, bufSize_ - head_) != EOK) {
17606f6ba60Sopenharmony_ci            return 0;
17706f6ba60Sopenharmony_ci        }
17806f6ba60Sopenharmony_ci        if (memcpy_s(dest + bufSize_ - head_, len + head_ - bufSize_, buffer_, len + head_ - bufSize_) != EOK) {
17906f6ba60Sopenharmony_ci            return 0;
18006f6ba60Sopenharmony_ci        }
18106f6ba60Sopenharmony_ci    } else {
18206f6ba60Sopenharmony_ci        if (memcpy_s(dest, len, buffer_ + head_, len) != EOK) {
18306f6ba60Sopenharmony_ci            return 0;
18406f6ba60Sopenharmony_ci        }
18506f6ba60Sopenharmony_ci    }
18606f6ba60Sopenharmony_ci    // update buffer status
18706f6ba60Sopenharmony_ci    head_ += len;
18806f6ba60Sopenharmony_ci    while (head_ >= bufSize_) {
18906f6ba60Sopenharmony_ci        head_ -= bufSize_;
19006f6ba60Sopenharmony_ci    }
19106f6ba60Sopenharmony_ci    return len;
19206f6ba60Sopenharmony_ci}
19306f6ba60Sopenharmony_ci
19406f6ba60Sopenharmony_ciint RingBuffer::Put(const char* str, const std::size_t len)
19506f6ba60Sopenharmony_ci{
19606f6ba60Sopenharmony_ci    if (str == nullptr) {
19706f6ba60Sopenharmony_ci        return -1;
19806f6ba60Sopenharmony_ci    }
19906f6ba60Sopenharmony_ci    if (len == 0) {
20006f6ba60Sopenharmony_ci        return 0;
20106f6ba60Sopenharmony_ci    }
20206f6ba60Sopenharmony_ci    // resize if free space is not big enough
20306f6ba60Sopenharmony_ci    std::lock_guard<std::mutex> lk {mtx_};
20406f6ba60Sopenharmony_ci    while (len >= FreeSize()) {
20506f6ba60Sopenharmony_ci        // the equal sign makes sure the buffer will not be fully filled
20606f6ba60Sopenharmony_ci        if (Resize() != 0) {
20706f6ba60Sopenharmony_ci            return -1;
20806f6ba60Sopenharmony_ci        }
20906f6ba60Sopenharmony_ci    }
21006f6ba60Sopenharmony_ci    if (buffer_ == nullptr) {
21106f6ba60Sopenharmony_ci        return -1;
21206f6ba60Sopenharmony_ci    }
21306f6ba60Sopenharmony_ci    if (tail_ + len < bufSize_) {
21406f6ba60Sopenharmony_ci        // continuous free space
21506f6ba60Sopenharmony_ci        if (memcpy_s(buffer_ + tail_, bufSize_ - tail_, str, len) != EOK) {
21606f6ba60Sopenharmony_ci            return -1;
21706f6ba60Sopenharmony_ci        }
21806f6ba60Sopenharmony_ci    } else {
21906f6ba60Sopenharmony_ci        // splitted free space
22006f6ba60Sopenharmony_ci        if (memcpy_s(buffer_ + tail_, bufSize_ - tail_, str, bufSize_ - tail_) != EOK) {
22106f6ba60Sopenharmony_ci            return -1;
22206f6ba60Sopenharmony_ci        }
22306f6ba60Sopenharmony_ci        if (memcpy_s(buffer_, bufSize_, str + bufSize_ - tail_, len + tail_ - bufSize_) != EOK) {
22406f6ba60Sopenharmony_ci            return -1;
22506f6ba60Sopenharmony_ci        }
22606f6ba60Sopenharmony_ci    }
22706f6ba60Sopenharmony_ci    // update buffer status
22806f6ba60Sopenharmony_ci    tail_ += len;
22906f6ba60Sopenharmony_ci    while (tail_ >= bufSize_) {
23006f6ba60Sopenharmony_ci        tail_ -= bufSize_;
23106f6ba60Sopenharmony_ci    }
23206f6ba60Sopenharmony_ci    return len;
23306f6ba60Sopenharmony_ci}
23406f6ba60Sopenharmony_ci
23506f6ba60Sopenharmony_ciint RingBuffer::Put(const std::string& str)
23606f6ba60Sopenharmony_ci{
23706f6ba60Sopenharmony_ci    if (str.empty()) {
23806f6ba60Sopenharmony_ci        return -1;
23906f6ba60Sopenharmony_ci    }
24006f6ba60Sopenharmony_ci    std::size_t len = str.length();
24106f6ba60Sopenharmony_ci    if (len == 0) {
24206f6ba60Sopenharmony_ci        return 0;
24306f6ba60Sopenharmony_ci    }
24406f6ba60Sopenharmony_ci    // resize if free space is not big enough
24506f6ba60Sopenharmony_ci    std::lock_guard<std::mutex> lk {mtx_};
24606f6ba60Sopenharmony_ci    while (len >= FreeSize()) {
24706f6ba60Sopenharmony_ci        // the equal sign makes sure the buffer will not be fully filled
24806f6ba60Sopenharmony_ci        if (Resize() != 0) {
24906f6ba60Sopenharmony_ci            return -1;
25006f6ba60Sopenharmony_ci        }
25106f6ba60Sopenharmony_ci    }
25206f6ba60Sopenharmony_ci    if (buffer_ == nullptr) {
25306f6ba60Sopenharmony_ci        return -1;
25406f6ba60Sopenharmony_ci    }
25506f6ba60Sopenharmony_ci    if (tail_ + len < bufSize_) {
25606f6ba60Sopenharmony_ci        // continuous free space
25706f6ba60Sopenharmony_ci        if (memcpy_s(buffer_ + tail_, bufSize_ - tail_, str.c_str(), len) != EOK) {
25806f6ba60Sopenharmony_ci            return -1;
25906f6ba60Sopenharmony_ci        }
26006f6ba60Sopenharmony_ci    } else {
26106f6ba60Sopenharmony_ci        // splitted free space
26206f6ba60Sopenharmony_ci        if (memcpy_s(buffer_ + tail_, bufSize_ - tail_, str.c_str(), bufSize_ - tail_) != EOK) {
26306f6ba60Sopenharmony_ci            return -1;
26406f6ba60Sopenharmony_ci        }
26506f6ba60Sopenharmony_ci        if (memcpy_s(buffer_, bufSize_, str.c_str() + bufSize_ - tail_, len + tail_ - bufSize_) != EOK) {
26606f6ba60Sopenharmony_ci            return -1;
26706f6ba60Sopenharmony_ci        }
26806f6ba60Sopenharmony_ci    }
26906f6ba60Sopenharmony_ci    // update buffer status
27006f6ba60Sopenharmony_ci    tail_ += len;
27106f6ba60Sopenharmony_ci    while (tail_ >= bufSize_) {
27206f6ba60Sopenharmony_ci        tail_ -= bufSize_;
27306f6ba60Sopenharmony_ci    }
27406f6ba60Sopenharmony_ci    return len;
27506f6ba60Sopenharmony_ci}
27606f6ba60Sopenharmony_ci
27706f6ba60Sopenharmony_cichar* RingBuffer::Allocate(std::size_t bufSize)
27806f6ba60Sopenharmony_ci{
27906f6ba60Sopenharmony_ci    char *newBuffer {nullptr};
28006f6ba60Sopenharmony_ci    switch (alignShift_) {
28106f6ba60Sopenharmony_ci        case B_ALIGN_SHIFT: {
28206f6ba60Sopenharmony_ci            bufSize = (bufSize >> B_ALIGN_SHIFT);
28306f6ba60Sopenharmony_ci            newBuffer = new(std::nothrow) char[bufSize];
28406f6ba60Sopenharmony_ci            break;
28506f6ba60Sopenharmony_ci        }
28606f6ba60Sopenharmony_ci        case H_ALIGN_SHIFT: {
28706f6ba60Sopenharmony_ci            bufSize = (bufSize >> H_ALIGN_SHIFT);
28806f6ba60Sopenharmony_ci            uint16_t *temp = new(std::nothrow) uint16_t[bufSize];
28906f6ba60Sopenharmony_ci            if (temp != nullptr) {
29006f6ba60Sopenharmony_ci                newBuffer = reinterpret_cast<char *>(temp);
29106f6ba60Sopenharmony_ci            }
29206f6ba60Sopenharmony_ci            break;
29306f6ba60Sopenharmony_ci        }
29406f6ba60Sopenharmony_ci        case W_ALIGN_SHIFT: {
29506f6ba60Sopenharmony_ci            bufSize = (bufSize >> W_ALIGN_SHIFT);
29606f6ba60Sopenharmony_ci            uint32_t *temp = new(std::nothrow) uint32_t[bufSize];
29706f6ba60Sopenharmony_ci            if (temp != nullptr) {
29806f6ba60Sopenharmony_ci                newBuffer = reinterpret_cast<char *>(temp);
29906f6ba60Sopenharmony_ci            }
30006f6ba60Sopenharmony_ci            break;
30106f6ba60Sopenharmony_ci        }
30206f6ba60Sopenharmony_ci        case D_ALIGN_SHIFT: {
30306f6ba60Sopenharmony_ci            bufSize = (bufSize >> D_ALIGN_SHIFT);
30406f6ba60Sopenharmony_ci            uint64_t *temp = new(std::nothrow) uint64_t[bufSize];
30506f6ba60Sopenharmony_ci            if (temp != nullptr) {
30606f6ba60Sopenharmony_ci                newBuffer = reinterpret_cast<char *>(temp);
30706f6ba60Sopenharmony_ci            }
30806f6ba60Sopenharmony_ci            break;
30906f6ba60Sopenharmony_ci        }
31006f6ba60Sopenharmony_ci    }
31106f6ba60Sopenharmony_ci    return newBuffer;
31206f6ba60Sopenharmony_ci}
31306f6ba60Sopenharmony_ci
31406f6ba60Sopenharmony_ciint RingBuffer::Resize()
31506f6ba60Sopenharmony_ci{
31606f6ba60Sopenharmony_ci    std::size_t expandedSize {bufSize_ << 1};
31706f6ba60Sopenharmony_ci    char* newBuf = Allocate(expandedSize);
31806f6ba60Sopenharmony_ci    if (newBuf == nullptr) {
31906f6ba60Sopenharmony_ci        return -1;
32006f6ba60Sopenharmony_ci    }
32106f6ba60Sopenharmony_ci    if (buffer_ == nullptr) {
32206f6ba60Sopenharmony_ci        return -1;
32306f6ba60Sopenharmony_ci    }
32406f6ba60Sopenharmony_ci    // copy data to the new buffer
32506f6ba60Sopenharmony_ci    auto dataSize = DataSize();
32606f6ba60Sopenharmony_ci    if (head_ + dataSize > bufSize_) {
32706f6ba60Sopenharmony_ci        // data splitted
32806f6ba60Sopenharmony_ci        if (memcpy_s(newBuf, expandedSize, buffer_ + head_, bufSize_ - head_) != EOK) {
32906f6ba60Sopenharmony_ci            delete[] newBuf;
33006f6ba60Sopenharmony_ci            return -1;
33106f6ba60Sopenharmony_ci        }
33206f6ba60Sopenharmony_ci        if (memcpy_s(newBuf + bufSize_ - head_,
33306f6ba60Sopenharmony_ci                     expandedSize - (bufSize_ - head_),
33406f6ba60Sopenharmony_ci                     buffer_,
33506f6ba60Sopenharmony_ci                     dataSize - (bufSize_ - head_)) != EOK) {
33606f6ba60Sopenharmony_ci            delete[] newBuf;
33706f6ba60Sopenharmony_ci            return -1;
33806f6ba60Sopenharmony_ci        }
33906f6ba60Sopenharmony_ci    } else {
34006f6ba60Sopenharmony_ci        // continuous data
34106f6ba60Sopenharmony_ci        if (memcpy_s(newBuf, expandedSize, buffer_ + head_, dataSize) != EOK) {
34206f6ba60Sopenharmony_ci            delete[] newBuf;
34306f6ba60Sopenharmony_ci            return -1;
34406f6ba60Sopenharmony_ci        }
34506f6ba60Sopenharmony_ci    }
34606f6ba60Sopenharmony_ci    // update buffer status
34706f6ba60Sopenharmony_ci    delete[] buffer_;
34806f6ba60Sopenharmony_ci    buffer_ = newBuf;
34906f6ba60Sopenharmony_ci    bufSize_ = expandedSize;
35006f6ba60Sopenharmony_ci    head_ = 0;
35106f6ba60Sopenharmony_ci    tail_ = dataSize;
35206f6ba60Sopenharmony_ci
35306f6ba60Sopenharmony_ci    return 0;
35406f6ba60Sopenharmony_ci}