/** This file is a part of rexy's matrix client Copyright (C) 2019-2020 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 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; } } rexy::string json_escape(const rexy::string_base& str){ size_t len = detail::_calc_escaped_len(str.get()); char* tmp = reinterpret_cast(rexy::string::allocator_type::allocate(len+1)); detail::_sanitize_json_copy(tmp, str); tmp[len] = 0; return rexy::string(tmp, len, 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; } } } rexy::string itostr(int i){ if(i == 0) return rexy::string("0"); int place = intlen(i); rexy::string ret(place, place); char* buf = ret.get(); buf[place] = 0; while(i != 0){ int rem = i % 10; buf[--place] = rem + '0'; i /= 10; } return ret; } }