utils: cleanup Split and Join
This commit is contained in:
parent
39a896f5b6
commit
e330f8553d
|
@ -213,7 +213,7 @@ void LibvlcCamera::Terminate() {
|
|||
int LibvlcCamera::PrimeCapture() {
|
||||
Debug(1, "Priming capture from %s, libvlc version %s", mPath.c_str(), (*libvlc_get_version_f)());
|
||||
|
||||
StringVector opVect = split(Options(), ",");
|
||||
StringVector opVect = Split(Options(), ",");
|
||||
|
||||
// Set transport method as specified by method field, rtpUni is default
|
||||
if ( Method() == "rtpMulti" )
|
||||
|
|
|
@ -166,7 +166,7 @@ void Logger::initialise(const std::string &id, const Options &options) {
|
|||
tempSyslogLevel = atoi(envPtr);
|
||||
|
||||
if ( config.log_debug ) {
|
||||
StringVector targets = split(config.log_debug_target, "|");
|
||||
StringVector targets = Split(config.log_debug_target, "|");
|
||||
for ( unsigned int i = 0; i < targets.size(); i++ ) {
|
||||
const std::string &target = targets[i];
|
||||
if ( target == mId || target == "_"+mId || target == "_"+mIdRoot || target == "" ) {
|
||||
|
|
|
@ -34,7 +34,7 @@ RtspThread::PortSet RtspThread::smAssignedPorts;
|
|||
|
||||
bool RtspThread::sendCommand(std::string message) {
|
||||
if ( mNeedAuth ) {
|
||||
StringVector parts = split(message, " ");
|
||||
StringVector parts = Split(message, " ");
|
||||
if ( parts.size() > 1 )
|
||||
message += mAuthenticator->getAuthHeader(parts[0], parts[1]);
|
||||
}
|
||||
|
@ -172,7 +172,7 @@ RtspThread::RtspThread(
|
|||
mHttpSession = stringtf("%d", rand());
|
||||
|
||||
mNeedAuth = false;
|
||||
StringVector parts = split(auth, ":");
|
||||
StringVector parts = Split(auth, ":");
|
||||
Debug(2, "# of auth parts %d", parts.size());
|
||||
if ( parts.size() > 1 )
|
||||
mAuthenticator = new zm::Authenticator(parts[0], parts[1]);
|
||||
|
@ -320,7 +320,7 @@ void RtspThread::Run() {
|
|||
} // end if failed response maybe due to auth
|
||||
|
||||
char publicLine[256] = "";
|
||||
StringVector lines = split(response, "\r\n");
|
||||
StringVector lines = Split(response, "\r\n");
|
||||
for ( size_t i = 0; i < lines.size(); i++ )
|
||||
sscanf(lines[i].c_str(), "Public: %[^\r\n]\r\n", publicLine);
|
||||
|
||||
|
@ -352,7 +352,7 @@ void RtspThread::Run() {
|
|||
std::string DescHeader = response.substr(0, sdpStart);
|
||||
Debug(1, "Processing DESCRIBE response header '%s'", DescHeader.c_str());
|
||||
|
||||
lines = split(DescHeader, "\r\n");
|
||||
lines = Split(DescHeader, "\r\n");
|
||||
for ( size_t i = 0; i < lines.size(); i++ ) {
|
||||
// If the device sends us a url value for Content-Base in the response header, we should use that instead
|
||||
if ( ( lines[i].size() > 13 ) && ( lines[i].substr( 0, 13 ) == "Content-Base:" ) ) {
|
||||
|
@ -453,14 +453,14 @@ void RtspThread::Run() {
|
|||
if ( !recvResponse(response) )
|
||||
return;
|
||||
|
||||
lines = split(response, "\r\n");
|
||||
lines = Split(response, "\r\n");
|
||||
std::string session;
|
||||
int timeout = 0;
|
||||
char transport[256] = "";
|
||||
|
||||
for ( size_t i = 0; i < lines.size(); i++ ) {
|
||||
if ( ( lines[i].size() > 8 ) && ( lines[i].substr(0, 8) == "Session:" ) ) {
|
||||
StringVector sessionLine = split(lines[i].substr(9), ";");
|
||||
StringVector sessionLine = Split(lines[i].substr(9), ";");
|
||||
session = TrimSpaces(sessionLine[0]);
|
||||
if ( sessionLine.size() == 2 )
|
||||
sscanf(TrimSpaces(sessionLine[1]).c_str(), "timeout=%d", &timeout);
|
||||
|
@ -483,33 +483,33 @@ void RtspThread::Run() {
|
|||
int remoteChannels[2] = { 0, 0 };
|
||||
std::string distribution = "";
|
||||
unsigned long ssrc = 0;
|
||||
StringVector parts = split( transport, ";" );
|
||||
StringVector parts = Split(transport, ";");
|
||||
for ( size_t i = 0; i < parts.size(); i++ ) {
|
||||
if ( parts[i] == "unicast" || parts[i] == "multicast" )
|
||||
distribution = parts[i];
|
||||
else if (StartsWith(parts[i], "server_port=") ) {
|
||||
method = "RTP/UNICAST";
|
||||
StringVector subparts = split( parts[i], "=" );
|
||||
StringVector ports = split( subparts[1], "-" );
|
||||
StringVector subparts = Split(parts[i], "=");
|
||||
StringVector ports = Split(subparts[1], "-");
|
||||
remotePorts[0] = strtol( ports[0].c_str(), nullptr, 10 );
|
||||
remotePorts[1] = strtol( ports[1].c_str(), nullptr, 10 );
|
||||
} else if (StartsWith(parts[i], "interleaved=") ) {
|
||||
method = "RTP/RTSP";
|
||||
StringVector subparts = split( parts[i], "=" );
|
||||
StringVector channels = split( subparts[1], "-" );
|
||||
StringVector subparts = Split(parts[i], "=");
|
||||
StringVector channels = Split(subparts[1], "-");
|
||||
remoteChannels[0] = strtol( channels[0].c_str(), nullptr, 10 );
|
||||
remoteChannels[1] = strtol( channels[1].c_str(), nullptr, 10 );
|
||||
} else if (StartsWith(parts[i], "port=") ) {
|
||||
method = "RTP/MULTICAST";
|
||||
StringVector subparts = split( parts[i], "=" );
|
||||
StringVector ports = split( subparts[1], "-" );
|
||||
StringVector subparts = Split(parts[i], "=");
|
||||
StringVector ports = Split(subparts[1], "-");
|
||||
localPorts[0] = strtol( ports[0].c_str(), nullptr, 10 );
|
||||
localPorts[1] = strtol( ports[1].c_str(), nullptr, 10 );
|
||||
} else if (StartsWith(parts[i], "destination=") ) {
|
||||
StringVector subparts = split( parts[i], "=" );
|
||||
StringVector subparts = Split(parts[i], "=");
|
||||
localHost = subparts[1];
|
||||
} else if (StartsWith(parts[i], "ssrc=") ) {
|
||||
StringVector subparts = split( parts[i], "=" );
|
||||
StringVector subparts = Split(parts[i], "=");
|
||||
ssrc = strtoll( subparts[1].c_str(), nullptr, 16 );
|
||||
}
|
||||
}
|
||||
|
@ -528,14 +528,14 @@ void RtspThread::Run() {
|
|||
if ( !recvResponse(response) )
|
||||
return;
|
||||
|
||||
lines = split(response, "\r\n");
|
||||
lines = Split(response, "\r\n");
|
||||
std::string rtpInfo;
|
||||
for ( size_t i = 0; i < lines.size(); i++ ) {
|
||||
if ( ( lines[i].size() > 9 ) && ( lines[i].substr(0, 9) == "RTP-Info:" ) )
|
||||
rtpInfo = TrimSpaces(lines[i].substr(9));
|
||||
// Check for a timeout again. Some rtsp devices don't send a timeout until after the PLAY command is sent
|
||||
if ( ( lines[i].size() > 8 ) && ( lines[i].substr(0, 8) == "Session:" ) && ( timeout == 0 ) ) {
|
||||
StringVector sessionLine = split(lines[i].substr(9), ";");
|
||||
StringVector sessionLine = Split(lines[i].substr(9), ";");
|
||||
if ( sessionLine.size() == 2 )
|
||||
sscanf(TrimSpaces(sessionLine[1]).c_str(), "timeout=%d", &timeout);
|
||||
if ( timeout > 0 )
|
||||
|
@ -551,18 +551,18 @@ void RtspThread::Run() {
|
|||
} else {
|
||||
Debug( 2, "Got RTP Info %s", rtpInfo.c_str() );
|
||||
// More than one stream can be included in the RTP Info
|
||||
streams = split( rtpInfo.c_str(), "," );
|
||||
streams = Split(rtpInfo.c_str(), ",");
|
||||
for ( size_t i = 0; i < streams.size(); i++ ) {
|
||||
// We want the stream that matches the trackUrl we are using
|
||||
if ( streams[i].find(controlUrl.c_str()) != std::string::npos ) {
|
||||
// Parse the sequence and rtptime values
|
||||
parts = split( streams[i].c_str(), ";" );
|
||||
parts = Split(streams[i].c_str(), ";");
|
||||
for ( size_t j = 0; j < parts.size(); j++ ) {
|
||||
if (StartsWith(parts[j], "seq=") ) {
|
||||
StringVector subparts = split( parts[j], "=" );
|
||||
StringVector subparts = Split(parts[j], "=");
|
||||
seq = strtol( subparts[1].c_str(), nullptr, 10 );
|
||||
} else if (StartsWith(parts[j], "rtptime=") ) {
|
||||
StringVector subparts = split( parts[j], "=" );
|
||||
StringVector subparts = Split(parts[j], "=");
|
||||
rtpTime = strtol( subparts[1].c_str(), nullptr, 10 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,10 +68,10 @@ void Authenticator::authHandleHeader(std::string headerData) {
|
|||
else if ( strncasecmp(headerData.c_str(), digest_match, digest_match_len) == 0) {
|
||||
fAuthMethod = AUTH_DIGEST;
|
||||
Debug(2, "Set authMethod to Digest");
|
||||
StringVector subparts = split(headerData.substr(digest_match_len, headerData.length() - digest_match_len), ",");
|
||||
StringVector subparts = Split(headerData.substr(digest_match_len, headerData.length() - digest_match_len), ",");
|
||||
// subparts are key="value"
|
||||
for ( size_t i = 0; i < subparts.size(); i++ ) {
|
||||
StringVector kvPair = split(TrimSpaces(subparts[i]), "=");
|
||||
StringVector kvPair = Split(TrimSpaces(subparts[i]), "=");
|
||||
std::string key = TrimSpaces(kvPair[0]);
|
||||
if ( key == "realm" ) {
|
||||
fRealm = Trim(kvPair[1], "\"");
|
||||
|
@ -194,7 +194,7 @@ std::string Authenticator::computeDigestResponse(std::string &method, std::strin
|
|||
|
||||
void Authenticator::checkAuthResponse(std::string &response) {
|
||||
std::string authLine;
|
||||
StringVector lines = split(response, "\r\n");
|
||||
StringVector lines = Split(response, "\r\n");
|
||||
const char* authenticate_match = "WWW-Authenticate:";
|
||||
size_t authenticate_match_len = strlen(authenticate_match);
|
||||
|
||||
|
|
|
@ -107,7 +107,7 @@ SessionDescriptor::ConnInfo::ConnInfo( const std::string &connInfo ) :
|
|||
mTtl( 16 ),
|
||||
mNoAddresses( 0 )
|
||||
{
|
||||
StringVector tokens = split(connInfo, " ");
|
||||
StringVector tokens = Split(connInfo, " ");
|
||||
if ( tokens.size() < 3 )
|
||||
throw Exception( "Unable to parse SDP connection info from '"+connInfo+"'" );
|
||||
mNetworkType = tokens[0];
|
||||
|
@ -116,7 +116,7 @@ SessionDescriptor::ConnInfo::ConnInfo( const std::string &connInfo ) :
|
|||
mAddressType = tokens[1];
|
||||
if ( mAddressType != "IP4" && mAddressType != "IP6" )
|
||||
throw Exception( "Invalid SDP address type '"+mAddressType+"' in connection info '"+connInfo+"'" );
|
||||
StringVector addressTokens = split( tokens[2], "/" );
|
||||
StringVector addressTokens = Split(tokens[2], "/");
|
||||
if ( addressTokens.size() < 1 )
|
||||
throw Exception( "Invalid SDP address '"+tokens[2]+"' in connection info '"+connInfo+"'" );
|
||||
mAddress = addressTokens[0];
|
||||
|
@ -129,7 +129,7 @@ SessionDescriptor::ConnInfo::ConnInfo( const std::string &connInfo ) :
|
|||
SessionDescriptor::BandInfo::BandInfo( const std::string &bandInfo ) :
|
||||
mValue( 0 )
|
||||
{
|
||||
StringVector tokens = split( bandInfo, ":" );
|
||||
StringVector tokens = Split(bandInfo, ":");
|
||||
if ( tokens.size() < 2 )
|
||||
throw Exception( "Unable to parse SDP bandwidth info from '"+bandInfo+"'" );
|
||||
mType = tokens[0];
|
||||
|
@ -165,7 +165,7 @@ SessionDescriptor::SessionDescriptor( const std::string &url, const std::string
|
|||
{
|
||||
MediaDescriptor *currMedia = nullptr;
|
||||
|
||||
StringVector lines = split( sdp, "\r\n" );
|
||||
StringVector lines = Split(sdp, "\r\n");
|
||||
for ( StringVector::const_iterator iter = lines.begin(); iter != lines.end(); ++iter ) {
|
||||
std::string line = *iter;
|
||||
if ( line.empty() )
|
||||
|
@ -208,7 +208,7 @@ SessionDescriptor::SessionDescriptor( const std::string &url, const std::string
|
|||
case 'a' :
|
||||
{
|
||||
mAttributes.push_back( line );
|
||||
StringVector tokens = split( line, ":", 2 );
|
||||
StringVector tokens = Split(line, ":", 2);
|
||||
std::string attrName = tokens[0];
|
||||
if ( currMedia ) {
|
||||
if ( attrName == "control" ) {
|
||||
|
@ -220,14 +220,14 @@ SessionDescriptor::SessionDescriptor( const std::string &url, const std::string
|
|||
// a=rtpmap:96 MP4V-ES/90000
|
||||
if ( tokens.size() < 2 )
|
||||
throw Exception( "Unable to parse SDP rtpmap attribute '"+line+"' for media '"+currMedia->getType()+"'" );
|
||||
StringVector attrTokens = split( tokens[1], " " );
|
||||
StringVector attrTokens = Split(tokens[1], " ");
|
||||
int payloadType = atoi(attrTokens[0].c_str());
|
||||
if ( payloadType != currMedia->getPayloadType() )
|
||||
throw Exception( stringtf( "Payload type mismatch, expected %d, got %d in '%s'", currMedia->getPayloadType(), payloadType, line.c_str() ) );
|
||||
std::string payloadDesc = attrTokens[1];
|
||||
//currMedia->setPayloadType( payloadType );
|
||||
if ( attrTokens.size() > 1 ) {
|
||||
StringVector payloadTokens = split( attrTokens[1], "/" );
|
||||
StringVector payloadTokens = Split(attrTokens[1], "/");
|
||||
std::string payloadDesc = payloadTokens[0];
|
||||
int payloadClock = atoi(payloadTokens[1].c_str());
|
||||
currMedia->setPayloadDesc( payloadDesc );
|
||||
|
@ -237,13 +237,13 @@ SessionDescriptor::SessionDescriptor( const std::string &url, const std::string
|
|||
// a=framesize:96 320-240
|
||||
if ( tokens.size() < 2 )
|
||||
throw Exception("Unable to parse SDP framesize attribute '"+line+"' for media '"+currMedia->getType()+"'");
|
||||
StringVector attrTokens = split(tokens[1], " ");
|
||||
StringVector attrTokens = Split(tokens[1], " ");
|
||||
int payloadType = atoi(attrTokens[0].c_str());
|
||||
if ( payloadType != currMedia->getPayloadType() )
|
||||
throw Exception( stringtf("Payload type mismatch, expected %d, got %d in '%s'",
|
||||
currMedia->getPayloadType(), payloadType, line.c_str()));
|
||||
//currMedia->setPayloadType( payloadType );
|
||||
StringVector sizeTokens = split(attrTokens[1], "-");
|
||||
StringVector sizeTokens = Split(attrTokens[1], "-");
|
||||
int width = atoi(sizeTokens[0].c_str());
|
||||
int height = atoi(sizeTokens[1].c_str());
|
||||
currMedia->setFrameSize(width, height);
|
||||
|
@ -257,16 +257,16 @@ SessionDescriptor::SessionDescriptor( const std::string &url, const std::string
|
|||
// a=fmtp:96 profile-level-id=247; config=000001B0F7000001B509000001000000012008D48D8803250F042D14440F
|
||||
if ( tokens.size() < 2 )
|
||||
throw Exception("Unable to parse SDP fmtp attribute '"+line+"' for media '"+currMedia->getType()+"'");
|
||||
StringVector attrTokens = split(tokens[1], " ", 2);
|
||||
StringVector attrTokens = Split(tokens[1], " ", 2);
|
||||
int payloadType = atoi(attrTokens[0].c_str());
|
||||
if ( payloadType != currMedia->getPayloadType() )
|
||||
throw Exception(stringtf("Payload type mismatch, expected %d, got %d in '%s'",
|
||||
currMedia->getPayloadType(), payloadType, line.c_str()));
|
||||
//currMedia->setPayloadType( payloadType );
|
||||
if ( attrTokens.size() > 1 ) {
|
||||
StringVector attr2Tokens = split( attrTokens[1], "; " );
|
||||
StringVector attr2Tokens = Split(attrTokens[1], "; ");
|
||||
for ( unsigned int i = 0; i < attr2Tokens.size(); i++ ) {
|
||||
StringVector attr3Tokens = split( attr2Tokens[i], "=" );
|
||||
StringVector attr3Tokens = Split(attr2Tokens[i], "=");
|
||||
//Info( "Name = %s, Value = %s", attr3Tokens[0].c_str(), attr3Tokens[1].c_str() );
|
||||
if ( attr3Tokens[0] == "profile-level-id" ) {
|
||||
} else if ( attr3Tokens[0] == "config" ) {
|
||||
|
@ -294,13 +294,13 @@ SessionDescriptor::SessionDescriptor( const std::string &url, const std::string
|
|||
}
|
||||
case 'm' :
|
||||
{
|
||||
StringVector tokens = split(line, " ");
|
||||
StringVector tokens = Split(line, " ");
|
||||
if ( tokens.size() < 4 )
|
||||
throw Exception("Can't parse SDP media description '"+line+"'");
|
||||
std::string mediaType = tokens[0];
|
||||
if ( mediaType != "audio" && mediaType != "video" && mediaType != "application" )
|
||||
throw Exception("Unsupported media type '"+mediaType+"' in SDP media attribute '"+line+"'");
|
||||
StringVector portTokens = split(tokens[1], "/");
|
||||
StringVector portTokens = Split(tokens[1], "/");
|
||||
int mediaPort = atoi(portTokens[0].c_str());
|
||||
int mediaNumPorts = 1;
|
||||
if ( portTokens.size() > 1 )
|
||||
|
|
|
@ -54,7 +54,7 @@ User::User(const MYSQL_ROW &dbrow) {
|
|||
system = (Permission)atoi(dbrow[index++]);
|
||||
char *monitor_ids_str = dbrow[index++];
|
||||
if ( monitor_ids_str && *monitor_ids_str ) {
|
||||
StringVector ids = split(monitor_ids_str, ",");
|
||||
StringVector ids = Split(monitor_ids_str, ",");
|
||||
for ( StringVector::iterator i = ids.begin(); i < ids.end(); ++i ) {
|
||||
monitor_ids.push_back(atoi((*i).c_str()));
|
||||
}
|
||||
|
|
109
src/zm_utils.cpp
109
src/zm_utils.cpp
|
@ -61,53 +61,62 @@ std::string ReplaceAll(std::string str, const std::string &old_value, const std:
|
|||
return str;
|
||||
}
|
||||
|
||||
std::vector<std::string> split(const std::string &s, char delim) {
|
||||
std::vector<std::string> elems;
|
||||
std::stringstream ss(s);
|
||||
std::string item;
|
||||
while(std::getline(ss, item, delim)) {
|
||||
elems.push_back(TrimSpaces(item));
|
||||
StringVector Split(const std::string &str, char delim) {
|
||||
std::vector<std::string> tokens;
|
||||
|
||||
size_t start = 0;
|
||||
for (size_t end = str.find(delim); end != std::string::npos; end = str.find(delim, start)) {
|
||||
tokens.push_back(str.substr(start, end - start));
|
||||
start = end + 1;
|
||||
}
|
||||
return elems;
|
||||
|
||||
tokens.push_back(str.substr(start));
|
||||
|
||||
return tokens;
|
||||
}
|
||||
|
||||
StringVector split(const std::string &string, const std::string &chars, int limit) {
|
||||
StringVector stringVector;
|
||||
std::string tempString = string;
|
||||
std::string::size_type startIndex = 0;
|
||||
std::string::size_type endIndex = 0;
|
||||
StringVector Split(const std::string &str, const std::string &delim, size_t limit) {
|
||||
StringVector tokens;
|
||||
size_t start = 0;
|
||||
|
||||
//Info( "Looking for '%s' in '%s', limit %d", chars.c_str(), string.c_str(), limit );
|
||||
do {
|
||||
// Find delimiters
|
||||
endIndex = string.find_first_of( chars, startIndex );
|
||||
//Info( "Got endIndex at %d", endIndex );
|
||||
if ( endIndex > 0 ) {
|
||||
//Info( "Adding '%s'", string.substr( startIndex, endIndex-startIndex ).c_str() );
|
||||
stringVector.push_back( string.substr( startIndex, endIndex-startIndex ) );
|
||||
size_t end = str.find_first_of(delim, start);
|
||||
if (end > 0) {
|
||||
tokens.push_back(str.substr(start, end - start));
|
||||
}
|
||||
if ( endIndex == std::string::npos )
|
||||
if (end == std::string::npos) {
|
||||
break;
|
||||
}
|
||||
// Find non-delimiters
|
||||
startIndex = tempString.find_first_not_of( chars, endIndex );
|
||||
if ( limit && (stringVector.size() == (unsigned int)(limit-1)) ) {
|
||||
stringVector.push_back( string.substr( startIndex ) );
|
||||
start = str.find_first_not_of(delim, end);
|
||||
if (limit && (tokens.size() == limit - 1)) {
|
||||
tokens.push_back(str.substr(start));
|
||||
break;
|
||||
}
|
||||
//Info( "Got new startIndex at %d", startIndex );
|
||||
} while ( startIndex != std::string::npos );
|
||||
//Info( "Finished with %d strings", stringVector.size() );
|
||||
} while (start != std::string::npos);
|
||||
|
||||
return stringVector;
|
||||
return tokens;
|
||||
}
|
||||
|
||||
const std::string join(const StringVector &v, const char * delim=",") {
|
||||
std::pair<std::string, std::string> PairSplit(const std::string &str, char delim) {
|
||||
if (str.empty())
|
||||
return std::make_pair("", "");
|
||||
|
||||
size_t pos = str.find(delim);
|
||||
|
||||
if (pos == std::string::npos)
|
||||
return std::make_pair("", "");
|
||||
|
||||
return std::make_pair(str.substr(0, pos), str.substr(pos + 1, std::string::npos));
|
||||
}
|
||||
|
||||
std::string Join(const StringVector &values, const std::string &delim) {
|
||||
std::stringstream ss;
|
||||
|
||||
for (size_t i = 0; i < v.size(); ++i) {
|
||||
for (size_t i = 0; i < values.size(); ++i) {
|
||||
if ( i != 0 )
|
||||
ss << delim;
|
||||
ss << v[i];
|
||||
ss << values[i];
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
@ -159,46 +168,6 @@ const std::string base64Encode(const std::string &inString) {
|
|||
return outString;
|
||||
}
|
||||
|
||||
int split(const char* string, const char delim, std::vector<std::string>& items) {
|
||||
if ( string == nullptr )
|
||||
return -1;
|
||||
|
||||
if ( string[0] == 0 )
|
||||
return -2;
|
||||
|
||||
std::string str(string);
|
||||
|
||||
while ( true ) {
|
||||
size_t pos = str.find(delim);
|
||||
items.push_back(str.substr(0, pos));
|
||||
str.erase(0, pos+1);
|
||||
|
||||
if ( pos == std::string::npos )
|
||||
break;
|
||||
}
|
||||
|
||||
return items.size();
|
||||
}
|
||||
|
||||
int pairsplit(const char* string, const char delim, std::string& name, std::string& value) {
|
||||
if ( string == nullptr )
|
||||
return -1;
|
||||
|
||||
if ( string[0] == 0 )
|
||||
return -2;
|
||||
|
||||
std::string str(string);
|
||||
size_t pos = str.find(delim);
|
||||
|
||||
if ( pos == std::string::npos || pos == 0 || pos >= str.length() )
|
||||
return -3;
|
||||
|
||||
name = str.substr(0, pos);
|
||||
value = str.substr(pos+1, std::string::npos);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Detect special hardware features, such as SIMD instruction sets */
|
||||
void hwcaps_detect() {
|
||||
neonversion = 0;
|
||||
|
|
|
@ -35,6 +35,12 @@ std::string Trim(const std::string &str, const std::string &char_set);
|
|||
inline std::string TrimSpaces(const std::string &str) { return Trim(str, " \t"); }
|
||||
std::string ReplaceAll(std::string str, const std::string& old_value, const std::string& new_value);
|
||||
|
||||
StringVector Split(const std::string &str, char delim);
|
||||
StringVector Split(const std::string &str, const std::string &delim, size_t limit = 0);
|
||||
std::pair<std::string, std::string> PairSplit(const std::string &str, char delim);
|
||||
|
||||
std::string Join(const StringVector &values, const std::string &delim = ",");
|
||||
|
||||
inline bool StartsWith(const std::string &haystack, const std::string &needle) {
|
||||
return (haystack.substr(0, needle.length()) == needle);
|
||||
}
|
||||
|
@ -50,15 +56,9 @@ std::string stringtf(const std::string &format, Args... args) {
|
|||
return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside
|
||||
}
|
||||
|
||||
StringVector split( const std::string &string, const std::string &chars, int limit=0 );
|
||||
const std::string join( const StringVector &, const char * );
|
||||
|
||||
const std::string base64Encode( const std::string &inString );
|
||||
void string_toupper(std::string& str);
|
||||
|
||||
int split(const char* string, const char delim, std::vector<std::string>& items);
|
||||
int pairsplit(const char* string, const char delim, std::string& name, std::string& value);
|
||||
|
||||
void* sse2_aligned_memcpy(void* dest, const void* src, size_t bytes);
|
||||
void timespec_diff(struct timespec *start, struct timespec *end, struct timespec *diff);
|
||||
|
||||
|
|
|
@ -73,77 +73,71 @@ TEST_CASE("StartsWith") {
|
|||
REQUIRE(StartsWith(" test=abc", "test") == false);
|
||||
}
|
||||
|
||||
TEST_CASE("split (char delimiter)") {
|
||||
std::vector<std::string> items;
|
||||
int res;
|
||||
TEST_CASE("Split (char delimiter)") {
|
||||
std::vector<std::string> items = Split("", ' ');
|
||||
REQUIRE(items == std::vector<std::string>{""});
|
||||
|
||||
res = split(nullptr, ' ', items);
|
||||
REQUIRE(res == -1);
|
||||
REQUIRE(items.size() == 0);
|
||||
|
||||
res = split("", ' ', items);
|
||||
REQUIRE(res == -2);
|
||||
REQUIRE(items.size() == 0);
|
||||
|
||||
res = split("abc def ghi", ' ', items);
|
||||
REQUIRE(res == 3);
|
||||
items = Split("abc def ghi", ' ');
|
||||
REQUIRE(items == std::vector<std::string>{"abc", "def", "ghi"});
|
||||
|
||||
items = Split("abc,def,,ghi", ',');
|
||||
REQUIRE(items == std::vector<std::string>{"abc", "def", "", "ghi"});
|
||||
}
|
||||
|
||||
TEST_CASE("split (string delimiter)") {
|
||||
TEST_CASE("Split (string delimiter)") {
|
||||
std::vector<std::string> items;
|
||||
|
||||
items = split("", "");
|
||||
items = Split("", "");
|
||||
REQUIRE(items == std::vector<std::string>{""});
|
||||
|
||||
items = split("", " ");
|
||||
items = Split("", " ");
|
||||
REQUIRE(items == std::vector<std::string>{""});
|
||||
|
||||
items = split("", " \t");
|
||||
items = Split("", " \t");
|
||||
REQUIRE(items == std::vector<std::string>{""});
|
||||
|
||||
items = split("", " \t");
|
||||
items = Split("", " \t");
|
||||
REQUIRE(items == std::vector<std::string>{""});
|
||||
|
||||
items = split(" ", " ");
|
||||
items = Split(" ", " ");
|
||||
REQUIRE(items.size() == 0);
|
||||
|
||||
items = split(" ", " ");
|
||||
items = Split(" ", " ");
|
||||
REQUIRE(items.size() == 0);
|
||||
|
||||
items = split(" ", " \t");
|
||||
items = Split(" ", " \t");
|
||||
REQUIRE(items.size() == 0);
|
||||
|
||||
items = split("a b", "");
|
||||
items = Split("a b", "");
|
||||
REQUIRE(items == std::vector<std::string>{"a b"});
|
||||
|
||||
items = split("a b", " ");
|
||||
items = Split("a b", " ");
|
||||
REQUIRE(items == std::vector<std::string>{"a", "b"});
|
||||
|
||||
items = split("a \tb", " \t");
|
||||
items = Split("a \tb", " \t");
|
||||
REQUIRE(items == std::vector<std::string>{"a", "b"});
|
||||
|
||||
items = split(" a \tb ", " \t");
|
||||
items = Split(" a \tb ", " \t");
|
||||
REQUIRE(items == std::vector<std::string>{"a", "b"});
|
||||
|
||||
items = split(" a=b ", "=");
|
||||
items = Split(" a=b ", "=");
|
||||
REQUIRE(items == std::vector<std::string>{" a", "b "});
|
||||
|
||||
items = split(" a=b ", " =");
|
||||
items = Split(" a=b ", " =");
|
||||
REQUIRE(items == std::vector<std::string>{"a", "b"});
|
||||
|
||||
items = split("a b c", " ", 2);
|
||||
items = Split("a b c", " ", 2);
|
||||
REQUIRE(items == std::vector<std::string>{"a", "b c"});
|
||||
}
|
||||
|
||||
TEST_CASE("join") {
|
||||
REQUIRE(join({}, "") == "");
|
||||
REQUIRE(join({}, " ") == "");
|
||||
REQUIRE(join({""}, "") == "");
|
||||
REQUIRE(join({"a"}, "") == "a");
|
||||
REQUIRE(join({"a"}, ",") == "a");
|
||||
REQUIRE(join({"a", "b"}, ",") == "a,b");
|
||||
REQUIRE(join({"a", "b"}, "") == "ab");
|
||||
TEST_CASE("Join") {
|
||||
REQUIRE(Join({}, "") == "");
|
||||
REQUIRE(Join({}, " ") == "");
|
||||
REQUIRE(Join({""}, "") == "");
|
||||
REQUIRE(Join({"a"}, "") == "a");
|
||||
REQUIRE(Join({"a"}, ",") == "a");
|
||||
REQUIRE(Join({"a", "b"}, ",") == "a,b");
|
||||
REQUIRE(Join({"a", "b"}, "") == "ab");
|
||||
}
|
||||
|
||||
TEST_CASE("base64Encode") {
|
||||
|
|
Loading…
Reference in New Issue