Diff
checker
Text
Text
Bilder
Dokumente
Excel
Ordner
Legal
Enterprise
Desktop-App
Preise
Einloggen
Diffchecker Desktop herunterladen
Texte vergleichen
Finde den Unterschied zwischen zwei Textdateien
Werkzeuge
Verlauf
Live-Editor
Gleiches ausblenden
Zeilenumbruch aus
Ansicht
Zweispaltig
Einspaltig
Vergleichsgenauigkeit
Intelligent
Wort
Zeichen
Syntaxhervorhebung
Syntax auswählen
Ignorieren
Text umwandeln
Zur ersten Änderung
Eingabe bearbeiten
Diffchecker Desktop
Der sicherste Weg, Diffchecker zu nutzen. Hol dir die Desktop-App: Deine Diffs verlassen nie deinen Computer!
Desktop holen
Untitled diff
Erstellt
vor 8 Jahren
Diff läuft nie ab
Löschen
Exportieren
Teilen
Erklären
29 Entfernungen
Zeilen
Gesamt
Entfernt
Zeichen
Gesamt
Entfernt
Um diese Funktion weiterhin zu nutzen, aktualisiere auf
Diff
checker
Pro
Preise anzeigen
255 Zeilen
Kopieren
84 Hinzufügungen
Zeilen
Gesamt
Hinzugefügt
Zeichen
Gesamt
Hinzugefügt
Um diese Funktion weiterhin zu nutzen, aktualisiere auf
Diff
checker
Pro
Preise anzeigen
306 Zeilen
Kopieren
#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();
Kopieren
Kopiert
Kopieren
Kopiert
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);
Kopieren
Kopiert
Kopieren
Kopiert
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; }
Kopieren
Kopiert
Kopieren
Kopiert
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:
Kopieren
Kopiert
Kopieren
Kopiert
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];
Kopieren
Kopiert
Kopieren
Kopiert
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');
}
}
Kopieren
Kopiert
Kopieren
Kopiert
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 ) {
Kopieren
Kopiert
Kopieren
Kopiert
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 ) {
Kopieren
Kopiert
Kopieren
Kopiert
_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;
Kopieren
Kopiert
Kopieren
Kopiert
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 ) {
Kopieren
Kopiert
Kopieren
Kopiert
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);
Kopieren
Kopiert
Kopieren
Kopiert
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;
Kopieren
Kopiert
Kopieren
Kopiert
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);
}
}
Kopieren
Kopiert
Kopieren
Kopiert
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() {
Kopieren
Kopiert
Kopieren
Kopiert
_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) {
Kopieren
Kopiert
Kopieren
Kopiert
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 ) {
Kopieren
Kopiert
Kopieren
Kopiert
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;
}
}
Kopieren
Kopiert
Kopieren
Kopiert
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
Kopieren
Kopiert
Kopieren
Kopiert
Gespeicherte Diffs
Originaltext
Datei öffnen
#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
Bearbeitung
Datei öffnen
#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
Unterschied finden