2020-05-25 03:58:04 -04:00
|
|
|
#pragma once
|
2013-11-06 16:32:29 -05:00
|
|
|
//
|
|
|
|
// FILE: XMLWriter.h
|
|
|
|
// AUTHOR: Rob Tillaart
|
2021-11-11 14:36:58 -05:00
|
|
|
// VERSION: 0.3.1
|
2013-11-06 16:32:29 -05:00
|
|
|
// DATE: 2013-11-06
|
2020-05-25 03:58:04 -04:00
|
|
|
// PURPOSE: Arduino library for creating XML
|
2013-11-06 16:32:29 -05:00
|
|
|
//
|
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
|
2013-11-08 11:13:13 -05:00
|
|
|
#include "Arduino.h"
|
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
|
2021-11-11 14:36:58 -05:00
|
|
|
#define XMLWRITER_VERSION (F("0.3.1"))
|
2021-01-29 06:31:58 -05:00
|
|
|
|
2013-11-06 16:32:29 -05:00
|
|
|
|
2013-11-08 11:13:13 -05:00
|
|
|
// for comment()
|
2021-01-29 06:31:58 -05:00
|
|
|
#define NOMULTILINE false
|
|
|
|
#define MULTILINE true
|
2013-11-08 11:13:13 -05:00
|
|
|
|
|
|
|
// for tagOpen(), tagEnd()
|
2021-01-29 06:31:58 -05:00
|
|
|
#define NEWLINE true
|
|
|
|
#define NONEWLINE false
|
|
|
|
#define NOINDENT false // for tagClose()
|
2013-11-08 11:13:13 -05:00
|
|
|
|
|
|
|
// for tagEnd()
|
2021-01-29 06:31:58 -05:00
|
|
|
#define SLASH true
|
|
|
|
#define NOSLASH false
|
2013-11-08 11:13:13 -05:00
|
|
|
|
2013-11-07 14:02:40 -05:00
|
|
|
// deepness of XML tree 5..10
|
2015-03-07 18:11:56 -05:00
|
|
|
// needed for stack of tagStack
|
2020-05-25 03:58:04 -04:00
|
|
|
#ifndef XMLWRITER_MAXLEVEL
|
2021-01-29 06:31:58 -05:00
|
|
|
#define XMLWRITER_MAXLEVEL 5 // adjust for deeper nested structures
|
2020-05-25 03:58:04 -04:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef XMLWRITER_MAXTAGSIZE
|
2021-01-29 06:31:58 -05:00
|
|
|
#define XMLWRITER_MAXTAGSIZE 15 // adjust for longer fields - !! eats memory !!
|
2020-05-25 03:58:04 -04:00
|
|
|
#endif
|
2013-11-06 16:32:29 -05:00
|
|
|
|
2016-04-27 08:14:37 -04:00
|
|
|
// reduce footprint by commenting next line
|
2013-11-08 11:13:13 -05:00
|
|
|
#define XMLWRITER_ESCAPE_SUPPORT
|
2013-11-06 16:32:29 -05:00
|
|
|
|
2020-05-25 03:58:04 -04:00
|
|
|
// configuration - setConfig
|
2021-01-29 06:31:58 -05:00
|
|
|
#define XMLWRITER_NONE 0x00
|
|
|
|
#define XMLWRITER_COMMENT 0x01
|
|
|
|
#define XMLWRITER_INDENT 0x02
|
|
|
|
#define XMLWRITER_NEWLINE 0x04
|
2020-05-25 03:58:04 -04:00
|
|
|
|
|
|
|
// uncomment next line to reduce ~30bytes RAM in escape() (AVR oonly)
|
|
|
|
// #define __PROGMEM__
|
|
|
|
|
|
|
|
|
2020-11-27 05:33:55 -05:00
|
|
|
class XMLWriter : public Print
|
2013-11-06 16:32:29 -05:00
|
|
|
{
|
|
|
|
public:
|
2020-05-25 03:58:04 -04:00
|
|
|
// default = Serial
|
2021-11-11 14:36:58 -05:00
|
|
|
XMLWriter(Print* stream = &Serial, uint8_t bufferSize = 10);
|
2020-05-25 03:58:04 -04:00
|
|
|
~XMLWriter();
|
2017-12-09 05:58:17 -05:00
|
|
|
|
|
|
|
void reset();
|
|
|
|
|
2020-05-25 03:58:04 -04:00
|
|
|
// to show/strip comment, indent, newLine
|
|
|
|
// to minimize the output setConfig(0);
|
2021-11-11 14:36:58 -05:00
|
|
|
void setConfig(uint8_t config) { _config = config; };
|
2020-05-25 03:58:04 -04:00
|
|
|
|
2017-12-09 05:58:17 -05:00
|
|
|
// standard XML header
|
|
|
|
void header();
|
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
// prints XMLWRITER_VERSION as comment
|
|
|
|
void version();
|
|
|
|
|
|
|
|
// prints debug information into the XML as comment
|
|
|
|
void debug();
|
|
|
|
|
|
|
|
|
2017-12-09 05:58:17 -05:00
|
|
|
// if multiline == true it does not indent to allow bigger text blocks
|
|
|
|
// <!-- text -->
|
2020-05-25 03:58:04 -04:00
|
|
|
void comment(const char* text, const bool multiLine = false);
|
|
|
|
|
|
|
|
// add a number of newlines to the output, default = 1.
|
|
|
|
void newLine(uint8_t n = 1);
|
2017-12-09 05:58:17 -05:00
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
// TAG
|
|
|
|
//
|
2017-12-09 05:58:17 -05:00
|
|
|
// <tag>
|
2020-05-25 03:58:04 -04:00
|
|
|
void tagOpen(const char* tag, const bool newline = true);
|
2017-12-09 05:58:17 -05:00
|
|
|
// <tag name="name">
|
2020-05-25 03:58:04 -04:00
|
|
|
void tagOpen(const char* tag, const char* name, const bool newline = true);
|
2017-12-09 05:58:17 -05:00
|
|
|
// </tag>
|
2020-05-25 03:58:04 -04:00
|
|
|
void tagClose(const bool ind = true);
|
2017-12-09 05:58:17 -05:00
|
|
|
|
|
|
|
// <tag
|
|
|
|
void tagStart(const char* tag);
|
|
|
|
// field="value"
|
|
|
|
void tagField(const char* field, const char* value);
|
|
|
|
// />
|
2020-05-25 03:58:04 -04:00
|
|
|
void tagEnd(const bool newline = true, const bool addSlash = true);
|
2017-12-09 05:58:17 -05:00
|
|
|
|
|
|
|
// <tag>value</tag>
|
|
|
|
void writeNode(const char* tag, const char* value);
|
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
|
|
|
|
// INDENT
|
|
|
|
//
|
2017-12-09 05:58:17 -05:00
|
|
|
// typically 0,2,4; default == 2;
|
2020-05-25 03:58:04 -04:00
|
|
|
// multiple of 2;
|
2021-01-29 06:31:58 -05:00
|
|
|
void setIndentSize(const uint8_t size = 2) { _indentStep = size; };
|
|
|
|
uint8_t getIndentSize() { return _indentStep; };
|
2017-12-09 05:58:17 -05:00
|
|
|
// for manual layout control
|
|
|
|
void incrIndent() { _indent += _indentStep; };
|
|
|
|
void decrIndent() { _indent -= _indentStep; };
|
|
|
|
void indent();
|
2020-05-25 03:58:04 -04:00
|
|
|
void raw(const char * str) { print(str); };
|
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
|
2020-05-25 03:58:04 -04:00
|
|
|
void tagField(const char* field, const uint8_t value, const uint8_t base = DEC);
|
|
|
|
void tagField(const char* field, const uint16_t value, const uint8_t base = DEC);
|
|
|
|
void tagField(const char* field, const uint32_t value, const uint8_t base = DEC);
|
|
|
|
void tagField(const char* field, const int8_t value, const uint8_t base = DEC);
|
|
|
|
void tagField(const char* field, const int16_t value, const uint8_t base = DEC);
|
|
|
|
void tagField(const char* field, const int32_t value, const uint8_t base = DEC);
|
2021-01-29 06:31:58 -05:00
|
|
|
void tagField(const char* field, const int value, const int base = DEC);
|
2020-05-25 03:58:04 -04:00
|
|
|
void tagField(const char* field, const bool value);
|
2021-01-29 06:31:58 -05:00
|
|
|
void tagField(const char* field, const float value, const uint8_t decimals = 2);
|
2020-05-25 03:58:04 -04:00
|
|
|
void tagField(const char* field, const double value, const uint8_t decimals = 2);
|
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
|
|
|
|
|
2020-05-25 03:58:04 -04:00
|
|
|
void writeNode(const char* tag, const uint8_t value, const uint8_t base = DEC);
|
|
|
|
void writeNode(const char* tag, const uint16_t value, const uint8_t base = DEC);
|
|
|
|
void writeNode(const char* tag, const uint32_t value, const uint8_t base = DEC);
|
|
|
|
void writeNode(const char* tag, const int8_t value, const uint8_t base = DEC);
|
|
|
|
void writeNode(const char* tag, const int16_t value, const uint8_t base = DEC);
|
|
|
|
void writeNode(const char* tag, const int32_t value, const uint8_t base = DEC);
|
2021-01-29 06:31:58 -05:00
|
|
|
void writeNode(const char* tag, const int value, const int base = DEC);
|
2017-12-09 05:58:17 -05:00
|
|
|
void writeNode(const char* tag, const bool value);
|
2021-01-29 06:31:58 -05:00
|
|
|
void writeNode(const char* tag, const float value, const uint8_t decimals = 2);
|
2020-05-25 03:58:04 -04:00
|
|
|
void writeNode(const char* tag, const double value, const uint8_t decimals = 2);
|
2013-11-06 16:32:29 -05:00
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
|
|
|
|
|
2013-11-08 11:13:13 -05:00
|
|
|
#ifdef XMLWRITER_ESCAPE_SUPPORT
|
2017-12-09 05:58:17 -05:00
|
|
|
// expands the special xml chars
|
|
|
|
void escape(const char* str);
|
2013-11-08 11:13:13 -05:00
|
|
|
#endif
|
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
|
|
|
|
// One need to call flush() at the end of writing to empty the internal buffer.
|
|
|
|
// Note: this is overridden of the Print interface
|
|
|
|
void flush();
|
|
|
|
|
|
|
|
|
2020-05-25 03:58:04 -04:00
|
|
|
// metrics
|
2021-11-11 14:36:58 -05:00
|
|
|
uint8_t bufferIndex() { return _bufferIndex; };
|
2021-01-29 06:31:58 -05:00
|
|
|
uint32_t bytesWritten() { return _bytesOut; };
|
|
|
|
|
2020-05-25 03:58:04 -04:00
|
|
|
|
2013-11-08 11:13:13 -05:00
|
|
|
private:
|
2021-11-11 14:36:58 -05:00
|
|
|
// output stream, Print Class
|
2020-05-25 03:58:04 -04:00
|
|
|
Print* _stream;
|
|
|
|
size_t write(uint8_t c);
|
2015-05-23 04:24:59 -04:00
|
|
|
|
2017-12-09 05:58:17 -05:00
|
|
|
// for indentation
|
2020-05-25 03:58:04 -04:00
|
|
|
uint8_t _indent;
|
|
|
|
uint8_t _indentStep;
|
|
|
|
|
|
|
|
// configuration
|
|
|
|
uint8_t _config;
|
2013-11-07 14:02:40 -05:00
|
|
|
|
2017-12-09 05:58:17 -05:00
|
|
|
// stack - used to remember the current tagname to create
|
|
|
|
// automatic the right close tag.
|
2021-11-11 14:36:58 -05:00
|
|
|
uint8_t _tagIndex;
|
2020-05-25 03:58:04 -04:00
|
|
|
char _tagStack[XMLWRITER_MAXLEVEL][XMLWRITER_MAXTAGSIZE + 1];
|
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
// output admin
|
2020-05-25 03:58:04 -04:00
|
|
|
char * _buffer;
|
2021-11-11 14:36:58 -05:00
|
|
|
uint8_t _bufferSize;
|
|
|
|
uint8_t _bufferIndex;
|
2020-05-25 03:58:04 -04:00
|
|
|
uint32_t _bytesOut;
|
2013-11-06 16:32:29 -05:00
|
|
|
};
|
|
|
|
|
2021-11-11 14:36:58 -05:00
|
|
|
|
2020-05-25 03:58:04 -04:00
|
|
|
// -- END OF FILE --
|
2021-11-11 14:36:58 -05:00
|
|
|
|