summaryrefslogtreecommitdiff
path: root/src/mongo/util/stringutils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/util/stringutils.cpp')
-rw-r--r--src/mongo/util/stringutils.cpp154
1 files changed, 154 insertions, 0 deletions
diff --git a/src/mongo/util/stringutils.cpp b/src/mongo/util/stringutils.cpp
new file mode 100644
index 00000000000..33fee4009e2
--- /dev/null
+++ b/src/mongo/util/stringutils.cpp
@@ -0,0 +1,154 @@
+// stringutils.cpp
+
+/**
+* Copyright (C) 2008 10gen Inc.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Affero General Public License, version 3,
+* as published by the Free Software Foundation.
+*
+* 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 "pch.h"
+
+#include "stringutils.h"
+
+namespace mongo {
+
+ void splitStringDelim( const string& str , vector<string>* res , char delim ) {
+ if ( str.empty() )
+ return;
+
+ size_t beg = 0;
+ size_t pos = str.find( delim );
+ while ( pos != string::npos ) {
+ res->push_back( str.substr( beg, pos - beg) );
+ beg = ++pos;
+ pos = str.find( delim, beg );
+ }
+ res->push_back( str.substr( beg ) );
+ }
+
+ void joinStringDelim( const vector<string>& strs , string* res , char delim ) {
+ for ( vector<string>::const_iterator it = strs.begin(); it != strs.end(); ++it ) {
+ if ( it !=strs.begin() ) res->push_back( delim );
+ res->append( *it );
+ }
+ }
+
+ LexNumCmp::LexNumCmp( bool lexOnly ) :
+ _lexOnly( lexOnly ) {
+ }
+
+ int LexNumCmp::cmp( const char *s1, const char *s2, bool lexOnly ) {
+ //cout << "START : " << s1 << "\t" << s2 << endl;
+
+ bool startWord = true;
+
+ while( *s1 && *s2 ) {
+
+ bool d1 = ( *s1 == '.' );
+ bool d2 = ( *s2 == '.' );
+ if ( d1 && !d2 )
+ return -1;
+ if ( d2 && !d1 )
+ return 1;
+ if ( d1 && d2 ) {
+ ++s1; ++s2;
+ startWord = true;
+ continue;
+ }
+
+ bool p1 = ( *s1 == (char)255 );
+ bool p2 = ( *s2 == (char)255 );
+ //cout << "\t\t " << p1 << "\t" << p2 << endl;
+ if ( p1 && !p2 )
+ return 1;
+ if ( p2 && !p1 )
+ return -1;
+
+ if ( !lexOnly ) {
+
+ bool n1 = isNumber( *s1 );
+ bool n2 = isNumber( *s2 );
+
+ if ( n1 && n2 ) {
+ // get rid of leading 0s
+ if ( startWord ) {
+ while ( *s1 == '0' ) s1++;
+ while ( *s2 == '0' ) s2++;
+ }
+
+ char * e1 = (char*)s1;
+ char * e2 = (char*)s2;
+
+ // find length
+ // if end of string, will break immediately ('\0')
+ while ( isNumber (*e1) ) e1++;
+ while ( isNumber (*e2) ) e2++;
+
+ int len1 = (int)(e1-s1);
+ int len2 = (int)(e2-s2);
+
+ int result;
+ // if one is longer than the other, return
+ if ( len1 > len2 ) {
+ return 1;
+ }
+ else if ( len2 > len1 ) {
+ return -1;
+ }
+ // if the lengths are equal, just strcmp
+ else if ( (result = strncmp(s1, s2, len1)) != 0 ) {
+ return result;
+ }
+
+ // otherwise, the numbers are equal
+ s1 = e1;
+ s2 = e2;
+ startWord = false;
+ continue;
+ }
+
+ if ( n1 )
+ return 1;
+
+ if ( n2 )
+ return -1;
+ }
+
+ if ( *s1 > *s2 )
+ return 1;
+
+ if ( *s2 > *s1 )
+ return -1;
+
+ s1++; s2++;
+ startWord = false;
+ }
+
+ if ( *s1 )
+ return 1;
+ if ( *s2 )
+ return -1;
+ return 0;
+ }
+
+ int LexNumCmp::cmp( const char *s1, const char *s2 ) const {
+ return cmp( s1, s2, _lexOnly );
+ }
+ bool LexNumCmp::operator()( const char *s1, const char *s2 ) const {
+ return cmp( s1, s2 ) < 0;
+ }
+ bool LexNumCmp::operator()( const string &s1, const string &s2 ) const {
+ return (*this)( s1.c_str(), s2.c_str() );
+ }
+
+} // namespace mongo