Files
ArduinoJson/src/Internals/QuotedString.cpp

104 lines
2.0 KiB
C++
Raw Normal View History

2015-02-07 16:05:48 +01:00
// Copyright Benoit Blanchon 2014-2015
2014-10-23 23:39:22 +02:00
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
2014-10-16 16:25:42 +02:00
2014-11-03 18:35:22 +01:00
#include "../../include/ArduinoJson/Internals/QuotedString.hpp"
2014-10-16 16:25:42 +02:00
using namespace ArduinoJson::Internals;
2015-02-07 16:01:09 +01:00
// How to escape special chars:
// specialChars[2*i+1] => the special char
// specialChars[2*i] => the char to use instead
static const char specialChars[] = "\"\"\\\\b\bf\fn\nr\rt\t";
2014-10-23 19:54:00 +02:00
static inline char getSpecialChar(char c) {
// Optimized for code size on a 8-bit AVR
2014-10-16 16:25:42 +02:00
2015-02-07 16:01:09 +01:00
const char *p = specialChars;
2014-10-16 16:25:42 +02:00
2015-02-07 16:01:09 +01:00
while (p[0] && p[1] != c) {
2014-10-23 19:54:00 +02:00
p += 2;
}
2014-10-16 16:25:42 +02:00
2015-02-07 16:01:09 +01:00
return p[0];
2014-10-16 16:25:42 +02:00
}
2014-11-06 14:29:29 +01:00
static inline size_t printCharTo(char c, Print &p) {
2014-10-23 19:54:00 +02:00
char specialChar = getSpecialChar(c);
2014-10-16 16:25:42 +02:00
2014-11-06 14:29:29 +01:00
return specialChar ? p.write('\\') + p.write(specialChar) : p.write(c);
2014-10-16 16:25:42 +02:00
}
2014-11-06 14:29:29 +01:00
size_t QuotedString::printTo(const char *s, Print &p) {
if (!s) return p.print("null");
2014-10-16 16:25:42 +02:00
2014-11-06 14:29:29 +01:00
size_t n = p.write('\"');
2014-10-16 16:25:42 +02:00
2014-10-23 19:54:00 +02:00
while (*s) {
n += printCharTo(*s++, p);
}
2014-10-17 19:57:00 +02:00
2014-11-06 14:29:29 +01:00
return n + p.write('\"');
2014-10-23 19:54:00 +02:00
}
2014-10-17 19:57:00 +02:00
2014-10-23 19:54:00 +02:00
static char unescapeChar(char c) {
// Optimized for code size on a 8-bit AVR
2014-10-17 19:57:00 +02:00
2015-02-07 16:01:09 +01:00
const char *p = specialChars + 4;
2014-10-17 19:57:00 +02:00
2014-10-23 19:54:00 +02:00
for (;;) {
if (p[0] == '\0') return c;
if (p[0] == c) return p[1];
2014-10-23 19:54:00 +02:00
p += 2;
}
}
2014-10-23 19:54:00 +02:00
static inline bool isQuote(char c) { return c == '\"' || c == '\''; }
2014-10-23 19:54:00 +02:00
char *QuotedString::extractFrom(char *input, char **endPtr) {
char firstChar = *input;
2014-10-23 19:54:00 +02:00
if (!isQuote(firstChar)) {
// must start with a quote
return NULL;
2014-10-23 19:54:00 +02:00
}
2014-10-22 11:54:33 +02:00
char stopChar = firstChar; // closing quote is the same as opening quote
2014-10-17 19:57:00 +02:00
char *startPtr = input + 1; // skip the quote
2014-10-23 19:54:00 +02:00
char *readPtr = startPtr;
char *writePtr = startPtr;
char c;
2014-10-17 19:57:00 +02:00
2014-10-23 19:54:00 +02:00
for (;;) {
c = *readPtr++;
if (c == '\0') {
2014-10-23 19:54:00 +02:00
// premature ending
return NULL;
2014-10-23 19:54:00 +02:00
}
2014-10-17 19:57:00 +02:00
2014-10-23 19:54:00 +02:00
if (c == stopChar) {
// closing quote
break;
}
2014-10-17 19:57:00 +02:00
2014-10-23 19:54:00 +02:00
if (c == '\\') {
// replace char
c = unescapeChar(*readPtr++);
2014-10-22 10:55:36 +02:00
}
2014-10-17 19:57:00 +02:00
2014-10-23 19:54:00 +02:00
*writePtr++ = c;
}
// end the string here
*writePtr = '\0';
2014-10-17 19:57:00 +02:00
2014-10-23 19:54:00 +02:00
// update end ptr
*endPtr = readPtr;
2014-10-17 19:57:00 +02:00
2014-10-23 19:54:00 +02:00
return startPtr;
2014-10-23 23:45:36 +02:00
}