moved json escape out of string files

This commit is contained in:
rexy712 2019-03-20 16:12:01 -07:00
parent 1a4133bc92
commit e12acfe8bc
8 changed files with 165 additions and 121 deletions

View File

@ -41,17 +41,7 @@ namespace raii{
}
//curl allocated string
struct curl_string : public string_intermediary<detail::curl_allocator>
{
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<detail::curl_allocator>::string_intermediary;
using string_intermediary<detail::curl_allocator>::operator=;
};
using curl_string = string_intermediary<detail::curl_allocator>;
}

View File

@ -48,48 +48,8 @@ namespace raii{
}
//new allocated string
struct string : public string_intermediary<detail::default_allocator>
{
string(const string&) = default;
string(string&&) = default;
string& operator=(const string&) = default;
string& operator=(string&&) = default;
using string = string_intermediary<detail::default_allocator>;
using string_intermediary<detail::default_allocator>::string_intermediary;
using string_intermediary<detail::default_allocator>::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<class Tup, size_t I = 0>
void _js_assign(char* dest, Tup&& t, size_t offset){
size_t written = _sanitize_json_copy(dest+offset, std::get<I>(t));
if constexpr(I+2 < std::tuple_size<std::remove_reference_t<Tup>>::value){
_js_assign<Tup,I+2>(dest, std::forward<Tup>(t), offset+written);
}
}
template<class T, size_t I = 0>
size_t _calc_escaped_len_all(T&& t){
size_t len = _calc_escaped_len(std::get<I>(t));
if constexpr(I+2 < std::tuple_size<std::remove_reference_t<T>>::value){
len += _calc_escaped_len_all<T,I+2>(std::forward<T>(t));
}
return len;
}
}
template<class T, typename std::enable_if<detail::is_string<T>::value && !detail::is_concrete_string<T>::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<char*>(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

View File

@ -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 Allocator>
class string_intermediary : public string_base
@ -210,6 +214,8 @@ namespace raii{
}
};
//check for member function 'length'
namespace detail{
template<class T>
@ -227,6 +233,8 @@ namespace raii{
}
//Like an expression template but not really
template<class Left, class Right>
class string_cat_expr : public string_expr
@ -297,6 +305,8 @@ namespace raii{
}
template<class Right, typename std::enable_if<raii::detail::is_string<Right>::value,void>::type* = nullptr>
auto operator+(const char* left, Right&& right){
return raii::string_cat_expr<const char*,decltype(std::forward<Right>(right))>(left, std::forward<Right>(right));

59
include/raii/util.hpp Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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<class Tup, size_t I = 0>
void _js_assign(char* dest, Tup&& t, size_t offset){
size_t written = _sanitize_json_copy(dest+offset, std::get<I>(t));
if constexpr(I+2 < std::tuple_size<std::remove_reference_t<Tup>>::value){
_js_assign<Tup,I+2>(dest, std::forward<Tup>(t), offset+written);
}
}
template<class T, size_t I = 0>
size_t _calc_escaped_len_all(T&& t){
size_t len = _calc_escaped_len(std::get<I>(t));
if constexpr(I+2 < std::tuple_size<std::remove_reference_t<T>>::value){
len += _calc_escaped_len_all<T,I+2>(std::forward<T>(t));
}
return len;
}
}
template<class T, typename std::enable_if<detail::is_string<T>::value && !detail::is_concrete_string<T>::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<char*>(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

View File

@ -19,6 +19,7 @@
#include "fat_strings.hpp"
#include "matrix.hpp"
#include "raii/static_string.hpp"
#include "raii/util.hpp"
namespace matrix::detail{

View File

@ -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"

View File

@ -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<char*>(string::allocator_type::allocate(len+1));
detail::_sanitize_json_copy(tmp, str);
tmp[len] = 0;
return string(tmp, len);
}
}

92
src/raii/util.cpp Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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<char*>(string::allocator_type::allocate(len+1));
detail::_sanitize_json_copy(tmp, str);
tmp[len] = 0;
return string(tmp, len);
}
}