#include "WResp.h" #include "esp_log.h" static const char *TAG = "WResp"; void JsonSockEvent::beginEvent(AsyncWebSocket *server, const char *evt, char *buff, size_t buffSize) { this->server = server; this->buff = buff; this->buffSize = buffSize; this->_nocomma = true; this->_closed = false; snprintf(this->buff, buffSize, "42[%s,", evt); } void JsonSockEvent::closeEvent() { if(!this->_closed) { if(strlen(this->buff) < buffSize) strcat(this->buff, "]"); else this->buff[buffSize - 1] = ']'; } this->_nocomma = true; this->_closed = true; } void JsonSockEvent::endEvent(uint32_t clientId) { this->closeEvent(); if(clientId == 0) this->server->textAll(this->buff); else this->server->text(clientId, this->buff); } void JsonSockEvent::_safecat(const char *val, bool escape) { size_t len = (escape ? this->calcEscapedLength(val) : strlen(val)) + strlen(this->buff); if(escape) len += 2; if(len >= this->buffSize) { ESP_LOGE(TAG, "Socket exceeded buffer size %d - %d: %s", this->buffSize, len, this->buff); return; } if(escape) strcat(this->buff, "\""); if(escape) this->escapeString(val, &this->buff[strlen(this->buff)]); else strcat(this->buff, val); if(escape) strcat(this->buff, "\""); } void AsyncJsonResp::beginResponse(AsyncWebServerRequest *request, char *buff, size_t buffSize) { this->_request = request; this->buff = buff; this->buffSize = buffSize; this->buff[0] = 0x00; this->_nocomma = true; this->_headersSent = false; this->_stream = request->beginResponseStream("application/json"); } void AsyncJsonResp::endResponse() { if(strlen(this->buff)) this->flush(); if(this->_request && this->_stream) { this->_request->send(this->_stream); } } void AsyncJsonResp::flush() { if(this->_stream && strlen(this->buff) > 0) { this->_stream->print(this->buff); this->buff[0] = 0x00; } } void AsyncJsonResp::_safecat(const char *val, bool escape) { size_t len = (escape ? this->calcEscapedLength(val) : strlen(val)) + strlen(this->buff); if(escape) len += 2; if(len >= this->buffSize) { this->flush(); } if(escape) strcat(this->buff, "\""); if(escape) this->escapeString(val, &this->buff[strlen(this->buff)]); else strcat(this->buff, val); if(escape) strcat(this->buff, "\""); } void JsonFormatter::beginObject(const char *name) { if(name && strlen(name) > 0) this->appendElem(name); else if(!this->_nocomma) this->_safecat(","); this->_safecat("{"); this->_objects++; this->_nocomma = true; } void JsonFormatter::endObject() { //if(strlen(this->buff) + 1 > this->buffSize - 1) this->send(); this->_safecat("}"); this->_objects--; this->_nocomma = false; } void JsonFormatter::beginArray(const char *name) { if(name && strlen(name) > 0) this->appendElem(name); else if(!this->_nocomma) this->_safecat(","); this->_safecat("["); this->_arrays++; this->_nocomma = true; } void JsonFormatter::endArray() { //if(strlen(this->buff) + 1 > this->buffSize - 1) this->send(); this->_safecat("]"); this->_arrays--; this->_nocomma = false; } void JsonFormatter::appendElem(const char *name) { if(!this->_nocomma) this->_safecat(","); if(name && strlen(name) > 0) { this->_safecat(name, true); this->_safecat(":"); } this->_nocomma = false; } void JsonFormatter::addElem(const char *name, const char *val) { if(!val) return; this->appendElem(name); this->_safecat(val, true); } void JsonFormatter::addElem(const char *val) { this->addElem(nullptr, val); } void JsonFormatter::addElem(float fval) { sprintf(this->_numbuff, "%.4f", fval); this->_appendNumber(nullptr); } void JsonFormatter::addElem(int8_t nval) { sprintf(this->_numbuff, "%d", nval); this->_appendNumber(nullptr); } void JsonFormatter::addElem(uint8_t nval) { sprintf(this->_numbuff, "%u", nval); this->_appendNumber(nullptr); } void JsonFormatter::addElem(int32_t nval) { sprintf(this->_numbuff, "%ld", (long)nval); this->_appendNumber(nullptr); } void JsonFormatter::addElem(uint32_t nval) { sprintf(this->_numbuff, "%lu", (unsigned long)nval); this->_appendNumber(nullptr); } /* void JsonFormatter::addElem(int16_t nval) { sprintf(this->_numbuff, "%d", nval); this->_appendNumber(nullptr); } void JsonFormatter::addElem(uint16_t nval) { sprintf(this->_numbuff, "%u", nval); this->_appendNumber(nullptr); } void JsonFormatter::addElem(int64_t lval) { sprintf(this->_numbuff, "%lld", (long long)lval); this->_appendNumber(nullptr); } void JsonFormatter::addElem(uint64_t lval) { sprintf(this->_numbuff, "%llu", (unsigned long long)lval); this->_appendNumber(nullptr); } */ void JsonFormatter::addElem(bool bval) { strcpy(this->_numbuff, bval ? "true" : "false"); this->_appendNumber(nullptr); } void JsonFormatter::addElem(const char *name, float fval) { sprintf(this->_numbuff, "%.4f", fval); this->_appendNumber(name); } void JsonFormatter::addElem(const char *name, int8_t nval) { sprintf(this->_numbuff, "%d", nval); this->_appendNumber(name); } void JsonFormatter::addElem(const char *name, uint8_t nval) { sprintf(this->_numbuff, "%u", nval); this->_appendNumber(name); } void JsonFormatter::addElem(const char *name, int32_t nval) { sprintf(this->_numbuff, "%ld", (long)nval); this->_appendNumber(name); } void JsonFormatter::addElem(const char *name, uint32_t nval) { sprintf(this->_numbuff, "%lu", (unsigned long)nval); this->_appendNumber(name); } /* void JsonFormatter::addElem(const char *name, int16_t nval) { sprintf(this->_numbuff, "%d", nval); this->_appendNumber(name); } void JsonFormatter::addElem(const char *name, uint16_t nval) { sprintf(this->_numbuff, "%u", nval); this->_appendNumber(name); } void JsonFormatter::addElem(const char *name, int64_t lval) { sprintf(this->_numbuff, "%lld", (long long)lval); this->_appendNumber(name); } */ void JsonFormatter::addElem(const char *name, uint64_t lval) { sprintf(this->_numbuff, "%llu", (unsigned long long)lval); this->_appendNumber(name); } void JsonFormatter::addElem(const char *name, bool bval) { strcpy(this->_numbuff, bval ? "true" : "false"); this->_appendNumber(name); } void JsonFormatter::_safecat(const char *val, bool escape) { size_t len = (escape ? this->calcEscapedLength(val) : strlen(val)) + strlen(this->buff); if(escape) len += 2; if(len >= this->buffSize) { return; } if(escape) strcat(this->buff, "\""); if(escape) this->escapeString(val, &this->buff[strlen(this->buff)]); else strcat(this->buff, val); if(escape) strcat(this->buff, "\""); } void JsonFormatter::_appendNumber(const char *name) { this->appendElem(name); this->_safecat(this->_numbuff); } uint32_t JsonFormatter::calcEscapedLength(const char *raw) { uint32_t len = 0; for(size_t i = strlen(raw); i > 0; i--) { switch(raw[i]) { case '"': case '/': case '\b': case '\f': case '\n': case '\r': case '\t': case '\\': len += 2; break; default: len++; break; } } return len; } void JsonFormatter::escapeString(const char *raw, char *escaped) { for(uint32_t i = 0; i < strlen(raw); i++) { switch(raw[i]) { case '"': strcat(escaped, "\\\""); break; case '/': strcat(escaped, "\\/"); break; case '\b': strcat(escaped, "\\b"); break; case '\f': strcat(escaped, "\\f"); break; case '\n': strcat(escaped, "\\n"); break; case '\r': strcat(escaped, "\\r"); break; case '\t': strcat(escaped, "\\t"); break; case '\\': strcat(escaped, "\\\\"); break; default: size_t len = strlen(escaped); escaped[len] = raw[i]; escaped[len+1] = 0x00; break; } } }