- 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
    00031 namespace Passenger {
    00032
    00033 using namespace std;
    00034
    00035 /**
    00036  * An immutable, static byte buffer. This class will never copy data:
    00037  * it just holds a pointer to the data. So a StaticString will become unusable
    00038  * once the data it refers to has been freed.
    00039  *
    00040  * StaticString will never modify the data.
    00041  */
    00042 class StaticString {
    00043 private:
    00044         const char *content;
    00045         string::size_type len;
    00046
    00047 public:
    00048         /** A hash function object for StaticString. */
    00049         struct Hash {
    00050                 size_t operator()(const StaticString &str) const {
    00051                         size_t result = 0;
    00052                         const char *data = str.content;
    00053                         const char *end  = data + str.len;
    00054                         while (data != end) {
    00055                                 result = result * 33 + *data;
    00056                                 data++;
    00057                         }
    00058                         return result;
    00059                 }
    00060         };
    00061
    00062         StaticString() {
    00063                 content = "";
    00064                 len = 0;
    00065         }
    00066
    00067         StaticString(const StaticString &b) {
    00068                 content = b.content;
    00069                 len = b.len;
    00070         }
    00071
    00072         StaticString(const string &s) {
    00073                 content = s.data();
    00074                 len = s.size();
    00075         }
    00076
    00077         StaticString(const char *data) {
    00078                 content = data;
    00079                 len = strlen(data);
    00080         }
    00081
    00082         StaticString(const char *data, string::size_type len) {
    00083                 content = data;
    00084                 this->len = len;
    00085         }
    00086
    00087         bool empty() const {
    00088                 return len == 0;
    00089         }
    00090
    00091         string::size_type size() const {
    00092                 return len;
    00093         }
    00094
    00095         char operator[](string::size_type i) const {
    00096                 return content[i];
    00097         }
    00098
    00099         char at(string::size_type i) const {
    00100                 return content[i];
    00101         }
    00102
    00103         const char *c_str() const {
    00104                 return content;
    00105         }
    00106
    00107         const char *data() const {
    00108                 return content;
    00109         }
    00110
    00111         string toString() const {
    00112                 return string(content, len);
    00113         }
    00114
    00115         bool equals(const StaticString &other) const {
    00116                 return len == other.len && memcmp(content, other.content, len) == 0;
    00117         }
    00118
    00119         bool equals(const string &other) const {
    00120                 return len == other.size() && memcmp(content, other.data(), len) == 0;
    00121         }
    00122
    00123         bool operator==(const StaticString &other) const {
    00124                 return len == other.len && memcmp(content, other.content, len) == 0;
    00125         }
    00126
    00127         bool operator==(const char *other) const {
    00128                 return memcmp(content, other, strlen(other)) == 0;
    00129         }
    00130
    00131         bool operator!=(const StaticString &other) const {
    00132                 return len == other.len && memcmp(content, other.content, len) != 0;
    00133         }
    00134
    00135         bool operator!=(const char *other) const {
    00136                 return memcmp(content, other, strlen(other)) != 0;
    00137         }
    00138
    00139         bool operator<(const StaticString &other) const {
    00140                 size_t size = (len < other.size()) ? len : other.size();
    00141                 int result = memcmp(content, other.data(), size);
    00142                 if (result == 0) {
    00143                         return len < other.size();
    00144                 } else {
    00145                         return result < 0;
    00146                 }
    00147         }
    00148
    00149         bool operator<(const char *other) const {
    00150                 return *this < StaticString(other);
    00151         }
    00152
    00153         string operator+(const char *other) const {
    00154                 return string(content, len) + other;
    00155         }
    00156
    00157         string operator+(const string &other) const {
    00158                 return string(content, len) + other;
    00159         }
    00160
    00161         string operator+(const StaticString &other) const {
    00162                 string result(content, len);
    00163                 result.append(other.data(), other.size());
    00164                 return result;
    00165         }
    00166
    00167         operator string() const {
    00168                 return string(content, len);
    00169         }
    00170 };
    00171
    00172 inline string
    00173 operator+(const char *lhs, const StaticString &rhs) {
    00174         return StaticString(lhs) + rhs;
    00175 }
    00176
    00177 inline string
    00178 operator+(const string &lhs, const StaticString &rhs) {
    00179         string result = lhs;
    00180         result.append(rhs.data(), rhs.size());
    00181         return result;
    00182 }
    00183
    00184 } // namespace Passenger
    00185
    00186 #endif /* _PASSENGER_STATIC_STRING_H_ */