|
reSIProcate/rutil
9694
|
00001 #if !defined(RESIP_PARSEBUFFER_HXX) 00002 #define RESIP_PARSEBUFFER_HXX 00003 00004 #include "rutil/Data.hxx" 00005 #include "rutil/ParseException.hxx" 00006 00007 namespace resip 00008 { 00009 00017 class ParseBuffer 00018 { 00019 public: 00020 // does NOT OWN the buffer memory 00021 ParseBuffer(const char* buff, size_t len, 00022 const Data& errorContext = Data::Empty); 00023 00024 explicit ParseBuffer(const Data& data, 00025 const Data& errorContext = Data::Empty); 00026 00027 ParseBuffer(const ParseBuffer& other); 00028 00030 // .bwc. Backwards-compatibility hack; ParseException used to be 00031 // a full inner class of ParseBuffer, and we also had a separate 00032 // ParseException class that other things used. For consistency, we have 00033 // moved everything over to use ParseException, but there is app-code 00034 // out there that still expects ParseException to exist. 00035 typedef ParseException Exception; 00037 00038 private: 00045 class CurrentPosition 00046 { 00047 public: 00048 inline explicit CurrentPosition(const ParseBuffer& pb) : 00049 mPb(pb) 00050 {} 00051 00052 operator const char*() const 00053 { 00054 return mPb.mPosition; 00055 } 00056 00057 const char& operator*() const 00058 { 00059 mPb.assertNotEof(); 00060 return *mPb.mPosition; 00061 } 00062 00063 const ParseBuffer& mPb; 00064 }; 00065 00071 class Pointer 00072 { 00073 public: 00074 Pointer(const ParseBuffer& pb, 00075 const char* position, 00076 bool atEof); 00077 Pointer(const CurrentPosition& pos); 00078 00079 operator const char*() const 00080 { 00081 return mPosition; 00082 } 00083 00084 const char& operator*() const; 00085 private: 00086 const ParseBuffer& mPb; 00087 const char* mPosition; 00088 const bool mIsValid; 00089 static const Data msg; 00090 }; 00091 00092 public: 00093 const Data& getContext() const {return mErrorContext;} 00094 00095 // allow the buffer to be rolled back 00096 ParseBuffer& operator=(const ParseBuffer& other); 00097 void reset(const char* pos) 00098 { 00099 assert( mBuff <= mEnd); 00100 assert( (pos >= mBuff) && (pos <= mEnd) ); 00101 mPosition = pos; 00102 } 00103 00104 // abcdef 00105 // ^ ^ 00106 // begin end 00107 bool eof() const { return mPosition >= mEnd;} 00108 bool bof() const { return mPosition <= mBuff;} 00109 bool valid() const {return (!eof()) && (!bof());} 00110 Pointer start() const { return Pointer(*this, mBuff, eof()); } 00111 CurrentPosition position() const { return CurrentPosition(*this); } 00112 Pointer end() const { return Pointer(*this, mEnd, true); } 00113 00114 CurrentPosition skipChar() 00115 { 00116 if (eof()) 00117 { 00118 fail(__FILE__, __LINE__,"skipped over eof"); 00119 } 00120 ++mPosition; 00121 return CurrentPosition(*this); 00122 } 00123 00124 CurrentPosition skipChar(char c); 00125 CurrentPosition skipChars(const char* cs); 00126 CurrentPosition skipChars(const Data& cs); 00127 CurrentPosition skipNonWhitespace(); 00128 CurrentPosition skipWhitespace(); 00129 CurrentPosition skipLWS(); 00130 CurrentPosition skipToTermCRLF(); 00131 CurrentPosition skipToChar(char c) 00132 { 00133 mPosition = (const char*)memchr(mPosition, c, mEnd-mPosition); 00134 if(!mPosition) 00135 { 00136 mPosition=mEnd; 00137 } 00138 return CurrentPosition(*this); 00139 } 00140 CurrentPosition skipToChars(const char* cs); 00141 CurrentPosition skipToChars(const Data& cs); // ?dlb? case sensitivity arg? 00142 CurrentPosition skipToOneOf(const char* cs); 00143 CurrentPosition skipToOneOf(const char* cs1, const char* cs2); 00144 CurrentPosition skipToOneOf(const Data& cs); 00145 CurrentPosition skipToOneOf(const Data& cs1, const Data& cs2); 00146 00147 // std::bitset based parse function 00148 CurrentPosition skipChars(const std::bitset<256>& cs) 00149 { 00150 while (mPosition < mEnd) 00151 { 00152 if (cs.test((unsigned char)(*mPosition))) 00153 { 00154 mPosition++; 00155 } 00156 else 00157 { 00158 return CurrentPosition(*this); 00159 } 00160 } 00161 return CurrentPosition(*this); 00162 } 00163 00164 CurrentPosition skipToOneOf(const std::bitset<256>& cs) 00165 { 00166 while (mPosition < mEnd) 00167 { 00168 if (cs.test((unsigned char)(*mPosition))) 00169 { 00170 return CurrentPosition(*this); 00171 } 00172 else 00173 { 00174 mPosition++; 00175 } 00176 } 00177 return CurrentPosition(*this); 00178 } 00179 00180 const char* skipToEndQuote(char quote = '"'); 00181 CurrentPosition skipN(int count) 00182 { 00183 mPosition += count; 00184 if (mPosition > mEnd) 00185 { 00186 fail(__FILE__, __LINE__, "skipped eof"); 00187 } 00188 return CurrentPosition(*this); 00189 } 00190 00191 CurrentPosition skipToEnd() 00192 { 00193 mPosition = mEnd; 00194 return CurrentPosition(*this); 00195 } 00196 00197 // inverse of skipChar() -- end up at char not before it 00198 const char* skipBackChar(); 00199 const char* skipBackWhitespace(); 00200 const char* skipBackN(int count) 00201 { 00202 mPosition -= count; 00203 if (bof()) 00204 { 00205 fail(__FILE__, __LINE__,"backed over beginning of buffer"); 00206 } 00207 return mPosition; 00208 } 00209 00210 const char* skipBackChar(char c); 00211 const char* skipBackToChar(char c); 00212 const char* skipBackToOneOf(const char* cs); 00213 00214 void assertEof() const 00215 { 00216 if (!eof()) 00217 { 00218 fail(__FILE__, __LINE__,"expected eof"); 00219 } 00220 } 00221 00222 void assertNotEof() const 00223 { 00224 if (eof()) 00225 { 00226 fail(__FILE__, __LINE__,"unexpected eof"); 00227 } 00228 } 00229 00230 void fail(const char* file, unsigned int line, 00231 const Data& errmsg = Data::Empty) const; 00232 00234 void data(Data& data, const char* start) const; 00235 00236 Data data(const char* start) const; 00237 00238 void dataUnescaped(Data& data, const char* start) const; 00239 00240 int integer(); 00241 00242 00243 UInt8 uInt8(); 00244 UInt32 uInt32(); 00245 UInt64 uInt64(); 00246 00247 RESIP_DEPRECATED UInt64 unsignedLongLong(){return uInt64();} 00248 RESIP_DEPRECATED unsigned long unsignedInteger(){return uInt32();} 00249 00250 #ifndef RESIP_FIXED_POINT 00251 float floatVal(); 00252 #endif 00253 int qVal(); 00254 00255 static bool oneOf(char c, const char* cs); 00256 static bool oneOf(char c, const Data& cs); 00257 static const char* Whitespace; 00258 static const char* ParamTerm; 00259 private: 00260 friend class ParseBuffer::CurrentPosition; 00261 const char* mBuff; 00262 const char* mPosition; 00263 const char* mEnd; 00264 const Data& mErrorContext; 00265 }; 00266 00267 } 00268 00269 #endif 00270 00271 /* ==================================================================== 00272 * The Vovida Software License, Version 1.0 00273 * 00274 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. 00275 * 00276 * Redistribution and use in source and binary forms, with or without 00277 * modification, are permitted provided that the following conditions 00278 * are met: 00279 * 00280 * 1. Redistributions of source code must retain the above copyright 00281 * notice, this list of conditions and the following disclaimer. 00282 * 00283 * 2. Redistributions in binary form must reproduce the above copyright 00284 * notice, this list of conditions and the following disclaimer in 00285 * the documentation and/or other materials provided with the 00286 * distribution. 00287 * 00288 * 3. The names "VOCAL", "Vovida Open Communication Application Library", 00289 * and "Vovida Open Communication Application Library (VOCAL)" must 00290 * not be used to endorse or promote products derived from this 00291 * software without prior written permission. For written 00292 * permission, please contact vocal@vovida.org. 00293 * 00294 * 4. Products derived from this software may not be called "VOCAL", nor 00295 * may "VOCAL" appear in their name, without prior written 00296 * permission of Vovida Networks, Inc. 00297 * 00298 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 00299 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00300 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 00301 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA 00302 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES 00303 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, 00304 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00305 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00306 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 00307 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00308 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 00309 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 00310 * DAMAGE. 00311 * 00312 * ==================================================================== 00313 * 00314 * This software consists of voluntary contributions made by Vovida 00315 * Networks, Inc. and many individuals on behalf of Vovida Networks, 00316 * Inc. For more information on Vovida Networks, Inc., please see 00317 * <http://www.vovida.org/>. 00318 * 00319 */
1.7.5.1