SectionTemplate.h
Go to the documentation of this file.
1 /****
2  * Sming Framework Project - Open Source framework for high efficiency native ESP8266 development.
3  * Created 2015 by Skurydin Alexey
4  * http://github.com/SmingHub/Sming
5  * All files of the Sming Core are provided under the LGPL v3 license.
6  *
7  * SectionTemplate.h
8  *
9  * @author mikee47 <mike@sillyhouse.net> Nov 2020
10  *
11  ****/
12 
13 #pragma once
14 
15 #include "SectionStream.h"
16 #include "TemplateStream.h"
17 #include <Data/BitSet.h>
18 #include "../Format.h"
19 
36 #define SECTION_TEMPLATE_COMMAND_MAP(XX) \
37  XX(Qas_int, "{!int:A} Output A as integer") \
38  XX(Qas_float, "{!float:A} Output A as float") \
39  XX(Qas_string, "{!string:A} Output A as quoted string") \
40  XX(Qmime_type, "{!mime_type:A} Get MIME type string for a filename") \
41  XX(Qreplace, "{!replace:A:B:C} Copy of A with all occurrences of B replaced with C") \
42  XX(Qlength, "{!length:A} Number of characters in A") \
43  XX(Qpad, \
44  "{!pad:A:B:C} Copy of A padded to at least B characters with C (default is space). Use -ve B to left-pad. C") \
45  XX(Qrepeat, "{!repeat:A:B} Repeat A, number of iterations is B") \
46  XX(Qkb, "{!kb:A} Convert A to KB") \
47  XX(Qifdef, "{!ifdef:A} emit block if A is not zero-length") \
48  XX(Qifndef, "{!ifdef:A} emit block if A is zero-length") \
49  XX(Qifeq, "{!ifeq:A:B} emit block if A == B") \
50  XX(Qifneq, "{!ifneq:A:B} emit block if A != B") \
51  XX(Qifgt, "{!ifgt:A:B} emit block if A > B") \
52  XX(Qiflt, "{!iflt:A:B} emit block if A < B") \
53  XX(Qifge, "{!ifge:A:B} emit block if A >= B") \
54  XX(Qifle, "{!ifle:A:B} emit block if A <= B") \
55  XX(Qifbtw, "{!ifbtw:A:B:C} emit block if B <= A <= C") \
56  XX(Qifin, "{!ifin:A:B} emit block if A contains B") \
57  XX(Qifnin, "{!ifin:A:B} emit block if A does not contain B") \
58  XX(Qelse, "{!else}") \
59  XX(Qendif, "{!endif}") \
60  XX(Qadd, "{!add:A:B} A + B") \
61  XX(Qsub, "{!sub:A:B} A - B") \
62  XX(Qgoto, "{!goto:A} move to section A") \
63  XX(Qcount, "{!count:A} emit number of records in section A") \
64  XX(Qindex, "{!index:A} emit current record index for section A")
65 
66 #define SECTION_TEMPLATE_FIELD_MAP(XX) \
67  XX(section, "{$section} Current section index") \
68  XX(record, "{$record} Current record index")
69 
74 {
75 public:
76  enum class Command {
77  Qunknown = 0,
78 #define XX(name, comment) name,
80 #undef XX
81  };
82 
83  enum class Field {
84  unknown = 0,
85 #define XX(name, comment) name,
87 #undef XX
88  };
89 
90  SectionTemplate(IDataSourceStream* source, uint8_t maxSections = 5);
91 
99  using GetValue = Delegate<String(const char* name)>;
100 
102 
108  void onGetValue(GetValue callback)
109  {
110  getValueCallback = callback;
111  }
112 
118  {
119  activeFormatter = &formatter;
120  }
121 
127  {
128  return *activeFormatter;
129  }
130 
135  MimeType getMimeType() const override
136  {
137  return activeFormatter->mimeType();
138  }
139 
147  const SectionStream& stream() const
148  {
149  return sectionStream;
150  }
151 
156  int sectionIndex() const
157  {
158  return sectionStream.sectionIndex();
159  }
160 
165  uint8_t sectionCount() const
166  {
167  return sectionStream.count();
168  }
169 
174  int recordIndex() const
175  {
176  return sectionStream.recordIndex();
177  }
178 
184  bool gotoSection(uint8_t index);
185 
191  void onNextRecord(NextRecord callback)
192  {
193  nextRecordCallback = callback;
194  }
195 
196  String evaluate(char*& expr) override;
197  String getValue(const char* name) override;
198 
199 protected:
204  virtual bool nextRecord()
205  {
206  if(nextRecordCallback) {
207  return nextRecordCallback();
208  }
209 
210  // By default, emit section once
211  return recordIndex() < 0;
212  }
213 
214 private:
215  String openTag(bool enable);
216  String closeTag();
217  String elseTag();
218 
219  SectionStream sectionStream;
220  Formatter* activeFormatter{&Format::standard};
221  GetValue getValueCallback;
222  NextRecord nextRecordCallback;
223  BitSet32 conditionalFlags; // Enable state for each level
224  uint8_t conditionalLevel{0};
225  int8_t newSection{-1};
226 };
#define SECTION_TEMPLATE_COMMAND_MAP(XX)
Command map.
Definition: SectionTemplate.h:36
#define SECTION_TEMPLATE_FIELD_MAP(XX)
Definition: SectionTemplate.h:66
Virtual class to perform format-specific String adjustments.
Definition: Formatter.h:24
virtual MimeType mimeType() const =0
Corresponding MIME type for this format.
Base class for read-only stream.
Definition: DataSourceStream.h:46
Presents each section within a source stream as a separate stream.
Definition: SectionStream.h:26
Delegate< bool()> NextRecord
Application callback to move to next record.
Definition: SectionStream.h:49
int sectionIndex() const
Definition: SectionStream.h:86
int recordIndex() const
Definition: SectionStream.h:91
size_t count() const
Get number of sections in this stream.
Definition: SectionStream.h:100
Provides enhanced template tag processing for use with a SectionStream.
Definition: SectionTemplate.h:74
void onNextRecord(NextRecord callback)
Set a callback to be invoked when a new record is required.
Definition: SectionTemplate.h:191
bool gotoSection(uint8_t index)
Discard current output and change current section.
int sectionIndex() const
Get the index for the current section.
Definition: SectionTemplate.h:156
virtual bool nextRecord()
Move to next record.
Definition: SectionTemplate.h:204
SectionTemplate(IDataSourceStream *source, uint8_t maxSections=5)
void onGetValue(GetValue callback)
Set a callback to be invoked.
Definition: SectionTemplate.h:108
uint8_t sectionCount() const
Get number of sections in source stream.
Definition: SectionTemplate.h:165
String evaluate(char *&expr) override
Evaluate a template expression.
MimeType getMimeType() const override
Get the MIME type associated with this template stream.
Definition: SectionTemplate.h:135
SectionStream::NextRecord NextRecord
Definition: SectionTemplate.h:101
Command
Definition: SectionTemplate.h:76
Field
Definition: SectionTemplate.h:83
Formatter & formatter() const
Get the stream format.
Definition: SectionTemplate.h:126
int recordIndex() const
Get current record index.
Definition: SectionTemplate.h:174
const SectionStream & stream() const
Access the underlying section stream.
Definition: SectionTemplate.h:147
Delegate< String(const char *name)> GetValue
Application callback to process additional fields.
Definition: SectionTemplate.h:99
String getValue(const char *name) override
Fetch a templated value.
void setFormatter(Formatter &formatter)
Associate a text format with this template stream.
Definition: SectionTemplate.h:117
The String class.
Definition: WString.h:137
Stream which performs variable-value substitution on-the-fly.
Definition: TemplateStream.h:42
MimeType
Definition: WebConstants.h:53
void enable(Handler &commandHandler, HardwareSerial &serial)
Standard standard