00001 // stringdata.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 #ifndef BSON_STRINDATA_HEADER 00019 #define BSON_STRINDATA_HEADER 00020 00021 #include <string> 00022 #include <cstring> 00023 00024 namespace mongo { 00025 00026 using std::string; 00027 00028 // A StringData object wraps a 'const string&' or a 'const char*' without 00029 // copying its contents. The most common usage is as a function argument that 00030 // takes any of the two forms of strings above. Fundamentally, this class tries 00031 // go around the fact that string literals in C++ are char[N]'s. 00032 // 00033 // Note that the object StringData wraps around must be alive while the StringDAta 00034 // is. 00035 00036 class StringData { 00037 public: 00038 // Construct a StringData explicilty, for the case where the lenght of 00039 // string is not known. 'c' must be a pointer to a null-terminated string. 00040 StringData( const char* c ) 00041 : _data(c), _size((unsigned) strlen(c)) {} 00042 00043 // Construct a StringData explicitly, for the case where the length of the string 00044 // is already known. 'c' must be a pointer to a null-terminated string, and strlenOfc 00045 // must be the length that std::strlen(c) would return, a.k.a the index of the 00046 // terminator in c. 00047 StringData( const char* c, size_t strlenOfc ) 00048 : _data(c), _size((unsigned) strlenOfc) {} 00049 00050 // Construct a StringData explicitly, for the case of a std::string. 00051 StringData( const string& s ) 00052 : _data(s.c_str()), _size((unsigned) s.size()) {} 00053 00054 // Construct a StringData explicitly, for the case of a literal whose size is 00055 // known at compile time. 00056 struct LiteralTag {}; 00057 template<size_t N> 00058 StringData( const char (&val)[N], LiteralTag ) 00059 : _data(&val[0]), _size(N-1) {} 00060 00061 // accessors 00062 00063 const char* data() const { return _data; } 00064 unsigned size() const { return _size; } 00065 00066 private: 00067 // There are two assumptions we use bellow. 00068 // '_data' *always* finishes with a null terminator 00069 // 'size' does *not* account for the null terminator 00070 // These assumptions may make it easier to minimize changes to existing code. 00071 const char* const _data; 00072 const unsigned _size; 00073 }; 00074 00075 } // namespace mongo 00076 00077 #endif // BSON_STRINGDATA_HEADER