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#ifndef OHOS_SHARING_CIRCULAR_BUFFER_H
17#define OHOS_SHARING_CIRCULAR_BUFFER_H
18
19#include <cstddef>
20#include <deque>
21#include <memory>
22#include "common/sharing_log.h"
23namespace OHOS {
24namespace Sharing {
25
26template <class T>
27class circular_buffer {
28public:
29    typedef typename std::deque<T>::iterator Iterator;
30
31    circular_buffer() = default;
32
33    explicit circular_buffer(int32_t capacity)
34    {
35        if (capacity <= 0) {
36            return;
37        } else {
38            capacity_ = capacity;
39        }
40    }
41
42    explicit circular_buffer(circular_buffer& copy)
43    {
44        capacity_ = copy.capacity();
45        T *temp = copy.begin();
46        while (temp != copy.end()) {
47            circular_buffer_.push_back(*temp);
48            temp++;
49        }
50    }
51
52    ~circular_buffer()
53    {
54        if (!circular_buffer_.empty()) {
55            circular_buffer_.clear();
56        }
57    }
58
59private:
60    size_t capacity_ = 0;
61    std::deque<T> circular_buffer_;
62
63public:
64    void clear()
65    {
66        circular_buffer_.clear();
67        SHARING_LOGD("size is %{public}zu", size());
68        set_capacity(capacity_);
69    }
70
71    void pop_back()
72    {
73        circular_buffer_.pop_back();
74    }
75
76    void pop_front()
77    {
78        circular_buffer_.pop_front();
79    }
80
81    void push_back(T item)
82    {
83        if (size() >= capacity()) {
84            circular_buffer_.pop_front();
85        }
86
87        circular_buffer_.push_back(item);
88    }
89
90    void push_front(T &item)
91    {
92        if (size() >= capacity()) {
93            circular_buffer_.pop_back();
94        }
95
96        circular_buffer_.push_front(item);
97    }
98
99    void set_capacity(size_t new_capacity)
100    {
101        capacity_ = new_capacity;
102    }
103
104    bool full()
105    {
106        return size() == capacity_;
107    }
108
109    bool empty()
110    {
111        return size() == 0;
112    }
113
114    size_t size()
115    {
116        return circular_buffer_.size();
117    }
118
119    size_t reserve()
120    {
121        return capacity() - size();
122    }
123
124    size_t capacity()
125    {
126        return capacity_;
127    }
128
129    T &at(size_t index)
130    {
131        return circular_buffer_[index];
132    }
133
134    T &back()
135    {
136        return circular_buffer_.back();
137    }
138
139    T &front()
140    {
141        return circular_buffer_.front();
142    }
143
144    Iterator begin()
145    {
146        return circular_buffer_.begin();
147    }
148
149    Iterator end()
150    {
151        return circular_buffer_.end();
152    }
153
154    T &operator[](int32_t index)
155    {
156        return circular_buffer_[index];
157    }
158
159    circular_buffer &operator=(circular_buffer &copy)
160    {
161        if (this == &copy) {
162            return *this;
163        }
164
165        clear();
166        capacity_ = copy.capacity();
167        T *temp = copy.begin();
168        while (temp != copy.end()) {
169            circular_buffer_.push_back(*temp);
170            temp++;
171        }
172    }
173};
174
175} // namespace Sharing
176} // namespace OHOS
177#endif