/*========================================================================= Program: GDCM (Grassroots DICOM). A DICOM library Copyright (c) 2006-2011 Mathieu Malaterre All rights reserved. See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ #ifndef GDCMBYTEBUFFER_H #define GDCMBYTEBUFFER_H #include "gdcmTypes.h" #include #include #include // memmove #error should not be used namespace gdcm { /** * \brief ByteBuffer * * \details Detailed description here * \note * looks like a std::streambuf or std::filebuf class with the get and * peek pointer */ class ByteBuffer { static const int InitBufferSize = 1024; public: ByteBuffer() : Start(0), End(0),Limit(0) {} char *Get(int len) { char *buffer = &Internal[0]; if (len > Limit - End) { // FIXME avoid integer overflow int neededSize = len + (End - Start); if (neededSize <= Limit - buffer) { memmove(buffer, Start, End - Start); End = buffer + (End - Start); Start = buffer; } else { char *newBuf; int bufferSize = Limit - Start; if ( bufferSize == 0 ) { bufferSize = InitBufferSize; } do { bufferSize *= 2; } while (bufferSize < neededSize); //newBuf = malloc(bufferSize); try { Internal.reserve(bufferSize); newBuf = &Internal[0]; } catch(...) { //errorCode = NoMemoryError; return 0; } Limit = newBuf + bufferSize; if (Start) { memcpy(newBuf, Start, End - Start); } End = newBuf + (End - Start); Start = /*buffer =*/ newBuf; } } assert( (int)Internal.capacity() >= len ); return End; } void UpdatePosition() {} void ShiftEnd(int len) { End += len; } const char *GetStart() const { return Start; } private: typedef std::vector CharVector; const char *Start; char *End; const char *Limit; CharVector Internal; }; } // end namespace gdcm #endif //GDCMBYTEBUFFER_H