Implemented raii::binary to a usable level and polished the raii::string family a bit better.

This commit is contained in:
rexy712 2019-09-18 14:29:57 -07:00
parent 57ed5d979f
commit 60b380f14e
13 changed files with 334 additions and 220 deletions

View File

@ -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 <memory> //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;

View File

@ -21,12 +21,13 @@
#include "raii/rjp_string.hpp"
#include "raii/string.hpp"
#include "raii/binary.hpp"
#include <cstdlib> //size_t
namespace matrix{
struct file_details{
raii::string data;
raii::binary data;
raii::string name;
};
struct image_details : public file_details{

View File

@ -4,29 +4,13 @@
#include <cstdlib> //size_t
#include <utility> //move
#include <cstring> //memcpy
#include <algorithm> //max
#include <type_traits>
#include <new>
#include "raii/default_allocator.hpp"
namespace raii{
namespace detail{
template<size_t Alignment>
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<char*>(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<class Allocator>
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 Allocator = detail::default_binary_allocator<0>>
class binary : public binary_base
template<class Allocator = detail::default_allocator<>>
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<char*>(Allocator::copy(data, size)), size){}
binary_data(size_t size):
binary_base(reinterpret_cast<char*>(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<class T>
struct is_binary_type{
constexpr static bool value = std::is_same<decltype(is_binary_type_helper(std::declval<typename std::decay<T>::type>())),std::true_type>::value;
};
}
}
template<class Left, class Right, typename std::enable_if<raii::detail::is_binary_type<Left>::value && raii::detail::is_binary_type<Right>::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<class Left, class Right, typename std::enable_if<raii::detail::is_binary_type<Left>::value && raii::detail::is_binary_type<Right>::value,void>::type* = nullptr>
bool operator!=(Left&& l, Right&& r){
return !(std::forward<Left>(l) == std::forward<Right>(r));
}
template<class All, class Alr>
auto operator+(const raii::binary_data<All>& l, const raii::binary_data<Alr>& r){
raii::binary_data<All> retval(l.size() + r.size());
memcpy(retval.get(), l.get(), l.size());
memcpy(retval.get()+l.size(), r.get(), r.size());
return retval;
}
template<class All, class Alr>
decltype(auto) operator+=(raii::binary_data<All>& l, const raii::binary_data<Alr>& 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

View File

@ -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<class Al, class Str = raii::string, typename std::enable_if<raii::detail::is_concrete_string<Str>::value,void>::type* = nullptr>
auto binary_to_string(const binary_data<Al>& b){
Str s(b.size()+1);
memcpy(s.get(), b.get(), b.size());
s[b.size()] = 0;
return s;
}
template<class Al, class Str = raii::string, typename std::enable_if<raii::detail::is_concrete_string<Str>::value && std::is_same<typename std::decay<Al>::type,typename Str::allocator_type>::value,void>::type* = nullptr>
auto binary_to_string(binary_data<Al>&& b){
Str s;
s.reset(b.get(), b.size());
b.release();
return s;
}
template<class Bin = raii::binary, typename std::enable_if<raii::detail::is_binary_type<Bin>::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<class Al, class Bin = raii::binary, typename std::enable_if<raii::detail::is_binary_type<Bin>::value && std::is_same<typename std::decay<Al>::type,typename Bin::allocator_type>::value,void>::type* = nullptr>
auto string_to_binary(string_intermediary<Al>&& s){
Bin b;
b.reset(s.get(), s.length()+1);
s.release();
return b;
}
}
template<class L, class R, typename std::enable_if<raii::detail::is_binary_type<L>::value && raii::detail::is_concrete_string<R>::value,void>::type* = nullptr>
decltype(auto) operator+=(L& l, R&& r){
l.append(r.get(), r.length()+1);
return l;
}
template<class L, class R, typename std::enable_if<raii::detail::is_binary_type<L>::value && raii::detail::is_string<R>::value && !raii::detail::is_concrete_string<R>::value,void>::type* = nullptr>
decltype(auto) operator+=(L& l, R&& r){
raii::string concrete = r;
return (l = concrete);
}
template<class L, class R, typename std::enable_if<raii::detail::is_concrete_string<L>::value && raii::detail::is_binary_type<R>::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

View File

@ -0,0 +1,30 @@
#ifndef RAII_DEFAULT_ALLOCATOR_HPP
#define RAII_DEFAULT_ALLOCATOR_HPP
#include <cstdlib> //size_t
#include <cstring> //memcpy
#include <new>
namespace raii{
namespace detail{
template<size_t Alignment = __STDCPP_DEFAULT_NEW_ALIGNMENT__>
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<char*>(allocate(size));
memcpy(tmp, c, size);
return tmp;
}
};
}
}
#endif

View File

@ -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;}
};
}

View File

@ -20,35 +20,12 @@
#define RAII_STRING_HPP
#include "raii/string_base.hpp"
#include <new> //operator new/delete
#include <cstring> //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<char*>(allocate(size));
memcpy(tmp, c, size-1);
tmp[size-1] = 0;
return tmp;
}
};
}
//new allocated string
using string = string_intermediary<detail::default_allocator>;
using string = string_intermediary<detail::default_allocator<>>;
}

View File

@ -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<class T, typename std::enable_if<detail::is_string<T>::value && !detail::is_concrete_string<T>::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<class Tup, size_t I = 0>
static void _assign(char* dest, Tup&& t, size_t offset){
memcpy(dest+offset, std::get<I>(t), std::get<I+1>(t));
if constexpr(I+2 < std::tuple_size<Tup>::value){
_assign<Tup,I+2>(dest, std::forward<Tup>(t), offset+std::get<I+1>(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<class T, typename std::enable_if<detail::is_string<T>::value && !detail::is_concrete_string<T>::value,void>::type* = nullptr>
string_base& operator=(T&& t){
size_t len = t.length();
char* tmp;
if(len > m_length){
tmp = reinterpret_cast<char*>(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<char*>(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<char*>(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<char*>(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<char*>(Allocator::copy(ptr, len));
template<class Tup, size_t I = 0>
static void _assign(char* dest, Tup&& t, size_t offset){
memcpy(dest+offset, std::get<I>(t), std::get<I+1>(t));
if constexpr(I+2 < std::tuple_size<Tup>::value){
_assign<Tup,I+2>(dest, std::forward<Tup>(t), offset+std::get<I+1>(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

View File

@ -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<raii::string*>(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;
}
}

View File

@ -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<raii::string*>(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<raii::binary*>(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);

View File

@ -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){

View File

@ -28,8 +28,7 @@ namespace raii{
}
void* rjp_allocator::copy(const void* data, size_t len){
char* tmp = reinterpret_cast<char*>(allocate(len));
memcpy(tmp, data, len-1);
tmp[len-1] = 0;
memcpy(tmp, data, len);
return tmp;
}
}

View File

@ -24,70 +24,14 @@
#include <cstring> //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<char*>(_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;
}
}