SectionStream.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  * SectionStream.h
8  *
9  * @author mikee47 <mike@sillyhouse.net> Nov 2020
10  *
11  ****/
12 
13 #pragma once
14 
15 #include "DataSourceStream.h"
16 #include <memory>
17 
26 {
27 public:
28  struct Section {
29  uint32_t start; // Within stream
30  uint32_t size;
31  uint32_t recordCount;
32  int recordIndex;
33 
34  uint32_t end() const
35  {
36  return start + size;
37  }
38  };
39 
43  using NextSection = Delegate<void()>;
44 
49  using NextRecord = Delegate<bool()>;
50 
54  SectionStream(IDataSourceStream* source, uint8_t maxSections = 5)
55  : SectionStream(source, maxSections, F("{SECTION}"), F("{/SECTION}"))
56  {
57  }
58 
65  SectionStream(IDataSourceStream* source, uint8_t maxSections, const String& startTag, const String& endTag)
66  : startTag(startTag), endTag(endTag)
67  {
68  stream.reset(source);
69  scanSource(maxSections);
70  }
71 
72  int available() override
73  {
74  return -1;
75  }
76 
77  uint16_t readMemoryBlock(char* data, int bufSize) override;
78 
79  int seekFrom(int offset, SeekOrigin origin) override;
80 
81  bool isFinished() override
82  {
83  return finished;
84  }
85 
86  int sectionIndex() const
87  {
88  return currentSectionIndex;
89  }
90 
91  int recordIndex() const
92  {
93  auto section = getSection();
94  return section ? section->recordIndex : -1;
95  }
96 
100  size_t count() const
101  {
102  return sectionCount;
103  }
104 
109  const Section* getSection() const
110  {
111  return getSection(currentSectionIndex);
112  }
113 
118  const Section* getSection(unsigned index) const
119  {
120  if(index < sectionCount) {
121  return &sections[index];
122  } else {
123  return nullptr;
124  }
125  }
126 
130  void onNextSection(NextSection callback)
131  {
132  nextSectionCallback = callback;
133  }
134 
138  void onNextRecord(NextRecord callback)
139  {
140  nextRecordCallback = callback;
141  }
142 
146  bool gotoSection(uint8_t index);
147 
151  bool setNewSection(int8_t index)
152  {
153  if(index < 0 || index >= sectionCount) {
154  return false;
155  }
156  newSection = index;
157  return true;
158  }
159 
160 protected:
164  virtual void nextSection();
165 
170  virtual bool nextRecord()
171  {
172  if(nextRecordCallback) {
173  return nextRecordCallback();
174  }
175 
176  // By default, emit section once
177  return recordIndex() < 0;
178  }
179 
180 private:
181  void scanSource(uint8_t maxSections);
182 
183  std::unique_ptr<IDataSourceStream> stream;
184  NextSection nextSectionCallback;
185  NextRecord nextRecordCallback;
186  String startTag;
187  String endTag;
188  std::unique_ptr<Section[]> sections;
189  uint32_t readOffset{0};
190  uint32_t sectionOffset{0};
191  uint8_t sectionCount{0};
192  int8_t currentSectionIndex{-1};
193  int8_t newSection{-1};
194  bool finished{false};
195 };
int available() override
Return the total length of the stream.
Definition: SectionStream.h:82
Base class for read-only stream.
Definition: DataSourceStream.h:45
bool isFinished() override
Check if all data has been read.
Definition: SectionStream.h:91
int seekFrom(int offset, SeekOrigin origin) override
Change position in stream.
void onNextSection(NextSection callback)
Register a callback to be invoked when moving to a new section.
Definition: SectionStream.h:140
size_t count() const
Get number of sections in this stream.
Definition: SectionStream.h:110
uint32_t end() const
Definition: SectionStream.h:54
int recordIndex
Definition: SectionStream.h:52
The String class.
Definition: WString.h:136
Delegate< void()> NextSection
Application notification callback when section changes.
Definition: SectionStream.h:53
uint32_t start
Definition: SectionStream.h:49
const Section * getSection() const
Get description of the current section.
Definition: SectionStream.h:119
SectionStream(IDataSourceStream *source, uint8_t maxSections=5)
Construct a section stream with default options.
Definition: SectionStream.h:64
uint32_t size
Definition: SectionStream.h:50
uint32_t recordCount
Definition: SectionStream.h:51
virtual void nextSection()
Invoked when moving to a new section.
void onNextRecord(NextRecord callback)
Register a callback to be invoked when moving to a new record.
Definition: SectionStream.h:148
int sectionIndex() const
Definition: SectionStream.h:96
uint16_t readMemoryBlock(char *data, int bufSize) override
Read a block of memory.
bool gotoSection(uint8_t index)
Goto a new section immediately.
Presents each section within a source stream as a separate stream.
Definition: SectionStream.h:25
int recordIndex() const
Definition: SectionStream.h:101
bool setNewSection(int8_t index)
Goto a new section after current tag has been processed.
Definition: SectionStream.h:161
SeekOrigin
Stream/file seek origins.
Definition: SeekOrigin.h:18
#define F(string_literal)
Wrap a string literal stored in flash and access it using a String object.
Definition: WString.h:113
Definition: SectionStream.h:38
virtual bool nextRecord()
Move to first/next record.
Definition: SectionStream.h:180
Delegate< bool()> NextRecord
Application callback to move to next record.
Definition: SectionStream.h:59