String comparison fails when key value is assigned with `const char *` but not String
Created by: sticilface
I've written a function to compare Json objects and bail if the key, values are not found or a different in the target. The target can have more keys.
here is the function
bool DeviceHandle::canHandle(JsonObject & event)
{
DynamicJsonDocument handleDoc(256);
DeserializationError error = deserializeMsgPack(handleDoc, _handle); //serializeMsgPack
if (!error) {
if (handleDoc.is<JsonObject>()) {
Serial.print("Comparing handleDoc: ");
serializeJson(handleDoc, Serial);
Serial.print("\nwith event: ");
serializeJson(event, Serial);
Serial.println();
for (JsonPair kv : handleDoc.as<JsonObject>()) {
if (!event.containsKey(kv.key())) {
Serial.printf(" no match, doesn't contain key: %s\n", kv.key().c_str());
return false; // if it doesn't contain the key
} else if (event.containsKey(kv.key()) && kv.value() != event.getMember(kv.key())) {
String H;
String E;
serializeJson(kv.value(), H);
serializeJson( event.getMember(kv.key()) , E);
Serial.printf(" no match, %s [%s != %s]\n", kv.key().c_str(), H.c_str(), E.c_str() );
return false; //
}
}
Serial.println("Event Matches ** ");
return true; // if is contains all keys ==.
}
} else {
Serial.printf("canHandle: Deserialisation error: %s\n", error.c_str());
}
return false;
}
Now the input to this function is shown below: type
is a string assigned to the key touchtype
.
template <>
bool PacketToJson<TouchPacket>(const Packet<TouchPacket> & packet, JsonObject & root)
{
root["type"] = "TouchPacket";
const char * type = nullptr;
//String type;
switch (packet.data.touchType.c) {
case Touch_t::BUTTON_SHORT_PRESS : { type = "short" ; break; }
case Touch_t::BUTTON_LONG_PRESS : { type = "long" ; break; }
case Touch_t::BUTTON_HOLD : { type = "held" ; break; }
case Touch_t::BUTTON_LEDS : { type = "leds" ; break; }
case Touch_t::READY : { type = "ready" ; break; }
case Touch_t::NONE : { type = "none" ; break; }
}
root["touchtype"] = type;
root["button"] = packet.data.value;
return true;
}
I initially used const char *
but the debug output is shown below, and the line kv.value() != event.getMember(kv.key())
was evaluating as false, but you can see from the debug that the values are the same.
Comparing handleDoc: {"source":"TouchTest","touchtype":"short","button":1}
with event: {"source":"TouchTest","pjonID":10,"time":29463,"type":"TouchPacket","touchtype":"short","button":1}
no match, touchtype ["short" != "short"] <--- Now this should be true!!!
Comparing handleDoc: {"source":"TouchTest","touchtype":"long","button":1}
with event: {"source":"TouchTest","pjonID":10,"time":29463,"type":"TouchPacket","touchtype":"short","button":1}
no match, touchtype ["long" != "short"]
Comparing handleDoc: {"source":"TouchTest","touchtype":"held","button":1}
with event: {"source":"TouchTest","pjonID":10,"time":29463,"type":"TouchPacket","touchtype":"short","button":1}
no match, touchtype ["held" != "short"]
If I then change const char *
to String:
[TouchTest] parseEvent: _handles.empty()
Comparing handleDoc: {"source":"TouchTest","touchtype":"short","button":1}
with event: {"source":"TouchTest","pjonID":10,"time":15645,"type":"TouchPacket","touchtype":"short","button":1}
Event Matches **
Comparing handleDoc: {"source":"TouchTest","touchtype":"long","button":1}
with event: {"source":"TouchTest","pjonID":10,"time":15645,"type":"TouchPacket","touchtype":"short","button":1}
no match, touchtype ["long" != "short"]
Comparing handleDoc: {"source":"TouchTest","touchtype":"held","button":1}
with event: {"source":"TouchTest","pjonID":10,"time":15645,"type":"TouchPacket","touchtype":"short","button":1}
no match, touchtype ["held" != "short"]
The output works.
So it looks like JsonVariant == operator
is not getting it quite right when comparing strings held in the document with those held as a pointer.
Any thoughts?