1 #include "RedisInternal.h" 5 #if ARDUINO_REDIS_SERIAL_TRACE && 0 6 void pbytes(uint8_t* bytes, ssize_t len,
const char* header =
nullptr)
9 const uint _break = 0x20;
10 Serial.printf(
"[%d bytes] %s\n", len, header ? header :
"");
11 for (
int i = 0; i < len; i++)
13 if (!(i%_break)) Serial.printf(
"[H] %08x> ", i);
14 Serial.printf(
"%02x ", *(bytes + i));
15 if (!((i+1)%_break)) Serial.printf(
"\n");
18 for (
int i = 0; i < len; i++)
20 if (!(i%_break)) Serial.printf(
"[C] %08x> ", i);
21 Serial.printf(
"% 2c ", *(bytes + i));
22 if (!((i+1)%_break)) Serial.printf(
"\n");
33 data = client.readStringUntil(
'\r');
34 pbytes((uint8_t*)data.c_str(), data.length(),
"RedisObject::init()::readStringUntil");
40 String emitStr((
char)_type);
43 data.replace(CRLF, F(
""));
51 auto dLen = data.toInt();
55 data = (
const char*)
nullptr;
59 auto charBuf =
new char[dLen + 1];
60 bzero(charBuf, dLen + 1);
62 auto crlfCstr = String(CRLF).c_str();
63 auto readB = client.readBytes(charBuf, dLen);
64 pbytes((uint8_t*)charBuf, readB,
"RedisBulkString::init()::readBytes");
66 Serial.printf(
"ERROR! Bad read (%d ?= %d)\n", readB, dLen);
70 data = String(charBuf);
76 String emitStr((
char)_type);
77 emitStr += String(data.length());
86 for (
int i = 0; i < data.toInt(); i++)
87 add(RedisObject::parseType(client));
90 RedisArray::operator std::vector<String>()
const 92 std::vector<String> rv;
94 rv.push_back((String)*ro.get());
100 String emitStr((
char)_type);
101 emitStr += String(vec.size());
103 for (
auto rTypeInst : vec) {
104 emitStr += rTypeInst->RESP();
111 if (!cmdClient.connected())
112 return std::shared_ptr<RedisObject>(
new RedisInternalError(
"Client is not connected"));
114 auto cmdRespStr =
RESP();
115 sprint(
"----- CMD ----\n%s---- /CMD ----\n", cmdRespStr.c_str());
116 cmdClient.print(cmdRespStr);
117 auto ret = RedisObject::parseType(cmdClient);
118 if (ret && ret->type() == RedisObject::Type::InternalError)
124 int RedisCommand::issue_typed<int>(Client& cmdClient)
126 auto cmdRet = issue(cmdClient);
128 return INT_MAX - 0x0f;
129 if (cmdRet->type() != RedisObject::Type::Integer)
130 return INT_MAX - 0xf0;
135 bool RedisCommand::issue_typed<bool>(Client& cmdClient)
137 auto cmdRet = issue(cmdClient);
138 if (cmdRet && cmdRet->type() == RedisObject::Type::Integer)
144 String RedisCommand::issue_typed<String>(Client& cmdClient)
146 return (String)*issue(cmdClient);
149 typedef std::map<RedisObject::Type, std::function<RedisObject*(Client&)>> TypeParseMap;
151 static TypeParseMap g_TypeParseMap {
152 { RedisObject::Type::SimpleString, [](Client& c) {
return new RedisSimpleString(c); } },
153 { RedisObject::Type::BulkString, [](Client& c) {
return new RedisBulkString(c); } },
154 { RedisObject::Type::Integer, [](Client& c) {
return new RedisInteger(c); } },
155 { RedisObject::Type::Array, [](Client& c) {
return new RedisArray(c); } },
156 { RedisObject::Type::Error, [](Client& c) {
return new RedisError(c); } }
159 std::shared_ptr<RedisObject> RedisObject::parseType(Client& client)
161 if (client.connected()) {
162 while (!client.available());
164 #if ARDUINO_REDIS_SERIAL_TRACE 170 #if ARDUINO_REDIS_SERIAL_TRACE 173 }
while (typeChar == -1 || typeChar ==
'\r' || typeChar ==
'\n');
175 #if ARDUINO_REDIS_SERIAL_TRACE 176 sprint(
"Parsed type character '%c' (after %d reads) (0x%x, %dd)\n", typeChar, readB, typeChar, (
int)typeChar);
179 if (g_TypeParseMap.find(typeChar) != g_TypeParseMap.end()) {
180 auto retVal = g_TypeParseMap[typeChar](client);
182 if (!retVal || retVal->type() == RedisObject::Type::Error) {
183 String err = retVal ? (String)*retVal :
"(nil)";
187 return std::shared_ptr<RedisObject>(retVal);
190 return std::shared_ptr<RedisObject>(
new RedisInternalError(
"Unable to find type: " + typeChar));
virtual String RESP() override
std::shared_ptr< RedisObject > issue(Client &cmdClient)
virtual String RESP() override
virtual void init(Client &client) override
virtual String RESP() override
virtual void init(Client &client) override
virtual void init(Client &client)