diff --git a/include/matrix/connection.hpp b/include/matrix/connection.hpp index abf3d37..5725071 100644 --- a/include/matrix/connection.hpp +++ b/include/matrix/connection.hpp @@ -22,6 +22,7 @@ #include "raii/curler.hpp" #include "raii/string.hpp" #include "raii/rjp_string.hpp" +#include "raii/binary.hpp" #include "matrix/session_info.hpp" #include //shared_ptr @@ -66,10 +67,12 @@ namespace matrix{ protected: void _set_curl_useragent(const raii::string_base& useragent); - 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::binary _get_curl_binary(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; + raii::binary _post_curl_binary(const raii::string_base& postdata, const raii::string_base& url, const raii::curl_llist& header)const; raii::string _put_curl(const raii::string_base& postdata, const raii::string_base& url, const raii::curl_llist& header)const; + raii::binary _put_curl_binary(const raii::string_base& postdata, const raii::string_base& url, const raii::curl_llist& header)const; raii::rjp_string _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::rjp_string _get_and_find(const raii::string_base& url, const raii::string_base& search)const; raii::rjp_string _curl_reply_search(const raii::string_base& reply, const raii::string_base& search)const; diff --git a/include/matrix/upload_info.hpp b/include/matrix/upload_info.hpp index 70db1cc..4fbef62 100644 --- a/include/matrix/upload_info.hpp +++ b/include/matrix/upload_info.hpp @@ -21,12 +21,13 @@ #include "raii/rjp_string.hpp" #include "raii/string.hpp" +#include "raii/binary.hpp" #include //size_t namespace matrix{ struct file_details{ - raii::string data; + raii::binary data; raii::string name; }; struct image_details : public file_details{ diff --git a/include/raii/binary.hpp b/include/raii/binary.hpp index 278bbb2..5c34165 100644 --- a/include/raii/binary.hpp +++ b/include/raii/binary.hpp @@ -4,29 +4,13 @@ #include //size_t #include //move #include //memcpy +#include //max +#include #include +#include "raii/default_allocator.hpp" namespace raii{ - namespace detail{ - - template - struct default_binary_allocator{ - static void free(void* data){ - ::operator delete(data); - } - static void* allocate(size_t size){ - return ::operator new(size, std::align_val_t(Alignment)); - } - static void* copy(const void* c, size_t size){ - char* tmp = reinterpret_cast(allocate(size)); - memcpy(tmp, c, size); - return tmp; - } - }; - - } - class binary_base { protected: @@ -34,19 +18,19 @@ namespace raii{ size_t m_size = 0; size_t m_cap = 0; public: + protected: constexpr binary_base(void) = default; constexpr binary_base(char* data, size_t size): m_data(data), m_size(size){} - protected: template binary_base(const binary_base& b): m_data(Allocator::copy(b.m_data, b.m_cap)), m_size(b.m_size), m_cap(b.m_cap){} binary_base(binary_base&&); - public: ~binary_base(void) = default; + public: char* release(void); constexpr size_t size(void)const{return m_size;} @@ -59,30 +43,32 @@ namespace raii{ const char& operator[](size_t i)const; }; - template> - class binary : public binary_base + template> + class binary_data : public binary_base { public: - constexpr binary(void) = default; - binary(char* data, size_t size): - binary_base(Allocator::copy(data, size), size){} - binary(size_t size): - binary_base(Allocator::allocate(size), size){} - binary(const binary& b): + using allocator_type = Allocator; + public: + constexpr binary_data(void) = default; + binary_data(char* data, size_t size): + binary_base(reinterpret_cast(Allocator::copy(data, size)), size){} + binary_data(size_t size): + binary_base(reinterpret_cast(Allocator::allocate(size)), size){} + binary_data(const binary_data& b): binary_base(b) { m_data = Allocator::copy(b.m_data, b.m_cap); } - binary(binary&& b): + binary_data(binary_data&& b): binary_base(std::move(b)){} - ~binary(void){ + ~binary_data(void){ Allocator::free(m_data); } - binary& operator=(const binary& b){ - binary tmp(b); + binary_data& operator=(const binary_data& b){ + binary_data tmp(b); return (*this = std::move(tmp)); } - binary& operator=(binary&& b){ + binary_data& operator=(binary_data&& b){ m_size = b.m_size; m_cap = b.m_cap; std::swap(m_data, b.m_data); @@ -102,15 +88,59 @@ namespace raii{ bool resize(size_t newsize){ if(newsize < m_cap) return false; - binary tmp(newsize); + binary_data tmp(newsize); if(!tmp) return false; memcpy(tmp.m_data, m_data, m_size); - *this = std::move(tmp); + std::swap(m_data, tmp.m_data); + m_cap = tmp.m_cap; return true; } + void append(const char* data, size_t len){ + if(m_size + len > m_cap) + resize(std::max(m_cap*2, m_size+len)); + memcpy(m_data+m_size, data, len); + m_size += len; + } }; + using binary = binary_data<>; + + namespace detail{ + std::true_type is_binary_type_helper(binary_base); + std::false_type is_binary_type_helper(...); + + template + struct is_binary_type{ + constexpr static bool value = std::is_same::type>())),std::true_type>::value; + }; + } } +template::value && raii::detail::is_binary_type::value,void>::type* = nullptr> +bool operator==(Left&& l, Right&& r){ + return l && r && l.size() == r.size() && l.capacity() == r.capacity() && !memcmp(l.get(), r.get(), l.size()); +} +template::value && raii::detail::is_binary_type::value,void>::type* = nullptr> +bool operator!=(Left&& l, Right&& r){ + return !(std::forward(l) == std::forward(r)); +} +template +auto operator+(const raii::binary_data& l, const raii::binary_data& r){ + raii::binary_data retval(l.size() + r.size()); + memcpy(retval.get(), l.get(), l.size()); + memcpy(retval.get()+l.size(), r.get(), r.size()); + return retval; +} +template +decltype(auto) operator+=(raii::binary_data& l, const raii::binary_data& r){ + l.resize(l.size() + r.size()); + memcpy(l.get()+l.size(), r.get(), r.size()); + return l; +} + +#ifdef RAII_STRING_BASE_HPP +#include "raii/binary_string_conv.hpp" +#endif + #endif diff --git a/include/raii/binary_string_conv.hpp b/include/raii/binary_string_conv.hpp new file mode 100644 index 0000000..981e3a2 --- /dev/null +++ b/include/raii/binary_string_conv.hpp @@ -0,0 +1,53 @@ +#ifndef RAII_BINARY_STRING_CONV_HPP +#define RAII_BINARY_STRING_CONV_HPP + +#include "raii/string.hpp" +#include "raii/binary.hpp" + +namespace raii{ + template::value,void>::type* = nullptr> + auto binary_to_string(const binary_data& b){ + Str s(b.size()+1); + memcpy(s.get(), b.get(), b.size()); + s[b.size()] = 0; + return s; + } + template::value && std::is_same::type,typename Str::allocator_type>::value,void>::type* = nullptr> + auto binary_to_string(binary_data&& b){ + Str s; + s.reset(b.get(), b.size()); + b.release(); + return s; + } + template::value,void>::type* = nullptr> + auto string_to_binary(const string_base& s){ + Bin b(s.length()+1); + b.append(s.get(), s.length()+1); + return b; + } + template::value && std::is_same::type,typename Bin::allocator_type>::value,void>::type* = nullptr> + auto string_to_binary(string_intermediary&& s){ + Bin b; + b.reset(s.get(), s.length()+1); + s.release(); + return b; + } +} +template::value && raii::detail::is_concrete_string::value,void>::type* = nullptr> +decltype(auto) operator+=(L& l, R&& r){ + l.append(r.get(), r.length()+1); + return l; +} +template::value && raii::detail::is_string::value && !raii::detail::is_concrete_string::value,void>::type* = nullptr> +decltype(auto) operator+=(L& l, R&& r){ + raii::string concrete = r; + return (l = concrete); +} +template::value && raii::detail::is_binary_type::value,void>::type* = nullptr> +decltype(auto) operator+=(L& l, R&& r){ + l.resize(l.length(), r.size() + 1); + memcpy(l.get()+l.length()+1, r.get(), r.size()); + return l; +} + +#endif diff --git a/include/raii/default_allocator.hpp b/include/raii/default_allocator.hpp new file mode 100644 index 0000000..3791347 --- /dev/null +++ b/include/raii/default_allocator.hpp @@ -0,0 +1,30 @@ +#ifndef RAII_DEFAULT_ALLOCATOR_HPP +#define RAII_DEFAULT_ALLOCATOR_HPP + +#include //size_t +#include //memcpy +#include + +namespace raii{ + + namespace detail{ + + template + struct default_allocator + { + static void free(void* data){ + ::operator delete(data, std::align_val_t{Alignment}); + } + static void* allocate(size_t size){ + return ::operator new(size, std::align_val_t{Alignment}); + } + static void* copy(const void* c, size_t size){ + char* tmp = reinterpret_cast(allocate(size)); + memcpy(tmp, c, size); + return tmp; + } + }; + } +} + +#endif diff --git a/include/raii/static_string.hpp b/include/raii/static_string.hpp index b5a5a59..840a16a 100644 --- a/include/raii/static_string.hpp +++ b/include/raii/static_string.hpp @@ -51,11 +51,6 @@ namespace raii{ return *this; } static_string& operator=(static_string&&) = delete; - - private: - char* _allocate(size_t)const override final{return nullptr;} - void _free(char*)const override final{} - char* _copy(const char*,size_t)const override final{return nullptr;} }; } diff --git a/include/raii/string.hpp b/include/raii/string.hpp index e0fa53a..054f305 100644 --- a/include/raii/string.hpp +++ b/include/raii/string.hpp @@ -20,35 +20,12 @@ #define RAII_STRING_HPP #include "raii/string_base.hpp" - -#include //operator new/delete -#include //memcpy +#include "raii/default_allocator.hpp" namespace raii{ - namespace detail{ - - class default_allocator - { - public: - static void free(void* data){ - ::operator delete(data); - } - static void* allocate(size_t size){ - return ::operator new(size); - } - static void* copy(const void* c, size_t size){ - char* tmp = reinterpret_cast(allocate(size)); - memcpy(tmp, c, size-1); - tmp[size-1] = 0; - return tmp; - } - }; - - } - //new allocated string - using string = string_intermediary; + using string = string_intermediary>; } diff --git a/include/raii/string_base.hpp b/include/raii/string_base.hpp index 598d776..671696c 100644 --- a/include/raii/string_base.hpp +++ b/include/raii/string_base.hpp @@ -64,72 +64,31 @@ namespace raii{ protected: constexpr string_base(void) = default; + constexpr string_base(size_t len): + m_length(len){} //Initialize without copying constexpr string_base(char* data, size_t len): m_length(len), m_data(data){} - //Allocate without assigning - string_base(size_t len); //Copy ctor (do nothing) string_base(const string_base&){} + ~string_base(void) = default; public: - virtual ~string_base(void) = default; - - public: - //Copy from c string - string_base& operator=(const char* c); - //Copy from other string_base - string_base& operator=(const string_base& s); - //Move from other string base - template::value && !detail::is_concrete_string::value,void>::type* = nullptr> - string_base& operator=(T&& t){ - size_t len = t.length(); - char* tmp; - if(len > m_length){ - tmp = _allocate(len+1); - _assign(tmp, t.get(), 0); - _free(m_data); - }else{ - tmp = m_data; - _assign(tmp, t.get(), 0); - } - m_data = tmp; - m_data[len] = 0; - m_length = len; - return *this; - } - //Replace managed pointer. Frees existing value - void reset(char* val = nullptr); //Stop managing stored pointer. Does not free. char* release(void); - bool resize(size_t newsize); //Length of string not including null terminator constexpr size_t length(void)const{return m_length;} //direct access to managed pointer constexpr char* get(void){return m_data;} constexpr const char* get(void)const{return m_data;} - operator char*(void); - operator const char*(void)const; + constexpr operator char*(void){return m_data;} + constexpr operator const char*(void)const{return m_data;} //true if m_data is not null - operator bool(void)const; + constexpr operator bool(void)const{return m_data;} char& operator[](size_t i); const char& operator[](size_t i)const; - - protected: - string_base& _copy_string(const char* s, size_t len); - template - static void _assign(char* dest, Tup&& t, size_t offset){ - memcpy(dest+offset, std::get(t), std::get(t)); - if constexpr(I+2 < std::tuple_size::value){ - _assign(dest, std::forward(t), offset+std::get(t)); - } - } - private: - virtual char* _allocate(size_t)const = 0; - virtual void _free(char*)const = 0; - virtual char* _copy(const char*, size_t)const = 0; }; @@ -181,14 +140,43 @@ namespace raii{ Allocator::free(m_data); } - string_intermediary& operator=(const string_intermediary&) = default; + string_intermediary& operator=(const string_intermediary& s){ + string_intermediary tmp(s); + std::swap(m_data, tmp.m_data); + m_length = tmp.m_length; + return *this; + } string_intermediary& operator=(string_intermediary&& s){ std::swap(m_data, s.m_data); m_length = s.m_length; return *this; } - using string_base::operator=; - + //Copy from c string + string_intermediary& operator=(const char* c){ + return _copy_string(c, strlen(c)); + } + //Copy from other string_base + string_intermediary& operator=(const string_base& s){ + return _copy_string(s.get(), s.length()); + } + //Move from other string base + template::value && !detail::is_concrete_string::value,void>::type* = nullptr> + string_base& operator=(T&& t){ + size_t len = t.length(); + char* tmp; + if(len > m_length){ + tmp = reinterpret_cast(Allocator::allocate(len+1)); + _assign(tmp, t.get(), 0); + Allocator::free(m_data); + }else{ + tmp = m_data; + _assign(tmp, t.get(), 0); + } + m_data = tmp; + m_data[len] = 0; + m_length = len; + return *this; + } string_intermediary operator+(const string_base& s)const{ string_intermediary tmp(reinterpret_cast(Allocator::allocate(m_length + s.length() + 1)), m_length+s.length()); @@ -205,15 +193,67 @@ namespace raii{ return tmp; } + + //Replace managed pointer. Frees existing value + void reset(char* val = nullptr){ + Allocator::free(m_data); + m_data = val; + m_length = val ? strlen(val) : 0; + } + void reset(char* val, size_t len){ + Allocator::free(m_data); + m_data = val; + m_length = len; + } + bool resize(size_t newsize){ + if(newsize < m_length) + return false; + string_intermediary tmp(newsize); + memcpy(tmp.get(), m_data, m_length); + tmp[m_length] = 0; + *this = std::move(tmp); + return true; + } + void append(const char* data, size_t len){ + string_intermediary tmp(m_length + len); + memcpy(tmp.m_data, m_data, m_length); + memcpy(tmp.m_data+m_length, data, len); + tmp[m_length+len] = 0; + *this = std::move(tmp); + } + void append(const char* data){ + *this += data; + } + void append(const string_expr& s){ + *this += s; + } + private: - char* _allocate(size_t len)const override final{ - return reinterpret_cast(Allocator::allocate(len)); + string_intermediary& _copy_string(const char* s, size_t len){ + if(!len){ + Allocator::free(m_data); + m_length = 0; + return *this; + } + if(len <= m_length){ + strcpy(m_data, s); + }else{ + Allocator::free(m_data); + m_data = reinterpret_cast(Allocator::copy(s, len+1)); + if(!m_data){ + m_length = 0; + return *this; + } + } + m_length = len; + return *this; } - void _free(char* ptr)const override final{ - Allocator::free(ptr); - } - char* _copy(const char* ptr, size_t len)const override final{ - return reinterpret_cast(Allocator::copy(ptr, len)); + template + static void _assign(char* dest, Tup&& t, size_t offset){ + memcpy(dest+offset, std::get(t), std::get(t)); + if constexpr(I+2 < std::tuple_size::value){ + _assign(dest, std::forward(t), offset+std::get(t)); + } } }; @@ -338,4 +378,8 @@ decltype(auto) operator+=(Left& l, const char* r){ return l = (l + r); } +#ifdef RAII_BINARY_HPP +#include "raii/binary_string_conv.hpp" +#endif + #endif diff --git a/src/matrix/client.cpp b/src/matrix/client.cpp index 1cb4d95..254b933 100644 --- a/src/matrix/client.cpp +++ b/src/matrix/client.cpp @@ -136,7 +136,7 @@ namespace matrix{ } m_curl.setopt(CURLOPT_HEADERFUNCTION, _thumbnail_header_callback); m_curl.setopt(CURLOPT_HEADERDATA, &reply_header); - i.data = _get_curl(m_ses->urls.file_thumbnail(m_ses->homeserver, info.fileurl, info.thumb_width, info.thumb_height, "crop"_ss)); + i.data = _get_curl_binary(m_ses->urls.file_thumbnail(m_ses->homeserver, info.fileurl, info.thumb_width, info.thumb_height, "crop"_ss)); m_curl.setopt(CURLOPT_HEADERFUNCTION, NULL); m_curl.setopt(CURLOPT_HEADERDATA, NULL); if(!i.data){ @@ -175,10 +175,17 @@ namespace matrix{ return to_copy; } + static size_t _post_reply_curl_callback(char* ptr, size_t size, size_t nmemb, void* userdata){ + raii::string* data = reinterpret_cast(userdata); + size_t oldlen = data->length(); + data->resize(data->length() + (size*nmemb)); + memcpy(data->get()+oldlen, ptr, size*nmemb); + return size*nmemb; + } file_info client::_upload_file(const file_details& file, const raii::curl_llist& header)const{ raii::string fileurl; file_info retval = {}; - internal_upload_data upload_data = {file.data.get(), file.data.length()}; + internal_upload_data upload_data = {file.data.get(), file.data.size()}; m_curl.postreq(); m_curl.setopt(CURLOPT_POSTFIELDS, NULL); m_curl.setopt(CURLOPT_READFUNCTION, _upload_file_read_callback); @@ -206,7 +213,7 @@ namespace matrix{ return {}; retval.fileurl = res.value; retval.filename = file.name; - retval.filesize = file.data.length(); + retval.filesize = file.data.size(); return retval; } } diff --git a/src/matrix/connection.cpp b/src/matrix/connection.cpp index 91fa649..9c22fc1 100644 --- a/src/matrix/connection.cpp +++ b/src/matrix/connection.cpp @@ -47,18 +47,24 @@ namespace matrix{ void connection::_set_curl_useragent(const raii::string_base& useragent){ m_curl.setuseragent(useragent); } - size_t connection::_post_reply_curl_callback(char* ptr, size_t size, size_t nmemb, void* userdata){ + static size_t _post_reply_curl_callback(char* ptr, size_t size, size_t nmemb, void* userdata){ raii::string* data = reinterpret_cast(userdata); - size_t oldlen = data->length(); - data->resize(data->length() + (size*nmemb)); - memcpy(data->get()+oldlen, ptr, size*nmemb); + data->append(ptr, size*nmemb); return size*nmemb; } + static size_t _binary_reply_curl_callback(char* ptr, size_t size, size_t nmemb, void* userdata){ + raii::binary* data = reinterpret_cast(userdata); + data->append(ptr, size*nmemb); + return size*nmemb; + } + static void _get_curl_setup(const raii::string_base& url, raii::curler& curl){ + curl.getreq(); + curl.seturl(url); + curl.setheader(raii::curl_llist{}); + } raii::string connection::_get_curl(const raii::string_base& url)const{ raii::string reply; - m_curl.getreq(); - m_curl.seturl(url); - m_curl.setheader(raii::curl_llist{}); + _get_curl_setup(url, m_curl); m_curl.setopt(CURLOPT_WRITEFUNCTION, _post_reply_curl_callback); m_curl.setopt(CURLOPT_WRITEDATA, &reply); CURLcode res = m_curl.perform(); @@ -66,13 +72,25 @@ namespace matrix{ return {}; return reply; } + raii::binary connection::_get_curl_binary(const raii::string_base& url)const{ + raii::binary reply; + _get_curl_setup(url, m_curl); + m_curl.setopt(CURLOPT_WRITEFUNCTION, _binary_reply_curl_callback); + m_curl.setopt(CURLOPT_WRITEDATA, &reply); + CURLcode res = m_curl.perform(); + if(res != CURLE_OK) + return {}; + return reply; + } + static void _post_curl_setup(const raii::string_base& postdata, const raii::string_base& url, const raii::curl_llist& header, raii::curler& curl){ + curl.postreq(); + curl.setpostdata(postdata.get(), postdata.length()); + curl.seturl(url); + curl.setheader(header); + } 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()); - m_curl.setopt(CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)postdata.length()); - m_curl.seturl(url); - m_curl.setheader(header); + _post_curl_setup(postdata, url, header, m_curl); m_curl.setopt(CURLOPT_WRITEFUNCTION, _post_reply_curl_callback); m_curl.setopt(CURLOPT_WRITEDATA, &reply); CURLcode res = m_curl.perform(); @@ -80,6 +98,16 @@ namespace matrix{ return {}; return reply; } + raii::binary connection::_post_curl_binary(const raii::string_base& postdata, const raii::string_base& url, const raii::curl_llist& header)const{ + raii::binary reply; + _post_curl_setup(postdata, url, header, m_curl); + m_curl.setopt(CURLOPT_WRITEFUNCTION, _binary_reply_curl_callback); + m_curl.setopt(CURLOPT_WRITEDATA, &reply); + CURLcode res = m_curl.perform(); + if(res != CURLE_OK) + return {}; + return reply; + } struct put_data{ const char* data; size_t len; @@ -93,19 +121,35 @@ namespace matrix{ src->data += to_copy; return to_copy; } + static void _put_curl_setup(put_data& data, const raii::string_base& url, const raii::curl_llist& header, raii::curler& curl){ + curl.putreq(); + curl.setopt(CURLOPT_POSTFIELDS, data.data); + curl.setopt(CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)data.len); + curl.seturl(url); + curl.setheader(header); + curl.setopt(CURLOPT_READFUNCTION, _put_read_curl_callback); + curl.setopt(CURLOPT_READDATA, &data); + curl.setopt(CURLOPT_INFILESIZE, (curl_off_t)data.len); + } 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(); - m_curl.setopt(CURLOPT_POSTFIELDS, putdata.get()); - m_curl.setopt(CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)putdata.length()); - m_curl.seturl(url); - m_curl.setheader(header); m_curl.setopt(CURLOPT_WRITEFUNCTION, _post_reply_curl_callback); m_curl.setopt(CURLOPT_WRITEDATA, &reply); - m_curl.setopt(CURLOPT_READFUNCTION, _put_read_curl_callback); - m_curl.setopt(CURLOPT_READDATA, &data); - m_curl.setopt(CURLOPT_INFILESIZE, (curl_off_t)data.len); + _put_curl_setup(data, url, header, m_curl); + CURLcode res = m_curl.perform(); + m_curl.setopt(CURLOPT_READDATA, NULL); + m_curl.setopt(CURLOPT_READFUNCTION, NULL); + if(res != CURLE_OK) + return {}; + return reply; + } + raii::binary connection::_put_curl_binary(const raii::string_base& putdata, const raii::string_base& url, const raii::curl_llist& header)const{ + raii::binary reply; + put_data data{putdata.get(), putdata.length()}; + m_curl.setopt(CURLOPT_WRITEFUNCTION, _binary_reply_curl_callback); + m_curl.setopt(CURLOPT_WRITEDATA, &reply); + _put_curl_setup(data, url, header, m_curl); CURLcode res = m_curl.perform(); m_curl.setopt(CURLOPT_READDATA, NULL); m_curl.setopt(CURLOPT_READFUNCTION, NULL); diff --git a/src/matrix/session.cpp b/src/matrix/session.cpp index b719378..91fe97e 100644 --- a/src/matrix/session.cpp +++ b/src/matrix/session.cpp @@ -113,21 +113,8 @@ namespace matrix{ _do_login(a.name, a.pass); } raii::string session::_request_access_token(const raii::string_base& name, const raii::string_base& pass, const raii::string_base& loginurl)const{ - CURLcode result; raii::string postdata("{\"type\":\"m.login.password\", \"user\":\"" + raii::json_escape(name) + "\", \"password\":\"" + raii::json_escape(pass) + "\"}"); - raii::string 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 = m_curl.perform(); - - if(result != CURLE_OK) - return {}; - + raii::string reply = _post_curl(postdata, loginurl, raii::curl_llist{}); return reply; } raii::rjp_string session::_get_userid(void){ diff --git a/src/raii/rjp_string.cpp b/src/raii/rjp_string.cpp index 179933b..963b136 100644 --- a/src/raii/rjp_string.cpp +++ b/src/raii/rjp_string.cpp @@ -28,8 +28,7 @@ namespace raii{ } void* rjp_allocator::copy(const void* data, size_t len){ char* tmp = reinterpret_cast(allocate(len)); - memcpy(tmp, data, len-1); - tmp[len-1] = 0; + memcpy(tmp, data, len); return tmp; } } diff --git a/src/raii/string_base.cpp b/src/raii/string_base.cpp index 0679051..6ef3ed2 100644 --- a/src/raii/string_base.cpp +++ b/src/raii/string_base.cpp @@ -24,70 +24,14 @@ #include //strcpy, strlen namespace raii{ - string_base::string_base(size_t len): - m_length(len), - m_data(nullptr){} - string_base& string_base::operator=(const char* c){ - return _copy_string(c, strlen(c)); - } - string_base& string_base::operator=(const string_base& s){ - return _copy_string(s.m_data, s.m_length); - } - void string_base::reset(char* val){ - _free(m_data); - m_data = val; - m_length = val ? strlen(val) : 0; - } - - string_base::operator bool(void)const{ - return m_data; - } - string_base::operator char*(void){ - return m_data; - } - string_base::operator const char*(void)const{ - return m_data; - } char* string_base::release(void){ return std::exchange(m_data, nullptr); } - bool string_base::resize(size_t newsize){ - if(newsize < m_length) - return false; - char* newbuf = static_cast(_allocate(newsize+1)); - if(!newbuf) return false; - memset(newbuf, 0, newsize+1); - memcpy(newbuf, m_data, m_length); - newbuf[m_length] = 0; - m_length = newsize; - _free(m_data); - m_data = newbuf; - return true; - } char& string_base::operator[](size_t i){ return m_data[i]; } const char& string_base::operator[](size_t i)const{ return m_data[i]; } - string_base& string_base::_copy_string(const char* s, size_t len){ - if(!len){ - _free(m_data); - m_length = 0; - return *this; - } - if(len <= m_length){ - strcpy(m_data, s); - }else{ - _free(m_data); - m_data = _copy(s, len+1); - if(!m_data){ - m_length = 0; - return *this; - } - } - m_length = len; - return *this; - } }