mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
0.2.2 major updates XMLWriter
This commit is contained in:
parent
6680ecdffd
commit
5b156b7099
21
libraries/XMLWriter/LICENSE
Normal file
21
libraries/XMLWriter/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2013-2020 Rob Tillaart
|
||||
|
||||
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.
|
35
libraries/XMLWriter/README.md
Normal file
35
libraries/XMLWriter/README.md
Normal file
@ -0,0 +1,35 @@
|
||||
# XMLWriter
|
||||
|
||||
Arduino Library to create simple XML (messages, files, print, ...)
|
||||
|
||||
## Description
|
||||
|
||||
The XMLWriter class supports generating XML files and send these over a stream
|
||||
like Ethernet SD.File or Serial.
|
||||
|
||||
When instantiating an XMLWriter one can define the internal buffer size.
|
||||
This buffering makes the output faster, especially for Ethernet and SD.File.
|
||||
The buffer size should be at least 2 bytes.
|
||||
A bigger buffer is often faster but it also depends on the properties of the
|
||||
stream to see real performance gains.
|
||||
E.g. the baudrate and internal buffer of Serial, packet behaviour of Ethernet,
|
||||
or paging of SD cards.
|
||||
So if performance is an issue one should do some testruns with different sizes
|
||||
for the buffer and choose one that is appropriate.
|
||||
|
||||
Indicative sizes based upon the examples.
|
||||
Run your tests to find your application optimum.
|
||||
|
||||
| STREAM | SIZE |
|
||||
|:------------|:----------|
|
||||
| Ethernet | 20-30 |
|
||||
| Serial | 5 |
|
||||
| SD File | 10-16 |
|
||||
|
||||
Important to know when usinig buffering is that your code should always include
|
||||
a call to **XML.flush()** at the end of the XML generation to flush the buffer.
|
||||
|
||||
## Operation
|
||||
|
||||
See examples
|
||||
|
@ -1,9 +1,9 @@
|
||||
//
|
||||
// FILE: XMLWriter.cpp
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.8
|
||||
// VERSION: 0.2.2
|
||||
// DATE: 2013-11-06
|
||||
// PURPOSE: Simple XML library
|
||||
// PURPOSE: Arduino library for creating XML
|
||||
//
|
||||
// HISTORY:
|
||||
// 0.1.00 2013-11-06 initial version
|
||||
@ -15,39 +15,62 @@
|
||||
// 0.1.6 2016-03-16 added incrIndent(), decrIndent(), indent(), raw();
|
||||
// 0.1.7 2017-07-26 added const where possible
|
||||
// 0.1.8 2017-12-09 fix casting issue #83 (long -> int32_t);
|
||||
//
|
||||
// Released to the public domain
|
||||
// 0.1.9 2017-12-09 add PROGMEM support for escape() strings
|
||||
// 0.2.0 2020-04-24 refactor, added examples, #pragma, print as base class
|
||||
// 0.2.1 2020-04-26 performance optimized, setconfig() + newLine() added
|
||||
// 0.2.2 2020-04-29 dynamic buffer size in constructor
|
||||
//
|
||||
|
||||
#include <XMLWriter.h>
|
||||
|
||||
XMLWriter::XMLWriter(Print* stream)
|
||||
XMLWriter::XMLWriter(Print* stream, uint8_t bufsize)
|
||||
{
|
||||
_bufsize = constrain(bufsize, 2, 250);
|
||||
_buffer = (char *) malloc(_bufsize);
|
||||
_stream = stream;
|
||||
reset();
|
||||
}
|
||||
|
||||
XMLWriter::~XMLWriter()
|
||||
{
|
||||
if (_buffer != NULL) free(_buffer);
|
||||
}
|
||||
|
||||
void XMLWriter::reset()
|
||||
{
|
||||
_indent = 0;
|
||||
_indentStep = 2;
|
||||
_idx = 0;
|
||||
_tidx = 0;
|
||||
_bidx = 0;
|
||||
_config = XMLWRITER_COMMENT | XMLWRITER_INDENT | XMLWRITER_NEWLINE;
|
||||
_bytesOut = 0;
|
||||
}
|
||||
|
||||
void XMLWriter::header()
|
||||
{
|
||||
_stream->println(F("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"));
|
||||
print(F("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"));
|
||||
}
|
||||
|
||||
void XMLWriter::comment(const char* text, const bool multiLine)
|
||||
{
|
||||
_stream->println();
|
||||
if (!multiLine) indent();
|
||||
_stream->print(F("<!-- "));
|
||||
if (multiLine) _stream->println();
|
||||
_stream->print(text);
|
||||
if (multiLine) _stream->println();
|
||||
_stream->println(F(" -->"));
|
||||
if (_config & XMLWRITER_COMMENT)
|
||||
{
|
||||
print('\n');
|
||||
if (!multiLine) indent();
|
||||
print(F("<!-- "));
|
||||
if (multiLine) print('\n');
|
||||
print(text);
|
||||
if (multiLine) print('\n');
|
||||
print(F(" -->\n"));
|
||||
}
|
||||
}
|
||||
|
||||
void XMLWriter::newLine(uint8_t n)
|
||||
{
|
||||
if (_config & XMLWRITER_NEWLINE)
|
||||
{
|
||||
while(n--) print('\n');
|
||||
}
|
||||
}
|
||||
|
||||
void XMLWriter::tagOpen(const char* tag, const bool newline)
|
||||
@ -57,8 +80,15 @@ void XMLWriter::tagOpen(const char* tag, const bool newline)
|
||||
|
||||
void XMLWriter::tagOpen(const char* tag, const char* name, const bool newline)
|
||||
{
|
||||
// TODO STACK GUARD
|
||||
strncpy(tagStack[_idx++], tag, XMLWRITER_MAXTAGSIZE);
|
||||
if (_tidx > XMLWRITER_MAXLEVEL)
|
||||
{
|
||||
comment("XMLWRITER_MAXLEVEL exceeded.");
|
||||
comment(tag);
|
||||
comment(name);
|
||||
return;
|
||||
}
|
||||
// "unsafe" strcpy saves ~20 bytes
|
||||
strncpy(_tagStack[_tidx++], tag, XMLWRITER_MAXTAGSIZE);
|
||||
tagStart(tag);
|
||||
if (name[0] != 0) tagField("name", name);
|
||||
tagEnd(newline, NOSLASH);
|
||||
@ -69,36 +99,37 @@ void XMLWriter::tagClose(const bool ind)
|
||||
{
|
||||
_indent -= _indentStep;
|
||||
if (ind) indent();
|
||||
_stream->print(F("</"));
|
||||
_stream->print(tagStack[--_idx]);
|
||||
_stream->println(F(">"));
|
||||
print("</");
|
||||
print(_tagStack[--_tidx]);
|
||||
print(">\n");
|
||||
delay(10);
|
||||
}
|
||||
|
||||
void XMLWriter::tagStart(const char *tag)
|
||||
{
|
||||
indent();
|
||||
_stream->print('<');
|
||||
_stream->print(tag);
|
||||
print('<');
|
||||
print(tag);
|
||||
}
|
||||
|
||||
void XMLWriter::tagField(const char *field, const char* str)
|
||||
{
|
||||
_stream->print(' ');
|
||||
_stream->print(field);
|
||||
_stream->print(F("=\""));
|
||||
print(' ');
|
||||
print(field);
|
||||
print("=\"");
|
||||
#ifdef XMLWRITER_ESCAPE_SUPPORT
|
||||
escape(str);
|
||||
#else
|
||||
_stream->print(str);
|
||||
print(str);
|
||||
#endif
|
||||
_stream->print('"');
|
||||
print('"');
|
||||
}
|
||||
|
||||
void XMLWriter::tagEnd(const bool newline, const bool addSlash)
|
||||
{
|
||||
if (addSlash) _stream->print('/');
|
||||
_stream->print('>');
|
||||
if (newline) _stream->println();
|
||||
if (addSlash) print("/>");
|
||||
else print('>');
|
||||
if (newline) print('\n');
|
||||
}
|
||||
|
||||
void XMLWriter::writeNode(const char* tag, const char* str)
|
||||
@ -107,7 +138,7 @@ void XMLWriter::writeNode(const char* tag, const char* str)
|
||||
#ifdef XMLWRITER_ESCAPE_SUPPORT
|
||||
escape(str);
|
||||
#else
|
||||
_stream->print(str);
|
||||
print(str);
|
||||
#endif
|
||||
tagClose(NOINDENT);
|
||||
}
|
||||
@ -129,11 +160,11 @@ void XMLWriter::tagField(const char *field, const uint16_t value, const uint8_t
|
||||
|
||||
void XMLWriter::tagField(const char *field, const uint32_t value, const uint8_t base)
|
||||
{
|
||||
_stream->print(' ');
|
||||
_stream->print(field);
|
||||
_stream->print(F("=\""));
|
||||
_stream->print(value, base);
|
||||
_stream->print('"');
|
||||
print(' ');
|
||||
print(field);
|
||||
print("=\"");
|
||||
print(value, base);
|
||||
print('"');
|
||||
}
|
||||
|
||||
void XMLWriter::tagField(const char *field, const int8_t value, const uint8_t base)
|
||||
@ -148,30 +179,28 @@ void XMLWriter::tagField(const char *field, const int16_t value, const uint8_t b
|
||||
|
||||
void XMLWriter::tagField(const char *field, const int32_t value, const uint8_t base)
|
||||
{
|
||||
_stream->print(' ');
|
||||
_stream->print(field);
|
||||
_stream->print(F("=\""));
|
||||
_stream->print(value, base);
|
||||
_stream->print('"');
|
||||
print(' ');
|
||||
print(field);
|
||||
print("=\"");
|
||||
print(value, base);
|
||||
print('"');
|
||||
}
|
||||
|
||||
|
||||
void XMLWriter::tagField(const char *field, const bool value)
|
||||
{
|
||||
_stream->print(' ');
|
||||
_stream->print(field);
|
||||
_stream->print(F("=\""));
|
||||
_stream->print(value?F("true"):F("false"));
|
||||
_stream->print('"');
|
||||
print(' ');
|
||||
print(field);
|
||||
// F() is slower & uses less RAM but 15 bytes saved
|
||||
print(value ? F("=\"true\"") : F("=\"false\""));
|
||||
}
|
||||
|
||||
void XMLWriter::tagField(const char *field, const double value, const uint8_t decimals)
|
||||
{
|
||||
_stream->print(' ');
|
||||
_stream->print(field);
|
||||
_stream->print(F("=\""));
|
||||
_stream->print(value, decimals);
|
||||
_stream->print('"');
|
||||
print(' ');
|
||||
print(field);
|
||||
print(F("=\""));
|
||||
print(value, decimals);
|
||||
print('"');
|
||||
}
|
||||
|
||||
void XMLWriter::writeNode(const char* tag, const uint8_t value, const uint8_t base)
|
||||
@ -187,7 +216,7 @@ void XMLWriter::writeNode(const char* tag, const uint16_t value, const uint8_t b
|
||||
void XMLWriter::writeNode(const char* tag, const uint32_t value, const uint8_t base)
|
||||
{
|
||||
tagOpen(tag, "", NONEWLINE);
|
||||
_stream->print(value, base); // todo: leading zero's
|
||||
print(value, base);
|
||||
tagClose(NOINDENT);
|
||||
}
|
||||
|
||||
@ -204,46 +233,106 @@ void XMLWriter::writeNode(const char* tag, const int16_t value, const uint8_t ba
|
||||
void XMLWriter::writeNode(const char* tag, const int32_t value, const uint8_t base)
|
||||
{
|
||||
tagOpen(tag, "", NONEWLINE);
|
||||
_stream->print(value, base); // todo: leading zero's
|
||||
print(value, base);
|
||||
tagClose(NOINDENT);
|
||||
}
|
||||
|
||||
void XMLWriter::writeNode(const char* tag, const bool value)
|
||||
{
|
||||
tagOpen(tag, "", NONEWLINE);
|
||||
_stream->print(value?F("true"):F("false"));
|
||||
// F() is slower & uses less RAM but saves 9 bytes
|
||||
print(value ? F("true") : F("false"));
|
||||
tagClose(NOINDENT);
|
||||
}
|
||||
|
||||
void XMLWriter::writeNode(const char* tag, const double value, const uint8_t decimals)
|
||||
{
|
||||
tagOpen(tag, "", NONEWLINE);
|
||||
_stream->print(value, decimals);
|
||||
print(value, decimals);
|
||||
tagClose(NOINDENT);
|
||||
}
|
||||
|
||||
void XMLWriter::indent()
|
||||
{
|
||||
for (uint8_t i=_indent; i>0; i--) _stream->print(' ');
|
||||
if (_config & XMLWRITER_INDENT)
|
||||
{
|
||||
// as indentation is a multiple of 2
|
||||
// this is nice balance between speed and RAM.
|
||||
for (uint8_t i = _indent; i > 0; i-= 2) print(" ");
|
||||
}
|
||||
}
|
||||
|
||||
size_t XMLWriter::write(uint8_t c)
|
||||
{
|
||||
_buffer[_bidx++] = c;
|
||||
if (_bidx == (_bufsize - 1)) flush();
|
||||
return 1;
|
||||
};
|
||||
|
||||
void XMLWriter::flush()
|
||||
{
|
||||
_bytesOut += _bidx;
|
||||
if (_bidx > 0)
|
||||
{
|
||||
_buffer[_bidx] = 0;
|
||||
_stream->print(_buffer);
|
||||
_bidx = 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ESCAPE
|
||||
//
|
||||
|
||||
#ifdef XMLWRITER_ESCAPE_SUPPORT
|
||||
char c[6] = "\"\'<>&";
|
||||
char expanded[][7] = { """, "'","<",">","&"}; // todo in flash
|
||||
static char c[6] = "\"\'<>&";
|
||||
|
||||
#ifdef __PROGMEM__
|
||||
PROGMEM const char quote[] = """;
|
||||
PROGMEM const char apostrophe[] = "'";
|
||||
PROGMEM const char lessthen[] = "<";
|
||||
PROGMEM const char greaterthen[] = ">";
|
||||
PROGMEM const char ampersand[] = "&";
|
||||
|
||||
PROGMEM const char* const expanded[] =
|
||||
{
|
||||
quote, apostrophe, lessthen, greaterthen, ampersand
|
||||
};
|
||||
|
||||
#else
|
||||
// NOTE: & and ; are handled in code. // 25 bytes RAM
|
||||
static char expanded[][5] = { "quot", "apos","lt","gt","amp"};
|
||||
|
||||
#endif
|
||||
|
||||
void XMLWriter::escape(const char* str)
|
||||
{
|
||||
char* p = (char *)str;
|
||||
while(*p != 0)
|
||||
while (*p != 0)
|
||||
{
|
||||
char* q = strchr(c, *p);
|
||||
if (q == NULL) _stream->print(*p);
|
||||
else _stream->print(expanded[q - c]); // uint8_t idx = q-c;
|
||||
if (q == NULL) print(*p);
|
||||
#ifdef __PROGMEM__
|
||||
else
|
||||
{
|
||||
char buf[8];
|
||||
strcpy_P(buf, (char*)pgm_read_word(&(expanded[q - c])));
|
||||
print(buf);
|
||||
}
|
||||
#else
|
||||
else
|
||||
{
|
||||
print('&');
|
||||
print(expanded[q - c]); // uint8_t idx = q-c;
|
||||
print(';');
|
||||
}
|
||||
#endif
|
||||
p++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// END OF FILE
|
||||
|
||||
// -- END OF FILE --
|
||||
|
@ -1,19 +1,15 @@
|
||||
#ifndef XML_WRITER_H
|
||||
#define XML_WRITER_H
|
||||
#pragma once
|
||||
//
|
||||
// FILE: XMLWriter.h
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.8
|
||||
// VERSION: 0.2.2
|
||||
// DATE: 2013-11-06
|
||||
// PURPOSE: Simple XML writer library
|
||||
//
|
||||
// Released to the public domain
|
||||
// PURPOSE: Arduino library for creating XML
|
||||
//
|
||||
|
||||
#include "Arduino.h"
|
||||
// no pre 1.0 support!
|
||||
|
||||
#define XMLWRITER_VERSION "0.1.8"
|
||||
#define XMLWRITER_VERSION "0.2.2"
|
||||
|
||||
// for comment()
|
||||
#define NOMULTILINE false
|
||||
@ -30,88 +26,129 @@
|
||||
|
||||
// deepness of XML tree 5..10
|
||||
// needed for stack of tagStack
|
||||
#ifndef XMLWRITER_MAXLEVEL
|
||||
#define XMLWRITER_MAXLEVEL 5 // adjust for deeper nested structures
|
||||
#define XMLWRITER_MAXTAGSIZE 15 // adjust for longer fields - !! eats memory !!
|
||||
#endif
|
||||
|
||||
#ifndef XMLWRITER_MAXTAGSIZE
|
||||
#define XMLWRITER_MAXTAGSIZE 15 // adjust for longer fields - !! eats memory !!
|
||||
#endif
|
||||
|
||||
// reduce footprint by commenting next line
|
||||
#define XMLWRITER_ESCAPE_SUPPORT
|
||||
|
||||
class XMLWriter
|
||||
// configuration - setConfig
|
||||
#define XMLWRITER_NONE 0x00
|
||||
#define XMLWRITER_COMMENT 0x01
|
||||
#define XMLWRITER_INDENT 0x02
|
||||
#define XMLWRITER_NEWLINE 0x04
|
||||
|
||||
// uncomment next line to reduce ~30bytes RAM in escape() (AVR oonly)
|
||||
// #define __PROGMEM__
|
||||
|
||||
|
||||
class XMLWriter : Print
|
||||
{
|
||||
public:
|
||||
XMLWriter(Print* stream);
|
||||
// default = Serial
|
||||
XMLWriter(Print* stream = &Serial, uint8_t bufsize = 10);
|
||||
~XMLWriter();
|
||||
|
||||
void reset();
|
||||
|
||||
// to show/strip comment, indent, newLine
|
||||
// to minimize the output setConfig(0);
|
||||
void setConfig(uint8_t cfg) { _config = cfg; };
|
||||
|
||||
// standard XML header
|
||||
void header();
|
||||
|
||||
// if multiline == true it does not indent to allow bigger text blocks
|
||||
// <!-- text -->
|
||||
void comment(const char* text, const bool multiLine=false);
|
||||
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);
|
||||
|
||||
// <tag>
|
||||
void tagOpen(const char* tag, const bool newline=true);
|
||||
void tagOpen(const char* tag, const bool newline = true);
|
||||
// <tag name="name">
|
||||
void tagOpen(const char* tag, const char* name, const bool newline=true);
|
||||
void tagOpen(const char* tag, const char* name, const bool newline = true);
|
||||
// </tag>
|
||||
void tagClose(const bool ind=true);
|
||||
void tagClose(const bool ind = true);
|
||||
|
||||
// <tag
|
||||
void tagStart(const char* tag);
|
||||
// field="value"
|
||||
void tagField(const char* field, const char* value);
|
||||
// />
|
||||
void tagEnd(const bool newline=true, const bool addSlash=true);
|
||||
void tagEnd(const bool newline = true, const bool addSlash = true);
|
||||
|
||||
// <tag>value</tag>
|
||||
void writeNode(const char* tag, const char* value);
|
||||
|
||||
// typically 0,2,4; default == 2;
|
||||
// multiple of 2;
|
||||
void setIndentSize(const uint8_t size = 2);
|
||||
|
||||
// for manual layout control
|
||||
void incrIndent() { _indent += _indentStep; };
|
||||
void decrIndent() { _indent -= _indentStep; };
|
||||
void indent();
|
||||
void raw(const char * str) { _stream->print(str); }; // TODO Q:other types?
|
||||
void raw(const char * str) { print(str); };
|
||||
|
||||
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);
|
||||
void tagField(const char *field, const bool value);
|
||||
void tagField(const char* field, const double value, const uint8_t decimals=2);
|
||||
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);
|
||||
void tagField(const char* field, const bool value);
|
||||
void tagField(const char* field, const double value, const uint8_t decimals = 2);
|
||||
|
||||
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);
|
||||
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);
|
||||
void writeNode(const char* tag, const bool value);
|
||||
void writeNode(const char* tag, const double value, const uint8_t decimals=2);
|
||||
void writeNode(const char* tag, const double value, const uint8_t decimals = 2);
|
||||
|
||||
#ifdef XMLWRITER_ESCAPE_SUPPORT
|
||||
// expands the special xml chars
|
||||
void escape(const char* str);
|
||||
#endif
|
||||
|
||||
// One need to call flush() at the end of writing to empty
|
||||
// the internal buffer.
|
||||
void flush();
|
||||
|
||||
// metrics
|
||||
uint8_t bufferIndex() { return _bidx; };
|
||||
uint32_t bytesWritten() { return _bytesOut; } ;
|
||||
|
||||
private:
|
||||
// outputstream
|
||||
Print* _stream;
|
||||
// outputstream, Print Class
|
||||
Print* _stream;
|
||||
size_t write(uint8_t c);
|
||||
|
||||
// for indentation
|
||||
uint8_t _indent;
|
||||
uint8_t _indentStep;
|
||||
uint8_t _indent;
|
||||
uint8_t _indentStep;
|
||||
|
||||
// configuration
|
||||
uint8_t _config;
|
||||
|
||||
// stack - used to remember the current tagname to create
|
||||
// automatic the right close tag.
|
||||
uint8_t _idx;
|
||||
char tagStack[XMLWRITER_MAXLEVEL][XMLWRITER_MAXTAGSIZE+1];
|
||||
uint8_t _tidx;
|
||||
char _tagStack[XMLWRITER_MAXLEVEL][XMLWRITER_MAXTAGSIZE + 1];
|
||||
|
||||
char * _buffer;
|
||||
uint8_t _bufsize;
|
||||
uint8_t _bidx;
|
||||
uint32_t _bytesOut;
|
||||
};
|
||||
|
||||
#endif
|
||||
// END OF FILE
|
||||
// -- END OF FILE --
|
||||
|
@ -1,12 +1,10 @@
|
||||
//
|
||||
// FILE: KMLWriterTest.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.01
|
||||
// VERSION: 0.1.3
|
||||
// PURPOSE: simple KML writer
|
||||
// DATE: 2015-05-21
|
||||
// URL:
|
||||
//
|
||||
// Released to the public domain
|
||||
// URL: https://github.com/RobTillaart/XMLWriter
|
||||
//
|
||||
|
||||
#include <XMLWriter.h>
|
||||
@ -19,7 +17,11 @@ void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
|
||||
uint32_t start = micros();
|
||||
KMLTest();
|
||||
uint32_t stop = micros();
|
||||
Serial.println();
|
||||
Serial.println(stop - start);
|
||||
}
|
||||
|
||||
void loop()
|
||||
@ -86,3 +88,6 @@ This is a demo of the XMLWriter lib for Arduino
|
||||
</Document>
|
||||
</kml>
|
||||
*/
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
|
@ -0,0 +1,122 @@
|
||||
//
|
||||
// FILE: XMLWriterDefaultSerial.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.1
|
||||
// PURPOSE: make a simple XML generating lib
|
||||
// DATE: 2020-04-24
|
||||
// URL: https://github.com/RobTillaart/XMLWriter
|
||||
//
|
||||
|
||||
#include <XMLWriter.h>
|
||||
|
||||
XMLWriter XML;
|
||||
|
||||
char buffer[24];
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
uint32_t start = micros();
|
||||
XML.header();
|
||||
XML.comment("XMLWriterTest.ino\nThis is a demo of a simple XML lib for Arduino", true);
|
||||
|
||||
XML.tagOpen("Arduino", "42");
|
||||
|
||||
XML.tagOpen("Ports");
|
||||
AnalogPorts("before");
|
||||
DigitalPorts();
|
||||
AnalogPorts("after");
|
||||
XML.tagClose();
|
||||
|
||||
Weather();
|
||||
Weather2();
|
||||
DataTypes();
|
||||
|
||||
XML.tagClose();
|
||||
|
||||
uint32_t stop = micros();
|
||||
Serial.println();
|
||||
Serial.println(stop - start);
|
||||
}
|
||||
|
||||
void Weather2()
|
||||
{
|
||||
XML.comment("The weather in South Africa");
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
XML.tagStart("Weather");
|
||||
XML.tagField("Date", "20131106");
|
||||
XML.tagField("Time", "1:42");
|
||||
XML.tagField("Temp", "23.4");
|
||||
XML.tagField("Humi", "50%");
|
||||
XML.tagField("Rain", "10mm");
|
||||
XML.tagField("Sun", "40");
|
||||
XML.tagEnd();
|
||||
}
|
||||
}
|
||||
|
||||
void Weather()
|
||||
{
|
||||
XML.comment("The weather in Nebraska");
|
||||
XML.tagOpen("Weather");
|
||||
XML.writeNode("Date", "20131106");
|
||||
XML.writeNode("Time", "11:42");
|
||||
XML.writeNode("Temp", "23.4");
|
||||
XML.writeNode("Humi", "50%");
|
||||
XML.writeNode("Rain", "10mm");
|
||||
XML.writeNode("Sun", "40");
|
||||
XML.tagClose();
|
||||
}
|
||||
|
||||
void AnalogPorts(const char* name)
|
||||
{
|
||||
XML.comment("The analog ports are multiplexed");
|
||||
XML.tagOpen("Analog", name);
|
||||
XML.writeNode("Analog0", itoa(analogRead(A0), buffer, 10));
|
||||
XML.writeNode("Analog1", analogRead(A1));
|
||||
XML.writeNode("Analog2", (5.0 * analogRead(A2)) / 1023); // default nr decimals = 2
|
||||
XML.writeNode("Analog3", (5.0 * analogRead(A2)) / 1023, 3);
|
||||
XML.tagClose();
|
||||
}
|
||||
|
||||
void DigitalPorts()
|
||||
{
|
||||
XML.comment("The digital ports are not multiplexed");
|
||||
XML.tagOpen("Digital");
|
||||
XML.writeNode("D1", itoa(digitalRead(1), buffer, 10));
|
||||
XML.writeNode("D13", digitalRead(13));
|
||||
XML.tagClose();
|
||||
}
|
||||
|
||||
void DataTypes()
|
||||
{
|
||||
XML.comment("Testing dataTypes I");
|
||||
XML.tagOpen("Datatypes");
|
||||
XML.writeNode("Bool", 1 == 1);
|
||||
XML.writeNode("Bool", 1 == 0);
|
||||
XML.writeNode("BIN", 42, BIN);
|
||||
XML.writeNode("DEC", 42, DEC);
|
||||
XML.writeNode("HEX", 42, HEX);
|
||||
XML.writeNode("OCT", 42, OCT);
|
||||
XML.tagClose();
|
||||
|
||||
XML.comment("Testing dataTypes II");
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
XML.tagStart("dataTypes");
|
||||
XML.tagField("Bool", 1 == 1);
|
||||
XML.tagField("Bool", 1 == 0);
|
||||
int x = analogRead(A0);
|
||||
XML.tagField("BIN", x, BIN);
|
||||
XML.tagField("DEC", x, DEC);
|
||||
XML.tagField("HEX", x, HEX);
|
||||
XML.tagField("OCT", x, OCT);
|
||||
XML.tagEnd();
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
||||
// -- END OF FILE --
|
@ -0,0 +1,69 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
XMLWriterTest.ino
|
||||
This is a demo of a simple XML lib for Arduino
|
||||
-->
|
||||
<Arduino name="42">
|
||||
<Ports>
|
||||
|
||||
<!-- The analog ports are multiplexed -->
|
||||
<Analog name="before">
|
||||
<Analog0>389</Analog0>
|
||||
<Analog1>332</Analog1>
|
||||
<Analog2>1.55</Analog2>
|
||||
<Analog3>1.544</Analog3>
|
||||
</Analog>
|
||||
|
||||
<!-- The digital ports are not multiplexed -->
|
||||
<Digital>
|
||||
<D1>0</D1>
|
||||
<D13>1</D13>
|
||||
</Digital>
|
||||
|
||||
<!-- The analog ports are multiplexed -->
|
||||
<Analog name="after">
|
||||
<Analog0>343</Analog0>
|
||||
<Analog1>366</Analog1>
|
||||
<Analog2>1.94</Analog2>
|
||||
<Analog3>1.926</Analog3>
|
||||
</Analog>
|
||||
</Ports>
|
||||
|
||||
<!-- The weather in Nebraska -->
|
||||
<Weather>
|
||||
<Date>20131106</Date>
|
||||
<Time>11:42</Time>
|
||||
<Temp>23.4</Temp>
|
||||
<Humi>50%</Humi>
|
||||
<Rain>10mm</Rain>
|
||||
<Sun>40</Sun>
|
||||
</Weather>
|
||||
|
||||
<!-- The weather in South Africa -->
|
||||
<Weather Date="20131106" Time="1:42" Temp="23.4" Humi="50%" Rain="10mm" Sun="40"/>
|
||||
<Weather Date="20131106" Time="1:42" Temp="23.4" Humi="50%" Rain="10mm" Sun="40"/>
|
||||
<Weather Date="20131106" Time="1:42" Temp="23.4" Humi="50%" Rain="10mm" Sun="40"/>
|
||||
<Weather Date="20131106" Time="1:42" Temp="23.4" Humi="50%" Rain="10mm" Sun="40"/>
|
||||
<Weather Date="20131106" Time="1:42" Temp="23.4" Humi="50%" Rain="10mm" Sun="40"/>
|
||||
<Weather Date="20131106" Time="1:42" Temp="23.4" Humi="50%" Rain="10mm" Sun="40"/>
|
||||
<Weather Date="20131106" Time="1:42" Temp="23.4" Humi="50%" Rain="10mm" Sun="40"/>
|
||||
<Weather Date="20131106" Time="1:42" Temp="23.4" Humi="50%" Rain="10mm" Sun="40"/>
|
||||
<Weather Date="20131106" Time="1:42" Temp="23.4" Humi="50%" Rain="10mm" Sun="40"/>
|
||||
<Weather Date="20131106" Time="1:42" Temp="23.4" Humi="50%" Rain="10mm" Sun="40"/>
|
||||
|
||||
<!-- Testing dataTypes I -->
|
||||
<Datatypes>
|
||||
<Bool>true</Bool>
|
||||
<Bool>false</Bool>
|
||||
<BIN>101010</BIN>
|
||||
<DEC>42</DEC>
|
||||
<HEX>2A</HEX>
|
||||
<OCT>52</OCT>
|
||||
</Datatypes>
|
||||
|
||||
<!-- Testing dataTypes II -->
|
||||
<dataTypes Bool="true" Bool="false" BIN="101110111" DEC="375" HEX="177" OCT="567"/>
|
||||
<dataTypes Bool="true" Bool="false" BIN="101010010" DEC="338" HEX="152" OCT="522"/>
|
||||
<dataTypes Bool="true" Bool="false" BIN="101111010" DEC="378" HEX="17A" OCT="572"/>
|
||||
</Arduino>
|
@ -0,0 +1,271 @@
|
||||
//
|
||||
// FILE: XMLWriterEthernet.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.0
|
||||
// PURPOSE: demo XML writer for EthernetClient
|
||||
// DATE: 2020-04-24
|
||||
// URL:
|
||||
//
|
||||
|
||||
#include <XMLWriter.h>
|
||||
|
||||
#include <SPI.h>
|
||||
#include <Ethernet.h>
|
||||
|
||||
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
|
||||
IPAddress ip( 192, 168, 1, 177);
|
||||
|
||||
const int EthernetPIN = 10;
|
||||
|
||||
EthernetServer server(80); // change to your config
|
||||
|
||||
char httpRequest[40];
|
||||
uint8_t reqCnt;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// HTTP HELPER CODE
|
||||
//
|
||||
void HTTP_header(EthernetClient* cl, const char *contentType, bool keepAlive = false, int refresh = 5)
|
||||
{
|
||||
cl->println("HTTP/1.1 200 OK");
|
||||
cl->print("Content-Type: ");
|
||||
cl->println( contentType );
|
||||
cl->println("Connection: ");
|
||||
cl->println(keepAlive ? "keep-alive":"close");
|
||||
cl->println("Refresh: ");
|
||||
cl->println(refresh);
|
||||
cl->println();
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Based upon webServer example demo
|
||||
//
|
||||
void setup()
|
||||
{
|
||||
|
||||
Serial.begin(115200);
|
||||
Serial.println(__FILE__);
|
||||
|
||||
// Ethernet.init(pin) to configure the CS pin
|
||||
Ethernet.init(EthernetPIN);
|
||||
Ethernet.begin(mac, ip);
|
||||
|
||||
if (Ethernet.hardwareStatus() == EthernetNoHardware)
|
||||
{
|
||||
Serial.println("No hardware found");
|
||||
while (1);
|
||||
}
|
||||
|
||||
if (Ethernet.linkStatus() == LinkOFF)
|
||||
{
|
||||
Serial.println("Cable is not connected.");
|
||||
Serial.println("Connect cable");
|
||||
}
|
||||
while (Ethernet.linkStatus() == LinkOFF); // wait for cable
|
||||
|
||||
server.begin();
|
||||
Serial.print("ServerIP: ");
|
||||
Serial.println(Ethernet.localIP());
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
// listen for incoming clients
|
||||
EthernetClient client = server.available();
|
||||
|
||||
if (client)
|
||||
{
|
||||
Serial.print("\n<CONNECTION>\n ");
|
||||
// an http request ends with a blank line
|
||||
boolean currentLineIsBlank = true;
|
||||
reqCnt = 0;
|
||||
while (client.connected())
|
||||
{
|
||||
if (client.available())
|
||||
{
|
||||
char c = client.read();
|
||||
Serial.write(c); // collect HHTP request here..
|
||||
if (reqCnt < 39)
|
||||
{
|
||||
httpRequest[reqCnt++] = c;
|
||||
httpRequest[reqCnt] = 0;
|
||||
}
|
||||
|
||||
// if you've gotten to the end of the line (received a newline
|
||||
// character) and the line is blank, the http request has ended,
|
||||
// so you can send a reply
|
||||
if (c == '\n' && currentLineIsBlank)
|
||||
{
|
||||
if (strstr(httpRequest, "1.xml"))
|
||||
{
|
||||
// send a standard http response header
|
||||
HTTP_header(&client, "text/xml", true, 5);
|
||||
XMLWriter XML(&client);
|
||||
|
||||
// XML body
|
||||
XML.header();
|
||||
XML.comment("XMLWriterTest.ino\nThis is a demo of a simple XML lib for Arduino", true);
|
||||
|
||||
// use of {} to get indentation that follows the XML (sort of)
|
||||
// it adds no code size, but improves readability a lot
|
||||
XML.tagOpen("Arduino", "42");
|
||||
{
|
||||
XML.tagOpen("Ports");
|
||||
{
|
||||
AnalogPorts(XML, "before");
|
||||
DigitalPorts(XML);
|
||||
AnalogPorts(XML,"after");
|
||||
}
|
||||
XML.tagClose();
|
||||
}
|
||||
XML.tagClose();
|
||||
break;
|
||||
}
|
||||
if (strstr(httpRequest, "2.xml"))
|
||||
{
|
||||
// send a standard http response header
|
||||
HTTP_header(&client, "text/xml", true, 5);
|
||||
XMLWriter XML(&client);
|
||||
|
||||
// XML body
|
||||
XML.header();
|
||||
XML.comment("XMLWriterTest.ino\nThis is a demo of a simple XML lib for Arduino", true);
|
||||
|
||||
// use of {} to get indentation that follows the XML (sort of)
|
||||
// it adds no code size, but improves readability a lot
|
||||
XML.tagOpen("Arduino", "102");
|
||||
{
|
||||
Weather(XML);
|
||||
Weather2(XML);
|
||||
DataTypes(XML);
|
||||
}
|
||||
XML.tagClose();
|
||||
break;
|
||||
}
|
||||
|
||||
// default page is simple HTML
|
||||
// send a standard http response header
|
||||
HTTP_header(&client, "text/html", true, 5);
|
||||
|
||||
client.println("<!DOCTYPE HTML>");
|
||||
client.println("<html>");
|
||||
client.println("<head>");
|
||||
client.println("<title>Demo XML writer</title>");
|
||||
client.println("</head>");
|
||||
client.println("<body>");
|
||||
client.println("<h1>Demo XML writer for EthernetClient</h1>");
|
||||
client.println("<p>Get <a href=\"1.xml\">XML 1</a>.</p>");
|
||||
client.println("<p>Get <a href=\"2.xml\">XML 2</a>.</p>");
|
||||
client.println("</body>");
|
||||
client.println("</html>");
|
||||
break;
|
||||
}
|
||||
if (c == '\n') {
|
||||
Serial.print(" ");
|
||||
// you're starting a new line
|
||||
currentLineIsBlank = true;
|
||||
} else if (c != '\r') {
|
||||
// you've gotten a character on the current line
|
||||
currentLineIsBlank = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// give the web browser time to receive the data
|
||||
delay(1);
|
||||
client.stop();
|
||||
Serial.println("</CONNECTION>");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// XML CODE
|
||||
//
|
||||
void Weather2(XMLWriter xw)
|
||||
{
|
||||
xw.comment("The weather in South Africa");
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
xw.tagStart("Weather");
|
||||
xw.tagField("Date", "20131106");
|
||||
xw.tagField("Time", "1:42");
|
||||
xw.tagField("Temp", "23.4");
|
||||
xw.tagField("Humi", "50%");
|
||||
xw.tagField("Rain", "10mm");
|
||||
xw.tagField("Sun", "40");
|
||||
xw.tagEnd();
|
||||
}
|
||||
}
|
||||
|
||||
void Weather(XMLWriter xw)
|
||||
{
|
||||
xw.comment("The weather in Nebraska");
|
||||
xw.tagOpen("Weather");
|
||||
xw.writeNode("Date", "20131106");
|
||||
xw.writeNode("Time", "11:42");
|
||||
xw.writeNode("Temp", "23.4");
|
||||
xw.writeNode("Humi", "50%");
|
||||
xw.writeNode("Rain", "10mm");
|
||||
xw.writeNode("Sun", "40");
|
||||
xw.tagClose();
|
||||
}
|
||||
|
||||
|
||||
void AnalogPorts(XMLWriter xw, const char* name)
|
||||
{
|
||||
char buffer[24];
|
||||
|
||||
xw.comment("The analog ports are multiplexed");
|
||||
xw.tagOpen("Analog", name);
|
||||
xw.writeNode("Analog0", itoa(analogRead(A0), buffer, 10));
|
||||
xw.writeNode("Analog1", analogRead(A1));
|
||||
xw.writeNode("Analog2", (5.0 * analogRead(A2)) / 1023); // default nr decimals = 2
|
||||
xw.writeNode("Analog3", (5.0 * analogRead(A2)) / 1023, 3);
|
||||
xw.tagClose();
|
||||
}
|
||||
|
||||
void DigitalPorts(XMLWriter xw)
|
||||
{
|
||||
char buffer[24];
|
||||
|
||||
xw.comment("The digital ports are not multiplexed");
|
||||
xw.tagOpen("Digital");
|
||||
xw.writeNode("D1", itoa(digitalRead(1), buffer, 10));
|
||||
xw.writeNode("D13", digitalRead(13));
|
||||
xw.tagClose();
|
||||
}
|
||||
|
||||
void DataTypes(XMLWriter xw)
|
||||
{
|
||||
xw.comment("Testing dataTypes I");
|
||||
xw.tagOpen("Datatypes");
|
||||
xw.writeNode("BoolT", 1 == 1);
|
||||
xw.writeNode("BoolF", 1 == 0);
|
||||
xw.writeNode("BIN", 42, BIN);
|
||||
xw.writeNode("DEC", 42, DEC);
|
||||
xw.writeNode("HEX", 42, HEX);
|
||||
xw.writeNode("OCT", 42, OCT);
|
||||
xw.tagClose();
|
||||
|
||||
xw.comment("Testing dataTypes II");
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
xw.tagStart("dataTypes");
|
||||
xw.tagField("BoolT", 1 == 1);
|
||||
xw.tagField("BoolF", 1 == 0);
|
||||
int x = analogRead(A0);
|
||||
xw.tagField("BIN", x, BIN);
|
||||
xw.tagField("DEC", x, DEC);
|
||||
xw.tagField("HEX", x, HEX);
|
||||
xw.tagField("OCT", x, OCT);
|
||||
xw.tagEnd();
|
||||
}
|
||||
}
|
||||
|
||||
// -- END OF FILE --
|
@ -0,0 +1,289 @@
|
||||
//
|
||||
// FILE: XMLWriterEthernet.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.1
|
||||
// PURPOSE: demo XML writer for EthernetClient
|
||||
// DATE: 2020-04-24
|
||||
// URL: https://github.com/RobTillaart/XMLWriter
|
||||
//
|
||||
|
||||
#include <XMLWriter.h>
|
||||
|
||||
#include <SPI.h>
|
||||
#include <Ethernet.h>
|
||||
|
||||
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
|
||||
IPAddress ip( 192, 168, 1, 177);
|
||||
|
||||
const int EthernetPIN = 10;
|
||||
|
||||
EthernetServer server(80); // change to your config
|
||||
|
||||
char httpRequest[40];
|
||||
uint8_t reqCnt;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// HTTP HELPER CODE
|
||||
//
|
||||
void HTTP_header(EthernetClient* cl, const char *contentType, bool keepAlive = false, int refresh = 5)
|
||||
{
|
||||
cl->println("HTTP/1.1 200 OK");
|
||||
cl->print("Content-Type: ");
|
||||
cl->println( contentType );
|
||||
cl->println("Connection: ");
|
||||
cl->println(keepAlive ? "keep-alive" : "close");
|
||||
cl->println("Refresh: ");
|
||||
cl->println(refresh);
|
||||
cl->println();
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Based upon webServer example demo
|
||||
//
|
||||
void setup()
|
||||
{
|
||||
|
||||
Serial.begin(115200);
|
||||
Serial.println(__FILE__);
|
||||
|
||||
// Ethernet.init(pin) to configure the CS pin
|
||||
Ethernet.init(EthernetPIN);
|
||||
Ethernet.begin(mac, ip);
|
||||
|
||||
if (Ethernet.hardwareStatus() == EthernetNoHardware)
|
||||
{
|
||||
Serial.println("No hardware found");
|
||||
while (1);
|
||||
}
|
||||
|
||||
Serial.println(Ethernet.hardwareStatus());
|
||||
Serial.println(Ethernet.linkStatus());
|
||||
|
||||
if (Ethernet.linkStatus() == LinkOFF)
|
||||
{
|
||||
Serial.println("Cable is not connected.");
|
||||
Serial.println("Connect cable");
|
||||
}
|
||||
while (Ethernet.linkStatus() == LinkOFF); // wait for cable
|
||||
|
||||
server.begin();
|
||||
Serial.print("ServerIP: ");
|
||||
Serial.println(Ethernet.localIP());
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
// listen for incoming clients
|
||||
EthernetClient client = server.available();
|
||||
|
||||
if (client)
|
||||
{
|
||||
Serial.print("\n<CONNECTION>\n ");
|
||||
// Serial.println(client.remoteIP());
|
||||
// Serial.println(client.remotePort());
|
||||
|
||||
// an http request ends with a blank line
|
||||
boolean currentLineIsBlank = true;
|
||||
reqCnt = 0;
|
||||
while (client.connected())
|
||||
{
|
||||
if (client.available())
|
||||
{
|
||||
char c = client.read();
|
||||
Serial.write(c); // collect HHTP request here..
|
||||
if (reqCnt < 39)
|
||||
{
|
||||
httpRequest[reqCnt++] = c;
|
||||
httpRequest[reqCnt] = 0;
|
||||
}
|
||||
|
||||
// if you've gotten to the end of the line (received a newline
|
||||
// character) and the line is blank, the http request has ended,
|
||||
// so you can send a reply
|
||||
if (c == '\n' && currentLineIsBlank)
|
||||
{
|
||||
if (strstr(httpRequest, "1.xml"))
|
||||
{
|
||||
uint32_t start = micros();
|
||||
// send a standard http response header
|
||||
HTTP_header(&client, "text/xml", true, 5);
|
||||
XMLWriter XML(&client, 250);
|
||||
|
||||
// XML body
|
||||
XML.header();
|
||||
XML.comment("XMLWriterTest.ino\nThis is a demo of a simple XML lib for Arduino", true);
|
||||
|
||||
// use of {} to get indentation that follows the XML (sort of)
|
||||
// it adds no code size, but improves readability a lot
|
||||
XML.tagOpen("Arduino", "42");
|
||||
{
|
||||
XML.tagOpen("Ports");
|
||||
{
|
||||
AnalogPorts(&XML, "before");
|
||||
DigitalPorts(&XML);
|
||||
AnalogPorts(&XML, "after");
|
||||
}
|
||||
XML.tagClose();
|
||||
}
|
||||
XML.tagClose();
|
||||
XML.flush();
|
||||
uint32_t stop = micros();
|
||||
Serial.println(stop - start);
|
||||
Serial.println(XML.bytesWritten());
|
||||
Serial.println(XML.bytesWritten() * 1e6 / (stop - start));
|
||||
break;
|
||||
}
|
||||
if (strstr(httpRequest, "2.xml"))
|
||||
{
|
||||
uint32_t start = micros();
|
||||
// send a standard http response header
|
||||
HTTP_header(&client, "text/xml", true, 5);
|
||||
XMLWriter XML(&client, 250);
|
||||
|
||||
// XML body
|
||||
XML.header();
|
||||
XML.comment("XMLWriterTest.ino\nThis is a demo of a simple XML lib for Arduino", true);
|
||||
|
||||
// use of {} to get indentation that follows the XML (sort of)
|
||||
// it adds no code size, but improves readability a lot
|
||||
XML.tagOpen("Arduino", "102");
|
||||
{
|
||||
Weather(&XML);
|
||||
Weather2(&XML);
|
||||
DataTypes(&XML);
|
||||
}
|
||||
XML.tagClose();
|
||||
XML.flush();
|
||||
uint32_t stop = micros();
|
||||
Serial.println(stop - start);
|
||||
Serial.println(XML.bytesWritten());
|
||||
Serial.println(XML.bytesWritten() * 1e6 / (stop - start));
|
||||
break;
|
||||
}
|
||||
|
||||
// default page is simple HTML
|
||||
// send a standard http response header
|
||||
HTTP_header(&client, "text/html", true, 5);
|
||||
|
||||
client.println("<!DOCTYPE HTML>");
|
||||
client.println("<html>");
|
||||
client.println("<head>");
|
||||
client.println("<title>Demo XML writer</title>");
|
||||
client.println("</head>");
|
||||
client.println("<body>");
|
||||
client.println("<h1>Demo XML writer for EthernetClient</h1>");
|
||||
client.println("<p>Get <a href=\"1.xml\">XML 1</a>.</p>");
|
||||
client.println("<p>Get <a href=\"2.xml\">XML 2</a>.</p>");
|
||||
client.println("</body>");
|
||||
client.println("</html>");
|
||||
break;
|
||||
}
|
||||
if (c == '\n') {
|
||||
Serial.print(" ");
|
||||
// you're starting a new line
|
||||
currentLineIsBlank = true;
|
||||
} else if (c != '\r') {
|
||||
// you've gotten a character on the current line
|
||||
currentLineIsBlank = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// give the web browser time to receive the data
|
||||
delay(1);
|
||||
client.stop();
|
||||
Serial.println("</CONNECTION>");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// XML CODE
|
||||
//
|
||||
void Weather2(XMLWriter* xw)
|
||||
{
|
||||
xw->comment("The weather in South Africa");
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
xw->tagStart("Weather");
|
||||
xw->tagField("Date", "20131106");
|
||||
xw->tagField("Time", "1:42");
|
||||
xw->tagField("Temp", "23.4");
|
||||
xw->tagField("Humi", "50%");
|
||||
xw->tagField("Rain", "10mm");
|
||||
xw->tagField("Sun", "40");
|
||||
xw->tagEnd();
|
||||
}
|
||||
}
|
||||
|
||||
void Weather(XMLWriter* xw)
|
||||
{
|
||||
xw->comment("The weather in Nebraska");
|
||||
xw->tagOpen("Weather");
|
||||
xw->writeNode("Date", "20131106");
|
||||
xw->writeNode("Time", "11:42");
|
||||
xw->writeNode("Temp", "23.4");
|
||||
xw->writeNode("Humi", "50%");
|
||||
xw->writeNode("Rain", "10mm");
|
||||
xw->writeNode("Sun", "40");
|
||||
xw->tagClose();
|
||||
}
|
||||
|
||||
|
||||
void AnalogPorts(XMLWriter* xw, const char* name)
|
||||
{
|
||||
char buffer[24];
|
||||
|
||||
xw->comment("The analog ports are multiplexed");
|
||||
xw->tagOpen("Analog", name);
|
||||
xw->writeNode("Analog0", itoa(analogRead(A0), buffer, 10));
|
||||
xw->writeNode("Analog1", analogRead(A1));
|
||||
xw->writeNode("Analog2", (5.0 * analogRead(A2)) / 1023); // default nr decimals = 2
|
||||
xw->writeNode("Analog3", (5.0 * analogRead(A2)) / 1023, 3);
|
||||
xw->tagClose();
|
||||
}
|
||||
|
||||
void DigitalPorts(XMLWriter* xw)
|
||||
{
|
||||
char buffer[24];
|
||||
|
||||
xw->comment("The digital ports are not multiplexed");
|
||||
xw->tagOpen("Digital");
|
||||
xw->writeNode("D1", itoa(digitalRead(1), buffer, 10));
|
||||
xw->writeNode("D13", digitalRead(13));
|
||||
xw->tagClose();
|
||||
}
|
||||
|
||||
void DataTypes(XMLWriter* xw)
|
||||
{
|
||||
xw->comment("Testing dataTypes I");
|
||||
xw->tagOpen("Datatypes");
|
||||
xw->writeNode("BoolT", 1 == 1);
|
||||
xw->writeNode("BoolF", 1 == 0);
|
||||
xw->writeNode("BIN", 42, BIN);
|
||||
xw->writeNode("DEC", 42, DEC);
|
||||
xw->writeNode("HEX", 42, HEX);
|
||||
xw->writeNode("OCT", 42, OCT);
|
||||
xw->tagClose();
|
||||
|
||||
xw->comment("Testing dataTypes II");
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
xw->tagStart("dataTypes");
|
||||
xw->tagField("BoolT", 1 == 1);
|
||||
xw->tagField("BoolF", 1 == 0);
|
||||
int x = analogRead(A0);
|
||||
xw->tagField("BIN", x, BIN);
|
||||
xw->tagField("DEC", x, DEC);
|
||||
xw->tagField("HEX", x, HEX);
|
||||
xw->tagField("OCT", x, OCT);
|
||||
xw->tagEnd();
|
||||
}
|
||||
}
|
||||
|
||||
// -- END OF FILE --
|
@ -0,0 +1,96 @@
|
||||
//
|
||||
// FILE: XMLWriterSDcard.ino.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.1
|
||||
// PURPOSE: XML writing to SD card
|
||||
// DATE: 2020-04-24
|
||||
// URL: https://github.com/RobTillaart/XMLWriter
|
||||
//
|
||||
// Note: this application will write to the SD card immediately
|
||||
// and it will append to the data.xml file every time started.
|
||||
//
|
||||
|
||||
#include <SPI.h>
|
||||
#include <SD.h>
|
||||
// SPI PINS
|
||||
// MOSI 11
|
||||
// MISO 12
|
||||
// CLOCK 13
|
||||
// CS 10
|
||||
#define CS 10 // adjust this ChipSelect line if needed !
|
||||
|
||||
#include <XMLWriter.h>
|
||||
|
||||
char buffer[24];
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println(__FILE__);
|
||||
|
||||
// initialize the SD card
|
||||
if (!SD.begin(CS))
|
||||
{
|
||||
Serial.println("Error: SD card failure");
|
||||
while(1);
|
||||
}
|
||||
|
||||
// remove file for proper timing
|
||||
SD.remove("data.xml");
|
||||
delay(1000);
|
||||
|
||||
|
||||
uint32_t start = micros();
|
||||
File logfile = SD.open("data.xml", FILE_WRITE);
|
||||
if (!logfile)
|
||||
{
|
||||
Serial.println("Error: SD card failure");
|
||||
while(1);
|
||||
}
|
||||
|
||||
XMLWriter XML(&logfile);
|
||||
XML.header();
|
||||
XML.comment("XMLWriterSDcard.ino\nThis is a demo of a simple XML lib for Arduino", true);
|
||||
XML.tagOpen("Arduino", "42");
|
||||
XML.tagOpen("Ports");
|
||||
AnalogPorts(&XML, "measurement");
|
||||
DigitalPorts(&XML);
|
||||
XML.tagClose();
|
||||
XML.tagClose();
|
||||
XML.flush();
|
||||
|
||||
logfile.close();
|
||||
|
||||
uint32_t stop = micros();
|
||||
Serial.println();
|
||||
Serial.println(stop - start);
|
||||
Serial.println("Done...");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AnalogPorts(XMLWriter* xw, const char* name)
|
||||
{
|
||||
xw->comment("The analog ports are multiplexed");
|
||||
xw->tagOpen("Analog", name);
|
||||
xw->writeNode("Analog0", itoa(analogRead(A0), buffer, 10));
|
||||
xw->writeNode("Analog1", analogRead(A1));
|
||||
xw->writeNode("Analog2", (5.0*analogRead(A2))/1023); // default nr decimals = 2
|
||||
xw->writeNode("Analog3", (5.0*analogRead(A2))/1023, 3);
|
||||
xw->tagClose();
|
||||
}
|
||||
|
||||
void DigitalPorts(XMLWriter* xw)
|
||||
{
|
||||
xw->comment("The digital ports are not multiplexed");
|
||||
xw->tagOpen("Digital");
|
||||
xw->writeNode("D1", itoa(digitalRead(1), buffer, 10));
|
||||
xw->writeNode("D13", digitalRead(13));
|
||||
xw->tagClose();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
||||
// -- END OF FILE --
|
3
libraries/XMLWriter/examples/XMLWriterSDcard/note.txt
Normal file
3
libraries/XMLWriter/examples/XMLWriterSDcard/note.txt
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
|
||||
https://learn.adafruit.com/adafruit-data-logger-shield/using-the-sd-card
|
6
libraries/XMLWriter/examples/XMLWriterSDcard/readme.md
Normal file
6
libraries/XMLWriter/examples/XMLWriterSDcard/readme.md
Normal file
@ -0,0 +1,6 @@
|
||||
# XMLWriter
|
||||
|
||||
### SDCARD demo notes
|
||||
|
||||
Do not forget the **XML.flush();** before closing the FILE object.
|
||||
|
@ -1,12 +1,10 @@
|
||||
//
|
||||
// FILE: XMLWriterTest.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.03
|
||||
// VERSION: 0.1.5
|
||||
// PURPOSE: make a simple XML generating lib
|
||||
// DATE: 2013-11-06
|
||||
// URL:
|
||||
//
|
||||
// Released to the public domain
|
||||
// URL: https://github.com/RobTillaart/XMLWriter
|
||||
//
|
||||
|
||||
#include <XMLWriter.h>
|
||||
@ -19,9 +17,12 @@ void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
|
||||
uint32_t start = micros();
|
||||
XML.setConfig(0); // comment this line to see difference
|
||||
|
||||
XML.header();
|
||||
XML.comment("XMLWriterTest.ino\nThis is a demo of a simple XML lib for Arduino", true);
|
||||
|
||||
// XML.newLine(0);
|
||||
XML.tagOpen("Arduino", "42");
|
||||
|
||||
XML.tagOpen("Ports");
|
||||
@ -35,12 +36,15 @@ void setup()
|
||||
DataTypes();
|
||||
|
||||
XML.tagClose();
|
||||
uint32_t stop = micros();
|
||||
Serial.println(stop - start);
|
||||
Serial.println("done...");
|
||||
}
|
||||
|
||||
void Weather2()
|
||||
{
|
||||
XML.comment("The weather in South Africa");
|
||||
for (int i=0; i<10; i++)
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
XML.tagStart("Weather");
|
||||
XML.tagField("Date", "20131106");
|
||||
@ -72,8 +76,8 @@ void AnalogPorts(const char* name)
|
||||
XML.tagOpen("Analog", name);
|
||||
XML.writeNode("Analog0", itoa(analogRead(A0), buffer, 10));
|
||||
XML.writeNode("Analog1", analogRead(A1));
|
||||
XML.writeNode("Analog2", (5.0*analogRead(A2))/1023); // default nr decimals = 2
|
||||
XML.writeNode("Analog3", (5.0*analogRead(A2))/1023, 3);
|
||||
XML.writeNode("Analog2", (5.0 * analogRead(A2)) / 1023); // default nr decimals = 2
|
||||
XML.writeNode("Analog3", (5.0 * analogRead(A2)) / 1023, 3);
|
||||
XML.tagClose();
|
||||
}
|
||||
|
||||
@ -90,20 +94,20 @@ void DataTypes()
|
||||
{
|
||||
XML.comment("Testing dataTypes I");
|
||||
XML.tagOpen("Datatypes");
|
||||
XML.writeNode("Bool", 1 == 1);
|
||||
XML.writeNode("Bool", 1 == 0);
|
||||
XML.writeNode("BoolT", 1 == 1);
|
||||
XML.writeNode("BoolF", 1 == 0);
|
||||
XML.writeNode("BIN", 42, BIN);
|
||||
XML.writeNode("DEC", 42, DEC);
|
||||
XML.writeNode("HEX", 42, HEX);
|
||||
XML.writeNode("OCT", 42, OCT);
|
||||
XML.tagClose();
|
||||
|
||||
|
||||
XML.comment("Testing dataTypes II");
|
||||
for (int i=0; i<3; i++)
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
XML.tagStart("dataTypes");
|
||||
XML.tagField("Bool", 1 == 1);
|
||||
XML.tagField("Bool", 1 == 0);
|
||||
XML.tagField("BoolT", 1 == 1);
|
||||
XML.tagField("BoolF", 1 == 0);
|
||||
int x = analogRead(A0);
|
||||
XML.tagField("BIN", x, BIN);
|
||||
XML.tagField("DEC", x, DEC);
|
||||
@ -115,4 +119,6 @@ void DataTypes()
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
// -- END OF FILE --
|
||||
|
@ -1,12 +1,10 @@
|
||||
//
|
||||
// FILE: XMLWriterDemo01.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.00
|
||||
// VERSION: 0.1.2
|
||||
// PURPOSE: XML writer demo
|
||||
// DATE: 2016-03-16
|
||||
// URL:
|
||||
//
|
||||
// Released to the public domain
|
||||
// URL: https://github.com/RobTillaart/XMLWriter
|
||||
//
|
||||
|
||||
#include <XMLWriter.h>
|
||||
@ -21,7 +19,11 @@ void setup()
|
||||
float y = random(100) * 1.0;
|
||||
float r = random(100) * 1.0;
|
||||
|
||||
uint32_t start = micros();
|
||||
shoot(p, y, r);
|
||||
uint32_t stop = micros();
|
||||
Serial.println();
|
||||
Serial.println(stop - start);
|
||||
}
|
||||
|
||||
void shoot(float p, float y, float r)
|
||||
@ -80,9 +82,20 @@ void shoot(float p, float y, float r)
|
||||
XML.tagStart("/position");
|
||||
XML.tagEnd(NEWLINE, NOSLASH);
|
||||
|
||||
XML.comment("test escape() codes");
|
||||
XML.tagOpen("supported");
|
||||
XML.writeNode("ampersand", "&");
|
||||
XML.writeNode("lessthan", "<");
|
||||
XML.writeNode("greaterthan", ">");
|
||||
XML.writeNode("quote", "\"");
|
||||
XML.writeNode("apostrophe", "\'");
|
||||
XML.tagClose();
|
||||
|
||||
XML.tagClose(); // shoot
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
||||
// -- END OF FILE --
|
||||
|
@ -1,17 +1,9 @@
|
||||
#######################################
|
||||
# Syntax Coloring Map For XMLWriter
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
|
||||
XMLWriter KEYWORD1
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
|
||||
reset KEYWORD2
|
||||
header KEYWORD2
|
||||
comment KEYWORD2
|
||||
@ -27,16 +19,12 @@ decrIndent KEYWORD2
|
||||
indent KEYWORD2
|
||||
raw KEYWORD2
|
||||
escape KEYWORD2
|
||||
setConfig KEYWORD2
|
||||
newLine KEYWORD2
|
||||
|
||||
#######################################
|
||||
# Instances (KEYWORD2)
|
||||
#######################################
|
||||
|
||||
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
||||
|
||||
NOMULTILINE LITERAL1
|
||||
MULTILINE LITERAL1
|
||||
NEWLINE LITERAL1
|
||||
@ -44,3 +32,6 @@ NONEWLINE LITERAL1
|
||||
NOINDENT LITERAL1
|
||||
SLASH LITERAL1
|
||||
NOSLASH LITERAL1
|
||||
XMLWRITER_NONE LITERAL1
|
||||
XMLWRITER_COMMENT LITERAL1
|
||||
XMLWRITER_INDENT LITERAL1
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "XMLWriter",
|
||||
"keywords": "Write,XML,node,header,tag,indent,field,stream",
|
||||
"description": "Library for writing XML files.",
|
||||
"keywords": "Write, XML, node, header, tag, indent, field, stream,",
|
||||
"description": "Arduino library for creating XML",
|
||||
"authors":
|
||||
[
|
||||
{
|
||||
@ -13,12 +13,12 @@
|
||||
"repository":
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/RobTillaart/Arduino.git"
|
||||
"url": "https://github.com/RobTillaart/XMLWriter"
|
||||
},
|
||||
"version":"0.1.8",
|
||||
"version":"0.2.2",
|
||||
"frameworks": "arduino",
|
||||
"platforms": "*",
|
||||
"export": {
|
||||
"include": "libraries/XMLWriter"
|
||||
"include": "XMLWriter"
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
name=XMLWriter
|
||||
version=0.1.8
|
||||
version=0.2.2
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
sentence=Library for writing XML files.
|
||||
sentence=Arduino library for creating XML
|
||||
paragraph=
|
||||
category=Data Processing
|
||||
url=https://github.com/RobTillaart/Arduino/tree/master/libraries
|
||||
url=https://github.com/RobTillaart/XMLWriter
|
||||
architectures=*
|
||||
|
||||
includes=XMLWriter.h
|
||||
depends=
|
||||
|
Loading…
x
Reference in New Issue
Block a user