Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Propose TemplatePrinter #56

Merged
merged 3 commits into from
Aug 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions src/TemplatePrinter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/************************************************************

TemplatePrinter Class

A basic templating engine for a stream of text.
This wraps the Arduino Print interface and writes to any
Print interface.

Written by Christopher Andrews (https://github.com/Chris--A)

************************************************************/

#include "TemplatePrinter.h"

void TemplatePrinter::resetParam(bool flush){
if(flush && _inParam){
_stream.write(_delimiter);

if(_paramPos)
_stream.print(_paramBuffer);
}

memset(_paramBuffer, 0, sizeof(_paramBuffer));
_paramPos = 0;
_inParam = false;
}


void TemplatePrinter::flush(){
resetParam(true);
_stream.flush();
}

size_t TemplatePrinter::write(uint8_t data){

if(data == _delimiter){

// End of parameter, send to callback
if(_inParam){

// On false, return the parameter place holder as is: not a parameter
// Bug fix: ignore parameters that are zero length.
if(!_paramPos || !_cb(_stream, _paramBuffer)){
resetParam(true);
_stream.write(data);
}else{
resetParam(false);
}

// Start collecting parameter
}else{
_inParam = true;
}
}else{

// Are we collecting
if(_inParam){

// Is param still valid
if(isalnum(data) || data == '_'){

// Total param len must be 63, 1 for null.
if(_paramPos < sizeof(_paramBuffer) - 1){
_paramBuffer[_paramPos++] = data;

// Not a valid param
}else{
resetParam(true);
}
}else{
resetParam(true);
_stream.write(data);
}

// Just output
}else{
_stream.write(data);
}
}
return 1;
}

size_t TemplatePrinter::copyFrom(Stream &stream){
size_t count = 0;

while(stream.available())
count += this->write(stream.read());

return count;
}
51 changes: 51 additions & 0 deletions src/TemplatePrinter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#ifndef TemplatePrinter_h
#define TemplatePrinter_h

#include "PsychicCore.h"
#include <Print.h>

/************************************************************

TemplatePrinter Class

A basic templating engine for a stream of text.
This wraps the Arduino Print interface and writes to any
Print interface.

Written by Christopher Andrews (https://github.com/Chris--A)

************************************************************/

class TemplatePrinter;

typedef std::function<bool(Print &output, const char *parameter)> TemplateCallback;
typedef std::function<void(TemplatePrinter &printer)> TemplateSourceCallback;

class TemplatePrinter : public Print{
private:
bool _inParam;
char _paramBuffer[64];
uint8_t _paramPos;
Print &_stream;
TemplateCallback _cb;
char _delimiter;

void resetParam(bool flush);

public:
using Print::write;

static void start(Print &stream, TemplateCallback cb, TemplateSourceCallback entry){
TemplatePrinter printer(stream, cb);
entry(printer);
}

TemplatePrinter(Print &stream, TemplateCallback cb, const char delimeter = '%') : _stream(stream), _cb(cb), _delimiter(delimeter) { resetParam(false); }
~TemplatePrinter(){ flush(); }

void flush() override;
size_t write(uint8_t data) override;
size_t copyFrom(Stream &stream);
};

#endif
Loading