|
MemCacheClient
|
00001 00006 #include <new> 00007 #include <stdexcept> 00008 00009 // local 00010 #include "ReadWriteBuffer.h" 00011 00013 // ReadWriteBuffer 00014 00015 ReadWriteBuffer::ReadWriteBuffer() 00016 : mBufSiz(0) 00017 , mBufLen(0) 00018 , mBufIdx(0) 00019 , mGrowBy(1024) 00020 , mIsExt(false) 00021 , mBuf(NULL) 00022 { 00023 } 00024 00025 ReadWriteBuffer::ReadWriteBuffer( 00026 const ReadWriteBuffer & rhs 00027 ) 00028 : mBufSiz(0) 00029 , mBufLen(0) 00030 , mBufIdx(0) 00031 , mGrowBy(1024) 00032 , mIsExt(false) 00033 , mBuf(NULL) 00034 { 00035 operator=(rhs); 00036 } 00037 00038 ReadWriteBuffer & 00039 ReadWriteBuffer::operator=( 00040 const ReadWriteBuffer & rhs 00041 ) 00042 { 00043 Deallocate(); 00044 if (rhs.mBufSiz > 0) { 00045 SetInternalBuffer(rhs.mBufSiz, rhs.mGrowBy ? rhs.mGrowBy : 1024); 00046 char * pBuf = GetWriteBuffer(rhs.mBufLen); 00047 memcpy(pBuf, rhs.mBuf, rhs.mBufLen); 00048 mBufIdx = rhs.mBufIdx; 00049 mBufLen = rhs.mBufLen; 00050 } 00051 return *this; 00052 } 00053 00054 ReadWriteBuffer::~ReadWriteBuffer() 00055 { 00056 Deallocate(); 00057 } 00058 00059 void 00060 ReadWriteBuffer::Deallocate() 00061 { 00062 if (mBuf && !mIsExt) { 00063 free(mBuf); 00064 } 00065 00066 mBufSiz = 0; 00067 mBufIdx = 0; 00068 mBufLen = 0; 00069 mGrowBy = 1024; 00070 mIsExt = false; 00071 mBuf = NULL; 00072 } 00073 00074 void 00075 ReadWriteBuffer::SetEmpty() 00076 { 00077 mBufIdx = 0; 00078 mBufLen = 0; 00079 } 00080 00081 void 00082 ReadWriteBuffer::SetExternalBuffer( 00083 void * a_pBuf, 00084 size_t a_nBufSiz, 00085 size_t a_nBufLen, 00086 size_t a_nGrowBy 00087 ) 00088 { 00089 if (!a_pBuf) throw std::invalid_argument("a_pBuf"); 00090 if (a_nBufSiz < 1) throw std::invalid_argument("a_nBufSiz"); 00091 if (a_nBufLen > a_nBufSiz) throw std::invalid_argument("a_nBufLen"); 00092 00093 Deallocate(); 00094 00095 mBufSiz = a_nBufSiz; 00096 mBufIdx = 0; 00097 mBufLen = a_nBufLen; 00098 mGrowBy = a_nGrowBy; 00099 mIsExt = true; 00100 mBuf = (char *) a_pBuf; 00101 } 00102 00107 static inline size_t roundup(size_t nValue, size_t nBlock) { 00108 if ((nValue % nBlock) != 0) { 00109 nValue = (nValue / nBlock) * nBlock + nBlock; 00110 } 00111 return nValue; 00112 } 00113 00114 void 00115 ReadWriteBuffer::SetInternalBuffer( 00116 size_t a_nInitialSize, 00117 size_t a_nGrowBy 00118 ) 00119 { 00120 if (a_nInitialSize < 1) throw std::invalid_argument("a_nInitialSize"); 00121 if (a_nGrowBy < 1) throw std::invalid_argument("a_nGrowBy"); 00122 00123 Deallocate(); 00124 00125 // internal buffer 00126 a_nInitialSize = roundup(a_nInitialSize, a_nGrowBy); 00127 mBuf = (char *) malloc(a_nInitialSize); 00128 if (!mBuf) throw std::bad_alloc(); 00129 mBufSiz = a_nInitialSize; 00130 mGrowBy = a_nGrowBy; 00131 } 00132 00133 char * 00134 ReadWriteBuffer::GetWriteBuffer( 00135 size_t a_nMinBytes 00136 ) 00137 { 00138 if (mBufLen + a_nMinBytes > mBufSiz) { 00139 if (mIsExt) { 00140 if (0 == mGrowBy) throw std::overflow_error("external buffer full"); 00141 00142 size_t nNewSiz = mBufSiz + roundup(a_nMinBytes, mGrowBy); 00143 char * pBuf = (char *) malloc(nNewSiz); 00144 if (!pBuf) throw std::bad_alloc(); 00145 00146 memcpy(pBuf, mBuf, mBufLen); 00147 mBuf = pBuf; 00148 mBufSiz = nNewSiz; 00149 mIsExt = false; 00150 } 00151 else { 00152 size_t nNewSiz = mBufSiz + roundup(a_nMinBytes, mGrowBy); 00153 char * pBuf = (char *) realloc(mBuf, nNewSiz); 00154 if (!pBuf) throw std::bad_alloc(); 00155 mBuf = pBuf; 00156 mBufSiz = nNewSiz; 00157 } 00158 } 00159 return mBuf + mBufLen; 00160 } 00161 00162 void 00163 ReadWriteBuffer::CommitWriteBytes( 00164 size_t a_nBytes 00165 ) 00166 { 00167 if (mBufLen + a_nBytes > mBufSiz) throw std::invalid_argument("a_nBytes"); 00168 mBufLen += a_nBytes; 00169 } 00170 00171 size_t 00172 ReadWriteBuffer::GetWriteSize() const 00173 { 00174 return mBufSiz - mBufLen; 00175 } 00176 00177 void 00178 ReadWriteBuffer::WriteBytes( 00179 const void * a_pBuf, 00180 size_t a_nBufLen 00181 ) 00182 { 00183 char * pBuf = GetWriteBuffer(a_nBufLen); 00184 memcpy(pBuf, a_pBuf, a_nBufLen); 00185 CommitWriteBytes(a_nBufLen); 00186 } 00187 00188 const char * 00189 ReadWriteBuffer::GetReadBuffer() const 00190 { 00191 return mBuf + mBufIdx; 00192 } 00193 00194 void 00195 ReadWriteBuffer::CommitReadBytes( 00196 size_t a_nBytes 00197 ) 00198 { 00199 if (mBufIdx + a_nBytes > mBufLen) throw std::invalid_argument("a_nBytes"); 00200 mBufIdx += a_nBytes; 00201 } 00202 00203 size_t 00204 ReadWriteBuffer::GetReadSize() const 00205 { 00206 return mBufLen - mBufIdx; 00207 } 00208 00209 void 00210 ReadWriteBuffer::ReadBytes( 00211 void * a_pBuf, 00212 size_t a_nBufLen 00213 ) 00214 { 00215 if (GetReadSize() < a_nBufLen) { 00216 throw std::invalid_argument("a_nBufLen"); 00217 } 00218 00219 const char * pBuf = GetReadBuffer(); 00220 memcpy(a_pBuf, pBuf, a_nBufLen); 00221 CommitReadBytes(a_nBufLen); 00222 } 00223 00224 void 00225 ReadWriteBuffer::Compact() 00226 { 00227 if (GetReadSize() > 0) { 00228 memmove(mBuf, GetReadBuffer(), GetReadSize()); 00229 } 00230 00231 mBufLen -= mBufIdx; 00232 mBufIdx = 0; 00233 } 00234 00235 bool 00236 ReadWriteBuffer::operator==( 00237 const ReadWriteBuffer & rhs 00238 ) const 00239 { 00240 if (GetReadSize() != rhs.GetReadSize()) { 00241 return false; 00242 } 00243 return 0 == memcmp(GetReadBuffer(), rhs.GetReadBuffer(), GetReadSize()); 00244 }
1.7.3