MongoDB  2.0.3
stringutils.h
00001 // stringutils.h
00002 
00003 /*    Copyright 2010 10gen Inc.
00004  *
00005  *    Licensed under the Apache License, Version 2.0 (the "License");
00006  *    you may not use this file except in compliance with the License.
00007  *    You may obtain a copy of the License at
00008  *
00009  *    http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  *    Unless required by applicable law or agreed to in writing, software
00012  *    distributed under the License is distributed on an "AS IS" BASIS,
00013  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  *    See the License for the specific language governing permissions and
00015  *    limitations under the License.
00016  */
00017 
00018 #pragma once
00019 
00020 namespace mongo {
00021 
00022     // see also mongoutils/str.h - perhaps move these there?
00023     // see also text.h
00024 
00025     void splitStringDelim( const string& str , vector<string>* res , char delim );
00026 
00027     void joinStringDelim( const vector<string>& strs , string* res , char delim );
00028 
00029     inline string tolowerString( const string& input ) {
00030         string::size_type sz = input.size();
00031 
00032         boost::scoped_array<char> line(new char[sz+1]);
00033         char * copy = line.get();
00034 
00035         for ( string::size_type i=0; i<sz; i++ ) {
00036             char c = input[i];
00037             copy[i] = (char)tolower( (int)c );
00038         }
00039         copy[sz] = 0;
00040         return string(copy);
00041     }
00042 
00048     inline int lexNumCmp( const char *s1, const char *s2 ) {
00049         //cout << "START : " << s1 << "\t" << s2 << endl;
00050 
00051         bool startWord = true;
00052         
00053         while( *s1 && *s2 ) {
00054 
00055             bool d1 = ( *s1 == '.' );
00056             bool d2 = ( *s2 == '.' );
00057             if ( d1 && !d2 )
00058                 return -1;
00059             if ( d2 && !d1 )
00060                 return 1;
00061             if ( d1 && d2 ) {
00062                 ++s1; ++s2;
00063                 startWord = true;
00064                 continue;
00065             }
00066             
00067             bool p1 = ( *s1 == (char)255 );
00068             bool p2 = ( *s2 == (char)255 );
00069             //cout << "\t\t " << p1 << "\t" << p2 << endl;
00070             if ( p1 && !p2 )
00071                 return 1;
00072             if ( p2 && !p1 )
00073                 return -1;
00074 
00075             bool n1 = isNumber( *s1 );
00076             bool n2 = isNumber( *s2 );
00077 
00078             if ( n1 && n2 ) {
00079                 // get rid of leading 0s
00080                 if ( startWord ) {
00081                     while ( *s1 == '0' ) s1++;
00082                     while ( *s2 == '0' ) s2++;
00083                 }
00084 
00085                 char * e1 = (char*)s1;
00086                 char * e2 = (char*)s2;
00087 
00088                 // find length
00089                 // if end of string, will break immediately ('\0')
00090                 while ( isNumber (*e1) ) e1++;
00091                 while ( isNumber (*e2) ) e2++;
00092 
00093                 int len1 = (int)(e1-s1);
00094                 int len2 = (int)(e2-s2);
00095 
00096                 int result;
00097                 // if one is longer than the other, return
00098                 if ( len1 > len2 ) {
00099                     return 1;
00100                 }
00101                 else if ( len2 > len1 ) {
00102                     return -1;
00103                 }
00104                 // if the lengths are equal, just strcmp
00105                 else if ( (result = strncmp(s1, s2, len1)) != 0 ) {
00106                     return result;
00107                 }
00108 
00109                 // otherwise, the numbers are equal
00110                 s1 = e1;
00111                 s2 = e2;
00112                 startWord = false;
00113                 continue;
00114             }
00115             
00116             if ( n1 )
00117                 return 1;
00118 
00119             if ( n2 )
00120                 return -1;
00121 
00122             if ( *s1 > *s2 )
00123                 return 1;
00124 
00125             if ( *s2 > *s1 )
00126                 return -1;
00127             
00128             s1++; s2++;
00129             startWord = false;
00130         }
00131 
00132         if ( *s1 )
00133             return 1;
00134         if ( *s2 )
00135             return -1;
00136         return 0;
00137     }
00138 
00139 } // namespace mongo