#pragma once template struct TypeToMsgPackCode{}; template<> struct TypeToMsgPackCode { static const char CODE; }; template<> struct TypeToMsgPackCode{ static const char CODE; }; template<> struct TypeToMsgPackCode{ static const char CODE; }; template<> struct TypeToMsgPackCode { static const char CODE; }; template<> struct TypeToMsgPackCode { static const char CODE; }; template<> struct TypeToMsgPackCode { static const char CODE; }; const char TypeToMsgPackCode::CODE = '\xcc'; const char TypeToMsgPackCode::CODE = '\xcd'; const char TypeToMsgPackCode::CODE = '\xce'; const char TypeToMsgPackCode::CODE = '\xd0'; const char TypeToMsgPackCode::CODE = '\xd1'; const char TypeToMsgPackCode::CODE = '\xd2'; template class StreamingMsgPackEncoder { public: StreamingMsgPackEncoder(Writer * writer_) : writer(writer_), contentLength(0), sizeCountMode(false) {} void sendMap16(byte size) { if( sizeCountMode ) { contentLength += 1; } else { size |= 0b10000000; writer->write((const char*)(&size), 1); } } void sendString255(PGM_P s) { auto len = strlen_P(s); if( len >= 255 ) { Serial.println(F("ERROR: StreamingMsgPackEncoder::string255 - string too long")); return; } byte castedLen = (byte)(len); if( sizeCountMode ) { contentLength += 2 + castedLen; } else { writer->write("\xd9", 1); writer->write((const char*)&castedLen, 1); writer->write(s, len); } } template void sendInt(T value) { if( sizeCountMode ) { contentLength += 1 + sizeof(T); } else { if( sizeof(T) == 4 ) value = htonl(value); else if( sizeof(T) == 2) value = htons(value); writer->write(&TypeToMsgPackCode::CODE, 1); writer->write((const char*)&value, sizeof(T)); } } template void sendArray(const T * data, uint32_t length) { sendArrayHeader(length); sendArrayPartialContents(data, length); } template void sendArrayHeader(uint32_t length) { if( sizeCountMode ) { contentLength += 1 + sizeof(uint32_t) + 1 + length * sizeof(T); } else { uint32_t nlength = htonl(length * sizeof(T)); writer->write("\xc9", 1); // ext dtype since typed arrays are not supported by msgpack writer->write((char*)(&nlength), sizeof(uint32_t) ); writer->write(&TypeToMsgPackCode::CODE, 1); // put code for type here, this is not part of msgpack but custom } } template void sendArrayPartialContents(T * data, uint32_t length) { if( !sizeCountMode ) { writer->write((char*)(data), length * sizeof(T)); } } void setSizeCountMode(bool sizeCountMode_=true) { sizeCountMode = sizeCountMode_; } bool getSizeCountMode() const { return sizeCountMode; } uint32_t getContentLength() const { return contentLength; } private: Writer * writer; uint32_t contentLength; bool sizeCountMode; };