- refactoring
This commit is contained in:
parent
7db4c8cb53
commit
76aa7861f5
|
|
@ -81,7 +81,7 @@ bool WavFileReader::open(const std::tstring& filename)
|
|||
#ifdef WIN32
|
||||
mHandle = _wfopen(filename.c_str(), L"rb");
|
||||
#else
|
||||
mHandle = fopen(StringHelper::makeUtf8(filename).c_str(), "rb");
|
||||
mHandle = fopen(strx::makeUtf8(filename).c_str(), "rb");
|
||||
#endif
|
||||
if (NULL == mHandle)
|
||||
{
|
||||
|
|
@ -287,11 +287,11 @@ bool WavFileWriter::open(const std::tstring& filename, int rate, int channels)
|
|||
#ifdef WIN32
|
||||
mHandle = _wfopen(filename.c_str(), L"wb");
|
||||
#else
|
||||
mHandle = fopen(StringHelper::makeUtf8(filename).c_str(), "wb");
|
||||
mHandle = fopen(strx::makeUtf8(filename).c_str(), "wb");
|
||||
#endif
|
||||
if (nullptr == mHandle)
|
||||
{
|
||||
ICELogError(<< "Failed to create .wav file: filename = " << StringHelper::makeUtf8(filename) << " , error = " << errno);
|
||||
ICELogError(<< "Failed to create .wav file: filename = " << strx::makeUtf8(filename) << " , error = " << errno);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -312,7 +312,7 @@ namespace Calc
|
|||
{
|
||||
// Dot is here - is it float
|
||||
bool isFloat = false;
|
||||
StringHelper::toFloat(mCurrentLexem.mValue, 0.0f, &isFloat);
|
||||
strx::toFloat(mCurrentLexem.mValue, 0.0f, &isFloat);
|
||||
if (isFloat)
|
||||
mCurrentLexem.mType = LexemType::Float;
|
||||
else
|
||||
|
|
@ -488,7 +488,7 @@ namespace Calc
|
|||
|
||||
case LexemType::Hex:
|
||||
result->mType = Ast::Type::Number;
|
||||
result->mValue = StringHelper::fromHex2Int(l.mValue);
|
||||
result->mValue = strx::fromHex2Int(l.mValue);
|
||||
break;
|
||||
|
||||
case LexemType::Float:
|
||||
|
|
|
|||
|
|
@ -20,10 +20,10 @@ bool CsvReader::readLine(std::vector<std::string>& cells)
|
|||
std::string line;
|
||||
if (!std::getline(mInputStream, line))
|
||||
return false;
|
||||
StringHelper::trim(line);
|
||||
strx::trim(line);
|
||||
if (line.empty())
|
||||
return false;
|
||||
|
||||
StringHelper::split(line, cells, ",;");
|
||||
strx::split(line, cells, ",;");
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -287,7 +287,7 @@ std::shared_ptr<std::thread> OsProcess::asyncExecCommand(const std::string& cmdl
|
|||
if (d != std::string::npos)
|
||||
{
|
||||
if (line_callback)
|
||||
line_callback(StringHelper::trim(lines.substr(p, d-p)));
|
||||
line_callback(strx::trim(lines.substr(p, d-p)));
|
||||
p = d + 1;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
# include <cctype>
|
||||
#endif
|
||||
|
||||
std::string StringHelper::extractFilename(const std::string& path)
|
||||
std::string strx::extractFilename(const std::string& path)
|
||||
{
|
||||
if (path.empty())
|
||||
return std::string();
|
||||
|
|
@ -31,7 +31,7 @@ std::string StringHelper::extractFilename(const std::string& path)
|
|||
return path.substr(p_bs + 1);
|
||||
}
|
||||
|
||||
std::string StringHelper::appendPath(const std::string& s1, const std::string& s2)
|
||||
std::string strx::appendPath(const std::string& s1, const std::string& s2)
|
||||
{
|
||||
std::string result = s1;
|
||||
if (!endsWith(result, "/") && !endsWith(result, "\\"))
|
||||
|
|
@ -45,7 +45,7 @@ std::string StringHelper::appendPath(const std::string& s1, const std::string& s
|
|||
return result + s2;
|
||||
}
|
||||
|
||||
std::string StringHelper::makeUtf8(const std::tstring &arg)
|
||||
std::string strx::makeUtf8(const std::tstring &arg)
|
||||
{
|
||||
#if defined(TARGET_WIN)
|
||||
size_t required = WideCharToMultiByte(CP_UTF8, 0, arg.c_str(), -1, NULL, 0, NULL, NULL);
|
||||
|
|
@ -57,12 +57,12 @@ std::string StringHelper::makeUtf8(const std::tstring &arg)
|
|||
#endif
|
||||
}
|
||||
|
||||
std::string StringHelper::toUtf8(const std::tstring &arg)
|
||||
std::string strx::toUtf8(const std::tstring &arg)
|
||||
{
|
||||
return makeUtf8(arg);
|
||||
}
|
||||
|
||||
std::tstring StringHelper::makeTstring(const std::string& arg)
|
||||
std::tstring strx::makeTstring(const std::string& arg)
|
||||
{
|
||||
#if defined(TARGET_WIN)
|
||||
size_t count = MultiByteToWideChar(CP_UTF8, 0, arg.c_str(), -1, NULL, 0);
|
||||
|
|
@ -74,7 +74,7 @@ std::tstring StringHelper::makeTstring(const std::string& arg)
|
|||
#endif
|
||||
}
|
||||
|
||||
int StringHelper::toInt(const char *s, int defaultValue, bool* isOk)
|
||||
int strx::toInt(const char *s, int defaultValue, bool* isOk)
|
||||
{
|
||||
int result;
|
||||
if (sscanf(s, "%d", &result) != 1)
|
||||
|
|
@ -90,7 +90,7 @@ int StringHelper::toInt(const char *s, int defaultValue, bool* isOk)
|
|||
return result;
|
||||
}
|
||||
|
||||
uint64_t StringHelper::toUint64(const char* s, uint64_t def, bool *isOk)
|
||||
uint64_t strx::toUint64(const char* s, uint64_t def, bool *isOk)
|
||||
{
|
||||
uint64_t result = def;
|
||||
if (sscanf(s, "%" SCNu64, &result) != 1)
|
||||
|
|
@ -106,14 +106,14 @@ uint64_t StringHelper::toUint64(const char* s, uint64_t def, bool *isOk)
|
|||
return result;
|
||||
}
|
||||
|
||||
std::string StringHelper::toHex(unsigned int value)
|
||||
std::string strx::toHex(unsigned int value)
|
||||
{
|
||||
char buffer[32];
|
||||
sprintf(buffer, "%x", value);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
std::string StringHelper::toHex(const void *ptr)
|
||||
std::string strx::toHex(const void *ptr)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << std::fixed << std::setw(8) << std::setfill('0') << std::hex << ptr;
|
||||
|
|
@ -123,7 +123,7 @@ std::string StringHelper::toHex(const void *ptr)
|
|||
//must be lowercase for MD5
|
||||
static const char hexmap[] = "0123456789abcdef";
|
||||
|
||||
std::string StringHelper::toHex(const uint8_t* input, size_t inputLength)
|
||||
std::string strx::toHex(const uint8_t* input, size_t inputLength)
|
||||
{
|
||||
std::string result; result.resize(inputLength * 2);
|
||||
|
||||
|
|
@ -144,7 +144,7 @@ std::string StringHelper::toHex(const uint8_t* input, size_t inputLength)
|
|||
return result;
|
||||
}
|
||||
|
||||
std::string StringHelper::prefixLines(const std::string &source, const std::string &prefix)
|
||||
std::string strx::prefixLines(const std::string &source, const std::string &prefix)
|
||||
{
|
||||
// Read source line by line
|
||||
std::istringstream iss(source);
|
||||
|
|
@ -157,7 +157,7 @@ std::string StringHelper::prefixLines(const std::string &source, const std::stri
|
|||
return oss.str();
|
||||
}
|
||||
|
||||
std::string StringHelper::doubleToString(double value, int precision)
|
||||
std::string strx::doubleToString(double value, int precision)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::fixed << std::setprecision(precision) << value;
|
||||
|
|
@ -165,7 +165,7 @@ std::string StringHelper::doubleToString(double value, int precision)
|
|||
}
|
||||
|
||||
|
||||
const char* StringHelper::findSubstring(const char* buffer, const char* substring, size_t bufferLength)
|
||||
const char* strx::findSubstring(const char* buffer, const char* substring, size_t bufferLength)
|
||||
{
|
||||
#if defined(TARGET_WIN)
|
||||
return (const char*)strstr(buffer, substring);
|
||||
|
|
@ -175,7 +175,7 @@ const char* StringHelper::findSubstring(const char* buffer, const char* substrin
|
|||
}
|
||||
|
||||
|
||||
void StringHelper::split(const std::string& src, std::vector<std::string>& dst, const std::string& delims)
|
||||
void strx::split(const std::string& src, std::vector<std::string>& dst, const std::string& delims)
|
||||
{
|
||||
dst.clear();
|
||||
std::string::size_type p = 0;
|
||||
|
|
@ -199,21 +199,21 @@ void StringHelper::split(const std::string& src, std::vector<std::string>& dst,
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> StringHelper::split(const std::string& src, const std::string& delims)
|
||||
std::vector<std::string> strx::split(const std::string& src, const std::string& delims)
|
||||
{
|
||||
std::vector<std::string> r;
|
||||
split(src, r, delims);
|
||||
return r;
|
||||
}
|
||||
|
||||
std::pair<std::string, int> StringHelper::parseHost(const std::string& host, int defaultPort)
|
||||
std::pair<std::string, int> strx::parseHost(const std::string& host, int defaultPort)
|
||||
{
|
||||
std::pair<std::string, int> result;
|
||||
std::size_t p = host.find(':');
|
||||
if (p != std::string::npos)
|
||||
{
|
||||
result.first = host.substr(0, p);
|
||||
result.second = StringHelper::toInt(host.c_str() + p + 1, defaultPort);
|
||||
result.second = strx::toInt(host.c_str() + p + 1, defaultPort);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -223,15 +223,15 @@ std::pair<std::string, int> StringHelper::parseHost(const std::string& host, int
|
|||
return result;
|
||||
}
|
||||
|
||||
std::pair<std::string, std::string> StringHelper::parseAssignment(const std::string& s, bool trimQuotes)
|
||||
std::pair<std::string, std::string> strx::parseAssignment(const std::string& s, bool trimQuotes)
|
||||
{
|
||||
std::pair<std::string, std::string> result;
|
||||
|
||||
std::string::size_type p = s.find('=');
|
||||
if (p != std::string::npos)
|
||||
{
|
||||
result.first = StringHelper::trim(s.substr(0, p));
|
||||
result.second = StringHelper::trim(s.substr(p+1));
|
||||
result.first = strx::trim(s.substr(0, p));
|
||||
result.second = strx::trim(s.substr(p+1));
|
||||
if (trimQuotes && result.second.size() >= 2)
|
||||
{
|
||||
if ((result.second[0] == '"' && result.second[result.second.size()-1] == '"') ||
|
||||
|
|
@ -240,19 +240,19 @@ std::pair<std::string, std::string> StringHelper::parseAssignment(const std::str
|
|||
}
|
||||
}
|
||||
else
|
||||
result.first = StringHelper::trim(s);
|
||||
result.first = strx::trim(s);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string StringHelper::intToString(int value)
|
||||
std::string strx::intToString(int value)
|
||||
{
|
||||
char buffer[32];
|
||||
sprintf(buffer, "%d", value);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
float StringHelper::toFloat(const std::string &s, float v, bool* isOk)
|
||||
float strx::toFloat(const std::string &s, float v, bool* isOk)
|
||||
{
|
||||
float result = 0.0;
|
||||
int code = sscanf(s.c_str(), "%f", &result);
|
||||
|
|
@ -271,14 +271,14 @@ float StringHelper::toFloat(const std::string &s, float v, bool* isOk)
|
|||
return result;
|
||||
}
|
||||
|
||||
std::string StringHelper::trim(const std::string &s)
|
||||
std::string strx::trim(const std::string &s)
|
||||
{
|
||||
auto wsfront = std::find_if_not(s.begin(), s.end(), [](int c) { return std::isspace(c) || c == '\r' || c == '\n'; });
|
||||
auto wsback = std::find_if_not(s.rbegin(), s.rend(), [](int c) { return std::isspace(c) || c == '\r' || c == '\n'; }).base();
|
||||
return (wsback <= wsfront ? std::string() : std::string(wsfront,wsback));
|
||||
}
|
||||
|
||||
std::string StringHelper::timeToString(time_t t)
|
||||
std::string strx::timeToString(time_t t)
|
||||
{
|
||||
char buffer[128] = "";
|
||||
struct tm lt;
|
||||
|
|
@ -292,12 +292,12 @@ std::string StringHelper::timeToString(time_t t)
|
|||
return buffer;
|
||||
}
|
||||
|
||||
std::string StringHelper::millisecondsToString(uint64_t t)
|
||||
std::string strx::millisecondsToString(uint64_t t)
|
||||
{
|
||||
return timeToString(t/1000);
|
||||
}
|
||||
|
||||
int StringHelper::fromHex2Int(const std::string &s)
|
||||
int strx::fromHex2Int(const std::string &s)
|
||||
{
|
||||
int result = 0;
|
||||
sscanf(s.c_str(), "%x", &result);
|
||||
|
|
@ -320,7 +320,7 @@ static int hex2code(const char* s)
|
|||
return (hex2code(s[0]) << 4) + hex2code(s[1]);
|
||||
}
|
||||
|
||||
std::string StringHelper::fromHex2String(const std::string& s)
|
||||
std::string strx::fromHex2String(const std::string& s)
|
||||
{
|
||||
std::string result; result.resize(s.size() / 2);
|
||||
const char* t = s.c_str();
|
||||
|
|
@ -330,7 +330,7 @@ std::string StringHelper::fromHex2String(const std::string& s)
|
|||
return result;
|
||||
}
|
||||
|
||||
std::string StringHelper::replace(const std::string& s, char f, char r)
|
||||
std::string strx::replace(const std::string& s, char f, char r)
|
||||
{
|
||||
std::string result(s);
|
||||
for (std::string::size_type i = 0; i < result.size(); i++)
|
||||
|
|
@ -340,7 +340,7 @@ std::string StringHelper::replace(const std::string& s, char f, char r)
|
|||
return result;
|
||||
}
|
||||
|
||||
std::string StringHelper::replace(const std::string& s, const std::string& tmpl, const std::string& n)
|
||||
std::string strx::replace(const std::string& s, const std::string& tmpl, const std::string& n)
|
||||
{
|
||||
std::string result(s);
|
||||
std::string::size_type p = 0;
|
||||
|
|
@ -353,7 +353,7 @@ std::string StringHelper::replace(const std::string& s, const std::string& tmpl,
|
|||
return result;
|
||||
}
|
||||
|
||||
std::string StringHelper::decodeUri(const std::string& s)
|
||||
std::string strx::decodeUri(const std::string& s)
|
||||
{
|
||||
std::string ret;
|
||||
ret.reserve(s.size());
|
||||
|
|
@ -376,19 +376,19 @@ std::string StringHelper::decodeUri(const std::string& s)
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool StringHelper::startsWith(const std::string& s, const std::string& prefix)
|
||||
bool strx::startsWith(const std::string& s, const std::string& prefix)
|
||||
{
|
||||
std::string::size_type p = s.find(prefix);
|
||||
return p == 0;
|
||||
}
|
||||
|
||||
bool StringHelper::endsWith(const std::string& s, const std::string& suffix)
|
||||
bool strx::endsWith(const std::string& s, const std::string& suffix)
|
||||
{
|
||||
std::string::size_type p = s.rfind(suffix);
|
||||
return (p == s.size() - suffix.size());
|
||||
}
|
||||
|
||||
int StringHelper::stringToDuration(const std::string& s)
|
||||
int strx::stringToDuration(const std::string& s)
|
||||
{
|
||||
if (endsWith(s, "ms"))
|
||||
return std::stoi(s.substr(0, s.size()-2));
|
||||
|
|
@ -402,92 +402,9 @@ int StringHelper::stringToDuration(const std::string& s)
|
|||
return std::stoi(s) * 1000;
|
||||
}
|
||||
|
||||
#define XML_HEADER "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>"
|
||||
// --------------------- XcapHelper -----------------
|
||||
std::string XcapHelper::buildBuddyList(std::string listName, std::vector<std::string> buddies)
|
||||
std::string strx::uppercase(const std::string& s)
|
||||
{
|
||||
std::ostringstream result;
|
||||
result << XML_HEADER <<
|
||||
"<resource-lists xmlns=\"urn:ietf:params:xml:ns:resource-lists\">" <<
|
||||
"<list name=\"" << listName.c_str() << "\">";
|
||||
|
||||
// to test CT only!
|
||||
//result << "<entry uri=\"" << "sip:dbogovych1@10.11.1.25" << "\"/>";
|
||||
//result << "<entry uri=\"" << "sip:dbogovych2@10.11.1.25" << "\"/>";
|
||||
|
||||
for (unsigned i = 0; i<buddies.size(); i++)
|
||||
{
|
||||
result << "<entry uri=\"" << normalizeSipUri(buddies[i]).c_str() << "\"/>";
|
||||
}
|
||||
result << "</list></resource-lists>";
|
||||
return result.str();
|
||||
}
|
||||
|
||||
std::string XcapHelper::buildRules(std::vector<std::string> buddies)
|
||||
{
|
||||
std::ostringstream result;
|
||||
result << XML_HEADER <<
|
||||
"<ruleset xmlns=\"urn:ietf:params:xml:ns:common-policy\">" <<
|
||||
"<rule id=\"presence_allow\">" <<
|
||||
"<conditions>";
|
||||
|
||||
for (unsigned i = 0; i<buddies.size(); i++)
|
||||
{
|
||||
result << "<identity><one id=\"" <<
|
||||
normalizeSipUri(buddies[i]).c_str() << "\"/></identity>";
|
||||
}
|
||||
result << "</conditions>" <<
|
||||
"<actions>" <<
|
||||
"<sub-handling xmlns=\"urn:ietf:params:xml:ns:pres-rules\">" <<
|
||||
"allow" <<
|
||||
"</sub-handling>" <<
|
||||
"</actions>" <<
|
||||
"<transformations>" <<
|
||||
"<provide-devices xmlns=\"urn:ietf:params:xml:ns:pres-rules\">" <<
|
||||
"<all-devices/>" <<
|
||||
"</provide-devices>" <<
|
||||
"<provide-persons xmlns=\"urn:ietf:params:xml:ns:pres-rules\">" <<
|
||||
"<all-persons/>" <<
|
||||
"</provide-persons>" <<
|
||||
"<provide-services xmlns=\"urn:ietf:params:xml:ns:pres-rules\">" <<
|
||||
"<all-services/>" <<
|
||||
"</provide-services>" <<
|
||||
"</transformations>" <<
|
||||
"</rule>" <<
|
||||
"</ruleset>";
|
||||
return result.str();
|
||||
}
|
||||
|
||||
std::string XcapHelper::buildServices(std::string serviceUri, std::string listRef)
|
||||
{
|
||||
std::ostringstream result;
|
||||
|
||||
result << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl <<
|
||||
"<rls-services xmlns=\"urn:ietf:params:xml:ns:rls-services\"" << std::endl <<
|
||||
"xmlns:rl=\"urn:ietf:params:xml:ns:resource-lists\"" << std::endl <<
|
||||
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" << std::endl <<
|
||||
"<service uri=\"" << normalizeSipUri(serviceUri).c_str() << "\">" << std::endl <<
|
||||
"<resource-list>" << listRef.c_str() << "</resource-list>" << std::endl <<
|
||||
"<packages>" << std::endl <<
|
||||
"<package>presence</package>" << std::endl <<
|
||||
"</packages>" << std::endl <<
|
||||
"</service>" << std::endl <<
|
||||
"</rls-services>";
|
||||
|
||||
return result.str();
|
||||
}
|
||||
|
||||
std::string XcapHelper::normalizeSipUri(std::string uri)
|
||||
{
|
||||
if (uri.length())
|
||||
{
|
||||
if (uri[0] == '<')
|
||||
uri.erase(0,1);
|
||||
if (uri.length())
|
||||
{
|
||||
if (uri[uri.length()-1] == '>')
|
||||
uri.erase(uri.length()-1, 1);
|
||||
}
|
||||
}
|
||||
return uri;
|
||||
std::string r(s);
|
||||
std::transform(r.begin(), r.end(), r.begin(), ::toupper);
|
||||
return r;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,25 +16,30 @@
|
|||
#endif
|
||||
|
||||
|
||||
class StringHelper
|
||||
class strx
|
||||
{
|
||||
public:
|
||||
static std::string extractFilename(const std::string& path);
|
||||
static std::string appendPath(const std::string& s1, const std::string& s2);
|
||||
|
||||
static std::string makeUtf8(const std::tstring& arg);
|
||||
static std::string toUtf8(const std::tstring& arg);
|
||||
static std::tstring makeTstring(const std::string& arg);
|
||||
|
||||
static int toInt(const char* s, int defaultValue, bool* isOk = nullptr);
|
||||
static uint64_t toUint64(const char* s, uint64_t def, bool *isOk = nullptr);
|
||||
static std::string toHex(unsigned int value);
|
||||
static std::string toHex(const void* ptr);
|
||||
static std::string toHex(const uint8_t* input, size_t inputLength);
|
||||
static std::string intToString(int value);
|
||||
static std::string prefixLines(const std::string& source, const std::string& prefix);
|
||||
static std::string doubleToString(double value, int precision);
|
||||
static int fromHex2Int(const std::string& s);
|
||||
static std::string fromHex2String(const std::string& s);
|
||||
static float toFloat(const std::string& s, float defaultValue = 0.0, bool* isOk = nullptr);
|
||||
|
||||
static std::string extractFilename(const std::string& path);
|
||||
static std::string appendPath(const std::string& s1, const std::string& s2);
|
||||
|
||||
static std::string prefixLines(const std::string& source, const std::string& prefix);
|
||||
static const char* findSubstring(const char* buffer, const char* substring, size_t bufferLength);
|
||||
|
||||
static void split(const std::string& src, std::vector<std::string>& dst, const std::string& delims);
|
||||
static std::vector<std::string> split(const std::string& src, const std::string& delims = "\n");
|
||||
|
||||
|
|
@ -53,18 +58,17 @@ public:
|
|||
|
||||
static std::pair<std::string, int> parseHost(const std::string& host, int defaultPort);
|
||||
static std::pair<std::string, std::string> parseAssignment(const std::string& s, bool trimQuotes = true);
|
||||
static float toFloat(const std::string& s, float defaultValue = 0.0, bool* isOk = nullptr);
|
||||
static std::string trim(const std::string& s);
|
||||
static std::string timeToString(time_t t);
|
||||
static std::string millisecondsToString(uint64_t t);
|
||||
static int fromHex2Int(const std::string& s);
|
||||
static std::string fromHex2String(const std::string& s);
|
||||
static std::string replace(const std::string& s, char f, char r);
|
||||
static std::string replace(const std::string& s, const std::string& tmpl, const std::string& n);
|
||||
static std::string decodeUri(const std::string& s);
|
||||
static bool startsWith(const std::string& s, const std::string& prefix);
|
||||
static bool endsWith(const std::string& s, const std::string& suffix);
|
||||
static int stringToDuration(const std::string& s);
|
||||
static std::string uppercase(const std::string& s);
|
||||
|
||||
};
|
||||
|
||||
class XcapHelper
|
||||
|
|
|
|||
|
|
@ -0,0 +1,109 @@
|
|||
/* Copyright(C) 2007-2023 VoIPobjects (voipobjects.com)
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "HL_Xcap.h"
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <memory.h>
|
||||
#include <algorithm>
|
||||
#include <inttypes.h>
|
||||
|
||||
#ifdef TARGET_WIN
|
||||
# include <WinSock2.h>
|
||||
# include <Windows.h>
|
||||
# include <cctype>
|
||||
#endif
|
||||
|
||||
#define XML_HEADER "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>"
|
||||
// --------------------- XcapHelper -----------------
|
||||
std::string XcapHelper::buildBuddyList(const std::string& listName, const std::vector<std::string>& buddies)
|
||||
{
|
||||
std::ostringstream result;
|
||||
result << XML_HEADER <<
|
||||
"<resource-lists xmlns=\"urn:ietf:params:xml:ns:resource-lists\">" <<
|
||||
"<list name=\"" << listName.c_str() << "\">";
|
||||
|
||||
// to test CT only!
|
||||
//result << "<entry uri=\"" << "sip:dbogovych1@10.11.1.25" << "\"/>";
|
||||
//result << "<entry uri=\"" << "sip:dbogovych2@10.11.1.25" << "\"/>";
|
||||
|
||||
for (unsigned i = 0; i<buddies.size(); i++)
|
||||
{
|
||||
result << "<entry uri=\"" << normalizeSipUri(buddies[i]).c_str() << "\"/>";
|
||||
}
|
||||
result << "</list></resource-lists>";
|
||||
return result.str();
|
||||
}
|
||||
|
||||
std::string XcapHelper::buildRules(const std::vector<std::string>& buddies)
|
||||
{
|
||||
std::ostringstream result;
|
||||
result << XML_HEADER <<
|
||||
"<ruleset xmlns=\"urn:ietf:params:xml:ns:common-policy\">" <<
|
||||
"<rule id=\"presence_allow\">" <<
|
||||
"<conditions>";
|
||||
|
||||
for (unsigned i = 0; i<buddies.size(); i++)
|
||||
{
|
||||
result << "<identity><one id=\"" <<
|
||||
normalizeSipUri(buddies[i]).c_str() << "\"/></identity>";
|
||||
}
|
||||
result << "</conditions>" <<
|
||||
"<actions>" <<
|
||||
"<sub-handling xmlns=\"urn:ietf:params:xml:ns:pres-rules\">" <<
|
||||
"allow" <<
|
||||
"</sub-handling>" <<
|
||||
"</actions>" <<
|
||||
"<transformations>" <<
|
||||
"<provide-devices xmlns=\"urn:ietf:params:xml:ns:pres-rules\">" <<
|
||||
"<all-devices/>" <<
|
||||
"</provide-devices>" <<
|
||||
"<provide-persons xmlns=\"urn:ietf:params:xml:ns:pres-rules\">" <<
|
||||
"<all-persons/>" <<
|
||||
"</provide-persons>" <<
|
||||
"<provide-services xmlns=\"urn:ietf:params:xml:ns:pres-rules\">" <<
|
||||
"<all-services/>" <<
|
||||
"</provide-services>" <<
|
||||
"</transformations>" <<
|
||||
"</rule>" <<
|
||||
"</ruleset>";
|
||||
return result.str();
|
||||
}
|
||||
|
||||
std::string XcapHelper::buildServices(const std::string& serviceUri, const std::string& listRef)
|
||||
{
|
||||
std::ostringstream result;
|
||||
|
||||
result << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl <<
|
||||
"<rls-services xmlns=\"urn:ietf:params:xml:ns:rls-services\"" << std::endl <<
|
||||
"xmlns:rl=\"urn:ietf:params:xml:ns:resource-lists\"" << std::endl <<
|
||||
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" << std::endl <<
|
||||
"<service uri=\"" << normalizeSipUri(serviceUri).c_str() << "\">" << std::endl <<
|
||||
"<resource-list>" << listRef.c_str() << "</resource-list>" << std::endl <<
|
||||
"<packages>" << std::endl <<
|
||||
"<package>presence</package>" << std::endl <<
|
||||
"</packages>" << std::endl <<
|
||||
"</service>" << std::endl <<
|
||||
"</rls-services>";
|
||||
|
||||
return result.str();
|
||||
}
|
||||
|
||||
std::string XcapHelper::normalizeSipUri(const std::string& uri)
|
||||
{
|
||||
std::string t(uri);
|
||||
|
||||
if (t.length())
|
||||
{
|
||||
if (t[0] == '<')
|
||||
t.erase(0,1);
|
||||
if (t.length())
|
||||
{
|
||||
if (t[t.length()-1] == '>')
|
||||
t.erase(uri.length()-1, 1);
|
||||
}
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
/* Copyright(C) 2007-2024 VoIPobjects (voipobjects.com)
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef __HELPER_STRING_H
|
||||
#define __HELPER_STRING_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
class XcapHelper
|
||||
{
|
||||
public:
|
||||
static std::string buildBuddyList(const std::string& listName, const std::vector<std::string>& buddies);
|
||||
static std::string buildRules(const std::vector<std::string>& buddies);
|
||||
static std::string buildServices(const std::string& serviceUri, const std::string& listRef);
|
||||
static std::string normalizeSipUri(const std::string& uri);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -6,6 +6,7 @@ set (CMAKE_CXX_STANDARD_REQUIRED ON)
|
|||
|
||||
# Produce PIC code always
|
||||
set (CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
option (USE_RESIP_INTEGRATION "Use some resiprocate specific routines" OFF)
|
||||
|
||||
set (SOURCES
|
||||
MT_Statistics.cpp
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ int G729Codec::plc(int lostFrames, void* output, int outputCapacity)
|
|||
#define OPUS_CODEC_NAME "OPUS"
|
||||
#define OPUS_CODEC_RATE 16000
|
||||
#define OPUS_TARGET_BITRATE 64000
|
||||
#define OPUS_PACKET_LOSS 30
|
||||
#define OPUS_PACKET_LOSS 10
|
||||
#define OPUS_CODEC_COMPLEXITY 2
|
||||
|
||||
OpusCodec::Params::Params()
|
||||
|
|
@ -321,7 +321,7 @@ void OpusCodec::Params::parse(const resip::Data ¶ms)
|
|||
mStereo = paramIter->mValue == "1";
|
||||
else
|
||||
if (paramIter->mName == "ptime")
|
||||
mPtime = StringHelper::toInt(paramIter->mValue.c_str(), 20);
|
||||
mPtime = strx::toInt(paramIter->mValue.c_str(), 20);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -233,7 +233,7 @@ RtpBuffer::FetchResult RtpBuffer::fetch(ResultList& rl)
|
|||
unsigned seqno = mPacketList.front()->rtp()->GetExtendedSequenceNumber();
|
||||
|
||||
// Gap between new packet and previous on
|
||||
int gap = seqno - mFetchedPacket->rtp()->GetSequenceNumber() - 1;
|
||||
int gap = (int64_t)seqno - (int64_t)mFetchedPacket->rtp()->GetExtendedSequenceNumber() - 1;
|
||||
gap = std::min(gap, 127);
|
||||
if (gap > 0 && mPacketList.empty())
|
||||
{
|
||||
|
|
@ -354,6 +354,18 @@ AudioReceiver::~AudioReceiver()
|
|||
mDecodedDump.reset();
|
||||
}
|
||||
|
||||
// Update codec settings
|
||||
void AudioReceiver::setCodecSettings(const CodecList::Settings& codecSettings)
|
||||
{
|
||||
if (mCodecSettings == codecSettings)
|
||||
return;
|
||||
|
||||
mCodecSettings = codecSettings;
|
||||
mCodecMap.clear();
|
||||
mCodecList.setSettings(mCodecSettings);
|
||||
mCodecList.fillCodecMap(mCodecMap);
|
||||
}
|
||||
|
||||
size_t decode_packet(Codec& codec, RTPPacket& p, void* output_buffer, size_t output_capacity)
|
||||
{
|
||||
// How much data was produced
|
||||
|
|
|
|||
|
|
@ -125,6 +125,9 @@ namespace MT
|
|||
AudioReceiver(const CodecList::Settings& codecSettings, Statistics& stat);
|
||||
~AudioReceiver();
|
||||
|
||||
// Update codec settings
|
||||
void setCodecSettings(const CodecList::Settings& codecSettings);
|
||||
|
||||
// Returns false when packet is rejected as illegal. codec parameter will show codec which will be used for decoding.
|
||||
// Lifetime of pointer to codec is limited by lifetime of AudioReceiver (it is container).
|
||||
bool add(const std::shared_ptr<jrtplib::RTPPacket>& p, Codec** codec = nullptr);
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
using namespace MT;
|
||||
|
||||
using strx = StringHelper;
|
||||
using strx = strx;
|
||||
|
||||
// ---------------- EvsSpec ---------------
|
||||
|
||||
|
|
@ -125,13 +125,80 @@ CodecList::Settings::OpusSpec CodecList::Settings::OpusSpec::parse(const std::st
|
|||
return result;
|
||||
}
|
||||
|
||||
CodecList::Settings CodecList::Settings::parseSdp(const std::list<resip::Codec>& codeclist)
|
||||
{
|
||||
CodecList::Settings r{DefaultSettings};
|
||||
|
||||
for (auto& c: codeclist)
|
||||
{
|
||||
std::string codec_name = strx::uppercase(c.getName().c_str());
|
||||
int samplerate = c.getRate();
|
||||
int ptype = c.payloadType();
|
||||
|
||||
// Dynamic payload type codecs only - ISAC / iLBC / Speex / etc.
|
||||
if (codec_name == "OPUS")
|
||||
{
|
||||
// Check the parameters
|
||||
auto enc_params = c.encodingParameters(); // This must channels number for Opus codec
|
||||
auto params = c.parameters();
|
||||
int channels = strx::toInt(enc_params.c_str(), 1);
|
||||
r.mOpusSpec.push_back({ptype, samplerate, channels});
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
bool CodecList::Settings::operator == (const Settings& rhs) const
|
||||
{
|
||||
if (std::tie(mWrapIuUP, mSkipDecode, mIsac16KPayloadType, mIsac32KPayloadType, mIlbc20PayloadType, mIlbc30PayloadType, mGsmFrPayloadType, mGsmFrPayloadLength, mGsmEfrPayloadType, mGsmHrPayloadType) !=
|
||||
std::tie(rhs.mWrapIuUP, rhs.mSkipDecode, rhs.mIsac16KPayloadType, rhs.mIsac32KPayloadType, rhs.mIlbc20PayloadType, rhs.mIlbc30PayloadType, rhs.mGsmFrPayloadType, rhs.mGsmFrPayloadLength, rhs.mGsmEfrPayloadType, rhs.mGsmHrPayloadType))
|
||||
return false;
|
||||
|
||||
if (mAmrNbOctetPayloadType != rhs.mAmrNbOctetPayloadType)
|
||||
return false;
|
||||
|
||||
if (mAmrNbPayloadType != rhs.mAmrNbPayloadType)
|
||||
return false;
|
||||
|
||||
if (mAmrWbOctetPayloadType != rhs.mAmrWbOctetPayloadType)
|
||||
return false;
|
||||
|
||||
if (mAmrWbPayloadType != rhs.mAmrWbPayloadType)
|
||||
return false;
|
||||
|
||||
// ToDo: compare EVS and Opus specs
|
||||
if (mEvsSpec.size() != rhs.mEvsSpec.size())
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < mEvsSpec.size(); i++)
|
||||
if (mEvsSpec[i] != rhs.mEvsSpec[i])
|
||||
return false;
|
||||
|
||||
if (mOpusSpec.size() != rhs.mOpusSpec.size())
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < mOpusSpec.size(); i++)
|
||||
if (mOpusSpec[i] != rhs.mOpusSpec[i])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------
|
||||
CodecList::Settings CodecList::Settings::DefaultSettings;
|
||||
|
||||
CodecList::CodecList(const Settings& settings)
|
||||
:mSettings(settings)
|
||||
{
|
||||
//mFactoryList.push_back(new OpusCodec::OpusFactory(16000, 1));
|
||||
init(mSettings);
|
||||
}
|
||||
|
||||
void CodecList::init(const Settings& settings)
|
||||
{
|
||||
for (auto f: mFactoryList)
|
||||
delete f;
|
||||
mFactoryList.clear();
|
||||
|
||||
#if defined(USE_OPUS_CODEC)
|
||||
if (settings.mOpusSpec.empty())
|
||||
|
|
@ -191,8 +258,8 @@ CodecList::CodecList(const Settings& settings)
|
|||
|
||||
CodecList::~CodecList()
|
||||
{
|
||||
for (FactoryList::size_type i=0; i<mFactoryList.size(); i++)
|
||||
delete mFactoryList[i];
|
||||
for (auto f: mFactoryList)
|
||||
delete f;
|
||||
}
|
||||
|
||||
int CodecList::count() const
|
||||
|
|
@ -217,10 +284,12 @@ int CodecList::findCodec(const std::string &name) const
|
|||
|
||||
void CodecList::fillCodecMap(CodecMap& cm)
|
||||
{
|
||||
cm.clear();
|
||||
for (auto& factory: mFactoryList)
|
||||
{
|
||||
// Create codec here. Although they are not needed right now - they can be needed to find codec's info.
|
||||
cm[factory->payloadType()] = factory->create();
|
||||
PCodec c = factory->create();
|
||||
cm.insert({factory->payloadType(), c});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,6 +69,10 @@ public:
|
|||
Encoding mEncodingType = Encoding_MIME;
|
||||
bool isValid() const;
|
||||
static EvsSpec parse(const std::string& spec);
|
||||
|
||||
bool operator == (const EvsSpec& rhs) const { return std::tie(mPayloadType, mBandwidth, mEncodingType) == std::tie(rhs.mPayloadType, rhs.mBandwidth, rhs.mEncodingType);}
|
||||
bool operator != (const EvsSpec& rhs) const { return ! (operator ==) (rhs);};
|
||||
|
||||
};
|
||||
|
||||
std::vector<EvsSpec> mEvsSpec;
|
||||
|
|
@ -79,7 +83,14 @@ public:
|
|||
int mRate = -1;
|
||||
int mChannels = -1;
|
||||
|
||||
OpusSpec(int ptype = -1, int rate = -1, int channels = -1)
|
||||
:mPayloadType(ptype), mRate(rate), mChannels(channels)
|
||||
{}
|
||||
|
||||
bool isValid() const;
|
||||
bool operator == (const OpusSpec& rhs) const { return std::tie(mPayloadType, mRate, mChannels) == std::tie(rhs.mPayloadType, rhs.mRate, rhs.mChannels);}
|
||||
bool operator != (const OpusSpec& rhs) const { return ! (operator ==) (rhs);};
|
||||
|
||||
static OpusSpec parse(const std::string& spec);
|
||||
};
|
||||
std::vector<OpusSpec> mOpusSpec;
|
||||
|
|
@ -88,20 +99,29 @@ public:
|
|||
std::string toString() const;
|
||||
|
||||
static Settings DefaultSettings;
|
||||
|
||||
#if defined(USE_RESIP_INTEGRATION)
|
||||
static Settings parseSdp(const std::list<resip::Codec>& codeclist);
|
||||
#endif
|
||||
bool operator == (const Settings& rhs) const;
|
||||
};
|
||||
|
||||
CodecList(const Settings& settings);
|
||||
~CodecList();
|
||||
void setSettings(const Settings& settings) { init(settings); }
|
||||
|
||||
int count() const;
|
||||
Codec::Factory& codecAt(int index) const;
|
||||
int findCodec(const std::string& name) const;
|
||||
void fillCodecMap(CodecMap& cm);
|
||||
|
||||
|
||||
protected:
|
||||
typedef std::vector<Codec::Factory*> FactoryList;
|
||||
FactoryList mFactoryList;
|
||||
Settings mSettings;
|
||||
|
||||
void init(const Settings& settings);
|
||||
};
|
||||
|
||||
class CodecListPriority
|
||||
|
|
|
|||
|
|
@ -203,8 +203,8 @@ NetworkAddress::NetworkAddress(const uint8_t* ip_6, uint16_t port)
|
|||
mAddr6.sin6_port = port;
|
||||
}
|
||||
|
||||
NetworkAddress::NetworkAddress(const sockaddr& addr, unsigned addrLen)
|
||||
:mInitialized(true), mRelayed(false)
|
||||
NetworkAddress::NetworkAddress(const sockaddr& addr, size_t addrLen)
|
||||
:mInitialized(true), mRelayed(false)
|
||||
{
|
||||
switch (addr.sa_family)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ namespace ice
|
|||
|
||||
NetworkAddress(const in6_addr& ip, unsigned short port);
|
||||
NetworkAddress(const in_addr& ip, unsigned short port);
|
||||
NetworkAddress(const sockaddr& addr, unsigned addrLen);
|
||||
NetworkAddress(const sockaddr& addr, size_t addrLen);
|
||||
NetworkAddress(const NetworkAddress& src);
|
||||
~NetworkAddress();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue