00001 //------------------------------------------------------------------------------ 00002 // Copyright (c) 2011-2012 by European Organization for Nuclear Research (CERN) 00003 // Author: Lukasz Janyst <ljanyst@cern.ch> 00004 //------------------------------------------------------------------------------ 00005 // XRootD is free software: you can redistribute it and/or modify 00006 // it under the terms of the GNU Lesser General Public License as published by 00007 // the Free Software Foundation, either version 3 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // XRootD is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU Lesser General Public License 00016 // along with XRootD. If not, see <http://www.gnu.org/licenses/>. 00017 //------------------------------------------------------------------------------ 00018 00019 #ifndef __XRD_CL_BUFFER_HH__ 00020 #define __XRD_CL_BUFFER_HH__ 00021 00022 #include <cstdlib> 00023 #include <stdint.h> 00024 #include <new> 00025 #include <cstring> 00026 #include <string> 00027 00028 namespace XrdCl 00029 { 00030 //---------------------------------------------------------------------------- 00032 //---------------------------------------------------------------------------- 00033 class Buffer 00034 { 00035 public: 00036 //------------------------------------------------------------------------ 00038 //------------------------------------------------------------------------ 00039 Buffer( uint32_t size = 0 ): pBuffer(0), pSize(0), pCursor(0) 00040 { 00041 if( size ) 00042 { 00043 Allocate( size ); 00044 } 00045 } 00046 00047 //------------------------------------------------------------------------ 00049 //------------------------------------------------------------------------ 00050 Buffer( Buffer &&buffer ) 00051 { 00052 Steal( std::move( buffer ) ); 00053 } 00054 00055 //------------------------------------------------------------------------ 00057 //------------------------------------------------------------------------ 00058 Buffer& operator=( Buffer && buffer ) 00059 { 00060 Steal( std::move( buffer ) ); 00061 return *this; 00062 } 00063 00064 //------------------------------------------------------------------------ 00066 //------------------------------------------------------------------------ 00067 virtual ~Buffer() { Free(); } 00068 00069 //------------------------------------------------------------------------ 00071 //------------------------------------------------------------------------ 00072 const char *GetBuffer( uint32_t offset = 0 ) const 00073 { 00074 return pBuffer+offset; 00075 } 00076 00077 //------------------------------------------------------------------------ 00079 //------------------------------------------------------------------------ 00080 char *GetBuffer( uint32_t offset = 0 ) 00081 { 00082 return pBuffer+offset; 00083 } 00084 00085 //------------------------------------------------------------------------ 00087 //------------------------------------------------------------------------ 00088 void ReAllocate( uint32_t size ) 00089 { 00090 pBuffer = (char *)realloc( pBuffer, size ); 00091 if( !pBuffer ) 00092 throw std::bad_alloc(); 00093 pSize = size; 00094 } 00095 00096 //------------------------------------------------------------------------ 00098 //------------------------------------------------------------------------ 00099 void Free() 00100 { 00101 free( pBuffer ); 00102 pBuffer = 0; 00103 pSize = 0; 00104 pCursor = 0; 00105 } 00106 00107 //------------------------------------------------------------------------ 00109 //------------------------------------------------------------------------ 00110 void Allocate( uint32_t size ) 00111 { 00112 if( !size ) 00113 return; 00114 00115 pBuffer = (char *)malloc( size ); 00116 if( !pBuffer ) 00117 throw std::bad_alloc(); 00118 pSize = size; 00119 } 00120 00121 //------------------------------------------------------------------------ 00123 //------------------------------------------------------------------------ 00124 void Zero() 00125 { 00126 memset( pBuffer, 0, pSize ); 00127 } 00128 00129 //------------------------------------------------------------------------ 00131 //------------------------------------------------------------------------ 00132 uint32_t GetSize() const 00133 { 00134 return pSize; 00135 } 00136 00137 //------------------------------------------------------------------------ 00139 //------------------------------------------------------------------------ 00140 uint32_t GetCursor() const 00141 { 00142 return pCursor; 00143 } 00144 00145 //------------------------------------------------------------------------ 00147 //------------------------------------------------------------------------ 00148 void SetCursor( uint32_t cursor ) 00149 { 00150 pCursor = cursor; 00151 } 00152 00153 //------------------------------------------------------------------------ 00155 //------------------------------------------------------------------------ 00156 void AdvanceCursor( uint32_t delta ) 00157 { 00158 pCursor += delta; 00159 } 00160 00161 //------------------------------------------------------------------------ 00163 //------------------------------------------------------------------------ 00164 void Append( const char *buffer, uint32_t size ) 00165 { 00166 uint32_t remaining = pSize-pCursor; 00167 if( remaining < size ) 00168 ReAllocate( pCursor+size ); 00169 00170 memcpy( pBuffer+pCursor, buffer, size ); 00171 pCursor += size; 00172 } 00173 00174 //------------------------------------------------------------------------ 00176 //------------------------------------------------------------------------ 00177 void Append( const char *buffer, uint32_t size, uint32_t offset ) 00178 { 00179 uint32_t remaining = pSize-offset; 00180 if( remaining < size ) 00181 ReAllocate( offset+size ); 00182 00183 memcpy( pBuffer+offset, buffer, size ); 00184 } 00185 00186 //------------------------------------------------------------------------ 00188 //------------------------------------------------------------------------ 00189 char *GetBufferAtCursor() 00190 { 00191 return GetBuffer( pCursor ); 00192 } 00193 00194 //------------------------------------------------------------------------ 00196 //------------------------------------------------------------------------ 00197 const char *GetBufferAtCursor() const 00198 { 00199 return GetBuffer( pCursor ); 00200 } 00201 00202 //------------------------------------------------------------------------ 00204 //------------------------------------------------------------------------ 00205 void FromString( const std::string str ) 00206 { 00207 ReAllocate( str.length()+1 ); 00208 memcpy( pBuffer, str.c_str(), str.length() ); 00209 pBuffer[str.length()] = 0; 00210 } 00211 00212 //------------------------------------------------------------------------ 00214 //------------------------------------------------------------------------ 00215 std::string ToString() const 00216 { 00217 char *bf = new char[pSize+1]; 00218 bf[pSize] = 0; 00219 memcpy( bf, pBuffer, pSize ); 00220 std::string tmp = bf; 00221 delete [] bf; 00222 return tmp; 00223 } 00224 00225 //------------------------------------------------------------------------ 00227 //------------------------------------------------------------------------ 00228 void Grab( char *buffer, uint32_t size ) 00229 { 00230 Free(); 00231 pBuffer = buffer; 00232 pSize = size; 00233 } 00234 00235 //------------------------------------------------------------------------ 00237 //------------------------------------------------------------------------ 00238 char *Release() 00239 { 00240 char *buffer = pBuffer; 00241 pBuffer = 0; 00242 pSize = 0; 00243 pCursor = 0; 00244 return buffer; 00245 } 00246 00247 private: 00248 00249 void Steal( Buffer &&buffer ) 00250 { 00251 pBuffer = buffer.pBuffer; 00252 buffer.pBuffer = 0; 00253 00254 pSize = buffer.pSize; 00255 buffer.pSize = 0; 00256 00257 pCursor = buffer.pCursor; 00258 buffer.pCursor = 0; 00259 } 00260 00261 Buffer( const Buffer& ); 00262 Buffer& operator=( const Buffer& ); 00263 00264 char *pBuffer; 00265 uint32_t pSize; 00266 uint32_t pCursor; 00267 }; 00268 } 00269 00270 #endif // __XRD_CL_BUFFER_HH__