00001 /* 00002 * mstring.h : part of the Mace toolkit for building distributed systems 00003 * 00004 * Copyright (c) 2007, Charles Killian, Dejan Kostic, Ryan Braud, James W. Anderson, John Fisher-Ogden, Calvin Hubble, Duy Nguyen, Justin Burke, David Oppenheimer, Amin Vahdat, Adolfo Rodriguez, Sooraj Bhat 00005 * All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions are met: 00009 * 00010 * * Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * * Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in 00014 * the documentation and/or other materials provided with the 00015 * distribution. 00016 * * Neither the names of Duke University nor The University of 00017 * California, San Diego, nor the names of the authors or contributors 00018 * may be used to endorse or promote products derived from 00019 * this software without specific prior written permission. 00020 * 00021 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00022 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00023 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00024 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 00025 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00026 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00027 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00028 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00029 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 00030 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 * 00032 * ----END-OF-LEGAL-STUFF---- */ 00033 #include <string> 00034 #include "hash_string.h" 00035 // #include <iostream> 00036 // #include "Base64.h" 00037 // #include "Serializable.h" 00038 00039 #ifndef _MACE_STRING_H 00040 #define _MACE_STRING_H 00041 00047 namespace mace { 00048 00054 00055 typedef std::string string; 00056 00058 } 00059 00060 // namespace mace { 00061 00062 // class string : public std::string, public Serializable { 00063 00064 // public: 00065 // string() : std::string() { 00066 // } 00067 00068 // string(const char* s) : std::string(s) { 00069 // } 00070 00071 // string(const char* s, size_type len) : std::string(s, len) { 00072 // } 00073 00074 // string(const std::string& s) : std::string(s) { 00075 // } 00076 00077 // virtual ~string() { } 00078 00079 00080 // int deserialize(std::istream& in) throw(SerializationException){ 00081 // uint64_t sz; 00082 // char* buf; 00083 00084 // mace::deserialize(in, &sz); 00085 // // buf = new char[sz+1]; 00086 // if(sz == 0) { 00087 // clear(); 00088 // return sizeof(sz); 00089 // } 00090 // buf = new char[sz]; 00091 // if(buf == NULL) 00092 // throw SerializationException("Could not allocate memory to deserialize"); 00093 00094 // in.read(buf, sz); 00095 // if(!in) 00096 // throw SerializationException("String not long enough to deserialize"); 00097 // // buf[sz] = '\0'; 00098 // assign(buf, sz); 00099 // delete [] buf; 00100 // return sizeof(sz) + sz; 00101 // } 00102 00103 // void deserializeStr(const std::string& s) throw(SerializationException) { 00104 // assign(s); 00105 // } 00106 00107 // int deserializeXML_RPC(std::istream& in) throw(SerializationException) { 00108 // long offset = in.tellg(); 00109 // char ch, ch1, ch2, ch3, ch4; 00110 // std::string tag; 00111 // bool dhack = false; 00112 00113 // clear(); 00114 // in >> std::skipws; 00115 00116 // ch = in.peek(); 00117 // if (ch != '<') { 00118 // // this is a legit string, just with no <string></string> tag 00119 // dhack = true; 00120 // } 00121 // else { // we may be looking at <string></string> or </value> 00122 // long dsp = in.tellg(); 00123 // in >> ch >> ch1 >> ch2 >> ch3 >> ch4; 00124 // in.seekg(dsp); 00125 // if (ch1 == '/' && ch2 == 'v' && ch3 == 'a' && ch4 == 'l') { 00126 // // empty string and without a <string></string> tag 00127 // return (long)in.tellg() - offset; 00128 // } 00129 // else { 00130 // dhack = false; // proceed as normal 00131 // } 00132 // } 00133 00134 // if (!dhack) { 00135 // tag = SerializationUtil::getTag(in); 00136 // // SerializationUtil::expect(in, "<string>"); 00137 // } 00138 // if (dhack || tag == "<string>") { 00139 // in >> std::noskipws >> ch; 00140 // while(ch != '<') { 00141 // switch(ch) { 00142 // case '&': 00143 // in >> ch1 >> ch2 >> ch3; 00144 // //std:: cout << "got " << ch1 << ch2 << ch3; 00145 // if(!in) 00146 // throw SerializationException("String not long enough to deserialize"); 00147 // if(ch2 == 't' && ch3 == ';') { 00148 // if(ch1 == 'l') 00149 // push_back('<'); 00150 // else if(ch1 == 'g') 00151 // push_back('>'); 00152 // else 00153 // throw SerializationException("Unrecognizable escape sequence while deserializing string"); 00154 // } 00155 // else { 00156 // in >> ch4; 00157 // if(!in) 00158 // throw SerializationException("String not long enough to deserialize"); 00159 // if(ch1 != 'a' || ch2 != 'm' || ch3 != 'p'|| ch4 != ';') 00160 // throw SerializationException("Unrecognizable escape sequence while deserializing string"); 00161 // else 00162 // push_back('&'); 00163 // } 00164 // break; 00165 // default: 00166 // push_back(ch); 00167 // } 00168 // in >> ch; 00169 // if(!in) 00170 // throw SerializationException("String not long enough to deserialize"); 00171 // } 00172 // if (!dhack) { 00173 // SerializationUtil::expect(in, "/string>"); 00174 // in >> std::skipws; 00175 // } 00176 // else { 00177 // in.putback('<'); 00178 // } 00179 // } 00180 // else if (tag == "<base64>") { 00181 // std::string buf; 00182 // std::istringstream* is = dynamic_cast<std::istringstream*>(&in); 00183 // if (is) { 00184 // std::string ibuf = is->str(); 00185 // long ioff = is->tellg(); 00186 // size_t i = ibuf.find('<', ioff); 00187 // if (i == std::string::npos) { 00188 // throw SerializationException("String not long enough to deserialize"); 00189 // } 00190 // buf = ibuf.substr(ioff, i - ioff); 00191 // in.seekg(i + 1, std::ios::beg); 00192 // } 00193 // else { 00194 // in >> ch; 00195 // while (ch != '<') { 00196 // buf.push_back(ch); 00197 // in >> ch; 00198 // if (!in) { 00199 // throw SerializationException("String not long enough to deserialize"); 00200 // } 00201 // } 00202 // } 00203 // SerializationUtil::expect(in, "/base64>"); 00204 // append(Base64::decode(buf)); 00205 // } 00206 // else { 00207 // throw SerializationException("Bad tag for string: " + tag); 00208 // } 00209 // return (long)in.tellg() - offset; 00210 // } // deserializeXML_RPC 00211 00212 // void serialize(std::string &str) const { 00213 // uint64_t sz = size(); 00214 // mace::serialize(str, &sz); 00215 // if(sz > 0) { 00216 // str.append(data(), sz); 00217 // } 00218 // } 00219 00220 // std::string serializeStr() const { 00221 // return *this; 00222 // } 00223 00224 // void serializeXML_RPC(std::string& str) const throw(SerializationException) { 00225 // if (Base64::isPrintable(*this)) { 00226 // str.append("<string>"); 00227 // for(unsigned x=0; x<size(); x++) { 00228 // char c = operator[](x); 00229 // switch(c) { 00230 // case '<': 00231 // str.append("<"); 00232 // break; 00233 // case '>': 00234 // str.append(">"); 00235 // break; 00236 // case '&': 00237 // str.append("&"); 00238 // break; 00239 // default: 00240 // str.push_back(c); 00241 // } 00242 // } 00243 // str.append("</string>"); 00244 // } 00245 // else { 00246 // str.append("<base64>"); 00247 // str.append(Base64::encode(*this)); 00248 // str.append("</base64>"); 00249 // } 00250 // } // serializeXML_RPC 00251 // }; 00252 00253 // } // namespace mace 00254 00255 namespace __gnu_cxx { 00256 00257 template<> struct hash<mace::string> { 00258 size_t operator()(const mace::string& x) const { 00259 static const hash_string h = hash_string(); 00260 return h(x); 00261 } 00262 }; 00263 00264 // template<> struct hash<mace::string*> { 00265 // size_t operator()(const mace::string*& x) { 00266 // return (x==NULL?0:hash_string(*x)); 00267 // } 00268 // }; 00269 00270 } // namespace __gnu_cxx 00271 00272 // std::ostream& operator<<(std::ostream& o, const mace::string& s); 00273 00274 #endif // _MACE_STRING_H