00001 #ifndef BT_CIRCULAR_BUFFER_H_ 00002 #define BT_CIRCULAR_BUFFER_H_ 00003 00004 #include <stdexcept> 00005 #include <vector> 00006 00007 template<typename T> 00008 class bt_circular_buffer 00009 { 00010 public: 00011 00012 bt_circular_buffer() 00013 : begin_pos_(0), current_pos_(0) 00014 { 00015 try 00016 { 00017 data_ = new T[BUFFER_SIZE]; 00018 } 00019 catch (std::bad_alloc) 00020 { 00021 delete[] data_; 00022 } 00023 } 00024 00025 ~bt_circular_buffer() 00026 { 00027 delete[] data_; 00028 } 00029 00030 void push(T const& data) 00031 { 00032 data_[current_pos_] = data; 00033 00034 current_pos_ = increase_pos(current_pos_); 00035 if (++size_ >= BUFFER_SIZE) 00036 { 00037 size_ = BUFFER_SIZE; 00038 } 00039 00040 if (current_pos_ <= begin_pos_) 00041 { 00042 begin_pos_ = increase_pos(begin_pos_); 00043 } 00044 } 00045 00046 std::vector<T> read_all() 00047 { 00048 std::vector<T> return_data; 00049 int read_begin = current_pos_; 00050 00051 if (current_pos_ > begin_pos_ || (current_pos_ == 0 && begin_pos_ == BUFFER_SIZE - 1)) 00052 { 00053 for (int i = 0; i < current_pos_; ++i) 00054 { 00055 return_data.push_back(data_[i]); 00056 } 00057 } 00058 else 00059 { 00060 for (int i = 0; i < BUFFER_SIZE; ++i, ++read_begin) 00061 { 00062 return_data.push_back(data_[read_begin % BUFFER_SIZE]); 00063 } 00064 } 00065 00066 return return_data; 00067 } 00068 00069 T& pop(void) 00070 { 00071 if (current_pos_ - 1 < 0) 00072 { 00073 return data_[BUFFER_SIZE - 1]; 00074 } 00075 else 00076 { 00077 return data_[current_pos_ - 1]; 00078 } 00079 } 00080 00081 int size_max() 00082 { 00083 return BUFFER_SIZE; 00084 } 00085 00086 int size_used() 00087 { 00088 if (current_pos_ > begin_pos_ || (current_pos_ == 0 && begin_pos_ == BUFFER_SIZE - 1)) 00089 { 00090 return current_pos_; 00091 } 00092 else 00093 { 00094 return size_max(); 00095 } 00096 } 00097 00098 00099 private: 00100 00101 static const int BUFFER_SIZE = 132000; 00102 00103 T* data_; 00104 int current_pos_; 00105 00106 size_t size_; 00107 int begin_pos_; 00108 00109 int increase_pos(int pos) 00110 { 00111 return pos = (pos + 1) % BUFFER_SIZE; 00112 } 00113 }; 00114 00115 #endif