Diff
checker
文本
文本
圖像
文檔
Excel
文件夾
Legal
Enterprise
桌面版
定價
登入
下載 Diffchecker 桌面版
比較文本
尋找兩個文字檔案之間的差異
工具
歷史
即時編輯器
摺疊未變更行
關閉換行
檢視
拆分
統一
比對精度
智能
單詞
字符
語法突出顯示
選擇語法
忽略
文字轉換
前往第一個差異
編輯輸入
Diffchecker Desktop
執行Diffchecker最安全的方式。取得Diffchecker桌面應用程式:您的差異永遠不會離開您的電腦!
取得桌面版
Untitled diff
建立於
8 年前
差異永不過期
清除
匯出
分享
解釋
29 刪除
行
總計
刪除
字符
總計
刪除
要繼續使用此功能,請升級到
Diff
checker
Pro
查看價格
255 行
全部複製
84 新增
行
總計
新增
字符
總計
新增
要繼續使用此功能,請升級到
Diff
checker
Pro
查看價格
306 行
全部複製
#ifndef CIRCULAR_BUFFER_H
#ifndef CIRCULAR_BUFFER_H
#define CIRCULAR_BUFFER_H
#define CIRCULAR_BUFFER_H
template<typename T, uint16_t _size, uint16_t multi = 0>
template<typename T, uint16_t _size, uint16_t multi = 0>
class Circular_Buffer {
class Circular_Buffer {
public:
public:
void push_back(T value) { return write(value); }
void push_back(T value) { return write(value); }
void push_front(T value);
void push_front(T value);
T pop_front() { return read(); }
T pop_front() { return read(); }
T pop_back();
T pop_back();
void write(T value);
void write(T value);
void push_back(const T *buffer, uint16_t length) { write(buffer, length); }
void push_back(const T *buffer, uint16_t length) { write(buffer, length); }
void write(const T *buffer, uint16_t length);
void write(const T *buffer, uint16_t length);
void push_front(const T *buffer, uint16_t length);
void push_front(const T *buffer, uint16_t length);
T peek(uint16_t pos = 0);
T peek(uint16_t pos = 0);
T peekBytes(T *buffer, uint16_t length);
T peekBytes(T *buffer, uint16_t length);
T read();
T read();
複製
已複製
複製
已複製
T list();
T pop_front(T *buffer, uint16_t length) { readBytes(buffer,length); }
T pop_front(T *buffer, uint16_t length) { readBytes(buffer,length); }
T read(T *buffer, uint16_t length) { readBytes(buffer,length); }
T read(T *buffer, uint16_t length) { readBytes(buffer,length); }
T readBytes(T *buffer, uint16_t length);
T readBytes(T *buffer, uint16_t length);
複製
已複製
複製
已複製
T pop_back(T *buffer, uint16_t length);
void flush() { return head = tail = _available = 0; }
void flush() { return head = tail = _available = 0; }
void print(const char *p);
void print(const char *p);
void println(const char *p);
void println(const char *p);
uint16_t size() { return _available; }
uint16_t size() { return _available; }
uint16_t available() { return _available; }
uint16_t available() { return _available; }
複製
已複製
複製
已複製
T* front() { return _cabuf[
peek()]
; }
T* front() { return _cabuf[
_cbuf[(head)&(_size-1)]]+1
; }
T* back() { return _cabuf[(tail-1)&(_size-1)]
; }
T* back() { return _cabuf[(tail-1)&(_size-1)]
+1
; }
void match(T *buffer, uint16_t length, int pos1, int pos2, int pos3, int pos4 = -1, int pos5 = -1);
void match(T *buffer, uint16_t length, int pos1, int pos2, int pos3, int pos4 = -1, int pos5 = -1);
protected:
protected:
private:
private:
複製
已複製
複製
已複製
uint16_t head = 0, tail = 0, _available = 0
, _array_pointer
=
0
;
volatile
uint16_t head = 0, tail = 0, _available = 0
;
bool init_ca
=
1
;
T _cbuf[_size];
T _cbuf[_size];
T _cabuf[_size][multi];
T _cabuf[_size][multi];
複製
已複製
複製
已複製
void _init();
// T _peek(uint16_t pos = 0); // internal array peek version
};
};
template<typename T, uint16_t _size, uint16_t multi>
template<typename T, uint16_t _size, uint16_t multi>
void Circular_Buffer<T, _size, multi>::match(T *buffer, uint16_t length, int pos1, int pos2, int pos3, int pos4, int pos5) {
void Circular_Buffer<T, _size, multi>::match(T *buffer, uint16_t length, int pos1, int pos2, int pos3, int pos4, int pos5) {
uint8_t input_count = 3;
uint8_t input_count = 3;
uint8_t queue_position = 0;
uint8_t queue_position = 0;
bool found = 0;
bool found = 0;
if ( pos4 != -1 ) input_count = 4;
if ( pos4 != -1 ) input_count = 4;
if ( pos5 != -1 ) input_count = 5;
if ( pos5 != -1 ) input_count = 5;
Serial.print("Q Size: "); Serial.println(_available);
Serial.print("Q Size: "); Serial.println(_available);
Serial.println("Displaying current queue: ");
Serial.println("Displaying current queue: ");
for ( uint8_t j = 0; j < _size; j++ ) {
for ( uint8_t j = 0; j < _size; j++ ) {
/*
/*
Serial.print("Peeking: ");
Serial.print("Peeking: ");
for ( uint8_t i = 0; i < _available; i++ ) {
for ( uint8_t i = 0; i < _available; i++ ) {
Serial.print(peek(i));
Serial.print(peek(i));
Serial.print(" ");
Serial.print(" ");
} Serial.println();
} Serial.println();
Serial.print(j); Serial.print(": ");
Serial.print(j); Serial.print(": ");
for ( uint8_t i = 0; i < multi; i++ ) {
for ( uint8_t i = 0; i < multi; i++ ) {
Serial.print(_cabuf[peek(j)][i]);
Serial.print(_cabuf[peek(j)][i]);
Serial.print(" ");
Serial.print(" ");
} Serial.println();
} Serial.println();
*/
*/
}
}
//Serial.print(head); Serial.print(" "); Serial.println(tail);
//Serial.print(head); Serial.print(" "); Serial.println(tail);
// good when head is in front of tail
// good when head is in front of tail
Serial.println("Displaying current queue: ");
Serial.println("Displaying current queue: ");
for ( uint8_t j = 0; j < size(); j++ ) {
for ( uint8_t j = 0; j < size(); j++ ) {
Serial.print(j); Serial.print(": ");
Serial.print(j); Serial.print(": ");
for ( uint8_t i = 0; i < multi; i++ ) {
for ( uint8_t i = 0; i < multi; i++ ) {
Serial.print(_cabuf[peek(j)][i]);
Serial.print(_cabuf[peek(j)][i]);
Serial.print(" ");
Serial.print(" ");
} Serial.println();
} Serial.println();
}
}
for ( uint8_t j = 0; j <= _available; j++ ) {
for ( uint8_t j = 0; j <= _available; j++ ) {
queue_position = j;
queue_position = j;
switch ( input_count ) {
switch ( input_count ) {
case 3: {
case 3: {
if ( _cabuf[j][pos1] == buffer[pos1] && _cabuf[j][pos2] == buffer[pos2] &&
if ( _cabuf[j][pos1] == buffer[pos1] && _cabuf[j][pos2] == buffer[pos2] &&
_cabuf[j][pos3] == buffer[pos3] ) {
_cabuf[j][pos3] == buffer[pos3] ) {
found = 1;
found = 1;
break;
break;
}
}
}
}
case 4: {
case 4: {
if ( _cabuf[j][pos1] == buffer[pos1] && _cabuf[j][pos2] == buffer[pos2] &&
if ( _cabuf[j][pos1] == buffer[pos1] && _cabuf[j][pos2] == buffer[pos2] &&
_cabuf[j][pos3] == buffer[pos3] && _cabuf[j][pos4] == buffer[pos4] ) {
_cabuf[j][pos3] == buffer[pos3] && _cabuf[j][pos4] == buffer[pos4] ) {
found = 1;
found = 1;
break;
break;
}
}
}
}
case 5: {
case 5: {
if ( _cabuf[j][pos1] == buffer[pos1] && _cabuf[j][pos2] == buffer[pos2] &&
if ( _cabuf[j][pos1] == buffer[pos1] && _cabuf[j][pos2] == buffer[pos2] &&
_cabuf[j][pos3] == buffer[pos3] && _cabuf[j][pos4] == buffer[pos4] &&
_cabuf[j][pos3] == buffer[pos3] && _cabuf[j][pos4] == buffer[pos4] &&
_cabuf[j][pos5] == buffer[pos5] ) {
_cabuf[j][pos5] == buffer[pos5] ) {
found = 1;
found = 1;
break;
break;
}
}
}
}
}
}
if ( found ) {
if ( found ) {
memmove(_cabuf[j],buffer,length*sizeof(T));
memmove(_cabuf[j],buffer,length*sizeof(T));
break;
break;
}
}
}
}
Serial.print("Q Size: "); Serial.println(_available);
Serial.print("Q Size: "); Serial.println(_available);
if ( !found ) { Serial.println("Nothing Found"); }
if ( !found ) { Serial.println("Nothing Found"); }
Serial.println();
Serial.println();
Serial.println("Displaying updated queue: ");
Serial.println("Displaying updated queue: ");
for ( uint8_t j = 0; j < _available; j++ ) {
for ( uint8_t j = 0; j < _available; j++ ) {
Serial.print(j); Serial.print(": ");
Serial.print(j); Serial.print(": ");
for ( uint8_t i = 0; i < multi; i++ ) {
for ( uint8_t i = 0; i < multi; i++ ) {
Serial.print(_cabuf[j][i]);
Serial.print(_cabuf[j][i]);
Serial.print(" ");
Serial.print(" ");
} Serial.println();
} Serial.println();
}
}
}
}
template<typename T, uint16_t _size, uint16_t multi>
template<typename T, uint16_t _size, uint16_t multi>
void Circular_Buffer<T,_size,multi>::print(const char *p) {
void Circular_Buffer<T,_size,multi>::print(const char *p) {
if ( multi ) return;
if ( multi ) return;
write((T*)p,strlen(p));
write((T*)p,strlen(p));
}
}
template<typename T, uint16_t _size, uint16_t multi>
template<typename T, uint16_t _size, uint16_t multi>
void Circular_Buffer<T,_size,multi>::println(const char *p) {
void Circular_Buffer<T,_size,multi>::println(const char *p) {
if ( multi ) return;
if ( multi ) return;
write((T*)p,strlen(p));
write((T*)p,strlen(p));
write('\n');
write('\n');
}
}
複製
已複製
複製
已複製
template<typename T, uint16_t _size, uint16_t multi>
void Circular_Buffer<T,_size,multi>::_init() {
for ( uint16_t i = 0; i < _size; i++ ) _cbuf[i] = i;
init_ca = 0;
}
template<typename T, uint16_t _size, uint16_t multi>
template<typename T, uint16_t _size, uint16_t multi>
void Circular_Buffer<T,_size,multi>::push_front(const T *buffer, uint16_t length) {
void Circular_Buffer<T,_size,multi>::push_front(const T *buffer, uint16_t length) {
if ( multi ) {
if ( multi ) {
複製
已複製
複製
已複製
push_front(_array_pointer);
if ( init_ca ) _init();
memmove(_cabuf[
peek()]
,buffer,length*sizeof(T));
if ( tail == (head ^ _size) ) tail = (tail - 1)&(2*_size-1);
if ( _
array_pointer++ >=
_size
-1
) _
array_pointer = 0
;
head = (head - 1)&(2*_size-1);
_cabuf[_cbuf[(head)&(_size-1)]][0] = length;
memmove(_cabuf[
_cbuf[(head)&(_size-1)]]+1
,buffer,length*sizeof(T));
if ( _
available <
_size
) _
available++
;
return;
return;
}
}
for ( uint16_t i = length-1; i > 0; i-- ) push_front(buffer[i]);
for ( uint16_t i = length-1; i > 0; i-- ) push_front(buffer[i]);
push_front(buffer[0]);
push_front(buffer[0]);
}
}
template<typename T, uint16_t _size, uint16_t multi>
template<typename T, uint16_t _size, uint16_t multi>
T Circular_Buffer<T,_size,multi>::pop_back() {
T Circular_Buffer<T,_size,multi>::pop_back() {
if ( _available ) {
if ( _available ) {
複製
已複製
複製
已複製
_available--;
( !_available ) ? _available = 0 :
_available--;
tail = (tail - 1)&(2*_size-1);
tail = (tail - 1)&(2*_size-1);
return _cbuf[tail&(_size-1)];
return _cbuf[tail&(_size-1)];
}
}
return -1;
return -1;
}
}
template<typename T, uint16_t _size, uint16_t multi>
template<typename T, uint16_t _size, uint16_t multi>
void Circular_Buffer<T,_size,multi>::push_front(T value) {
void Circular_Buffer<T,_size,multi>::push_front(T value) {
if ( multi ) return;
if ( multi ) return;
head = (head - 1)&(2*_size-1);
head = (head - 1)&(2*_size-1);
_cbuf[head&(_size-1)] = value;
_cbuf[head&(_size-1)] = value;
複製
已複製
複製
已複製
if ( _available
++ >=
_size ) _available
= _size
;
if ( _available
<
_size ) _available
++
;
}
}
template<typename T, uint16_t _size, uint16_t multi>
template<typename T, uint16_t _size, uint16_t multi>
void Circular_Buffer<T,_size,multi>::write(const T *buffer, uint16_t length) {
void Circular_Buffer<T,_size,multi>::write(const T *buffer, uint16_t length) {
if ( multi ) {
if ( multi ) {
複製
已複製
複製
已複製
memmove(_cabuf[_
array_pointer]
,buffer,length*sizeof(T));
if ( init_ca ) _init();
if ( _available++ >= _size ) _available = _size;
_cabuf[_cbuf[tail&(_size-1)]][0] = length;
_cbuf[tail&(_size-1)] = _array_pointer;
memmove(_cabuf[_
cbuf[tail&(_size-1)]]+1
,buffer,length*sizeof(T));
if ( tail == (head ^ _size) ) head = (head + 1)&(2*_size-1);
if ( tail == (head ^ _size) ) head = (head + 1)&(2*_size-1);
tail = (tail + 1)&(2*_size-1);
tail = (tail + 1)&(2*_size-1);
複製
已複製
複製
已複製
if ( _
array_pointer++ >=
_size
-1
) _
array_pointer = 0
;
if ( _
available <
_size
) _
available++
;
return;
return;
}
}
if ( ( _available += length ) >= _size ) _available = _size;
if ( ( _available += length ) >= _size ) _available = _size;
if ( length < ( _size - tail ) ) {
if ( length < ( _size - tail ) ) {
memmove(_cbuf+tail,buffer,length*sizeof(T));
memmove(_cbuf+tail,buffer,length*sizeof(T));
tail = (tail + length)&(2*_size-1);
tail = (tail + length)&(2*_size-1);
}
}
else for ( uint16_t i = 0; i < length; i++ ) write(buffer[i]);
else for ( uint16_t i = 0; i < length; i++ ) write(buffer[i]);
}
}
template<typename T, uint16_t _size, uint16_t multi>
template<typename T, uint16_t _size, uint16_t multi>
void Circular_Buffer<T,_size,multi>::write(T value) {
void Circular_Buffer<T,_size,multi>::write(T value) {
if ( multi ) return;
if ( multi ) return;
複製
已複製
複製
已複製
if ( _available
++ >=
_size ) _available
= _size
;
if ( _available
<
_size ) _available
++
;
_cbuf[tail&(_size-1)] = value;
_cbuf[tail&(_size-1)] = value;
if ( tail == (head ^ _size) ) head = (head + 1)&(2*_size-1);
if ( tail == (head ^ _size) ) head = (head + 1)&(2*_size-1);
tail = (tail + 1)&(2*_size-1);
tail = (tail + 1)&(2*_size-1);
}
}
複製
已複製
複製
已複製
template<typename T, uint16_t _size, uint16_t multi>
T Circular_Buffer<T,_size,multi>::list() {
if ( multi ) {
if ( init_ca ) _init();
Serial.print("Queue Size: "); Serial.print(size()); Serial.print(", Index order: ");
for ( uint8_t i = 0; i < size(); i++ ) {
Serial.print(_cbuf[(head+i)&(_size-1)]); Serial.print(" ");
} Serial.println();
Serial.print("First Entry: ");
for ( uint8_t i = 1; i <= _cabuf[_cbuf[(head)&(_size-1)]][0]; i++ ) {
Serial.print(_cabuf[_cbuf[(head)&(_size-1)]][i]); Serial.print(" ");
} Serial.print("("); Serial.print(_cabuf[_cbuf[(head)&(_size-1)]][0]); Serial.println(" entries.)");
Serial.print("Last Entry: ");
for ( uint8_t i = 1; i <= _cabuf[_cbuf[(head+size()-1)&(_size-1)]][0]; i++ ) {
Serial.print(_cabuf[_cbuf[(head+size()-1)&(_size-1)]][i]); Serial.print(" ");
} Serial.print("("); Serial.print(_cabuf[_cbuf[(head+size()-1)&(_size-1)]][0]); Serial.println(" entries.)");
Serial.println();
Serial.println("Queue list: ");
for ( uint8_t i = 0; i < _available; i++ ) {
Serial.print(i); Serial.print(") ");
for ( uint8_t j = 1; j <= _cabuf[_cbuf[(head+i)&(_size-1)]][0]; j++ ) {
Serial.print(_cabuf[_cbuf[(head+i)&(_size-1)]][j]); Serial.print(" ");
} Serial.print("("); Serial.print(_cabuf[_cbuf[(head+i)&(_size-1)]][0]); Serial.println(" entries.)");
} Serial.println();
}
}
template<typename T, uint16_t _size, uint16_t multi>
template<typename T, uint16_t _size, uint16_t multi>
T Circular_Buffer<T,_size,multi>::read() {
T Circular_Buffer<T,_size,multi>::read() {
複製
已複製
複製
已複製
_available--;
if ( multi ) {
if ( init_ca ) _init();
if ( tail == (head ^ _size) ) tail = (size() - 1)&(2*_size-1);
head = (head + 1)&(2*_size-1);
( !_available ) ? _available = 0 : _available--;
return 0;
}
( !_available ) ? _available = 0 :
_available--;
T value = _cbuf[head&(_size-1)];
T value = _cbuf[head&(_size-1)];
head = (head + 1)&(2*_size-1);
head = (head + 1)&(2*_size-1);
return value;
return value;
}
}
template<typename T, uint16_t _size, uint16_t multi>
template<typename T, uint16_t _size, uint16_t multi>
T Circular_Buffer<T,_size,multi>::peek(uint16_t pos) {
T Circular_Buffer<T,_size,multi>::peek(uint16_t pos) {
複製
已複製
複製
已複製
if ( multi ) {
return _cbuf[(head+pos)&(_size-1)];
}
if ( pos > _size ) return 0;
if ( pos > _size ) return 0;
return _cbuf[(head+pos)&(_size-1)];
return _cbuf[(head+pos)&(_size-1)];
}
}
template<typename T, uint16_t _size, uint16_t multi>
template<typename T, uint16_t _size, uint16_t multi>
T Circular_Buffer<T,_size,multi>::peekBytes(T *buffer, uint16_t length) {
T Circular_Buffer<T,_size,multi>::peekBytes(T *buffer, uint16_t length) {
if ( multi ) return 0;
if ( multi ) return 0;
uint16_t _count;
uint16_t _count;
( _available < length ) ? _count = _available : _count = length;
( _available < length ) ? _count = _available : _count = length;
if ( _count < ( _size - head ) ) memmove(buffer,_cbuf,_count*sizeof(T));
if ( _count < ( _size - head ) ) memmove(buffer,_cbuf,_count*sizeof(T));
else for ( uint16_t i = 0; i < _count; i++ ) buffer[i] = peek(i);
else for ( uint16_t i = 0; i < _count; i++ ) buffer[i] = peek(i);
return _count;
return _count;
}
}
template<typename T, uint16_t _size, uint16_t multi>
template<typename T, uint16_t _size, uint16_t multi>
T Circular_Buffer<T,_size,multi>::readBytes(T *buffer, uint16_t length) {
T Circular_Buffer<T,_size,multi>::readBytes(T *buffer, uint16_t length) {
if ( multi ) {
if ( multi ) {
複製
已複製
複製
已複製
memmove(&buffer[0],&_cabuf[
peek()]
,length*sizeof(T)); // update CA buffer
if ( init_ca ) _init();
read();
// deque item
memmove(&buffer[0],&_cabuf[
_cbuf[(head)&(_size-1)]][1]
,length*sizeof(T)); // update CA buffer
read();
return 0;
return 0;
}
}
uint16_t _count;
uint16_t _count;
( _available < length ) ? _count = _available : _count = length; // memmove if aligned
( _available < length ) ? _count = _available : _count = length; // memmove if aligned
if ( _count < ( _size - head ) ) {
if ( _count < ( _size - head ) ) {
_available -= length;
_available -= length;
memmove(buffer,_cbuf,_count*sizeof(T));
memmove(buffer,_cbuf,_count*sizeof(T));
head = (head + _count)&(2*_size-1);
head = (head + _count)&(2*_size-1);
}
}
else for ( uint16_t i = 0; i < _count; i++ ) buffer[i] = read(); // if buffer rollover
else for ( uint16_t i = 0; i < _count; i++ ) buffer[i] = read(); // if buffer rollover
return _count;
return _count;
}
}
複製
已複製
複製
已複製
template<typename T, uint16_t _size, uint16_t multi>
T Circular_Buffer<T,_size,multi>::pop_back(T *buffer, uint16_t length) {
if ( multi ) {
if ( init_ca ) _init();
memmove(&buffer[0],&_cabuf[(tail-1)&(_size-1)][1],length*sizeof(T));
tail = (tail - 1)&(2*_size-1);
( !_available ) ? _available = 0 : _available--;
return 0;
}
}
#endif // Circular_Buffer_H
#endif // Circular_Buffer_H
複製
已複製
複製
已複製
已保存差異
原始文本
開啟檔案
#ifndef CIRCULAR_BUFFER_H #define CIRCULAR_BUFFER_H template<typename T, uint16_t _size, uint16_t multi = 0> class Circular_Buffer { public: void push_back(T value) { return write(value); } void push_front(T value); T pop_front() { return read(); } T pop_back(); void write(T value); void push_back(const T *buffer, uint16_t length) { write(buffer, length); } void write(const T *buffer, uint16_t length); void push_front(const T *buffer, uint16_t length); T peek(uint16_t pos = 0); T peekBytes(T *buffer, uint16_t length); T read(); T pop_front(T *buffer, uint16_t length) { readBytes(buffer,length); } T read(T *buffer, uint16_t length) { readBytes(buffer,length); } T readBytes(T *buffer, uint16_t length); void flush() { return head = tail = _available = 0; } void print(const char *p); void println(const char *p); uint16_t size() { return _available; } uint16_t available() { return _available; } T* front() { return _cabuf[peek()]; } T* back() { return _cabuf[(tail-1)&(_size-1)]; } void match(T *buffer, uint16_t length, int pos1, int pos2, int pos3, int pos4 = -1, int pos5 = -1); protected: private: uint16_t head = 0, tail = 0, _available = 0, _array_pointer = 0; T _cbuf[_size]; T _cabuf[_size][multi]; }; template<typename T, uint16_t _size, uint16_t multi> void Circular_Buffer<T, _size, multi>::match(T *buffer, uint16_t length, int pos1, int pos2, int pos3, int pos4, int pos5) { uint8_t input_count = 3; uint8_t queue_position = 0; bool found = 0; if ( pos4 != -1 ) input_count = 4; if ( pos5 != -1 ) input_count = 5; Serial.print("Q Size: "); Serial.println(_available); Serial.println("Displaying current queue: "); for ( uint8_t j = 0; j < _size; j++ ) { /* Serial.print("Peeking: "); for ( uint8_t i = 0; i < _available; i++ ) { Serial.print(peek(i)); Serial.print(" "); } Serial.println(); Serial.print(j); Serial.print(": "); for ( uint8_t i = 0; i < multi; i++ ) { Serial.print(_cabuf[peek(j)][i]); Serial.print(" "); } Serial.println(); */ } //Serial.print(head); Serial.print(" "); Serial.println(tail); // good when head is in front of tail Serial.println("Displaying current queue: "); for ( uint8_t j = 0; j < size(); j++ ) { Serial.print(j); Serial.print(": "); for ( uint8_t i = 0; i < multi; i++ ) { Serial.print(_cabuf[peek(j)][i]); Serial.print(" "); } Serial.println(); } for ( uint8_t j = 0; j <= _available; j++ ) { queue_position = j; switch ( input_count ) { case 3: { if ( _cabuf[j][pos1] == buffer[pos1] && _cabuf[j][pos2] == buffer[pos2] && _cabuf[j][pos3] == buffer[pos3] ) { found = 1; break; } } case 4: { if ( _cabuf[j][pos1] == buffer[pos1] && _cabuf[j][pos2] == buffer[pos2] && _cabuf[j][pos3] == buffer[pos3] && _cabuf[j][pos4] == buffer[pos4] ) { found = 1; break; } } case 5: { if ( _cabuf[j][pos1] == buffer[pos1] && _cabuf[j][pos2] == buffer[pos2] && _cabuf[j][pos3] == buffer[pos3] && _cabuf[j][pos4] == buffer[pos4] && _cabuf[j][pos5] == buffer[pos5] ) { found = 1; break; } } } if ( found ) { memmove(_cabuf[j],buffer,length*sizeof(T)); break; } } Serial.print("Q Size: "); Serial.println(_available); if ( !found ) { Serial.println("Nothing Found"); } Serial.println(); Serial.println("Displaying updated queue: "); for ( uint8_t j = 0; j < _available; j++ ) { Serial.print(j); Serial.print(": "); for ( uint8_t i = 0; i < multi; i++ ) { Serial.print(_cabuf[j][i]); Serial.print(" "); } Serial.println(); } } template<typename T, uint16_t _size, uint16_t multi> void Circular_Buffer<T,_size,multi>::print(const char *p) { if ( multi ) return; write((T*)p,strlen(p)); } template<typename T, uint16_t _size, uint16_t multi> void Circular_Buffer<T,_size,multi>::println(const char *p) { if ( multi ) return; write((T*)p,strlen(p)); write('\n'); } template<typename T, uint16_t _size, uint16_t multi> void Circular_Buffer<T,_size,multi>::push_front(const T *buffer, uint16_t length) { if ( multi ) { push_front(_array_pointer); memmove(_cabuf[peek()],buffer,length*sizeof(T)); if ( _array_pointer++ >= _size -1 ) _array_pointer = 0; return; } for ( uint16_t i = length-1; i > 0; i-- ) push_front(buffer[i]); push_front(buffer[0]); } template<typename T, uint16_t _size, uint16_t multi> T Circular_Buffer<T,_size,multi>::pop_back() { if ( _available ) { _available--; tail = (tail - 1)&(2*_size-1); return _cbuf[tail&(_size-1)]; } return -1; } template<typename T, uint16_t _size, uint16_t multi> void Circular_Buffer<T,_size,multi>::push_front(T value) { if ( multi ) return; head = (head - 1)&(2*_size-1); _cbuf[head&(_size-1)] = value; if ( _available++ >= _size ) _available = _size; } template<typename T, uint16_t _size, uint16_t multi> void Circular_Buffer<T,_size,multi>::write(const T *buffer, uint16_t length) { if ( multi ) { memmove(_cabuf[_array_pointer],buffer,length*sizeof(T)); if ( _available++ >= _size ) _available = _size; _cbuf[tail&(_size-1)] = _array_pointer; if ( tail == (head ^ _size) ) head = (head + 1)&(2*_size-1); tail = (tail + 1)&(2*_size-1); if ( _array_pointer++ >= _size -1 ) _array_pointer = 0; return; } if ( ( _available += length ) >= _size ) _available = _size; if ( length < ( _size - tail ) ) { memmove(_cbuf+tail,buffer,length*sizeof(T)); tail = (tail + length)&(2*_size-1); } else for ( uint16_t i = 0; i < length; i++ ) write(buffer[i]); } template<typename T, uint16_t _size, uint16_t multi> void Circular_Buffer<T,_size,multi>::write(T value) { if ( multi ) return; if ( _available++ >= _size ) _available = _size; _cbuf[tail&(_size-1)] = value; if ( tail == (head ^ _size) ) head = (head + 1)&(2*_size-1); tail = (tail + 1)&(2*_size-1); } template<typename T, uint16_t _size, uint16_t multi> T Circular_Buffer<T,_size,multi>::read() { _available--; T value = _cbuf[head&(_size-1)]; head = (head + 1)&(2*_size-1); return value; } template<typename T, uint16_t _size, uint16_t multi> T Circular_Buffer<T,_size,multi>::peek(uint16_t pos) { if ( multi ) { return _cbuf[(head+pos)&(_size-1)]; } if ( pos > _size ) return 0; return _cbuf[(head+pos)&(_size-1)]; } template<typename T, uint16_t _size, uint16_t multi> T Circular_Buffer<T,_size,multi>::peekBytes(T *buffer, uint16_t length) { if ( multi ) return 0; uint16_t _count; ( _available < length ) ? _count = _available : _count = length; if ( _count < ( _size - head ) ) memmove(buffer,_cbuf,_count*sizeof(T)); else for ( uint16_t i = 0; i < _count; i++ ) buffer[i] = peek(i); return _count; } template<typename T, uint16_t _size, uint16_t multi> T Circular_Buffer<T,_size,multi>::readBytes(T *buffer, uint16_t length) { if ( multi ) { memmove(&buffer[0],&_cabuf[peek()],length*sizeof(T)); // update CA buffer read(); // deque item return 0; } uint16_t _count; ( _available < length ) ? _count = _available : _count = length; // memmove if aligned if ( _count < ( _size - head ) ) { _available -= length; memmove(buffer,_cbuf,_count*sizeof(T)); head = (head + _count)&(2*_size-1); } else for ( uint16_t i = 0; i < _count; i++ ) buffer[i] = read(); // if buffer rollover return _count; } #endif // Circular_Buffer_H
更改後文本
開啟檔案
#ifndef CIRCULAR_BUFFER_H #define CIRCULAR_BUFFER_H template<typename T, uint16_t _size, uint16_t multi = 0> class Circular_Buffer { public: void push_back(T value) { return write(value); } void push_front(T value); T pop_front() { return read(); } T pop_back(); void write(T value); void push_back(const T *buffer, uint16_t length) { write(buffer, length); } void write(const T *buffer, uint16_t length); void push_front(const T *buffer, uint16_t length); T peek(uint16_t pos = 0); T peekBytes(T *buffer, uint16_t length); T read(); T list(); T pop_front(T *buffer, uint16_t length) { readBytes(buffer,length); } T read(T *buffer, uint16_t length) { readBytes(buffer,length); } T readBytes(T *buffer, uint16_t length); T pop_back(T *buffer, uint16_t length); void flush() { return head = tail = _available = 0; } void print(const char *p); void println(const char *p); uint16_t size() { return _available; } uint16_t available() { return _available; } T* front() { return _cabuf[_cbuf[(head)&(_size-1)]]+1; } T* back() { return _cabuf[(tail-1)&(_size-1)]+1; } void match(T *buffer, uint16_t length, int pos1, int pos2, int pos3, int pos4 = -1, int pos5 = -1); protected: private: volatile uint16_t head = 0, tail = 0, _available = 0; bool init_ca = 1; T _cbuf[_size]; T _cabuf[_size][multi]; void _init(); // T _peek(uint16_t pos = 0); // internal array peek version }; template<typename T, uint16_t _size, uint16_t multi> void Circular_Buffer<T, _size, multi>::match(T *buffer, uint16_t length, int pos1, int pos2, int pos3, int pos4, int pos5) { uint8_t input_count = 3; uint8_t queue_position = 0; bool found = 0; if ( pos4 != -1 ) input_count = 4; if ( pos5 != -1 ) input_count = 5; Serial.print("Q Size: "); Serial.println(_available); Serial.println("Displaying current queue: "); for ( uint8_t j = 0; j < _size; j++ ) { /* Serial.print("Peeking: "); for ( uint8_t i = 0; i < _available; i++ ) { Serial.print(peek(i)); Serial.print(" "); } Serial.println(); Serial.print(j); Serial.print(": "); for ( uint8_t i = 0; i < multi; i++ ) { Serial.print(_cabuf[peek(j)][i]); Serial.print(" "); } Serial.println(); */ } //Serial.print(head); Serial.print(" "); Serial.println(tail); // good when head is in front of tail Serial.println("Displaying current queue: "); for ( uint8_t j = 0; j < size(); j++ ) { Serial.print(j); Serial.print(": "); for ( uint8_t i = 0; i < multi; i++ ) { Serial.print(_cabuf[peek(j)][i]); Serial.print(" "); } Serial.println(); } for ( uint8_t j = 0; j <= _available; j++ ) { queue_position = j; switch ( input_count ) { case 3: { if ( _cabuf[j][pos1] == buffer[pos1] && _cabuf[j][pos2] == buffer[pos2] && _cabuf[j][pos3] == buffer[pos3] ) { found = 1; break; } } case 4: { if ( _cabuf[j][pos1] == buffer[pos1] && _cabuf[j][pos2] == buffer[pos2] && _cabuf[j][pos3] == buffer[pos3] && _cabuf[j][pos4] == buffer[pos4] ) { found = 1; break; } } case 5: { if ( _cabuf[j][pos1] == buffer[pos1] && _cabuf[j][pos2] == buffer[pos2] && _cabuf[j][pos3] == buffer[pos3] && _cabuf[j][pos4] == buffer[pos4] && _cabuf[j][pos5] == buffer[pos5] ) { found = 1; break; } } } if ( found ) { memmove(_cabuf[j],buffer,length*sizeof(T)); break; } } Serial.print("Q Size: "); Serial.println(_available); if ( !found ) { Serial.println("Nothing Found"); } Serial.println(); Serial.println("Displaying updated queue: "); for ( uint8_t j = 0; j < _available; j++ ) { Serial.print(j); Serial.print(": "); for ( uint8_t i = 0; i < multi; i++ ) { Serial.print(_cabuf[j][i]); Serial.print(" "); } Serial.println(); } } template<typename T, uint16_t _size, uint16_t multi> void Circular_Buffer<T,_size,multi>::print(const char *p) { if ( multi ) return; write((T*)p,strlen(p)); } template<typename T, uint16_t _size, uint16_t multi> void Circular_Buffer<T,_size,multi>::println(const char *p) { if ( multi ) return; write((T*)p,strlen(p)); write('\n'); } template<typename T, uint16_t _size, uint16_t multi> void Circular_Buffer<T,_size,multi>::_init() { for ( uint16_t i = 0; i < _size; i++ ) _cbuf[i] = i; init_ca = 0; } template<typename T, uint16_t _size, uint16_t multi> void Circular_Buffer<T,_size,multi>::push_front(const T *buffer, uint16_t length) { if ( multi ) { if ( init_ca ) _init(); if ( tail == (head ^ _size) ) tail = (tail - 1)&(2*_size-1); head = (head - 1)&(2*_size-1); _cabuf[_cbuf[(head)&(_size-1)]][0] = length; memmove(_cabuf[_cbuf[(head)&(_size-1)]]+1,buffer,length*sizeof(T)); if ( _available < _size ) _available++; return; } for ( uint16_t i = length-1; i > 0; i-- ) push_front(buffer[i]); push_front(buffer[0]); } template<typename T, uint16_t _size, uint16_t multi> T Circular_Buffer<T,_size,multi>::pop_back() { if ( _available ) { ( !_available ) ? _available = 0 : _available--; tail = (tail - 1)&(2*_size-1); return _cbuf[tail&(_size-1)]; } return -1; } template<typename T, uint16_t _size, uint16_t multi> void Circular_Buffer<T,_size,multi>::push_front(T value) { if ( multi ) return; head = (head - 1)&(2*_size-1); _cbuf[head&(_size-1)] = value; if ( _available < _size ) _available++; } template<typename T, uint16_t _size, uint16_t multi> void Circular_Buffer<T,_size,multi>::write(const T *buffer, uint16_t length) { if ( multi ) { if ( init_ca ) _init(); _cabuf[_cbuf[tail&(_size-1)]][0] = length; memmove(_cabuf[_cbuf[tail&(_size-1)]]+1,buffer,length*sizeof(T)); if ( tail == (head ^ _size) ) head = (head + 1)&(2*_size-1); tail = (tail + 1)&(2*_size-1); if ( _available < _size ) _available++; return; } if ( ( _available += length ) >= _size ) _available = _size; if ( length < ( _size - tail ) ) { memmove(_cbuf+tail,buffer,length*sizeof(T)); tail = (tail + length)&(2*_size-1); } else for ( uint16_t i = 0; i < length; i++ ) write(buffer[i]); } template<typename T, uint16_t _size, uint16_t multi> void Circular_Buffer<T,_size,multi>::write(T value) { if ( multi ) return; if ( _available < _size ) _available++; _cbuf[tail&(_size-1)] = value; if ( tail == (head ^ _size) ) head = (head + 1)&(2*_size-1); tail = (tail + 1)&(2*_size-1); } template<typename T, uint16_t _size, uint16_t multi> T Circular_Buffer<T,_size,multi>::list() { if ( multi ) { if ( init_ca ) _init(); Serial.print("Queue Size: "); Serial.print(size()); Serial.print(", Index order: "); for ( uint8_t i = 0; i < size(); i++ ) { Serial.print(_cbuf[(head+i)&(_size-1)]); Serial.print(" "); } Serial.println(); Serial.print("First Entry: "); for ( uint8_t i = 1; i <= _cabuf[_cbuf[(head)&(_size-1)]][0]; i++ ) { Serial.print(_cabuf[_cbuf[(head)&(_size-1)]][i]); Serial.print(" "); } Serial.print("("); Serial.print(_cabuf[_cbuf[(head)&(_size-1)]][0]); Serial.println(" entries.)"); Serial.print("Last Entry: "); for ( uint8_t i = 1; i <= _cabuf[_cbuf[(head+size()-1)&(_size-1)]][0]; i++ ) { Serial.print(_cabuf[_cbuf[(head+size()-1)&(_size-1)]][i]); Serial.print(" "); } Serial.print("("); Serial.print(_cabuf[_cbuf[(head+size()-1)&(_size-1)]][0]); Serial.println(" entries.)"); Serial.println(); Serial.println("Queue list: "); for ( uint8_t i = 0; i < _available; i++ ) { Serial.print(i); Serial.print(") "); for ( uint8_t j = 1; j <= _cabuf[_cbuf[(head+i)&(_size-1)]][0]; j++ ) { Serial.print(_cabuf[_cbuf[(head+i)&(_size-1)]][j]); Serial.print(" "); } Serial.print("("); Serial.print(_cabuf[_cbuf[(head+i)&(_size-1)]][0]); Serial.println(" entries.)"); } Serial.println(); } } template<typename T, uint16_t _size, uint16_t multi> T Circular_Buffer<T,_size,multi>::read() { if ( multi ) { if ( init_ca ) _init(); if ( tail == (head ^ _size) ) tail = (size() - 1)&(2*_size-1); head = (head + 1)&(2*_size-1); ( !_available ) ? _available = 0 : _available--; return 0; } ( !_available ) ? _available = 0 : _available--; T value = _cbuf[head&(_size-1)]; head = (head + 1)&(2*_size-1); return value; } template<typename T, uint16_t _size, uint16_t multi> T Circular_Buffer<T,_size,multi>::peek(uint16_t pos) { if ( pos > _size ) return 0; return _cbuf[(head+pos)&(_size-1)]; } template<typename T, uint16_t _size, uint16_t multi> T Circular_Buffer<T,_size,multi>::peekBytes(T *buffer, uint16_t length) { if ( multi ) return 0; uint16_t _count; ( _available < length ) ? _count = _available : _count = length; if ( _count < ( _size - head ) ) memmove(buffer,_cbuf,_count*sizeof(T)); else for ( uint16_t i = 0; i < _count; i++ ) buffer[i] = peek(i); return _count; } template<typename T, uint16_t _size, uint16_t multi> T Circular_Buffer<T,_size,multi>::readBytes(T *buffer, uint16_t length) { if ( multi ) { if ( init_ca ) _init(); memmove(&buffer[0],&_cabuf[_cbuf[(head)&(_size-1)]][1],length*sizeof(T)); // update CA buffer read(); return 0; } uint16_t _count; ( _available < length ) ? _count = _available : _count = length; // memmove if aligned if ( _count < ( _size - head ) ) { _available -= length; memmove(buffer,_cbuf,_count*sizeof(T)); head = (head + _count)&(2*_size-1); } else for ( uint16_t i = 0; i < _count; i++ ) buffer[i] = read(); // if buffer rollover return _count; } template<typename T, uint16_t _size, uint16_t multi> T Circular_Buffer<T,_size,multi>::pop_back(T *buffer, uint16_t length) { if ( multi ) { if ( init_ca ) _init(); memmove(&buffer[0],&_cabuf[(tail-1)&(_size-1)][1],length*sizeof(T)); tail = (tail - 1)&(2*_size-1); ( !_available ) ? _available = 0 : _available--; return 0; } } #endif // Circular_Buffer_H
尋找差異