Changed api to allow user to create clients and syncers at will.

This commit is contained in:
rexy712 2019-07-17 16:56:07 -07:00
parent 2f8bb781a1
commit 6634f30c28
11 changed files with 77 additions and 83 deletions

View File

@ -25,7 +25,7 @@
#include "raii/filerd.hpp"
#include "matrix/session_info.hpp"
#include "matrix/upload_info.hpp"
#include "matrix/client_base.hpp"
#include "matrix/connection.hpp"
#include <vector> //vector
#include <memory> //shared_ptr
#include <cstdlib> //size_t
@ -33,14 +33,11 @@
namespace matrix{
class session;
//main class
class client : public internal::client_base
class client : public connection
{
friend class ::matrix::session;
private:
const std::shared_ptr<internal::session_info> m_ses;
public:
client(std::shared_ptr<internal::session_info>&);
client(const std::shared_ptr<internal::session_info>&);
client(const client& b) = default;
client(client&& b) = default;
~client(void) = default;

View File

@ -16,30 +16,35 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MATRIX_CLIENT_BASE_HPP
#define MATRIX_CLIENT_BASE_HPP
#ifndef MATRIX_CONNECTION_HPP
#define MATRIX_CONNECTION_HPP
#include "raii/curler.hpp"
#include "raii/string.hpp"
#include "raii/rjp_string.hpp"
#include "matrix/session_info.hpp"
#include <memory> //shared_ptr
namespace matrix::internal{
namespace matrix{
class client_base
class connection
{
protected:
mutable raii::curler m_curl;
std::shared_ptr<internal::session_info> m_ses;
protected:
client_base(void);
client_base(const client_base&) = default;
client_base(client_base&&) = default;
~client_base(void) = default;
client_base& operator=(const client_base&) = default;
client_base& operator=(client_base&&) = default;
connection(const std::shared_ptr<internal::session_info>&);
connection(const connection&) = default;
connection(connection&&) = default;
connection& operator=(const connection&) = default;
connection& operator=(connection&&) = default;
public:
~connection(void) = default;
protected:
void _set_curl_useragent(const raii::string_base& useragent);
protected:
static size_t _post_reply_curl_callback(char* ptr, size_t size, size_t nmemb, void* userdata);
raii::string _get_curl(const raii::string_base& url)const;
raii::string _post_curl(const raii::string_base& postdata, const raii::string_base& url, const raii::curl_llist& header)const;

View File

@ -23,30 +23,25 @@
#include "matrix/syncer.hpp"
#include "matrix/session_info.hpp"
#include "matrix/auth.hpp"
#include "raii/curler.hpp"
#include "raii/string.hpp"
#include <memory> //shared_ptr
#include "matrix/connection.hpp"
#include <utility> //pair
namespace matrix{
class session
class session : protected connection
{
private:
std::shared_ptr<internal::session_info> m_ses;
client m_client;
syncer m_sync;
public:
session(const auth_data&);
//local setter
void set_useragent(const raii::string_base&);
void set_useragent(raii::string&&);
client& get_client(void);
const client& get_client(void)const;
syncer& get_syncer(void);
const syncer& get_syncer(void)const;
bool valid(void)const;
client create_client(void)const;
syncer create_syncer(void)const;
void invalidate(void);
private:
void _populate_session_info(const auth_data& a);

View File

@ -23,21 +23,20 @@
#include "raii/rjp_string.hpp"
#include "raii/string.hpp"
#include "matrix/session_info.hpp"
#include "matrix/client_base.hpp"
#include "matrix/connection.hpp"
#include <cstdlib> //size_t
#include <memory> //shared_ptr
namespace matrix{
class session;
class syncer : public internal::client_base
class syncer : public connection
{
friend class ::matrix::session;
private:
const std::shared_ptr<internal::session_info> m_ses;
raii::rjp_string m_next_batch; //string which tracks where we are in the server history
public:
syncer(std::shared_ptr<internal::session_info>&);
syncer(const std::shared_ptr<internal::session_info>&);
syncer(const syncer& b) = default;
syncer(syncer&& b) = default;
~syncer(void) = default;

View File

@ -38,6 +38,8 @@ namespace raii{
curler(curler&& c)noexcept;
~curler(void);
curler& operator=(const curler&);
curler& operator=(curler&&);
template<class T>
curler& setopt(CURLoption option, T&& t){
curl_easy_setopt(m_curl, option, t);

View File

@ -35,9 +35,8 @@
namespace matrix{
//Ctor
client::client(std::shared_ptr<internal::session_info>& ses):
client_base(),
m_ses(ses){}
client::client(const std::shared_ptr<internal::session_info>& ses):
connection(ses){}
//local getter
const raii::rjp_string& client::access_token(void)const{

View File

@ -16,28 +16,29 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "matrix/client_base.hpp"
#include "matrix/connection.hpp"
#include "raii/rjp_ptr.hpp"
#include "raii/static_string.hpp"
#include <cstdlib> //size_t
#include <algorithm> //min, max
namespace matrix::internal{
namespace matrix{
client_base::client_base(void):
m_curl()
connection::connection(const std::shared_ptr<internal::session_info>& ses):
m_curl(),
m_ses(ses)
{
_set_curl_defaults(""_ss);
}
void client_base::_set_curl_useragent(const raii::string_base& useragent){
void connection::_set_curl_useragent(const raii::string_base& useragent){
m_curl.setuseragent(useragent);
}
size_t client_base::_post_reply_curl_callback(char* ptr, size_t size, size_t nmemb, void* userdata){
size_t connection::_post_reply_curl_callback(char* ptr, size_t size, size_t nmemb, void* userdata){
raii::string* data = reinterpret_cast<raii::string*>(userdata);
(*data) += ptr;
return size*nmemb;
}
raii::string client_base::_get_curl(const raii::string_base& url)const{
raii::string connection::_get_curl(const raii::string_base& url)const{
raii::string reply;
m_curl.getreq();
m_curl.seturl(url);
@ -49,7 +50,7 @@ namespace matrix::internal{
return {};
return reply;
}
raii::string client_base::_post_curl(const raii::string_base& postdata, const raii::string_base& url, const raii::curl_llist& header)const{
raii::string connection::_post_curl(const raii::string_base& postdata, const raii::string_base& url, const raii::curl_llist& header)const{
raii::string reply;
m_curl.postreq();
m_curl.setopt(CURLOPT_POSTFIELDS, postdata.get());
@ -76,7 +77,7 @@ namespace matrix::internal{
src->data += to_copy;
return to_copy;
}
raii::string client_base::_put_curl(const raii::string_base& putdata, const raii::string_base& url, const raii::curl_llist& header)const{
raii::string connection::_put_curl(const raii::string_base& putdata, const raii::string_base& url, const raii::curl_llist& header)const{
raii::string reply;
put_data data{putdata.get(), putdata.length()};
m_curl.putreq();
@ -96,7 +97,7 @@ namespace matrix::internal{
return {};
return reply;
}
raii::rjp_string client_base::_post_and_find(const raii::string_base& data, const raii::string_base& url,
raii::rjp_string connection::_post_and_find(const raii::string_base& data, const raii::string_base& url,
const raii::curl_llist& header, const raii::string_base& target)const
{
raii::string reply = _post_curl(data, url, header);
@ -104,13 +105,13 @@ namespace matrix::internal{
return {};
return _curl_reply_search(reply, target);
}
raii::rjp_string client_base::_get_and_find(const raii::string_base& url, const raii::string_base& target)const{
raii::rjp_string connection::_get_and_find(const raii::string_base& url, const raii::string_base& target)const{
raii::string reply = _get_curl(url);
if(!reply)
return {};
return _curl_reply_search(reply, target);
}
raii::rjp_string client_base::_curl_reply_search(const raii::string_base& reply, const raii::string_base& target)const{
raii::rjp_string connection::_curl_reply_search(const raii::string_base& reply, const raii::string_base& target)const{
raii::rjp_ptr root(rjp_parse(reply));
if(!root)
return {};
@ -119,7 +120,7 @@ namespace matrix::internal{
return {};
return raii::rjp_string(res.value);
}
void client_base::_set_curl_defaults(const raii::string_base& useragent)const{
void connection::_set_curl_defaults(const raii::string_base& useragent)const{
m_curl.setopt(CURLOPT_BUFFERSIZE, 102400L);
m_curl.setopt(CURLOPT_NOPROGRESS, 1L);
m_curl.setuseragent(useragent);

View File

@ -24,13 +24,10 @@
namespace matrix{
session::session(const auth_data& auth):
m_ses(new internal::session_info),
m_client(m_ses),
m_sync(m_ses)
connection(std::make_shared<internal::session_info>())
{
_populate_session_info(auth);
m_client._set_curl_useragent(m_ses->useragent);
m_sync._set_curl_useragent(m_ses->useragent);
_set_curl_defaults(m_ses->useragent);
}
void session::set_useragent(const raii::string_base& agent){
@ -40,23 +37,16 @@ namespace matrix{
m_ses->useragent = std::move(agent);
}
client& session::get_client(void){
return m_client;
}
const client& session::get_client(void)const{
return m_client;
}
syncer& session::get_syncer(void){
return m_sync;
}
const syncer& session::get_syncer(void)const{
return m_sync;
}
bool session::valid(void)const{
return m_ses->access_token;
}
client session::create_client(void)const{
return client(m_ses);
}
syncer session::create_syncer(void)const{
return syncer(m_ses);
}
void session::invalidate(void){
m_ses->useragent.reset();
m_ses->homeserver.reset();
@ -69,7 +59,7 @@ namespace matrix{
m_ses->useragent = a.useragent;
m_ses->homeserver = a.homeserver;
m_ses->access_token = a.access_token;
auto reply = m_client._get_curl(mat_url_list::stat_whoami(m_ses->homeserver, m_ses->access_token));
auto reply = _get_curl(mat_url_list::stat_whoami(m_ses->homeserver, m_ses->access_token));
if(!reply){
auto [token, id] = _get_new_access_token(a.name, a.pass, mat_url_list::login(m_ses->homeserver));
if(token && id){
@ -89,15 +79,14 @@ namespace matrix{
CURLcode result;
raii::string postdata("{\"type\":\"m.login.password\", \"user\":\"" + raii::json_escape(name) + "\", \"password\":\"" + raii::json_escape(pass) + "\"}");
raii::string reply;
raii::curler& cur = m_client.m_curl;
cur.seturl(loginurl);
cur.setpostdata(postdata);
cur.postreq();
cur.setopt(CURLOPT_WRITEFUNCTION, client::_post_reply_curl_callback);
cur.setopt(CURLOPT_WRITEDATA, &reply);
m_curl.seturl(loginurl);
m_curl.setpostdata(postdata);
m_curl.postreq();
m_curl.setopt(CURLOPT_WRITEFUNCTION, client::_post_reply_curl_callback);
m_curl.setopt(CURLOPT_WRITEDATA, &reply);
result = cur.perform();
result = m_curl.perform();
if(result != CURLE_OK)
return {};
@ -105,7 +94,7 @@ namespace matrix{
return reply;
}
raii::rjp_string session::_get_userid(void){
auto reply = m_client._get_curl(mat_url_list::stat_whoami(m_ses->homeserver, m_ses->access_token));
auto reply = _get_curl(mat_url_list::stat_whoami(m_ses->homeserver, m_ses->access_token));
if(!reply)
return {};
raii::rjp_ptr root(rjp_parse(reply));

View File

@ -22,9 +22,8 @@
#include "raii/util.hpp"
namespace matrix{
syncer::syncer(std::shared_ptr<internal::session_info>& ses):
client_base(),
m_ses(ses){}
syncer::syncer(const std::shared_ptr<internal::session_info>& ses):
connection(ses){}
raii::string syncer::sync(size_t timeout){
raii::string reply = _get_curl(m_ses->urls.sync(m_ses->homeserver, m_ses->access_token, m_next_batch, raii::itostr(timeout)));

View File

@ -33,6 +33,14 @@ namespace raii{
curl_easy_cleanup(m_curl);
}
curler& curler::operator=(const curler& c){
curler tmp(c);
return *this = std::move(tmp);
}
curler& curler::operator=(curler&& c){
std::swap(m_curl, c.m_curl);
return *this;
}
curler& curler::putreq(void){
setopt(CURLOPT_HTTPGET, 0L);
setopt(CURLOPT_POST, 0L);

View File

@ -26,7 +26,7 @@
#include <future>
#include <chrono>
void sync_fn(matrix::syncer& syn, std::atomic_bool& should_quit){
void sync_fn(matrix::syncer syn, std::atomic_bool& should_quit){
auto sync_reply = syn.sync(0);
while(!should_quit){
@ -34,7 +34,7 @@ void sync_fn(matrix::syncer& syn, std::atomic_bool& should_quit){
printf("%s\n", sync_reply.get());
}
}
void keyboard_fn(matrix::client& client, std::atomic_bool& should_quit){
void keyboard_fn(matrix::client client, std::atomic_bool& should_quit){
char buffer[2048];
while(!should_quit){
fgets(buffer, 2048, stdin);
@ -61,8 +61,8 @@ int main(){
fprintf(stderr, "Succ\n");
std::atomic_bool should_quit = false;
std::thread sync_thread(sync_fn, std::ref(ses.get_syncer()), std::ref(should_quit));
std::thread key_thread(keyboard_fn, std::ref(ses.get_client()), std::ref(should_quit));
std::thread sync_thread(sync_fn, ses.create_syncer(), std::ref(should_quit));
std::thread key_thread(keyboard_fn, ses.create_client(), std::ref(should_quit));
//one of these threads will always hang until another input is recieved
sync_thread.join();