From 582fc32574a3b158c81e49cb00e6ae59205e66ba Mon Sep 17 00:00:00 2001 From: Antonin Kral Date: Thu, 17 Mar 2011 00:05:43 +0100 Subject: Imported Upstream version 1.8.0 --- util/mongoutils/README | 8 ++- util/mongoutils/checksum.h | 4 +- util/mongoutils/hash.h | 41 ++++++++++++ util/mongoutils/html.h | 44 ++++++------- util/mongoutils/mongoutils.vcxproj | 2 + util/mongoutils/str.h | 126 +++++++++++++++++++++++++++++++------ util/mongoutils/test.cpp | 79 +++++++++++++---------- 7 files changed, 227 insertions(+), 77 deletions(-) create mode 100644 util/mongoutils/hash.h mode change 100755 => 100644 util/mongoutils/test.cpp (limited to 'util/mongoutils') diff --git a/util/mongoutils/README b/util/mongoutils/README index ab614b6..fd2a589 100755 --- a/util/mongoutils/README +++ b/util/mongoutils/README @@ -3,5 +3,11 @@ (1) code is not database specific, rather, true utilities (2) are cross platform (3) may require boost headers, but not libs - (4) are clean and easy to use in any c++ project without pulling in lots of other stuff + (4) are clean and easy to use in any c++ project without pulling in lots of other stuff. + specifically, does not use anything in the mongo namespace! (5) apache license + (6) must be documented! if you aren't going to bother (but don't do that), stick it in util. + (7) ideally header only (in the spirit of #3) + + So basically, easy to use, general purpose stuff, with no arduous dependencies to drop into + any new project. diff --git a/util/mongoutils/checksum.h b/util/mongoutils/checksum.h index 6beb7f4..ea3d051 100644 --- a/util/mongoutils/checksum.h +++ b/util/mongoutils/checksum.h @@ -1,4 +1,4 @@ -/** @checksum.h */ +/** @file checksum.h */ /* Copyright 2009 10gen Inc. * @@ -22,7 +22,7 @@ namespace mongoutils { /** * this is a silly temporary implementation */ - inline int checksum( const char* x , int size ){ + inline int checksum( const char* x , int size ) { int ck = 0; for ( int i=0; i\n"; } inline string tr() { return ""; } - inline string tr(string a, string b) { + inline string tr(string a, string b) { stringstream ss; ss << "" << a << "" << b << "\n"; return ss.str(); } template - inline string td(T x) { + inline string td(T x) { stringstream ss; ss << "" << x << ""; return ss.str(); } - inline string td(string x) { + inline string td(string x) { return "" + x + ""; } - inline string th(string x) { + inline string th(string x) { return "" + x + ""; } - inline void tablecell( stringstream& ss , bool b ){ + inline void tablecell( stringstream& ss , bool b ) { ss << "" << (b ? "X" : "") << ""; } - template< typename T> - inline void tablecell( stringstream& ss , const T& t ){ + template< typename T> + inline void tablecell( stringstream& ss , const T& t ) { ss << "" << t << ""; } - - inline string table(const char *headers[] = 0, bool border = true) { + + inline string table(const char *headers[] = 0, bool border = true) { stringstream ss; - ss << "\n\n"; - if( headers ) { + ss << "\n
\n"; + if( headers ) { ss << ""; - while( *headers ) { + while( *headers ) { ss << ""; headers++; } @@ -80,18 +80,18 @@ namespace mongoutils { return ss.str(); } - inline string start(string title) { + inline string start(string title) { stringstream ss; ss << "\n"; ss << title; ss << "\n"; ss << "\n"; + "body { font-family: helvetica, arial, san-serif }\n" + "table { border-collapse:collapse; border-color:#999; margin-top:.5em }\n" + "th { background-color:#bbb; color:#000 }\n" + "td,th { padding:.25em }\n" + "\n"; ss << "\n\n"; return ss.str(); @@ -141,7 +141,7 @@ namespace mongoutils { } /* does NOT escape the strings. */ - inline string a(string href, string title="", string contentHtml = "") { + inline string a(string href, string title="", string contentHtml = "") { stringstream ss; ss << " Level3 Disabled + c:\boost;\boost true @@ -53,6 +54,7 @@ MaxSpeed true true + c:\boost;\boost true diff --git a/util/mongoutils/str.h b/util/mongoutils/str.h index 2028264..ea8f938 100644 --- a/util/mongoutils/str.h +++ b/util/mongoutils/str.h @@ -17,36 +17,37 @@ #pragma once -/* Things in the mongoutils namespace +/* Things in the mongoutils namespace (1) are not database specific, rather, true utilities (2) are cross platform (3) may require boost headers, but not libs (4) are clean and easy to use in any c++ project without pulling in lots of other stuff - Note: within this module, we use int for all offsets -- there are no unsigned offsets - and no size_t's. If you need 3 gigabyte long strings, don't use this module. + Note: within this module, we use int for all offsets -- there are no unsigned offsets + and no size_t's. If you need 3 gigabyte long strings, don't use this module. */ #include #include +#include "../../bson/util/builder.h" namespace mongoutils { namespace str { - using namespace std; + typedef std::string string; - /** the idea here is to make one liners easy. e.g.: + /** the idea here is to make one liners easy. e.g.: return str::stream() << 1 << ' ' << 2; since the following doesn't work: - + (stringstream() << 1).str(); */ class stream { public: - stringstream ss; + mongo::StringBuilder ss; template stream& operator<<(const T& v) { @@ -60,7 +61,7 @@ namespace mongoutils { inline bool startsWith(const char *str, const char *prefix) { const char *s = str; const char *p = prefix; - while( *p ) { + while( *p ) { if( *p != *s ) return false; p++; s++; } @@ -68,37 +69,56 @@ namespace mongoutils { } inline bool startsWith(string s, string p) { return startsWith(s.c_str(), p.c_str()); } - inline bool endsWith(string s, string p) { + inline bool endsWith(string s, string p) { int l = p.size(); int x = s.size(); if( x < l ) return false; return strncmp(s.c_str()+x-l, p.c_str(), l) == 0; } + inline bool equals( const char * a , const char * b ) { return strcmp( a , b ) == 0; } + /** find char x, and return rest of string thereafter, or "" if not found */ inline const char * after(const char *s, char x) { const char *p = strchr(s, x); - return (p != 0) ? p+1 : ""; } + return (p != 0) ? p+1 : ""; + } inline string after(const string& s, char x) { const char *p = strchr(s.c_str(), x); - return (p != 0) ? string(p+1) : ""; } + return (p != 0) ? string(p+1) : ""; + } + /** find string x, and return rest of string thereafter, or "" if not found */ inline const char * after(const char *s, const char *x) { const char *p = strstr(s, x); - return (p != 0) ? p+strlen(x) : ""; } + return (p != 0) ? p+strlen(x) : ""; + } inline string after(string s, string x) { const char *p = strstr(s.c_str(), x.c_str()); - return (p != 0) ? string(p+x.size()) : ""; } + return (p != 0) ? string(p+x.size()) : ""; + } - inline bool contains(string s, string x) { - return strstr(s.c_str(), x.c_str()) != 0; } + /** @return true if s contains x */ + inline bool contains(string s, string x) { + return strstr(s.c_str(), x.c_str()) != 0; + } + inline bool contains(string s, char x) { + return strchr(s.c_str(), x) != 0; + } /** @return everything befor the character x, else entire string */ inline string before(const string& s, char x) { const char *p = strchr(s.c_str(), x); - return (p != 0) ? s.substr(0, p-s.c_str()) : s; } + return (p != 0) ? s.substr(0, p-s.c_str()) : s; + } - /** check if if strings share a common starting prefix + /** @return everything befor the string x, else entire string */ + inline string before(const string& s, const string& x) { + const char *p = strstr(s.c_str(), x.c_str()); + return (p != 0) ? s.substr(0, p-s.c_str()) : s; + } + + /** check if if strings share a common starting prefix @return offset of divergence (or length if equal). 0=nothing in common. */ inline int shareCommonPrefix(const char *p, const char *q) { int ofs = 0; @@ -109,10 +129,80 @@ namespace mongoutils { break; p++; q++; ofs++; } - return ofs; } + return ofs; + } inline int shareCommonPrefix(const string &a, const string &b) { return shareCommonPrefix(a.c_str(), b.c_str()); } + /** string to unsigned. zero if not a number. can end with non-num chars */ + inline unsigned toUnsigned(const string& a) { + unsigned x = 0; + const char *p = a.c_str(); + while( 1 ) { + if( !isdigit(*p) ) + break; + x = x * 10 + (*p - '0'); + p++; + } + return x; + } + + /** split a string on a specific char. We don't split N times, just once + on the first occurrence. If char not present entire string is in L + and R is empty. + @return true if char found + */ + inline bool splitOn(const string &s, char c, string& L, string& R) { + const char *start = s.c_str(); + const char *p = strchr(start, c); + if( p == 0 ) { + L = s; R.clear(); + return false; + } + L = string(start, p-start); + R = string(p+1); + return true; + } + /** split scanning reverse direction. Splits ONCE ONLY. */ + inline bool rSplitOn(const string &s, char c, string& L, string& R) { + const char *start = s.c_str(); + const char *p = strrchr(start, c); + if( p == 0 ) { + L = s; R.clear(); + return false; + } + L = string(start, p-start); + R = string(p+1); + return true; + } + + /** @return number of occurrences of c in s */ + inline unsigned count( const string& s , char c ) { + unsigned n=0; + for ( unsigned i=0; i - -using namespace std; -using namespace mongoutils; - -int main() { - string x = str::after("abcde", 'c'); - assert( x == "de" ); - assert( str::after("abcde", 'x') == "" ); - return 0; -} +/* @file test.cpp + utils/mongoutils/test.cpp + unit tests for mongoutils +*/ + +/* + * Copyright 2010 10gen Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "str.h" +#include "html.h" +#include + +using namespace std; +using namespace mongoutils; + +int main() { + { + string s = "abcde"; + str::stripTrailing(s, "ef"); + assert( s == "abcd" ); + str::stripTrailing(s, "abcd"); + assert( s.empty() ); + s = "abcddd"; + str::stripTrailing(s, "d"); + assert( s == "abc" ); + } + + string x = str::after("abcde", 'c'); + assert( x == "de" ); + assert( str::after("abcde", 'x') == "" ); + return 0; +} -- cgit v1.2.3
" << *headers << "