diff --git a/include/raii/curl_string.hpp b/include/raii/curl_string.hpp index cc9508a..1488035 100644 --- a/include/raii/curl_string.hpp +++ b/include/raii/curl_string.hpp @@ -41,17 +41,7 @@ namespace raii{ } - //curl allocated string - struct curl_string : public string_intermediary - { - curl_string(const curl_string&) = default; - curl_string(curl_string&&) = default; - curl_string& operator=(const curl_string&) = default; - curl_string& operator=(curl_string&&) = default; - - using string_intermediary::string_intermediary; - using string_intermediary::operator=; - }; + using curl_string = string_intermediary; } diff --git a/include/raii/string.hpp b/include/raii/string.hpp index 7d5174c..4bd4732 100644 --- a/include/raii/string.hpp +++ b/include/raii/string.hpp @@ -48,48 +48,8 @@ namespace raii{ } //new allocated string - struct string : public string_intermediary - { - string(const string&) = default; - string(string&&) = default; - string& operator=(const string&) = default; - string& operator=(string&&) = default; + using string = string_intermediary; - using string_intermediary::string_intermediary; - using string_intermediary::operator=; - }; - - namespace detail{ - size_t _calc_escaped_len(const char* str); - char _escape_to_letter(char escape); - size_t _sanitize_json_copy(char* dest, const char* in); - - template - void _js_assign(char* dest, Tup&& t, size_t offset){ - size_t written = _sanitize_json_copy(dest+offset, std::get(t)); - if constexpr(I+2 < std::tuple_size>::value){ - _js_assign(dest, std::forward(t), offset+written); - } - } - template - size_t _calc_escaped_len_all(T&& t){ - size_t len = _calc_escaped_len(std::get(t)); - if constexpr(I+2 < std::tuple_size>::value){ - len += _calc_escaped_len_all(std::forward(t)); - } - return len; - } - } - template::value && !detail::is_concrete_string::value,void>::type* = nullptr> - string json_escape(T&& t){ - auto tup = t.get(); - size_t len = detail::_calc_escaped_len_all(tup); - char* tmp = reinterpret_cast(string::allocator_type::allocate(len+1)); - detail::_js_assign(tmp, tup, 0); - tmp[len] = 0; - return string(tmp, len); - } - string json_escape(const string_base& str); } #endif diff --git a/include/raii/string_base.hpp b/include/raii/string_base.hpp index be3ab32..cc251d6 100644 --- a/include/raii/string_base.hpp +++ b/include/raii/string_base.hpp @@ -53,6 +53,8 @@ namespace raii{ }; } + + //Base of all RAII strings. Its use is allowing passing of raii strings to functions without knowing the exact type class string_base : public string_expr { @@ -129,6 +131,8 @@ namespace raii{ virtual char* _copy(const char*, size_t)const = 0; }; + + //Supplies all functions that string_base can't implement template class string_intermediary : public string_base @@ -210,6 +214,8 @@ namespace raii{ } }; + + //check for member function 'length' namespace detail{ template @@ -227,6 +233,8 @@ namespace raii{ } + + //Like an expression template but not really template class string_cat_expr : public string_expr @@ -297,6 +305,8 @@ namespace raii{ } + + template::value,void>::type* = nullptr> auto operator+(const char* left, Right&& right){ return raii::string_cat_expr(right))>(left, std::forward(right)); diff --git a/include/raii/util.hpp b/include/raii/util.hpp new file mode 100644 index 0000000..3fa8b6b --- /dev/null +++ b/include/raii/util.hpp @@ -0,0 +1,59 @@ +/** + This file is a part of rexy's matrix bot + Copyright (C) 2019 rexy712 + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +#ifndef RAII_UTIL_HPP +#define RAII_UTIL_HPP + +#include "raii/string.hpp" + +namespace raii{ + + namespace detail{ + size_t _calc_escaped_len(const char* str); + char _escape_to_letter(char escape); + size_t _sanitize_json_copy(char* dest, const char* in); + + template + void _js_assign(char* dest, Tup&& t, size_t offset){ + size_t written = _sanitize_json_copy(dest+offset, std::get(t)); + if constexpr(I+2 < std::tuple_size>::value){ + _js_assign(dest, std::forward(t), offset+written); + } + } + template + size_t _calc_escaped_len_all(T&& t){ + size_t len = _calc_escaped_len(std::get(t)); + if constexpr(I+2 < std::tuple_size>::value){ + len += _calc_escaped_len_all(std::forward(t)); + } + return len; + } + } + template::value && !detail::is_concrete_string::value,void>::type* = nullptr> + string json_escape(T&& t){ + auto tup = t.get(); + size_t len = detail::_calc_escaped_len_all(tup); + char* tmp = reinterpret_cast(string::allocator_type::allocate(len+1)); + detail::_js_assign(tmp, tup, 0); + tmp[len] = 0; + return string(tmp, len); + } + string json_escape(const string_base& str); +} + +#endif diff --git a/src/fat_strings.cpp b/src/fat_strings.cpp index 134d55a..becfeed 100644 --- a/src/fat_strings.cpp +++ b/src/fat_strings.cpp @@ -19,6 +19,7 @@ #include "fat_strings.hpp" #include "matrix.hpp" #include "raii/static_string.hpp" +#include "raii/util.hpp" namespace matrix::detail{ diff --git a/src/matrix.cpp b/src/matrix.cpp index 34833bf..1233ccf 100644 --- a/src/matrix.cpp +++ b/src/matrix.cpp @@ -25,6 +25,7 @@ #include "raii/rjp_ptr.hpp" #include "raii/filerd.hpp" #include "fat_strings.hpp" +#include "raii/util.hpp" #include "libav/frame.hpp" #include "libav/codec/context.hpp" diff --git a/src/raii/string_base.cpp b/src/raii/string_base.cpp index cac98ee..90e4483 100644 --- a/src/raii/string_base.cpp +++ b/src/raii/string_base.cpp @@ -89,73 +89,4 @@ namespace raii{ return m_data[i]; } - namespace detail{ - - size_t _calc_escaped_len(const char* str){ - size_t ret = 0; - for(const char* c = str;*c;++c){ - switch(*c){ - case '\\': - case '"': - case '/': - case '\n': - case '\r': - case '\b': - case '\f': - case '\t': - ++ret; - break; - }; - ++ret; - } - return ret; - } - char _escape_to_letter(char escape){ - switch(escape){ - case '\n': - return 'n'; - case '\r': - return 'r'; - case '\b': - return 'b'; - case '\f': - return 'f'; - case '\t': - return 't'; - }; - return '\\'; - } - size_t _sanitize_json_copy(char* dest, const char* in){ - size_t pos = 0; - for(const char* c = in;*c;++c){ - switch(*c){ - case '"': - case '\\': - case '/': - dest[pos++] = '\\'; - dest[pos++] = *c; - break; - case '\n': - case '\r': - case '\b': - case '\f': - case '\t': - dest[pos++] = '\\'; - dest[pos++] = _escape_to_letter(*c); - break; - default: - dest[pos++] = *c; - }; - } - dest[pos] = 0; - return pos; - } - } - string json_escape(const string_base& str){ - size_t len = detail::_calc_escaped_len(str.get()); - char* tmp = reinterpret_cast(string::allocator_type::allocate(len+1)); - detail::_sanitize_json_copy(tmp, str); - tmp[len] = 0; - return string(tmp, len); - } } diff --git a/src/raii/util.cpp b/src/raii/util.cpp new file mode 100644 index 0000000..9359035 --- /dev/null +++ b/src/raii/util.cpp @@ -0,0 +1,92 @@ +/** + This file is a part of rexy's matrix bot + Copyright (C) 2019 rexy712 + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +#include "raii/string.hpp" + +namespace raii{ + + namespace detail{ + + size_t _calc_escaped_len(const char* str){ + size_t ret = 0; + for(const char* c = str;*c;++c){ + switch(*c){ + case '\\': + case '"': + case '/': + case '\n': + case '\r': + case '\b': + case '\f': + case '\t': + ++ret; + break; + }; + ++ret; + } + return ret; + } + char _escape_to_letter(char escape){ + switch(escape){ + case '\n': + return 'n'; + case '\r': + return 'r'; + case '\b': + return 'b'; + case '\f': + return 'f'; + case '\t': + return 't'; + }; + return '\\'; + } + size_t _sanitize_json_copy(char* dest, const char* in){ + size_t pos = 0; + for(const char* c = in;*c;++c){ + switch(*c){ + case '"': + case '\\': + case '/': + dest[pos++] = '\\'; + dest[pos++] = *c; + break; + case '\n': + case '\r': + case '\b': + case '\f': + case '\t': + dest[pos++] = '\\'; + dest[pos++] = _escape_to_letter(*c); + break; + default: + dest[pos++] = *c; + }; + } + dest[pos] = 0; + return pos; + } + } + string json_escape(const string_base& str){ + size_t len = detail::_calc_escaped_len(str.get()); + char* tmp = reinterpret_cast(string::allocator_type::allocate(len+1)); + detail::_sanitize_json_copy(tmp, str); + tmp[len] = 0; + return string(tmp, len); + } +}