Diff
checker
Texto
Texto
Imágenes
Documentos
Excel
Carpetas
Legal
Enterprise
Aplicación de escritorio
Precios
Iniciar sesión
Descargar Diffchecker Desktop
Comparar texto
Encuentra la diferencia entre dos archivos de texto
Herramientas
Historial
Editor live
Ocultar sin cambios
Sin ajuste de línea
Vista
Dividido
Unificado
Nivel de detalle
Inteligente
Palabra
Letra
Resaltado de sintaxis
Elegir sintaxis
Ignorar
Transformar texto
Ir al primer cambio
Editar entrada
Diffchecker Desktop
La forma más segura de usar Diffchecker. ¡Obtén la app de Diffchecker Desktop: tus diffs nunca salen de tu computadora!
Obtener Desktop
Untitled diff
Creado
hace 8 años
El diff nunca expira
Borrar
Exportar
Compartir
Explicar
29 eliminaciones
Líneas
Total
Eliminado
Caracteres
Total
Eliminado
Para continuar usando esta función, actualice a
Diff
checker
Pro
Ver precios
255 líneas
Copiar todo
84 adiciones
Líneas
Total
Añadido
Caracteres
Total
Añadido
Para continuar usando esta función, actualice a
Diff
checker
Pro
Ver precios
306 líneas
Copiar todo
#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();
Copiar
Copiado
Copiar
Copiado
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);
Copiar
Copiado
Copiar
Copiado
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; }
Copiar
Copiado
Copiar
Copiado
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:
Copiar
Copiado
Copiar
Copiado
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];
Copiar
Copiado
Copiar
Copiado
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');
}
}
Copiar
Copiado
Copiar
Copiado
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 ) {
Copiar
Copiado
Copiar
Copiado
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 ) {
Copiar
Copiado
Copiar
Copiado
_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;
Copiar
Copiado
Copiar
Copiado
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 ) {
Copiar
Copiado
Copiar
Copiado
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);
Copiar
Copiado
Copiar
Copiado
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;
Copiar
Copiado
Copiar
Copiado
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);
}
}
Copiar
Copiado
Copiar
Copiado
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() {
Copiar
Copiado
Copiar
Copiado
_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) {
Copiar
Copiado
Copiar
Copiado
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 ) {
Copiar
Copiado
Copiar
Copiado
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;
}
}
Copiar
Copiado
Copiar
Copiado
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
Copiar
Copiado
Copiar
Copiado
Diferencias guardadas
Texto original
Abrir archivo
#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
Texto modificado
Abrir archivo
#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
Encontrar la diferencia