Passenger: StaticString.h Source File

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List

# StaticString.h

    00001 /*
    00002  *  Phusion Passenger - http://www.modrails.com/
    00003  *  Copyright (c) 2010 Phusion
    00004  *
    00005  *  "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
    00006  *
    00007  *  Permission is hereby granted, free of charge, to any person obtaining a copy
    00008  *  of this software and associated documentation files (the "Software"), to deal
    00009  *  in the Software without restriction, including without limitation the rights
    00010  *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    00011  *  copies of the Software, and to permit persons to whom the Software is
    00012  *  furnished to do so, subject to the following conditions:
    00013  *
    00014  *  The above copyright notice and this permission notice shall be included in
    00015  *  all copies or substantial portions of the Software.
    00016  *
    00017  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    00018  *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    00019  *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    00020  *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    00021  *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    00022  *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    00023  *  THE SOFTWARE.
    00024  */
    00025 #ifndef _PASSENGER_STATIC_STRING_H_
    00026 #define _PASSENGER_STATIC_STRING_H_
    00027
    00028 #include <string>
    00029 #include <cstring>
    00030 #include <ostream>
    00031
    00032 namespace Passenger {
    00033
    00034 using namespace std;
    00035
    00036 /**
    00037  * An immutable, static byte buffer. This class will never copy data:
    00038  * it just holds a pointer to the data. So a StaticString will become unusable
    00039  * once the data it refers to has been freed.
    00040  *
    00041  * StaticString will never modify the data.
    00042  */
    00043 class StaticString {
    00044 private:
    00045         const char *content;
    00046         string::size_type len;
    00047
    00048 public:
    00049         /** A hash function object for StaticString. */
    00050         struct Hash {
    00051                 size_t operator()(const StaticString &str) const {
    00052                         size_t result = 0;
    00053                         const char *data = str.content;
    00054                         const char *end  = data + str.len;
    00055                         while (data != end) {
    00056                                 result = result * 33 + *data;
    00057                                 data++;
    00058                         }
    00059                         return result;
    00060                 }
    00061         };
    00062
    00063         StaticString() {
    00064                 content = "";
    00065                 len = 0;
    00066         }
    00067
    00068         StaticString(const StaticString &b) {
    00069                 content = b.content;
    00070                 len = b.len;
    00071         }
    00072
    00073         StaticString(const string &s) {
    00074                 content = s.data();
    00075                 len = s.size();
    00076         }
    00077
    00078         StaticString(const char *data) {
    00079                 content = data;
    00080                 len = strlen(data);
    00081         }
    00082
    00083         StaticString(const char *data, string::size_type len) {
    00084                 content = data;
    00085                 this->len = len;
    00086         }
    00087
    00088         bool empty() const {
    00089                 return len == 0;
    00090         }
    00091
    00092         string::size_type size() const {
    00093                 return len;
    00094         }
    00095
    00096         char operator[](string::size_type i) const {
    00097                 return content[i];
    00098         }
    00099
    00100         char at(string::size_type i) const {
    00101                 return content[i];
    00102         }
    00103
    00104         const char *c_str() const {
    00105                 return content;
    00106         }
    00107
    00108         const char *data() const {
    00109                 return content;
    00110         }
    00111
    00112         string toString() const {
    00113                 return string(content, len);
    00114         }
    00115
    00116         bool equals(const StaticString &other) const {
    00117                 return len == other.len && memcmp(content, other.content, len) == 0;
    00118         }
    00119
    00120         bool equals(const string &other) const {
    00121                 return len == other.size() && memcmp(content, other.data(), len) == 0;
    00122         }
    00123
    00124         bool operator==(const StaticString &other) const {
    00125                 return len == other.len && memcmp(content, other.content, len) == 0;
    00126         }
    00127
    00128         bool operator==(const string &other) const {
    00129                 return len == other.size() && memcmp(content, other.data(), len) == 0;
    00130         }
    00131
    00132         bool operator==(const char *other) const {
    00133                 size_t other_len = strlen(other);
    00134                 return len == other_len && memcmp(content, other, other_len) == 0;
    00135         }
    00136
    00137         bool operator!=(const StaticString &other) const {
    00138                 return len != other.len || memcmp(content, other.content, len) != 0;
    00139         }
    00140
    00141         bool operator!=(const string &other) const {
    00142                 return len != other.size() || memcmp(content, other.data(), len) != 0;
    00143         }
    00144
    00145         bool operator!=(const char *other) const {
    00146                 size_t other_len = strlen(other);
    00147                 return len != other_len || memcmp(content, other, other_len) != 0;
    00148         }
    00149
    00150         bool operator<(const StaticString &other) const {
    00151                 size_t size = (len < other.size()) ? len : other.size();
    00152                 int result = memcmp(content, other.data(), size);
    00153                 if (result == 0) {
    00154                         return len < other.size();
    00155                 } else {
    00156                         return result < 0;
    00157                 }
    00158         }
    00159
    00160         bool operator<(const char *other) const {
    00161                 return *this < StaticString(other);
    00162         }
    00163
    00164         string operator+(const char *other) const {
    00165                 return string(content, len) + other;
    00166         }
    00167
    00168         string operator+(const string &other) const {
    00169                 return string(content, len) + other;
    00170         }
    00171
    00172         string operator+(const StaticString &other) const {
    00173                 string result(content, len);
    00174                 result.append(other.data(), other.size());
    00175                 return result;
    00176         }
    00177
    00178         operator string() const {
    00179                 return string(content, len);
    00180         }
    00181 };
    00182
    00183 inline string
    00184 operator+(const char *lhs, const StaticString &rhs) {
    00185         return StaticString(lhs) + rhs;
    00186 }
    00187
    00188 inline string
    00189 operator+(const string &lhs, const StaticString &rhs) {
    00190         string result = lhs;
    00191         result.append(rhs.data(), rhs.size());
    00192         return result;
    00193 }
    00194
    00195 inline ostream &
    00196 operator<<(ostream &os, const StaticString &str) {
    00197         os.write(str.data(), str.size());
    00198         return os;
    00199 }
    00200
    00201 inline bool
    00202 operator==(const string &other, const StaticString &str) {
    00203         return str == other;
    00204 }
    00205
    00206 inline bool
    00207 operator==(const char *other, const StaticString &str) {
    00208         return str == other;
    00209 }
    00210
    00211 inline bool
    00212 operator!=(const string &other, const StaticString &str) {
    00213         return str != other;
    00214 }
    00215
    00216 inline bool
    00217 operator!=(const char *other, const StaticString &str) {
    00218         return str != other;
    00219 }
    00220
    00221 } // namespace Passenger
    00222
    00223 #endif /* _PASSENGER_STATIC_STRING_H_ */