132 lines
2.7 KiB
C++
132 lines
2.7 KiB
C++
/**
|
|
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);
|
|
}
|
|
|
|
|
|
//shamelessly stolen from stackoverflow (of all the things to need to steal)
|
|
size_t intlen(int i){
|
|
if(i >= 100000){
|
|
if(i >= 10000000){
|
|
if(i >= 1000000000) return 10;
|
|
if(i >= 100000000) return 9;
|
|
return 8;
|
|
}
|
|
if(i >= 1000000) return 7;
|
|
return 6;
|
|
}else{
|
|
if(i >= 1000){
|
|
if(i >= 10000) return 5;
|
|
return 4;
|
|
}else{
|
|
if(i >= 100) return 3;
|
|
if(i >= 10) return 2;
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
raii::string itostr(int i){
|
|
if(i == 0)
|
|
return raii::string("0");
|
|
int place = intlen(i);
|
|
raii::string ret(place);
|
|
char* buf = ret.get();
|
|
buf[place] = 0;
|
|
while(i != 0){
|
|
int rem = i % 10;
|
|
buf[--place] = rem + '0';
|
|
i /= 10;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
}
|