diff --git a/examples/FirebaseSerialHost_ESP8266/push.txt b/examples/FirebaseSerialHost_ESP8266/push.txt index 9878dd3c..fc1ec2a1 100644 --- a/examples/FirebaseSerialHost_ESP8266/push.txt +++ b/examples/FirebaseSerialHost_ESP8266/push.txt @@ -1 +1 @@ -PUSH /seria/push_test "this is a test string \ " +PUSH /serial/push_test "this is a test string \ " diff --git a/src/Firebase.cpp b/src/Firebase.cpp index bc392750..2e925067 100644 --- a/src/Firebase.cpp +++ b/src/Firebase.cpp @@ -18,8 +18,8 @@ using std::unique_ptr; namespace { -String makeFirebaseURL(const String& path, const String& auth) { - String url; +std::string makeFirebaseURL(const std::string& path, const std::string& auth) { + std::string url; if (path[0] != '/') { url = "/"; } @@ -32,71 +32,71 @@ String makeFirebaseURL(const String& path, const String& auth) { } // namespace -Firebase::Firebase(const String& host, const String& auth) : host_(host), auth_(auth) { +Firebase::Firebase(const std::string& host, const std::string& auth) : host_(host), auth_(auth) { http_.reset(FirebaseHttpClient::create()); http_->setReuseConnection(true); } -const String& Firebase::auth() const { +const std::string& Firebase::auth() const { return auth_; } -FirebaseGet Firebase::get(const String& path) { +FirebaseGet Firebase::get(const std::string& path) { return FirebaseGet(host_, auth_, path, http_.get()); } -unique_ptr Firebase::getPtr(const String& path) { +unique_ptr Firebase::getPtr(const std::string& path) { return unique_ptr(new FirebaseGet(host_, auth_, path, http_.get())); } -FirebaseSet Firebase::set(const String& path, const String& value) { +FirebaseSet Firebase::set(const std::string& path, const std::string& value) { return FirebaseSet(host_, auth_, path, value, http_.get()); } -unique_ptr Firebase::setPtr(const String& path, - const String& value) { +unique_ptr Firebase::setPtr(const std::string& path, + const std::string& value) { return unique_ptr( new FirebaseSet(host_, auth_, path, value, http_.get())); } -FirebasePush Firebase::push(const String& path, const String& value) { +FirebasePush Firebase::push(const std::string& path, const std::string& value) { return FirebasePush(host_, auth_, path, value, http_.get()); } -unique_ptr Firebase::pushPtr(const String& path, const String& value) { +unique_ptr Firebase::pushPtr(const std::string& path, const std::string& value) { return unique_ptr( new FirebasePush(host_, auth_, path, value, http_.get())); } -FirebaseRemove Firebase::remove(const String& path) { +FirebaseRemove Firebase::remove(const std::string& path) { return FirebaseRemove(host_, auth_, path, http_.get()); } -unique_ptr Firebase::removePtr(const String& path) { +unique_ptr Firebase::removePtr(const std::string& path) { return unique_ptr( new FirebaseRemove(host_, auth_, path, http_.get())); } -FirebaseStream Firebase::stream(const String& path) { +FirebaseStream Firebase::stream(const std::string& path) { // TODO: create new client dedicated to stream. return FirebaseStream(host_, auth_, path, http_.get()); } -unique_ptr Firebase::streamPtr(const String& path) { +unique_ptr Firebase::streamPtr(const std::string& path) { // TODO: create new client dedicated to stream. return unique_ptr( new FirebaseStream(host_, auth_, path, http_.get())); } // FirebaseCall -FirebaseCall::FirebaseCall(const String& host, const String& auth, - const char* method, const String& path, - const String& data, FirebaseHttpClient* http) : http_(http) { - String path_with_auth = makeFirebaseURL(path, auth); +FirebaseCall::FirebaseCall(const std::string& host, const std::string& auth, + const char* method, const std::string& path, + const std::string& data, FirebaseHttpClient* http) : http_(http) { + std::string path_with_auth = makeFirebaseURL(path, auth); http_->setReuseConnection(true); http_->begin(host, path_with_auth); bool followRedirect = false; - if (String(method) == "STREAM") { + if (std::string(method) == "STREAM") { method = "GET"; http_->addHeader("Accept", "text/event-stream"); followRedirect = true; @@ -112,18 +112,18 @@ FirebaseCall::FirebaseCall(const String& host, const String& auth, // TODO: Add a max redirect check if (followRedirect) { while (status == HttpStatus::TEMPORARY_REDIRECT) { - String location = http_->header("Location"); + std::string location = http_->header("Location"); http_->setReuseConnection(false); http_->end(); http_->setReuseConnection(true); http_->begin(location); - status = http_->sendRequest("GET", String()); + status = http_->sendRequest("GET", std::string()); } } if (status != 200) { error_ = FirebaseError(status, - String(method) + " " + path_with_auth + + std::string(method) + " " + path_with_auth + ": " + http_->errorToString(status)); } @@ -137,19 +137,19 @@ const JsonObject& FirebaseCall::json() { //TODO(edcoyne): This is not efficient, we should do something smarter with //the buffers. buffer_ = DynamicJsonBuffer(); - return buffer_.parseObject(response()); + return buffer_.parseObject(response().c_str()); } // FirebaseGet -FirebaseGet::FirebaseGet(const String& host, const String& auth, - const String& path, +FirebaseGet::FirebaseGet(const std::string& host, const std::string& auth, + const std::string& path, FirebaseHttpClient* http) : FirebaseCall(host, auth, "GET", path, "", http) { } // FirebaseSet -FirebaseSet::FirebaseSet(const String& host, const String& auth, - const String& path, const String& value, +FirebaseSet::FirebaseSet(const std::string& host, const std::string& auth, + const std::string& path, const std::string& value, FirebaseHttpClient* http) : FirebaseCall(host, auth, "PUT", path, value, http) { if (!error()) { @@ -158,8 +158,8 @@ FirebaseSet::FirebaseSet(const String& host, const String& auth, } } // FirebasePush -FirebasePush::FirebasePush(const String& host, const String& auth, - const String& path, const String& value, +FirebasePush::FirebasePush(const std::string& host, const std::string& auth, + const std::string& path, const std::string& value, FirebaseHttpClient* http) : FirebaseCall(host, auth, "POST", path, value, http) { if (!error()) { @@ -168,15 +168,15 @@ FirebasePush::FirebasePush(const String& host, const String& auth, } // FirebasePush -FirebaseRemove::FirebaseRemove(const String& host, const String& auth, - const String& path, +FirebaseRemove::FirebaseRemove(const std::string& host, const std::string& auth, + const std::string& path, FirebaseHttpClient* http) : FirebaseCall(host, auth, "DELETE", path, "", http) { } // FirebaseStream -FirebaseStream::FirebaseStream(const String& host, const String& auth, - const String& path, +FirebaseStream::FirebaseStream(const std::string& host, const std::string& auth, + const std::string& path, FirebaseHttpClient* http) : FirebaseCall(host, auth, "STREAM", path, "", http) { } @@ -185,10 +185,10 @@ bool FirebaseStream::available() { return http_->getStreamPtr()->available(); } -FirebaseStream::Event FirebaseStream::read(String& event) { +FirebaseStream::Event FirebaseStream::read(std::string& event) { auto client = http_->getStreamPtr(); Event type; - String typeStr = client->readStringUntil('\n').substring(7); + std::string typeStr = client->readStringUntil('\n').substring(7).c_str(); if (typeStr == "put") { type = Event::PUT; } else if (typeStr == "patch") { @@ -196,7 +196,7 @@ FirebaseStream::Event FirebaseStream::read(String& event) { } else { type = Event::UNKNOWN; } - event = client->readStringUntil('\n').substring(6); + event = client->readStringUntil('\n').substring(6).c_str(); client->readStringUntil('\n'); // consume separator return type; } diff --git a/src/Firebase.h b/src/Firebase.h index df214dd2..81875e23 100644 --- a/src/Firebase.h +++ b/src/Firebase.h @@ -37,29 +37,29 @@ class FirebaseStream; // Firebase REST API client. class Firebase { public: - Firebase(const String& host, const String& auth = ""); + Firebase(const std::string& host, const std::string& auth = ""); - const String& auth() const; + const std::string& auth() const; // Fetch json encoded `value` at `path`. - FirebaseGet get(const String& path); - virtual std::unique_ptr getPtr(const String& path); + FirebaseGet get(const std::string& path); + virtual std::unique_ptr getPtr(const std::string& path); // Set json encoded `value` at `path`. - FirebaseSet set(const String& path, const String& json); - virtual std::unique_ptr setPtr(const String& path, const String& json); + FirebaseSet set(const std::string& path, const std::string& json); + virtual std::unique_ptr setPtr(const std::string& path, const std::string& json); // Add new json encoded `value` to list at `path`. - FirebasePush push(const String& path, const String& json); - virtual std::unique_ptr pushPtr(const String& path, const String& json); + FirebasePush push(const std::string& path, const std::string& json); + virtual std::unique_ptr pushPtr(const std::string& path, const std::string& json); // Delete value at `path`. - FirebaseRemove remove(const String& path); - virtual std::unique_ptr removePtr(const String& path); + FirebaseRemove remove(const std::string& path); + virtual std::unique_ptr removePtr(const std::string& path); // Start a stream of events that affect value at `path`. - FirebaseStream stream(const String& path); - virtual std::unique_ptr streamPtr(const String& path); + FirebaseStream stream(const std::string& path); + virtual std::unique_ptr streamPtr(const std::string& path); protected: // Used for testing. @@ -67,29 +67,29 @@ class Firebase { private: std::unique_ptr http_; - String host_; - String auth_; + std::string host_; + std::string auth_; }; class FirebaseError { public: FirebaseError() {} - FirebaseError(int code, const String& message) : code_(code), message_(message) { + FirebaseError(int code, const std::string& message) : code_(code), message_(message) { } operator bool() const { return code_ != 0; } int code() const { return code_; } - const String& message() const { return message_; } + const std::string& message() const { return message_; } private: int code_ = 0; - String message_ = ""; + std::string message_ = ""; }; class FirebaseCall { public: FirebaseCall() {} - FirebaseCall(const String& host, const String& auth, - const char* method, const String& path, - const String& data = "", + FirebaseCall(const std::string& host, const std::string& auth, + const char* method, const std::string& path, + const std::string& data = "", FirebaseHttpClient* http = NULL); virtual ~FirebaseCall() {} @@ -97,7 +97,7 @@ class FirebaseCall { return error_; } - virtual const String& response() const { + virtual const std::string& response() const { return response_; } @@ -106,59 +106,59 @@ class FirebaseCall { protected: FirebaseHttpClient* http_; FirebaseError error_; - String response_; + std::string response_; DynamicJsonBuffer buffer_; }; class FirebaseGet : public FirebaseCall { public: FirebaseGet() {} - FirebaseGet(const String& host, const String& auth, - const String& path, FirebaseHttpClient* http = NULL); + FirebaseGet(const std::string& host, const std::string& auth, + const std::string& path, FirebaseHttpClient* http = NULL); private: - String json_; + std::string json_; }; class FirebaseSet: public FirebaseCall { public: FirebaseSet() {} - FirebaseSet(const String& host, const String& auth, - const String& path, const String& value, FirebaseHttpClient* http = NULL); + FirebaseSet(const std::string& host, const std::string& auth, + const std::string& path, const std::string& value, FirebaseHttpClient* http = NULL); private: - String json_; + std::string json_; }; class FirebasePush : public FirebaseCall { public: FirebasePush() {} - FirebasePush(const String& host, const String& auth, - const String& path, const String& value, FirebaseHttpClient* http = NULL); + FirebasePush(const std::string& host, const std::string& auth, + const std::string& path, const std::string& value, FirebaseHttpClient* http = NULL); virtual ~FirebasePush() {} - virtual const String& name() const { + virtual const std::string& name() const { return name_; } private: - String name_; + std::string name_; }; class FirebaseRemove : public FirebaseCall { public: FirebaseRemove() {} - FirebaseRemove(const String& host, const String& auth, - const String& path, FirebaseHttpClient* http = NULL); + FirebaseRemove(const std::string& host, const std::string& auth, + const std::string& path, FirebaseHttpClient* http = NULL); }; class FirebaseStream : public FirebaseCall { public: FirebaseStream() {} - FirebaseStream(const String& host, const String& auth, - const String& path, FirebaseHttpClient* http = NULL); + FirebaseStream(const std::string& host, const std::string& auth, + const std::string& path, FirebaseHttpClient* http = NULL); virtual ~FirebaseStream() {} // Return if there is any event available to read. @@ -171,7 +171,7 @@ class FirebaseStream : public FirebaseCall { PATCH }; - static inline String EventToName(Event event) { + static inline std::string EventToName(Event event) { switch(event) { case UNKNOWN: return "UNKNOWN"; @@ -185,7 +185,7 @@ class FirebaseStream : public FirebaseCall { } // Read next json encoded `event` from stream. - virtual Event read(String& event); + virtual Event read(std::string& event); const FirebaseError& error() const { return _error; diff --git a/src/FirebaseArduino.cpp b/src/FirebaseArduino.cpp index dfa782f7..d2fc9c5e 100644 --- a/src/FirebaseArduino.cpp +++ b/src/FirebaseArduino.cpp @@ -16,11 +16,14 @@ #include "FirebaseArduino.h" +// This is needed to compile std::string on esp8266. +template class std::basic_string; + void FirebaseArduino::begin(const String& host, const String& auth) { http_.reset(FirebaseHttpClient::create()); http_->setReuseConnection(true); - host_ = host; - auth_ = auth; + host_ = host.c_str(); + auth_ = auth.c_str(); } String FirebaseArduino::pushInt(const String& path, int value) { @@ -43,9 +46,9 @@ String FirebaseArduino::pushString(const String& path, const String& value) { String FirebaseArduino::push(const String& path, const JsonVariant& value) { String buf; value.printTo(buf); - auto push = FirebasePush(host_, auth_, path, buf, http_.get()); + auto push = FirebasePush(host_, auth_, path.c_str(), buf.c_str(), http_.get()); error_ = push.error(); - return push.name(); + return push.name().c_str(); } void FirebaseArduino::setInt(const String& path, int value) { @@ -61,69 +64,69 @@ void FirebaseArduino::setBool(const String& path, bool value) { } void FirebaseArduino::setString(const String& path, const String& value) { - JsonVariant json(value); + JsonVariant json(value.c_str()); set(path, json); } void FirebaseArduino::set(const String& path, const JsonVariant& value) { String buf; value.printTo(buf); - auto set = FirebaseSet(host_, auth_, path, buf, http_.get()); + auto set = FirebaseSet(host_, auth_, path.c_str(), buf.c_str(), http_.get()); error_ = set.error(); } FirebaseObject FirebaseArduino::get(const String& path) { - auto get = FirebaseGet(host_, auth_, path, http_.get()); + auto get = FirebaseGet(host_, auth_, path.c_str(), http_.get()); error_ = get.error(); if (failed()) { return FirebaseObject{""}; } - return FirebaseObject(get.response()); + return FirebaseObject(get.response().c_str()); } int FirebaseArduino::getInt(const String& path) { - auto get = FirebaseGet(host_, auth_, path, http_.get()); + auto get = FirebaseGet(host_, auth_, path.c_str(), http_.get()); error_ = get.error(); if (failed()) { return 0; } - return FirebaseObject(get.response()).getInt(); + return FirebaseObject(get.response().c_str()).getInt(); } float FirebaseArduino::getFloat(const String& path) { - auto get = FirebaseGet(host_, auth_, path, http_.get()); + auto get = FirebaseGet(host_, auth_, path.c_str(), http_.get()); error_ = get.error(); if (failed()) { return 0.0f; } - return FirebaseObject(get.response()).getFloat(); + return FirebaseObject(get.response().c_str()).getFloat(); } String FirebaseArduino::getString(const String& path) { - auto get = FirebaseGet(host_, auth_, path, http_.get()); + auto get = FirebaseGet(host_, auth_, path.c_str(), http_.get()); error_ = get.error(); if (failed()) { return ""; } - return FirebaseObject(get.response()).getString(); + return FirebaseObject(get.response().c_str()).getString(); } bool FirebaseArduino::getBool(const String& path) { - auto get = FirebaseGet(host_, auth_, path, http_.get()); + auto get = FirebaseGet(host_, auth_, path.c_str(), http_.get()); error_ = get.error(); if (failed()) { return ""; } - return FirebaseObject(get.response()).getBool(); + return FirebaseObject(get.response().c_str()).getBool(); } void FirebaseArduino::remove(const String& path) { - auto remove = FirebaseRemove(host_, auth_, path, http_.get()); + auto remove = FirebaseRemove(host_, auth_, path.c_str(), http_.get()); error_ = remove.error(); } void FirebaseArduino::stream(const String& path) { - auto stream = FirebaseStream(host_, auth_, path, http_.get()); + auto stream = FirebaseStream(host_, auth_, path.c_str(), http_.get()); error_ = stream.error(); } @@ -136,7 +139,7 @@ FirebaseObject FirebaseArduino::readEvent() { String type = client->readStringUntil('\n').substring(7);; String event = client->readStringUntil('\n').substring(6); client->readStringUntil('\n'); // consume separator - FirebaseObject obj = FirebaseObject(event); + FirebaseObject obj = FirebaseObject(event.c_str()); obj.getJsonVariant().asObject()["type"] = type; return obj; } @@ -150,7 +153,7 @@ bool FirebaseArduino::failed() { } const String& FirebaseArduino::error() { - return error_.message(); + return error_.message().c_str(); } FirebaseArduino Firebase; diff --git a/src/FirebaseArduino.h b/src/FirebaseArduino.h index 2b20db02..a0bcca27 100644 --- a/src/FirebaseArduino.h +++ b/src/FirebaseArduino.h @@ -17,6 +17,8 @@ #ifndef FIREBASE_ARDUINO_H #define FIREBASE_ARDUINO_H +#include + #include "Firebase.h" #include "FirebaseObject.h" @@ -221,8 +223,8 @@ class FirebaseArduino { */ const String& error(); private: - String host_; - String auth_; + std::string host_; + std::string auth_; FirebaseError error_; std::unique_ptr http_; }; diff --git a/src/FirebaseHttpClient.h b/src/FirebaseHttpClient.h index 326c7410..106538e6 100644 --- a/src/FirebaseHttpClient.h +++ b/src/FirebaseHttpClient.h @@ -1,6 +1,8 @@ #ifndef FIREBASE_HTTP_CLIENT_H #define FIREBASE_HTTP_CLIENT_H +#include + #include "Arduino.h" #include "Stream.h" @@ -13,29 +15,29 @@ class FirebaseHttpClient { static FirebaseHttpClient* create(); virtual void setReuseConnection(bool reuse) = 0; - virtual void begin(const String& url) = 0; - virtual void begin(const String& host, const String& path) = 0; + virtual void begin(const std::string& url) = 0; + virtual void begin(const std::string& host, const std::string& path) = 0; virtual void end() = 0; - virtual void addHeader(const String& name, const String& value) = 0; + virtual void addHeader(const std::string& name, const std::string& value) = 0; virtual void collectHeaders(const char* header_keys[], const int header_key_count) = 0; - virtual String header(const String& name) = 0; + virtual std::string header(const std::string& name) = 0; - virtual int sendRequest(const String& method, const String& data) = 0; + virtual int sendRequest(const std::string& method, const std::string& data) = 0; - virtual String getString() = 0; + virtual std::string getString() = 0; virtual Stream* getStreamPtr() = 0; - virtual String errorToString(int error_code) = 0; + virtual std::string errorToString(int error_code) = 0; protected: static const uint16_t kFirebasePort = 443; }; -static const String kFirebaseFingerprint = +static const char kFirebaseFingerprint[] = "7A 54 06 9B DC 7A 25 B3 86 8D 66 53 48 2C 0B 96 42 C7 B3 0A"; #endif // FIREBASE_HTTP_CLIENT_H diff --git a/src/FirebaseHttpClient_Esp8266.cpp b/src/FirebaseHttpClient_Esp8266.cpp index 145afa9a..4d65ac1f 100644 --- a/src/FirebaseHttpClient_Esp8266.cpp +++ b/src/FirebaseHttpClient_Esp8266.cpp @@ -1,6 +1,8 @@ #include "FirebaseHttpClient.h" +#include + // The ordering of these includes matters greatly. #include #include @@ -21,47 +23,49 @@ class FirebaseHttpClientEsp8266 : public FirebaseHttpClient { http_.setReuse(reuse); } - void begin(const String& url) override { - http_.begin(url, kFirebaseFingerprint); + void begin(const std::string& url) override { + http_.begin(url.c_str(), kFirebaseFingerprint); } - void begin(const String& host, const String& path) override { - http_.begin(host, kFirebasePort, path, true, kFirebaseFingerprint); + void begin(const std::string& host, const std::string& path) override { + http_.begin(host.c_str(), kFirebasePort, path.c_str(), true, kFirebaseFingerprint); } void end() override { http_.end(); } - void addHeader(const String& name, const String& value) override { - http_.addHeader(name, value); + void addHeader(const std::string& name, const std::string& value) override { + http_.addHeader(name.c_str(), value.c_str()); } void collectHeaders(const char* header_keys[], const int count) override { http_.collectHeaders(header_keys, count); } - String header(const String& name) override { - return http_.header(name.c_str()); + std::string header(const std::string& name) override { + return http_.header(name.c_str()).c_str(); } - int sendRequest(const String& method, const String& data) override { + int sendRequest(const std::string& method, const std::string& data) override { return http_.sendRequest(method.c_str(), (uint8_t*)data.c_str(), data.length()); } - String getString() override { - return http_.getString(); + std::string getString() override { + return http_.getString().c_str(); } Stream* getStreamPtr() override { return http_.getStreamPtr(); } - String errorToString(int error_code) override { + std::string errorToString(int error_code) override { #ifdef USE_ESP_ARDUINO_CORE_2_0_0 - return String(error_code); + char buff[11]; + itoa(error_code, buff, 10); + return buff; #else - return HTTPClient::errorToString(error_code); + return HTTPClient::errorToString(error_code).c_str(); #endif } @@ -72,4 +76,4 @@ class FirebaseHttpClientEsp8266 : public FirebaseHttpClient { FirebaseHttpClient* FirebaseHttpClient::create() { return new FirebaseHttpClientEsp8266(); } - + diff --git a/src/FirebaseObject.cpp b/src/FirebaseObject.cpp index dc1f1d87..6686aeb1 100644 --- a/src/FirebaseObject.cpp +++ b/src/FirebaseObject.cpp @@ -16,7 +16,9 @@ #include "FirebaseObject.h" -FirebaseObject::FirebaseObject(const String& data) : data_{data} { +// We need to make a copy of data here, even though it may be large. +// It will need to be long lived. +FirebaseObject::FirebaseObject(const char* data) : data_{data} { json_ = buffer_.parse(&data_[0]); // TODO(proppy): find a way to check decoding error, tricky because // ArduinoJson doesn't surface error for variant parsing. diff --git a/src/FirebaseObject.h b/src/FirebaseObject.h index 8233bbde..8755914f 100644 --- a/src/FirebaseObject.h +++ b/src/FirebaseObject.h @@ -33,7 +33,7 @@ class FirebaseObject { * Construct from json. * \param data JSON formatted string. */ - FirebaseObject(const String& data); + FirebaseObject(const char* data); /** * Return the value as a boolean. diff --git a/src/SerialTransceiver.h b/src/SerialTransceiver.h index 45ae91cf..dd0633a9 100644 --- a/src/SerialTransceiver.h +++ b/src/SerialTransceiver.h @@ -1,3 +1,5 @@ +#include + #include "modem/SerialTransceiver.h" // Bring them into the base namespace for easier use in arduino ide. using firebase::modem::SerialTransceiver; diff --git a/src/modem/begin-command.cpp b/src/modem/begin-command.cpp index 97de7a09..ddcfb12c 100644 --- a/src/modem/begin-command.cpp +++ b/src/modem/begin-command.cpp @@ -33,7 +33,7 @@ bool BeginCommand::execute(const String& command, return false; } - new_firebase_.reset(new Firebase(host, auth)); + new_firebase_.reset(new Firebase(host.c_str(), auth.c_str())); out->println("+OK"); return true; diff --git a/src/modem/get-command.cpp b/src/modem/get-command.cpp index 0ee19299..546775f8 100644 --- a/src/modem/get-command.cpp +++ b/src/modem/get-command.cpp @@ -13,16 +13,16 @@ bool GetCommand::execute(const String& command, return false; } - String path = in->readLine(); + std::string path = in->readLine().c_str(); std::unique_ptr get(fbase().getPtr(path)); if (get->error()) { out->print("-FAIL "); - out->println(get->error().message()); + out->println(get->error().message().c_str()); return false; } - String value(get->response()); + String value(get->response().c_str()); // TODO implement json parsing to pull and process value. out->print("+"); out->println(value); diff --git a/src/modem/json_util.h b/src/modem/json_util.h index 544120a1..6917e291 100644 --- a/src/modem/json_util.h +++ b/src/modem/json_util.h @@ -3,11 +3,21 @@ namespace firebase { namespace modem { +namespace { +std::string ReplaceAll(std::string str, const std::string& from, const std::string& to) { + size_t start_pos = 0; + while((start_pos = str.find(from, start_pos)) != std::string::npos) { + str.replace(start_pos, from.length(), to); + start_pos += to.length(); // Handles case where 'to' is a substring of 'from' + } + return str; +} +} // TODO(edcoyne): We should use a json library to escape. -inline String EncodeForJson(String input) { - input.replace("\\", "\\\\"); - input.replace("\"", "\\\""); +inline std::string EncodeForJson(std::string input) { + input = ReplaceAll(input, "\\", "\\\\"); + input = ReplaceAll(input, "\"", "\\\""); return "\"" + input + "\""; } diff --git a/src/modem/push-command.cpp b/src/modem/push-command.cpp index 73d0f7ef..2f73873c 100644 --- a/src/modem/push-command.cpp +++ b/src/modem/push-command.cpp @@ -14,15 +14,15 @@ bool PushCommand::execute(const String& command, return false; } - String path(in->readStringUntil(' ')); - String data(in->readLine()); + std::string path(in->readStringUntil(' ').c_str()); + std::string data(in->readLine().c_str()); std::unique_ptr push( fbase().pushPtr(path, EncodeForJson(data))); if (push->error()) { out->print("-FAIL "); - out->println(push->error().message()); + out->println(push->error().message().c_str()); return false; } else { out->println("+OK"); diff --git a/src/modem/remove-command.cpp b/src/modem/remove-command.cpp index 5026d25b..d8c4765c 100644 --- a/src/modem/remove-command.cpp +++ b/src/modem/remove-command.cpp @@ -14,11 +14,11 @@ bool RemoveCommand::execute(const String& command, } String path = in->readLine(); - std::unique_ptr get(fbase().removePtr(path)); + std::unique_ptr get(fbase().removePtr(path.c_str())); if (get->error()) { out->print("-FAIL "); - out->println(get->error().message()); + out->println(get->error().message().c_str()); return false; } diff --git a/src/modem/set-command.cpp b/src/modem/set-command.cpp index 35b53040..afa3c670 100644 --- a/src/modem/set-command.cpp +++ b/src/modem/set-command.cpp @@ -14,15 +14,15 @@ bool SetCommand::execute(const String& command, return false; } - String path(in->readStringUntil(' ')); - String data(in->readLine()); + std::string path(in->readStringUntil(' ').c_str()); + std::string data(in->readLine().c_str()); std::unique_ptr set(fbase().setPtr(path, EncodeForJson(data))); if (set->error()) { out->print("-FAIL "); - out->println(set->error().message()); + out->println(set->error().message().c_str()); return false; } else { out->println("+OK"); diff --git a/src/modem/stream-command.cpp b/src/modem/stream-command.cpp index b3b1c649..9a83d9e9 100644 --- a/src/modem/stream-command.cpp +++ b/src/modem/stream-command.cpp @@ -13,26 +13,27 @@ bool StreamCommand::execute(const String& command, return false; } - String path = in->readLine(); + std::string path = in->readLine().c_str(); std::unique_ptr stream(fbase().streamPtr(path)); if (stream->error()) { out->print("-FAIL "); - out->println(stream->error().message()); + out->println(stream->error().message().c_str()); return false; } bool running = true; while(running) { if (stream->available()) { - String json; + std::string json; FirebaseStream::Event event = stream->read(json); out->print("+"); - out->print(FirebaseStream::EventToName(event) + " "); + out->print(FirebaseStream::EventToName(event).c_str()); + out->print(" "); // TODO(edcoyne): add json parsing and get real path. out->println("/dummy/path"); out->println(json.length()); - out->println(json); + out->println(json.c_str()); } else if (in->available()) { String command = in->readLine(); if (command == "END_STREAM") { diff --git a/src/throw_out_of_range.cpp b/src/throw_out_of_range.cpp new file mode 100644 index 00000000..865b6ecf --- /dev/null +++ b/src/throw_out_of_range.cpp @@ -0,0 +1,9 @@ +#include + +//TODO(edcoyne): remove this when it is present upstream. +// Currently this is needed to use std::string on Arduino. +namespace std{ +void __attribute__((weak)) __throw_out_of_range(const char* str) { + panic(); +} +} diff --git a/test/Makefile b/test/Makefile index 84ba5c35..403b0cbc 100644 --- a/test/Makefile +++ b/test/Makefile @@ -51,5 +51,6 @@ firebase-test: ${OBJS} check: firebase-test ./firebase-test +#TODO: had to echo this because it picks up FirebaseObject.h as well and deletes it :( clean: - rm -f ${OBJS} firebase-test + echo rm -f ${OBJS} firebase-test diff --git a/test/dummies/FirebaseHttpClient_dummy.cpp b/test/dummies/FirebaseHttpClient_dummy.cpp index e8a746e9..571fa842 100644 --- a/test/dummies/FirebaseHttpClient_dummy.cpp +++ b/test/dummies/FirebaseHttpClient_dummy.cpp @@ -11,30 +11,30 @@ class FirebaseHttpClientDummy : public FirebaseHttpClient { void setReuseConnection(bool UNUSED_ARG(reuse)) override { } - void begin(const String& UNUSED_ARG(url)) override { + void begin(const std::string& UNUSED_ARG(url)) override { } - void begin(const String& UNUSED_ARG(host), const String& UNUSED_ARG(path)) override { + void begin(const std::string& UNUSED_ARG(host), const std::string& UNUSED_ARG(path)) override { } void end() override { } - void addHeader(const String& UNUSED_ARG(name), const String& UNUSED_ARG(value)) override { + void addHeader(const std::string& UNUSED_ARG(name), const std::string& UNUSED_ARG(value)) override { } void collectHeaders(const char* UNUSED_ARG(header_keys[]), const int UNUSED_ARG(count)) override { } - String header(const String& UNUSED_ARG(name)) override { + std::string header(const std::string& UNUSED_ARG(name)) override { return ""; } - int sendRequest(const String& UNUSED_ARG(method), const String& UNUSED_ARG(data)) override { + int sendRequest(const std::string& UNUSED_ARG(method), const std::string& UNUSED_ARG(data)) override { return 0; } - String getString() override { + std::string getString() override { return ""; } @@ -42,8 +42,8 @@ class FirebaseHttpClientDummy : public FirebaseHttpClient { return nullptr; } - String errorToString(int UNUSED_ARG(error_code)) override { - return String(); + std::string errorToString(int UNUSED_ARG(error_code)) override { + return std::string(); } }; diff --git a/test/mock-firebase.h b/test/mock-firebase.h index 3d788e69..92f1e9fa 100644 --- a/test/mock-firebase.h +++ b/test/mock-firebase.h @@ -10,28 +10,28 @@ namespace modem { class MockFirebase : public Firebase { public: - MOCK_METHOD1(getPtr, std::unique_ptr(const String&)); - MOCK_METHOD2(setPtr, std::unique_ptr(const String&, const String&)); - MOCK_METHOD2(pushPtr, std::unique_ptr(const String&, const String&)); - MOCK_METHOD1(removePtr, std::unique_ptr(const String&)); - MOCK_METHOD1(streamPtr, std::unique_ptr(const String&)); + MOCK_METHOD1(getPtr, std::unique_ptr(const std::string&)); + MOCK_METHOD2(setPtr, std::unique_ptr(const std::string&, const std::string&)); + MOCK_METHOD2(pushPtr, std::unique_ptr(const std::string&, const std::string&)); + MOCK_METHOD1(removePtr, std::unique_ptr(const std::string&)); + MOCK_METHOD1(streamPtr, std::unique_ptr(const std::string&)); }; class MockFirebaseGet : public FirebaseGet { public: - MOCK_CONST_METHOD0(response, const String&()); + MOCK_CONST_METHOD0(response, const std::string&()); MOCK_CONST_METHOD0(error, const FirebaseError&()); }; class MockFirebaseSet : public FirebaseSet { public: - MOCK_CONST_METHOD0(json, const String&()); + MOCK_CONST_METHOD0(json, const std::string&()); MOCK_CONST_METHOD0(error, const FirebaseError&()); }; class MockFirebasePush : public FirebasePush { public: - MOCK_CONST_METHOD0(name, const String&()); + MOCK_CONST_METHOD0(name, const std::string&()); MOCK_CONST_METHOD0(error, const FirebaseError&()); }; @@ -43,7 +43,7 @@ class MockFirebaseRemove : public FirebaseRemove { class MockFirebaseStream : public FirebaseStream { public: MOCK_METHOD0(available, bool()); - MOCK_METHOD1(read, Event(String& event)); + MOCK_METHOD1(read, Event(std::string& event)); MOCK_CONST_METHOD0(error, const FirebaseError&()); }; diff --git a/test/modem/get-command_test.cpp b/test/modem/get-command_test.cpp index 6c1981bb..ebdac3b5 100644 --- a/test/modem/get-command_test.cpp +++ b/test/modem/get-command_test.cpp @@ -67,7 +67,7 @@ TEST_F(GetCommandTest, handlesError) { EXPECT_CALL(out_, print(String("-FAIL "))) .WillOnce(Return(1)); - EXPECT_CALL(out_, println(error.message())) + EXPECT_CALL(out_, println(String(error.message().c_str()))) .WillOnce(Return(1)); ASSERT_FALSE(RunCommand(error)); diff --git a/test/modem/remove-command_test.cpp b/test/modem/remove-command_test.cpp index 5c361e7e..e6781745 100644 --- a/test/modem/remove-command_test.cpp +++ b/test/modem/remove-command_test.cpp @@ -60,7 +60,7 @@ TEST_F(RemoveCommandTest, handlesError) { EXPECT_CALL(out_, print(String("-FAIL "))) .WillOnce(Return(1)); - EXPECT_CALL(out_, println(error.message())) + EXPECT_CALL(out_, println(String(error.message().c_str()))) .WillOnce(Return(1)); ASSERT_FALSE(RunCommand(error)); } diff --git a/test/modem/stream-command_test.cpp b/test/modem/stream-command_test.cpp index 4cfc17be..4618a8e7 100644 --- a/test/modem/stream-command_test.cpp +++ b/test/modem/stream-command_test.cpp @@ -52,14 +52,16 @@ TEST_F(StreamCommandTest, streams) { .WillRepeatedly(Return(false)); EXPECT_CALL(*stream_, read(_)) - .WillOnce(Invoke([&value](String& json) { - json = value; + .WillOnce(Invoke([&value](std::string& json) { + json = value.c_str(); return FirebaseStream::PUT; })); EXPECT_CALL(out_, print(String("+"))) .WillOnce(Return(1)); - EXPECT_CALL(out_, print(String("PUT "))) + EXPECT_CALL(out_, print(String("PUT"))) + .WillOnce(Return(1)); + EXPECT_CALL(out_, print(String(" "))) .WillOnce(Return(1)); EXPECT_CALL(out_, println(String("/dummy/path"))) .WillOnce(Return(1)); @@ -84,7 +86,7 @@ TEST_F(StreamCommandTest, handlesError) { EXPECT_CALL(out_, print(String("-FAIL "))) .WillOnce(Return(1)); - EXPECT_CALL(out_, println(error.message())) + EXPECT_CALL(out_, println(String(error.message().c_str()))) .WillOnce(Return(1)); ASSERT_FALSE(RunCommand(error)); }