Added InfluxDB-client library
Version 3.9.0 https://github.com/tobiasschuerg/InfluxDB-Client-for-Arduino
This commit is contained in:
108
lib/influxdb-client-3.9.0/query/CsvReader.cpp
Normal file
108
lib/influxdb-client-3.9.0/query/CsvReader.cpp
Normal file
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
*
|
||||
* CsvReader.cpp: Simple Csv parser for comma separated values, with double quotes suppport
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 InfluxData
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#include "CsvReader.h"
|
||||
|
||||
CsvReader::CsvReader(HttpStreamScanner *scanner) {
|
||||
_scanner = scanner;
|
||||
}
|
||||
|
||||
CsvReader::~CsvReader() {
|
||||
delete _scanner;
|
||||
}
|
||||
|
||||
std::vector<String> CsvReader::getRow() {
|
||||
return _row;
|
||||
};
|
||||
|
||||
void CsvReader::close() {
|
||||
clearRow();
|
||||
_scanner->close();
|
||||
}
|
||||
|
||||
void CsvReader::clearRow() {
|
||||
std::for_each(_row.begin(), _row.end(), [](String &value){ value = (const char *)nullptr; });
|
||||
_row.clear();
|
||||
}
|
||||
|
||||
enum class CsvParsingState {
|
||||
UnquotedField,
|
||||
QuotedField,
|
||||
QuotedQuote
|
||||
};
|
||||
|
||||
bool CsvReader::next() {
|
||||
clearRow();
|
||||
bool status = _scanner->next();
|
||||
if(!status) {
|
||||
_error = _scanner->getError();
|
||||
return false;
|
||||
}
|
||||
String line = _scanner->getLine();
|
||||
CsvParsingState state = CsvParsingState::UnquotedField;
|
||||
std::vector<String> fields {""};
|
||||
size_t i = 0; // index of the current field
|
||||
for (char c : line) {
|
||||
switch (state) {
|
||||
case CsvParsingState::UnquotedField:
|
||||
switch (c) {
|
||||
case ',': // end of field
|
||||
fields.push_back(""); i++;
|
||||
break;
|
||||
case '"': state = CsvParsingState::QuotedField;
|
||||
break;
|
||||
default: fields[i] += c;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case CsvParsingState::QuotedField:
|
||||
switch (c) {
|
||||
case '"': state = CsvParsingState::QuotedQuote;
|
||||
break;
|
||||
default: fields[i] += c;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case CsvParsingState::QuotedQuote:
|
||||
switch (c) {
|
||||
case ',': // , after closing quote
|
||||
fields.push_back(""); i++;
|
||||
state = CsvParsingState::UnquotedField;
|
||||
break;
|
||||
case '"': // "" -> "
|
||||
fields[i] += '"';
|
||||
state = CsvParsingState::QuotedField;
|
||||
break;
|
||||
default: // end of quote
|
||||
state = CsvParsingState::UnquotedField;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
_row = fields;
|
||||
return true;
|
||||
}
|
||||
51
lib/influxdb-client-3.9.0/query/CsvReader.h
Normal file
51
lib/influxdb-client-3.9.0/query/CsvReader.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
*
|
||||
* CsvReader.h: Simple Csv parser for comma separated values, with double quotes suppport
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 InfluxData
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#ifndef _CSV_READER_
|
||||
#define _CSV_READER_
|
||||
|
||||
#include "HttpStreamScanner.h"
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* CsvReader parses csv line to token by ',' (comma) character.
|
||||
* It suppports escaped quotes, excaped comma
|
||||
**/
|
||||
class CsvReader {
|
||||
public:
|
||||
CsvReader(HttpStreamScanner *scanner);
|
||||
~CsvReader();
|
||||
bool next();
|
||||
void close();
|
||||
std::vector<String> getRow();
|
||||
int getError() const { return _error; };
|
||||
private:
|
||||
void clearRow();
|
||||
HttpStreamScanner *_scanner = nullptr;
|
||||
std::vector<String> _row;
|
||||
int _error = 0;
|
||||
};
|
||||
#endif //_CSV_READER_
|
||||
275
lib/influxdb-client-3.9.0/query/FluxParser.cpp
Normal file
275
lib/influxdb-client-3.9.0/query/FluxParser.cpp
Normal file
@@ -0,0 +1,275 @@
|
||||
/**
|
||||
*
|
||||
* FluxParser.cpp: InfluxDB flux query result parser
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2018-2020 InfluxData
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "FluxParser.h"
|
||||
// Uncomment bellow in case of a problem and rebuild sketch
|
||||
//#define INFLUXDB_CLIENT_DEBUG_ENABLE
|
||||
#include "util/debug.h"
|
||||
|
||||
FluxQueryResult::FluxQueryResult(CsvReader *reader) {
|
||||
_data = std::make_shared<Data>(reader);
|
||||
}
|
||||
|
||||
FluxQueryResult::FluxQueryResult(String error):FluxQueryResult((CsvReader *)nullptr) {
|
||||
_data->_error = error;
|
||||
}
|
||||
|
||||
FluxQueryResult::FluxQueryResult(const FluxQueryResult &other) {
|
||||
_data = other._data;
|
||||
}
|
||||
FluxQueryResult &FluxQueryResult::operator=(const FluxQueryResult &other) {
|
||||
if(this != &other) {
|
||||
_data = other._data;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
FluxQueryResult::~FluxQueryResult() {
|
||||
}
|
||||
|
||||
int FluxQueryResult::getColumnIndex(String columnName) {
|
||||
int i = -1;
|
||||
std::vector<String>::iterator it = find(_data->_columnNames.begin(), _data->_columnNames.end(), columnName);
|
||||
if (it != _data->_columnNames.end()) {
|
||||
i = distance(_data->_columnNames.begin(), it);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
FluxValue FluxQueryResult::getValueByIndex(int index) {
|
||||
FluxValue ret;
|
||||
if(index >= 0 && index < (int)_data->_columnValues.size()) {
|
||||
ret = _data->_columnValues[index];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
FluxValue FluxQueryResult::getValueByName(String columnName) {
|
||||
FluxValue ret;
|
||||
int i = getColumnIndex(columnName);
|
||||
if(i > -1) {
|
||||
ret = getValueByIndex(i);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void FluxQueryResult::close() {
|
||||
clearValues();
|
||||
clearColumns();
|
||||
if(_data->_reader) {
|
||||
_data->_reader->close();
|
||||
}
|
||||
}
|
||||
|
||||
void FluxQueryResult::clearValues() {
|
||||
std::for_each(_data->_columnValues.begin(), _data->_columnValues.end(), [](FluxValue &value){ value = nullptr; });
|
||||
_data->_columnValues.clear();
|
||||
}
|
||||
|
||||
void FluxQueryResult::clearColumns() {
|
||||
std::for_each(_data->_columnNames.begin(), _data->_columnNames.end(), [](String &value){ value = (const char *)nullptr; });
|
||||
_data->_columnNames.clear();
|
||||
|
||||
std::for_each(_data->_columnDatatypes.begin(), _data->_columnDatatypes.end(), [](String &value){ value = (const char *)nullptr; });
|
||||
_data->_columnDatatypes.clear();
|
||||
}
|
||||
|
||||
FluxQueryResult::Data::Data(CsvReader *reader):_reader(reader) {}
|
||||
|
||||
FluxQueryResult::Data::~Data() {
|
||||
delete _reader;
|
||||
}
|
||||
|
||||
enum ParsingState {
|
||||
ParsingStateNormal = 0,
|
||||
ParsingStateNameRow,
|
||||
ParsingStateError
|
||||
};
|
||||
|
||||
bool FluxQueryResult::next() {
|
||||
if(!_data->_reader) {
|
||||
return false;
|
||||
}
|
||||
ParsingState parsingState = ParsingStateNormal;
|
||||
_data->_tableChanged = false;
|
||||
clearValues();
|
||||
_data->_error = "";
|
||||
readRow:
|
||||
bool stat = _data->_reader->next();
|
||||
if(!stat) {
|
||||
if(_data->_reader->getError()< 0) {
|
||||
_data->_error = HTTPClient::errorToString(_data->_reader->getError());
|
||||
INFLUXDB_CLIENT_DEBUG("Error '%s'\n", _data->_error.c_str());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
std::vector<String> vals = _data->_reader->getRow();
|
||||
INFLUXDB_CLIENT_DEBUG("[D] FluxQueryResult: vals.size %d\n", vals.size());
|
||||
if(vals.size() < 2) {
|
||||
goto readRow;
|
||||
}
|
||||
if(vals[0] == "") {
|
||||
if (parsingState == ParsingStateError) {
|
||||
String message ;
|
||||
if (vals.size() > 1 && vals[1].length() > 0) {
|
||||
message = vals[1];
|
||||
} else {
|
||||
message = F("Unknown query error");
|
||||
}
|
||||
String reference = "";
|
||||
if (vals.size() > 2 && vals[2].length() > 0) {
|
||||
reference = "," + vals[2];
|
||||
}
|
||||
_data->_error = message + reference;
|
||||
INFLUXDB_CLIENT_DEBUG("Error '%s'\n", _data->_error.c_str());
|
||||
return false;
|
||||
} else if (parsingState == ParsingStateNameRow) {
|
||||
if (vals[1] == "error") {
|
||||
parsingState = ParsingStateError;
|
||||
} else {
|
||||
if (vals.size()-1 != _data->_columnDatatypes.size()) {
|
||||
_data->_error = String(F("Parsing error, header has different number of columns than table: ")) + String(vals.size()-1) + " vs " + String(_data->_columnDatatypes.size());
|
||||
INFLUXDB_CLIENT_DEBUG("Error '%s'\n", _data->_error.c_str());
|
||||
return false;
|
||||
} else {
|
||||
for(unsigned int i=1;i < vals.size(); i++) {
|
||||
_data->_columnNames.push_back(vals[i]);
|
||||
}
|
||||
}
|
||||
parsingState = ParsingStateNormal;
|
||||
}
|
||||
goto readRow;
|
||||
}
|
||||
if(_data->_columnDatatypes.size() == 0) {
|
||||
_data->_error = F("Parsing error, datatype annotation not found");
|
||||
INFLUXDB_CLIENT_DEBUG("Error '%s'\n", _data->_error.c_str());
|
||||
return false;
|
||||
}
|
||||
if (vals.size()-1 != _data->_columnNames.size()) {
|
||||
_data->_error = String(F("Parsing error, row has different number of columns than table: ")) + String(vals.size()-1) + " vs " + String(_data->_columnNames.size());
|
||||
INFLUXDB_CLIENT_DEBUG("Error '%s'\n", _data->_error.c_str());
|
||||
return false;
|
||||
}
|
||||
for(unsigned int i=1;i < vals.size(); i++) {
|
||||
FluxBase *v = nullptr;
|
||||
if(vals[i].length() > 0) {
|
||||
v = convertValue(vals[i], _data->_columnDatatypes[i-1]);
|
||||
if(!v) {
|
||||
_data->_error = String(F("Unsupported datatype: ")) + _data->_columnDatatypes[i-1];
|
||||
INFLUXDB_CLIENT_DEBUG("Error '%s'\n", _data->_error.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
FluxValue val(v);
|
||||
_data->_columnValues.push_back(val);
|
||||
}
|
||||
} else if(vals[0] == "#datatype") {
|
||||
_data->_tablePosition++;
|
||||
clearColumns();
|
||||
_data->_tableChanged = true;
|
||||
for(unsigned int i=1;i < vals.size(); i++) {
|
||||
_data->_columnDatatypes.push_back(vals[i]);
|
||||
}
|
||||
parsingState = ParsingStateNameRow;
|
||||
goto readRow;
|
||||
} else {
|
||||
goto readRow;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
FluxDateTime *FluxQueryResult::convertRfc3339(String value, const char *type) {
|
||||
tm t = {0,0,0,0,0,0,0,0,0};
|
||||
// has the time part
|
||||
int zet = value.indexOf('Z');
|
||||
unsigned long fracts = 0;
|
||||
if(value.indexOf('T') > 0 && zet > 0) { //Full datetime string - 2020-05-22T11:25:22.037735433Z
|
||||
int f = sscanf(value.c_str(),"%d-%d-%dT%d:%d:%d", &t.tm_year,&t.tm_mon,&t.tm_mday, &t.tm_hour,&t.tm_min,&t.tm_sec);
|
||||
if(f != 6) {
|
||||
return nullptr;
|
||||
}
|
||||
t.tm_year -= 1900; //adjust to years after 1900
|
||||
t.tm_mon -= 1; //adjust to range 0-11
|
||||
int dot = value.indexOf('.');
|
||||
|
||||
if(dot > 0) {
|
||||
int tail = zet;
|
||||
int len = zet-dot-1;
|
||||
if (len > 6) {
|
||||
tail = dot + 7;
|
||||
len = 6;
|
||||
}
|
||||
String secParts = value.substring(dot+1, tail);
|
||||
fracts = strtoul((const char *) secParts.c_str(), NULL, 10);
|
||||
if(len < 6) {
|
||||
fracts *= 10^(6-len);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int f = sscanf(value.c_str(),"%d-%d-%d", &t.tm_year,&t.tm_mon,&t.tm_mday);
|
||||
if(f != 3) {
|
||||
return nullptr;
|
||||
}
|
||||
t.tm_year -= 1900; //adjust to years after 1900
|
||||
t.tm_mon -= 1; //adjust to range 0-11
|
||||
}
|
||||
return new FluxDateTime(value, type, t, fracts);
|
||||
}
|
||||
|
||||
FluxBase *FluxQueryResult::convertValue(String value, String dataType) {
|
||||
FluxBase *ret = nullptr;
|
||||
if(dataType.equals(FluxDatatypeDatetimeRFC3339) || dataType.equals(FluxDatatypeDatetimeRFC3339Nano)) {
|
||||
const char *type = FluxDatatypeDatetimeRFC3339;
|
||||
if(dataType.equals(FluxDatatypeDatetimeRFC3339Nano)) {
|
||||
type = FluxDatatypeDatetimeRFC3339Nano;
|
||||
}
|
||||
ret = convertRfc3339(value, type);
|
||||
if (!ret) {
|
||||
_data->_error = String(F("Invalid value for '")) + dataType + F("': ") + value;
|
||||
}
|
||||
} else if(dataType.equals(FluxDatatypeDouble)) {
|
||||
double val = strtod((const char *) value.c_str(), NULL);
|
||||
ret = new FluxDouble(value, val);
|
||||
} else if(dataType.equals(FluxDatatypeBool)) {
|
||||
bool val = value.equalsIgnoreCase("true");
|
||||
ret = new FluxBool(value, val);
|
||||
} else if(dataType.equals(FluxDatatypeLong)) {
|
||||
long l = strtol((const char *) value.c_str(), NULL, 10);
|
||||
ret = new FluxLong(value, l);
|
||||
} else if(dataType.equals(FluxDatatypeUnsignedLong)) {
|
||||
unsigned long ul = strtoul((const char *) value.c_str(), NULL, 10);
|
||||
ret = new FluxUnsignedLong(value, ul);
|
||||
} else if(dataType.equals(FluxBinaryDataTypeBase64)) {
|
||||
ret = new FluxString(value, FluxBinaryDataTypeBase64);
|
||||
} else if(dataType.equals(FluxDatatypeDuration)) {
|
||||
ret = new FluxString(value, FluxDatatypeDuration);
|
||||
} else if(dataType.equals(FluxDatatypeString)) {
|
||||
ret = new FluxString(value, FluxDatatypeString);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
109
lib/influxdb-client-3.9.0/query/FluxParser.h
Normal file
109
lib/influxdb-client-3.9.0/query/FluxParser.h
Normal file
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
*
|
||||
* FLuxParser.h: InfluxDB flux query result parser
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 InfluxData
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#ifndef _FLUX_PARSER_H_
|
||||
#define _FLUX_PARSER_H_
|
||||
|
||||
#include <vector>
|
||||
#include "CsvReader.h"
|
||||
#include "FluxTypes.h"
|
||||
|
||||
|
||||
/**
|
||||
* FluxQueryResult represents result from InfluxDB flux query.
|
||||
* It parses stream from server, line by line, so it allows to read a huge responses.
|
||||
*
|
||||
* Browsing thought the result is done by repeatedly calling the next() method, until it returns false.
|
||||
* Unsuccesful reading is distinqushed by non empty value from getError().
|
||||
*
|
||||
* As a flux query result can contain several tables differing by grouping key, use hasTableChanged() to
|
||||
* know when there is a new table.
|
||||
*
|
||||
* Single values are returned using getValueByIndex() or getValueByName() methods.
|
||||
* All row values are retreived by getValues().
|
||||
*
|
||||
* Always call close() at the of reading.
|
||||
*
|
||||
* FluxQueryResult supports passing by value.
|
||||
*/
|
||||
class FluxQueryResult {
|
||||
public:
|
||||
// Constructor for reading result
|
||||
FluxQueryResult(CsvReader *reader);
|
||||
// Constructor for error result
|
||||
FluxQueryResult(String error);
|
||||
// Copy constructor
|
||||
FluxQueryResult(const FluxQueryResult &other);
|
||||
// Assignment operator
|
||||
FluxQueryResult &operator=(const FluxQueryResult &other);
|
||||
// Advances to next values row in the result set.
|
||||
// Returns true on successful reading new row, false means end of the result set
|
||||
// or an error. Call getError() and check non empty value
|
||||
bool next();
|
||||
// Returns index of the column, or -1 if not found
|
||||
int getColumnIndex(String columnName);
|
||||
// Returns a converted value by index, or nullptr in case of missing value or wrong index
|
||||
FluxValue getValueByIndex(int index);
|
||||
// Returns a result value by column name, or nullptr in case of missing value or wrong column name
|
||||
FluxValue getValueByName(String columnName);
|
||||
// Returns flux datatypes of all columns
|
||||
std::vector<String> getColumnsDatatype() { return _data->_columnDatatypes; }
|
||||
// Returns names of all columns
|
||||
std::vector<String> getColumnsName() { return _data->_columnNames; }
|
||||
// Returns all values from current row
|
||||
std::vector<FluxValue> getValues() { return _data->_columnValues; }
|
||||
// Returns true if new table was encountered
|
||||
bool hasTableChanged() const { return _data->_tableChanged; }
|
||||
// Returns current table position in the results set
|
||||
int getTablePosition() const { return _data->_tablePosition; }
|
||||
// Returns an error found during parsing if any, othewise empty string
|
||||
String getError() { return _data->_error; }
|
||||
// Releases all resources and closes server reponse. It must be always called at end of reading.
|
||||
void close();
|
||||
// Descructor
|
||||
~FluxQueryResult();
|
||||
protected:
|
||||
FluxBase *convertValue(String value, String dataType);
|
||||
static FluxDateTime *convertRfc3339(String value, const char *type);
|
||||
void clearValues();
|
||||
void clearColumns();
|
||||
private:
|
||||
class Data {
|
||||
public:
|
||||
Data(CsvReader *reader);
|
||||
~Data();
|
||||
CsvReader *_reader;
|
||||
int _tablePosition = -1;
|
||||
bool _tableChanged = false;
|
||||
std::vector<String> _columnDatatypes;
|
||||
std::vector<String> _columnNames;
|
||||
std::vector<FluxValue> _columnValues;
|
||||
String _error;
|
||||
};
|
||||
std::shared_ptr<Data> _data;
|
||||
};
|
||||
|
||||
#endif //#_FLUX_PARSER_H_
|
||||
181
lib/influxdb-client-3.9.0/query/FluxTypes.cpp
Normal file
181
lib/influxdb-client-3.9.0/query/FluxTypes.cpp
Normal file
@@ -0,0 +1,181 @@
|
||||
/**
|
||||
*
|
||||
* FluxTypes.cpp: InfluxDB flux query types support
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2018-2020 InfluxData
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "FluxTypes.h"
|
||||
|
||||
const char *FluxDatatypeString = "string";
|
||||
const char *FluxDatatypeDouble = "double";
|
||||
const char *FluxDatatypeBool = "boolean";
|
||||
const char *FluxDatatypeLong = "long";
|
||||
const char *FluxDatatypeUnsignedLong = "unsignedLong";
|
||||
const char *FluxDatatypeDuration = "duration";
|
||||
const char *FluxBinaryDataTypeBase64 = "base64Binary";
|
||||
const char *FluxDatatypeDatetimeRFC3339 = "dateTime:RFC3339";
|
||||
const char *FluxDatatypeDatetimeRFC3339Nano = "dateTime:RFC3339Nano";
|
||||
|
||||
FluxBase::FluxBase(String rawValue) {
|
||||
_rawValue = rawValue;
|
||||
}
|
||||
|
||||
FluxBase::~FluxBase() {
|
||||
}
|
||||
|
||||
|
||||
FluxLong::FluxLong(String rawValue, long value):FluxBase(rawValue),value(value) {
|
||||
|
||||
}
|
||||
|
||||
const char *FluxLong::getType() {
|
||||
return FluxDatatypeLong;
|
||||
}
|
||||
|
||||
FluxUnsignedLong::FluxUnsignedLong(String rawValue, unsigned long value):FluxBase(rawValue),value(value) {
|
||||
}
|
||||
|
||||
const char *FluxUnsignedLong::getType() {
|
||||
return FluxDatatypeUnsignedLong;
|
||||
}
|
||||
|
||||
FluxDouble::FluxDouble(String rawValue, double value):FluxBase(rawValue),value(value) {
|
||||
|
||||
}
|
||||
|
||||
const char *FluxDouble::getType() {
|
||||
return FluxDatatypeDouble;
|
||||
}
|
||||
|
||||
FluxBool::FluxBool(String rawValue, bool value):FluxBase(rawValue),value(value) {
|
||||
}
|
||||
|
||||
const char *FluxBool::getType() {
|
||||
return FluxDatatypeBool;
|
||||
}
|
||||
|
||||
|
||||
FluxDateTime::FluxDateTime(String rawValue, const char *type, struct tm value, unsigned long microseconds):FluxBase(rawValue),_type(type),value(value), microseconds(microseconds) {
|
||||
|
||||
}
|
||||
|
||||
const char *FluxDateTime::getType() {
|
||||
return _type;
|
||||
}
|
||||
|
||||
String FluxDateTime::format(String formatString) {
|
||||
int len = formatString.length() + 20; //+20 for safety
|
||||
char *buff = new char[len];
|
||||
strftime(buff,len, formatString.c_str(),&value);
|
||||
String str = buff;
|
||||
delete [] buff;
|
||||
return str;
|
||||
}
|
||||
|
||||
FluxString::FluxString(String rawValue, const char *type):FluxBase(rawValue),_type(type),value(_rawValue) {
|
||||
|
||||
}
|
||||
|
||||
const char *FluxString::getType() {
|
||||
return _type;
|
||||
}
|
||||
|
||||
|
||||
FluxValue::FluxValue() {}
|
||||
|
||||
FluxValue::FluxValue(FluxBase *fluxValue):_data(fluxValue) {
|
||||
|
||||
}
|
||||
|
||||
FluxValue::FluxValue(const FluxValue &other) {
|
||||
_data = other._data;
|
||||
}
|
||||
|
||||
FluxValue& FluxValue::operator=(const FluxValue& other) {
|
||||
if(this != &other) {
|
||||
_data = other._data;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Type accessor. If value is different type zero value for given time is returned.
|
||||
String FluxValue::getString() {
|
||||
if(_data && (_data->getType() == FluxDatatypeString ||_data->getType() == FluxDatatypeDuration || _data->getType() == FluxBinaryDataTypeBase64)) {
|
||||
FluxString *s = (FluxString *)_data.get();
|
||||
return s->value;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
long FluxValue::getLong() {
|
||||
if(_data && _data->getType() == FluxDatatypeLong) {
|
||||
FluxLong *l = (FluxLong *)_data.get();
|
||||
return l->value;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long FluxValue::getUnsignedLong() {
|
||||
if(_data && _data->getType() == FluxDatatypeUnsignedLong) {
|
||||
FluxUnsignedLong *l = (FluxUnsignedLong *)_data.get();
|
||||
return l->value;
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
FluxDateTime FluxValue::getDateTime() {
|
||||
if(_data && (_data->getType() == FluxDatatypeDatetimeRFC3339 ||_data->getType() == FluxDatatypeDatetimeRFC3339Nano)) {
|
||||
FluxDateTime *d = (FluxDateTime *)_data.get();
|
||||
return *d;
|
||||
}
|
||||
return FluxDateTime("",FluxDatatypeDatetimeRFC3339, {0,0,0,0,0,0,0,0,0}, 0 );
|
||||
}
|
||||
|
||||
bool FluxValue::getBool() {
|
||||
if(_data && _data->getType() == FluxDatatypeBool) {
|
||||
FluxBool *b = (FluxBool *)_data.get();
|
||||
return b->value;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
double FluxValue::getDouble() {
|
||||
if(_data && _data->getType() == FluxDatatypeDouble) {
|
||||
FluxDouble *d = (FluxDouble *)_data.get();
|
||||
return d->value;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
// returns string representation of non-string values
|
||||
String FluxValue::getRawValue() {
|
||||
if(_data) {
|
||||
return _data->getRawValue();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
bool FluxValue::isNull() {
|
||||
return _data == nullptr;
|
||||
}
|
||||
167
lib/influxdb-client-3.9.0/query/FluxTypes.h
Normal file
167
lib/influxdb-client-3.9.0/query/FluxTypes.h
Normal file
@@ -0,0 +1,167 @@
|
||||
/**
|
||||
*
|
||||
* FLuxTypes.h: InfluxDB flux types representation
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 InfluxData
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#ifndef _FLUX_TYPES_H_
|
||||
#define _FLUX_TYPES_H_
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <memory>
|
||||
|
||||
/** Supported flux types:
|
||||
* - long - converts to long
|
||||
* - unsignedLong - converts to unsigned long
|
||||
* - double - converts to double
|
||||
* - bool - converts to bool
|
||||
* - dateTime:RFC3339 - converts to FluxDataTime
|
||||
* - dateTime:RFC3339Nano - converts to FluxDataTime
|
||||
* other types defaults to String
|
||||
*/
|
||||
|
||||
extern const char *FluxDatatypeString;
|
||||
extern const char *FluxDatatypeDouble;
|
||||
extern const char *FluxDatatypeBool;
|
||||
extern const char *FluxDatatypeLong;
|
||||
extern const char *FluxDatatypeUnsignedLong;
|
||||
extern const char *FluxDatatypeDuration;
|
||||
extern const char *FluxBinaryDataTypeBase64;
|
||||
extern const char *FluxDatatypeDatetimeRFC3339;
|
||||
extern const char *FluxDatatypeDatetimeRFC3339Nano;
|
||||
|
||||
// Base type for all specific flux types
|
||||
class FluxBase {
|
||||
protected:
|
||||
String _rawValue;
|
||||
public:
|
||||
FluxBase(String rawValue);
|
||||
virtual ~FluxBase();
|
||||
String getRawValue() const { return _rawValue; }
|
||||
virtual const char *getType() = 0;
|
||||
};
|
||||
|
||||
// Represents flux long
|
||||
class FluxLong : public FluxBase {
|
||||
public:
|
||||
FluxLong(String rawValue, long value);
|
||||
long value;
|
||||
virtual const char *getType() override;
|
||||
};
|
||||
|
||||
// Represents flux unsignedLong
|
||||
class FluxUnsignedLong : public FluxBase {
|
||||
public:
|
||||
FluxUnsignedLong(String rawValue, unsigned long value);
|
||||
unsigned long value;
|
||||
virtual const char *getType() override;
|
||||
};
|
||||
|
||||
// Represents flux double
|
||||
class FluxDouble : public FluxBase {
|
||||
public:
|
||||
FluxDouble(String rawValue, double value);
|
||||
double value;
|
||||
virtual const char *getType() override;
|
||||
};
|
||||
|
||||
// Represents flux bool
|
||||
class FluxBool : public FluxBase {
|
||||
public:
|
||||
FluxBool(String rawValue, bool value);
|
||||
bool value;
|
||||
virtual const char *getType() override;
|
||||
};
|
||||
|
||||
// Represents flux dateTime:RFC3339 and dateTime:RFC3339Nano
|
||||
// Date and time are stored in classic struct tm.
|
||||
// Fraction of second is stored in microseconds
|
||||
// There are several classic functions for using struct tm: http://www.cplusplus.com/reference/ctime/
|
||||
class FluxDateTime : public FluxBase {
|
||||
protected:
|
||||
const char *_type;
|
||||
public:
|
||||
FluxDateTime(String rawValue, const char *type, struct tm value, unsigned long microseconds);
|
||||
// Struct tm for date and time
|
||||
struct tm value;
|
||||
// microseconds part
|
||||
unsigned long microseconds;
|
||||
// Formats the value part to string according to the given format. Microseconds are skipped.
|
||||
// Format string must be compatible with the http://www.cplusplus.com/reference/ctime/strftime/
|
||||
String format(String formatString);
|
||||
virtual const char *getType() override;
|
||||
};
|
||||
|
||||
// Represents flux string, duration, base64binary
|
||||
class FluxString : public FluxBase {
|
||||
protected:
|
||||
const char *_type;
|
||||
public:
|
||||
FluxString(String rawValue, const char *type);
|
||||
String value;
|
||||
virtual const char *getType() override;
|
||||
};
|
||||
|
||||
/**
|
||||
* FluxValue wraps a value from a flux query result column.
|
||||
* It provides getter methods for supported flux types:
|
||||
* * getString() - string, base64binary or duration
|
||||
* * getLong() - long
|
||||
* * getUnsignedLong() - unsignedLong
|
||||
* * getDateTime() - dateTime:RFC3339 or dateTime:RFC3339Nano
|
||||
* * getBool() - bool
|
||||
* * getDouble() - double
|
||||
*
|
||||
* Calling improper type getter will result in zero (empty) value.
|
||||
* Check for null value usig isNull().
|
||||
* Use getRawValue() for getting original string form.
|
||||
*
|
||||
**/
|
||||
|
||||
class FluxValue {
|
||||
public:
|
||||
FluxValue();
|
||||
FluxValue(FluxBase *value);
|
||||
FluxValue(const FluxValue &other);
|
||||
FluxValue& operator=(const FluxValue& other);
|
||||
// Check if value represent null - not present - value.
|
||||
bool isNull();
|
||||
// Returns a value of string, base64binary or duration type column, or empty string if column is a different type.
|
||||
String getString();
|
||||
// Returns a value of long type column, or zero if column is a different type.
|
||||
long getLong();
|
||||
// Returns a value of unsigned long type column, or zero if column is a different type.
|
||||
unsigned long getUnsignedLong();
|
||||
// Returns a value of dateTime:RFC3339 or dateTime:RFC3339Nano, or zeroed FluxDateTime instance if column is a different type.
|
||||
FluxDateTime getDateTime();
|
||||
// Returns a value of bool type column, or false if column is a different type.
|
||||
bool getBool();
|
||||
// Returns a value of double type column, or 0.0 if column is a different type.
|
||||
double getDouble();
|
||||
// Returns a value in the original string form, as presented in the response.
|
||||
String getRawValue();
|
||||
private:
|
||||
std::shared_ptr<FluxBase> _data;
|
||||
};
|
||||
|
||||
#endif //_FLUX_TYPES_H_
|
||||
104
lib/influxdb-client-3.9.0/query/HttpStreamScanner.cpp
Normal file
104
lib/influxdb-client-3.9.0/query/HttpStreamScanner.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
/**
|
||||
*
|
||||
* HttpStreamScanner.cpp: Scannes HttpClient stream for lines. Supports chunking.
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 InfluxData
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#include "HttpStreamScanner.h"
|
||||
|
||||
// Uncomment bellow in case of a problem and rebuild sketch
|
||||
//#define INFLUXDB_CLIENT_DEBUG_ENABLE
|
||||
#include "util/debug.h"
|
||||
#include "util/helpers.h"
|
||||
|
||||
HttpStreamScanner::HttpStreamScanner(HTTPClient *client, bool chunked)
|
||||
{
|
||||
_client = client;
|
||||
_stream = client->getStreamPtr();
|
||||
_chunked = chunked;
|
||||
_chunkHeader = chunked;
|
||||
_len = client->getSize();
|
||||
INFLUXDB_CLIENT_DEBUG("[D] HttpStreamScanner: chunked: %s, size: %d\n", bool2string(_chunked), _len);
|
||||
}
|
||||
|
||||
bool HttpStreamScanner::next() {
|
||||
while(_client->connected() && (_len > 0 || _len == -1)) {
|
||||
_line = _stream->readStringUntil('\n');
|
||||
INFLUXDB_CLIENT_DEBUG("[D] HttpStreamScanner: line: %s\n", _line.c_str());
|
||||
++_linesNum;
|
||||
int lineLen = _line.length();
|
||||
if(lineLen == 0) {
|
||||
_error = HTTPC_ERROR_READ_TIMEOUT;
|
||||
return false;
|
||||
}
|
||||
int r = lineLen +1; //+1 for terminating \n
|
||||
_line.trim(); //remove \r
|
||||
if(!_chunked || !_chunkHeader) {
|
||||
_read += r;
|
||||
if(_lastChunkLine.length() > 0) { //fix broken line
|
||||
_line = _lastChunkLine + _line;
|
||||
_lastChunkLine = "";
|
||||
}
|
||||
|
||||
}
|
||||
if(_chunkHeader && r == 2) { //empty line at the end of chunk
|
||||
//last line was complete so return
|
||||
_line = _lastChunkLine;
|
||||
_lastChunkLine = "";
|
||||
return true;
|
||||
}
|
||||
if(_chunkHeader){
|
||||
_chunkLen = (int) strtol((const char *) _line.c_str(), NULL, 16);
|
||||
INFLUXDB_CLIENT_DEBUG("[D] HttpStreamScanner chunk len: %d\n", _chunkLen);
|
||||
_chunkHeader = false;
|
||||
_read = 0;
|
||||
if(_chunkLen == 0) { //last chunk
|
||||
_error = 0;
|
||||
_line = "";
|
||||
return false;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
} else if(_chunked && _read >= _chunkLen){ //we reached end of chunk.
|
||||
_lastChunkLine = _line;
|
||||
_chunkHeader = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(_len > 0) {
|
||||
_len -= r;
|
||||
INFLUXDB_CLIENT_DEBUG("[D] HttpStreamScanner new len: %d\n", _len);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if(!_client->connected() && ( (_chunked && _chunkLen > 0) || (!_chunked && _len > 0))) { //report error only if we didn't went to
|
||||
_error = HTTPC_ERROR_CONNECTION_LOST;
|
||||
INFLUXDB_CLIENT_DEBUG("HttpStreamScanner connection lost\n");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void HttpStreamScanner::close() {
|
||||
_client->end();
|
||||
}
|
||||
|
||||
64
lib/influxdb-client-3.9.0/query/HttpStreamScanner.h
Normal file
64
lib/influxdb-client-3.9.0/query/HttpStreamScanner.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
*
|
||||
* HttpStreamScanner.h: Scannes HttpClient stream for lines. Supports chunking.
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 InfluxData
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#ifndef _HTTP_STREAM_SCANNER_
|
||||
#define _HTTP_STREAM_SCANNER_
|
||||
|
||||
#if defined(ESP8266)
|
||||
# include <ESP8266HTTPClient.h>
|
||||
#elif defined(ESP32)
|
||||
# include <HTTPClient.h>
|
||||
#endif //ESP8266
|
||||
|
||||
/**
|
||||
* HttpStreamScanner parses response stream from HTTPClient for lines.
|
||||
* By repeatedly calling next() it searches for new line.
|
||||
* If next() returns false, it can mean end of stream or an error.
|
||||
* Check getError() for nonzero if an error occured
|
||||
*/
|
||||
class HttpStreamScanner {
|
||||
public:
|
||||
HttpStreamScanner(HTTPClient *client, bool chunked);
|
||||
bool next();
|
||||
void close();
|
||||
const String &getLine() const { return _line; }
|
||||
int getError() const { return _error; }
|
||||
int getLinesNum() const {return _linesNum; }
|
||||
private:
|
||||
HTTPClient *_client;
|
||||
Stream *_stream = nullptr;
|
||||
int _len;
|
||||
String _line;
|
||||
int _linesNum= 0;
|
||||
int _read = 0;
|
||||
bool _chunked;
|
||||
bool _chunkHeader;
|
||||
int _chunkLen = 0;
|
||||
String _lastChunkLine;
|
||||
int _error = 0;
|
||||
};
|
||||
|
||||
#endif //#_HTTP_STREAM_SCANNER_
|
||||
Reference in New Issue
Block a user