diff --git a/examples/example02_streaming.cpp b/examples/example02_streaming.cpp index 0f95343..389b16b 100644 --- a/examples/example02_streaming.cpp +++ b/examples/example02_streaming.cpp @@ -65,9 +65,13 @@ int main(int argc, char *argv[]) // Print new events every 2 seconds, for 10 seconds. for (auto counter{0}; counter < 5; ++counter) { - cout << "----------------------------------------" << endl; sleep_for(2s); - cout << connection.get_new_stream_contents() << endl; + for (const auto &event : connection.get_new_events()) + { + // Print typo of event and the beginning of the data. + cout << event.type << ": " + << event.data.substr(0, 70) << " …" << endl; + } } // Cancel the stream, … diff --git a/include/connection.hpp b/include/connection.hpp index b32acea..6885931 100644 --- a/include/connection.hpp +++ b/include/connection.hpp @@ -25,6 +25,7 @@ #include #include #include +#include namespace mastodonpp { @@ -32,6 +33,7 @@ namespace mastodonpp using std::string; using std::string_view; using std::variant; +using std::vector; /*! * @brief An endpoint. Either API::endpoint_type or `std::string_view`. @@ -40,6 +42,29 @@ using std::variant; */ using endpoint_variant = variant; +/*! + * @brief A stream event. + * + * @since 0.1.0 + * + * @headerfile connection.hpp mastodonpp/connection.hpp + */ +struct event_type +{ + /*! + * @brief The type of the event. + * + * Can be: “update”, “notification”, “delete” or “filters_changed”. For + * more information consult [the Mastodon documentation] + * (https://docs.joinmastodon.org/methods/timelines/streaming/ + * #event-types-a-idevent-typesa). + */ + string type; + + //! The payload. + string data; +}; + /*! * @brief Represents a connection to an instance. Used for requests. * @@ -106,10 +131,19 @@ public: * that you are calling this function mid-transfer. You have to check the * data integrity yourself. * + * Using get_new_events() instead is recommended. + * * @since 0.1.0 */ string get_new_stream_contents(); + /*! + * @brief Get new stream events. + * + * @since 0.1.0 + */ + vector get_new_events(); + private: Instance &_instance; const string_view _baseuri; diff --git a/src/connection.cpp b/src/connection.cpp index 0deaed8..4046d6c 100644 --- a/src/connection.cpp +++ b/src/connection.cpp @@ -58,4 +58,33 @@ string Connection::get_new_stream_contents() return buffer_copy; } +vector Connection::get_new_events() +{ + buffer_mutex.lock(); + auto &buffer{get_buffer()}; + vector events; + + size_t pos{0}; + while ((pos = buffer.find("event: ")) != string::npos) + { + const auto endpos{buffer.find("\n\n", pos)}; + if (endpos == string::npos) + { + break; + } + + event_type event; + pos += 7; // Length of "event: ". + event.type = buffer.substr(pos, buffer.find('\n', pos) - pos); + pos = buffer.find("data: ") + 6; + event.data = buffer.substr(pos, endpos - pos); + events.push_back(event); + + buffer.erase(0, endpos); + } + + buffer_mutex.unlock(); + return events; +} + } // namespace mastodonpp