Changeset 2935
- Timestamp:
- 22/04/2011 14:41:07 (13 months ago)
- Location:
- box/trunk/lib/common
- Files:
-
- 4 edited
- 2 copied
-
FdGetLine.cpp (modified) (5 diffs)
-
FdGetLine.h (modified) (3 diffs)
-
GetLine.cpp (copied) (copied from box/trunk/lib/common/FdGetLine.cpp) (10 diffs)
-
GetLine.h (copied) (copied from box/trunk/lib/common/FdGetLine.h) (1 diff)
-
IOStreamGetLine.cpp (modified) (3 diffs)
-
IOStreamGetLine.h (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
box/trunk/lib/common/FdGetLine.cpp
r2883 r2935 21 21 #include "MemLeakFindOn.h" 22 22 23 // utility whitespace function24 inline bool iw(int c)25 {26 return (c == ' ' || c == '\t' || c == '\v' || c == '\f'); // \r, \n are already excluded27 }28 29 30 23 // -------------------------------------------------------------------------- 31 24 // … … 37 30 // -------------------------------------------------------------------------- 38 31 FdGetLine::FdGetLine(int fd) 39 : mFileHandle(fd), 40 mLineNumber(0), 41 mBufferBegin(0), 42 mBytesInBuffer(0), 43 mPendingEOF(false), 44 mEOF(false) 32 : mFileHandle(fd) 45 33 { 46 34 if(mFileHandle < 0) {THROW_EXCEPTION(CommonException, BadArguments)} … … 75 63 { 76 64 if(mFileHandle == -1) {THROW_EXCEPTION(CommonException, GetLineNoHandle)} 77 78 // EOF?79 if(mEOF) {THROW_EXCEPTION(CommonException, GetLineEOF)}80 65 81 66 std::string r; 67 bool result = GetLineInternal(r, Preprocess); 82 68 83 bool foundLineEnd = false; 69 if(!result) 70 { 71 // should never fail for FdGetLine 72 THROW_EXCEPTION(CommonException, Internal); 73 } 74 75 return r; 76 } 84 77 85 while(!foundLineEnd && !mEOF) 78 79 // -------------------------------------------------------------------------- 80 // 81 // Function 82 // Name: FdGetLine::ReadMore() 83 // Purpose: Read more bytes from the handle, possible the 84 // console, into mBuffer and return the number of 85 // bytes read, 0 on EOF or -1 on error. 86 // Created: 2011/04/22 87 // 88 // -------------------------------------------------------------------------- 89 int FdGetLine::ReadMore(int Timeout) 90 { 91 int bytes; 92 93 #ifdef WIN32 94 if (mFileHandle == _fileno(stdin)) 86 95 { 87 // Use any bytes left in the buffer 88 while(mBufferBegin < mBytesInBuffer) 89 { 90 int c = mBuffer[mBufferBegin++]; 91 if(c == '\r') 92 { 93 // Ignore nasty Windows line ending extra chars 94 } 95 else if(c == '\n') 96 { 97 // Line end! 98 foundLineEnd = true; 99 break; 100 } 101 else 102 { 103 // Add to string 104 r += c; 105 } 106 107 // Implicit line ending at EOF 108 if(mBufferBegin >= mBytesInBuffer && mPendingEOF) 109 { 110 foundLineEnd = true; 111 } 112 } 113 114 // Check size 115 if(r.size() > FDGETLINE_MAX_LINE_SIZE) 116 { 117 THROW_EXCEPTION(CommonException, GetLineTooLarge) 118 } 119 120 // Read more in? 121 if(!foundLineEnd && mBufferBegin >= mBytesInBuffer && !mPendingEOF) 122 { 123 #ifdef WIN32 124 int bytes; 125 126 if (mFileHandle == _fileno(stdin)) 127 { 128 bytes = console_read(mBuffer, sizeof(mBuffer)); 129 } 130 else 131 { 132 bytes = ::read(mFileHandle, mBuffer, 133 sizeof(mBuffer)); 134 } 135 #else // !WIN32 136 int bytes = ::read(mFileHandle, mBuffer, sizeof(mBuffer)); 137 #endif // WIN32 138 139 // Error? 140 if(bytes == -1) 141 { 142 THROW_EXCEPTION(CommonException, OSFileError) 143 } 144 145 // Adjust buffer info 146 mBytesInBuffer = bytes; 147 mBufferBegin = 0; 148 149 // EOF / closed? 150 if(bytes == 0) 151 { 152 mPendingEOF = true; 153 } 154 } 155 156 // EOF? 157 if(mPendingEOF && mBufferBegin >= mBytesInBuffer) 158 { 159 // File is EOF, and now we've depleted the buffer completely, so tell caller as well. 160 mEOF = true; 161 } 162 } 163 164 if(!Preprocess) 165 { 166 return r; 96 bytes = console_read(mBuffer, sizeof(mBuffer)); 167 97 } 168 98 else 169 99 { 170 // Check for comment char, but char before must be whitespace 171 int end = 0; 172 int size = r.size(); 173 while(end < size) 174 { 175 if(r[end] == '#' && (end == 0 || (iw(r[end-1])))) 176 { 177 break; 178 } 179 end++; 180 } 181 182 // Remove whitespace 183 int begin = 0; 184 while(begin < size && iw(r[begin])) 185 { 186 begin++; 187 } 100 bytes = ::read(mFileHandle, mBuffer, sizeof(mBuffer)); 101 } 102 #else // !WIN32 103 bytes = ::read(mFileHandle, mBuffer, sizeof(mBuffer)); 104 #endif // WIN32 188 105 189 if(end < size && !iw(r[end])) 190 { 191 end--; 192 } 193 194 while(end > begin && end < size && iw(r[end])) 195 { 196 end--; 197 } 198 199 // Return a sub string 200 return r.substr(begin, end - begin + 1); 106 if(bytes == 0) 107 { 108 mPendingEOF = true; 201 109 } 202 110 } … … 208 116 // Name: FdGetLine::DetachFile() 209 117 // Purpose: Detaches the file handle, setting the file pointer correctly. 210 // Probably not good for sockets...118 // Probably not good for sockets... 211 119 // Created: 2003/07/24 212 120 // … … 231 139 } 232 140 233 -
box/trunk/lib/common/FdGetLine.h
r2415 r2935 13 13 #include <string> 14 14 15 #ifdef BOX_RELEASE_BUILD 16 #define FDGETLINE_BUFFER_SIZE 1024 17 #elif defined WIN32 18 // need enough space for at least one unicode character 19 // in UTF-8 when calling console_read() from bbackupquery 20 #define FDGETLINE_BUFFER_SIZE 5 21 #else 22 #define FDGETLINE_BUFFER_SIZE 4 23 #endif 24 25 // Just a very large upper bound for line size to avoid 26 // people sending lots of data over sockets and causing memory problems. 27 #define FDGETLINE_MAX_LINE_SIZE (1024*256) 15 #include "GetLine.h" 28 16 29 17 // -------------------------------------------------------------------------- … … 35 23 // 36 24 // -------------------------------------------------------------------------- 37 class FdGetLine 25 class FdGetLine : public GetLine 38 26 { 39 27 public: … … 44 32 45 33 public: 46 std::string GetLine(bool Preprocess = false); 47 bool IsEOF() {return mEOF;} 48 int GetLineNumber() {return mLineNumber;} 49 34 virtual std::string GetLine(bool Preprocess = false); 50 35 // Call to detach, setting file pointer correctly to last bit read. 51 36 // Only works for lseek-able file descriptors. 52 37 void DetachFile(); 53 38 // if we read 0 bytes from an fd, it must be end of stream, 39 // because we don't support timeouts 40 virtual bool IsStreamDataLeft() { return false; } 41 42 protected: 43 int ReadMore(int Timeout = IOStream::TimeOutInfinite); 44 54 45 private: 55 char mBuffer[FDGETLINE_BUFFER_SIZE];56 46 int mFileHandle; 57 int mLineNumber;58 int mBufferBegin;59 int mBytesInBuffer;60 bool mPendingEOF;61 bool mEOF;62 47 }; 63 48 -
box/trunk/lib/common/GetLine.cpp
r2883 r2935 2 2 // 3 3 // File 4 // Name: FdGetLine.cpp5 // Purpose: Line based file descriptor reading6 // Created: 20 03/07/244 // Name: GetLine.cpp 5 // Purpose: Common base class for line based file descriptor reading 6 // Created: 2011/04/22 7 7 // 8 8 // -------------------------------------------------------------------------- … … 16 16 #endif 17 17 18 #include " FdGetLine.h"18 #include "GetLine.h" 19 19 #include "CommonException.h" 20 20 … … 31 31 // 32 32 // Function 33 // Name: FdGetLine::FdGetLine(int)33 // Name: GetLine::GetLine(int) 34 34 // Purpose: Constructor, taking file descriptor 35 // Created: 20 03/07/2435 // Created: 2011/04/22 36 36 // 37 37 // -------------------------------------------------------------------------- 38 FdGetLine::FdGetLine(int fd) 39 : mFileHandle(fd), 40 mLineNumber(0), 41 mBufferBegin(0), 42 mBytesInBuffer(0), 43 mPendingEOF(false), 44 mEOF(false) 45 { 46 if(mFileHandle < 0) {THROW_EXCEPTION(CommonException, BadArguments)} 47 //printf("FdGetLine buffer size = %d\n", sizeof(mBuffer)); 48 } 49 38 GetLine::GetLine() 39 : mLineNumber(0), 40 mBufferBegin(0), 41 mBytesInBuffer(0), 42 mPendingEOF(false), 43 mEOF(false) 44 { } 50 45 51 46 // -------------------------------------------------------------------------- 52 47 // 53 48 // Function 54 // Name: FdGetLine::~FdGetLine() 55 // Purpose: Destructor 56 // Created: 2003/07/24 49 // Name: GetLine::GetLineInternal(std::string &, bool, int) 50 // Purpose: Gets a line from the file, returning it in rOutput. 51 // If Preprocess is true, leading and trailing 52 // whitespace is removed, and comments (after #) are 53 // deleted. Returns true if a line is available now, 54 // false if retrying may get a line (eg timeout, 55 // signal), and exceptions if it's EOF. 56 // Created: 2011/04/22 57 57 // 58 58 // -------------------------------------------------------------------------- 59 FdGetLine::~FdGetLine() 59 bool GetLine::GetLineInternal(std::string &rOutput, bool Preprocess, 60 int Timeout) 60 61 { 61 }62 63 64 // --------------------------------------------------------------------------65 //66 // Function67 // Name: FdGetLine::GetLine(bool)68 // Purpose: Returns a file from the file. If Preprocess is true, leading69 // and trailing whitespace is removed, and comments (after #)70 // are deleted.71 // Created: 2003/07/2472 //73 // --------------------------------------------------------------------------74 std::string FdGetLine::GetLine(bool Preprocess)75 {76 if(mFileHandle == -1) {THROW_EXCEPTION(CommonException, GetLineNoHandle)}77 78 62 // EOF? 79 63 if(mEOF) {THROW_EXCEPTION(CommonException, GetLineEOF)} 80 64 81 std::string r; 65 // Initialise string to stored into 66 rOutput = mPendingString; 67 mPendingString.erase(); 82 68 83 69 bool foundLineEnd = false; … … 102 88 { 103 89 // Add to string 104 r += c;90 rOutput += c; 105 91 } 106 92 … … 113 99 114 100 // Check size 115 if(r .size() > FDGETLINE_MAX_LINE_SIZE)101 if(rOutput.size() > GETLINE_MAX_LINE_SIZE) 116 102 { 117 103 THROW_EXCEPTION(CommonException, GetLineTooLarge) … … 121 107 if(!foundLineEnd && mBufferBegin >= mBytesInBuffer && !mPendingEOF) 122 108 { 123 #ifdef WIN32 124 int bytes; 125 126 if (mFileHandle == _fileno(stdin)) 127 { 128 bytes = console_read(mBuffer, sizeof(mBuffer)); 129 } 130 else 131 { 132 bytes = ::read(mFileHandle, mBuffer, 133 sizeof(mBuffer)); 134 } 135 #else // !WIN32 136 int bytes = ::read(mFileHandle, mBuffer, sizeof(mBuffer)); 137 #endif // WIN32 109 int bytes = ReadMore(Timeout); 138 110 139 111 // Error? … … 147 119 mBufferBegin = 0; 148 120 149 // EOF / closed?150 if(bytes == 0 )121 // No data returned? 122 if(bytes == 0 && IsStreamDataLeft()) 151 123 { 152 mPendingEOF = true; 124 // store string away 125 mPendingString = rOutput; 126 // Return false; 127 return false; 153 128 } 154 129 } … … 162 137 } 163 138 164 if(!Preprocess) 165 { 166 return r; 167 } 168 else 139 if(Preprocess) 169 140 { 170 141 // Check for comment char, but char before must be whitespace 142 // end points to a gap between characters, may equal start if 143 // the string to be extracted has zero length, and indexes the 144 // first character not in the string (== length, or a # mark 145 // or whitespace) 171 146 int end = 0; 172 int size = r .size();147 int size = rOutput.size(); 173 148 while(end < size) 174 149 { 175 if(r [end] == '#' && (end == 0 || (iw(r[end-1]))))150 if(rOutput[end] == '#' && (end == 0 || (iw(rOutput[end-1])))) 176 151 { 177 152 break; … … 182 157 // Remove whitespace 183 158 int begin = 0; 184 while(begin < size && iw(r [begin]))159 while(begin < size && iw(rOutput[begin])) 185 160 { 186 161 begin++; 187 162 } 188 163 189 if(end < size && !iw(r[end])) 190 { 191 end--; 192 } 193 194 while(end > begin && end < size && iw(r[end])) 164 while(end > begin && end <= size && iw(rOutput[end-1])) 195 165 { 196 166 end--; … … 198 168 199 169 // Return a sub string 200 r eturn r.substr(begin, end - begin + 1);170 rOutput = rOutput.substr(begin, end - begin); 201 171 } 172 173 return true; 202 174 } 203 175 204 176 205 // --------------------------------------------------------------------------206 //207 // Function208 // Name: FdGetLine::DetachFile()209 // Purpose: Detaches the file handle, setting the file pointer correctly.210 // Probably not good for sockets...211 // Created: 2003/07/24212 //213 // --------------------------------------------------------------------------214 void FdGetLine::DetachFile()215 {216 if(mFileHandle == -1) {THROW_EXCEPTION(CommonException, GetLineNoHandle)}217 218 // Adjust file pointer219 int bytesOver = mBufferBegin - mBufferBegin;220 ASSERT(bytesOver >= 0);221 if(bytesOver > 0)222 {223 if(::lseek(mFileHandle, 0 - bytesOver, SEEK_CUR) == -1)224 {225 THROW_EXCEPTION(CommonException, OSFileError)226 }227 }228 229 // Unset file pointer230 mFileHandle = -1;231 }232 233 -
box/trunk/lib/common/GetLine.h
r2415 r2935 2 2 // 3 3 // File 4 // Name: FdGetLine.h5 // Purpose: Line based file descriptor reading6 // Created: 20 03/07/244 // Name: GetLine.h 5 // Purpose: Common base class for line based file descriptor reading 6 // Created: 2011/04/22 7 7 // 8 8 // -------------------------------------------------------------------------- 9 9 10 #ifndef FDGETLINE__H11 #define FDGETLINE__H10 #ifndef GETLINE__H 11 #define GETLINE__H 12 12 13 13 #include <string> 14 14 15 15 #ifdef BOX_RELEASE_BUILD 16 #define FDGETLINE_BUFFER_SIZE 102416 #define GETLINE_BUFFER_SIZE 1024 17 17 #elif defined WIN32 18 18 // need enough space for at least one unicode character 19 19 // in UTF-8 when calling console_read() from bbackupquery 20 #define FDGETLINE_BUFFER_SIZE 520 #define GETLINE_BUFFER_SIZE 5 21 21 #else 22 #define FDGETLINE_BUFFER_SIZE 422 #define GETLINE_BUFFER_SIZE 4 23 23 #endif 24 24 25 25 // Just a very large upper bound for line size to avoid 26 26 // people sending lots of data over sockets and causing memory problems. 27 #define FDGETLINE_MAX_LINE_SIZE (1024*256)27 #define GETLINE_MAX_LINE_SIZE (1024*256) 28 28 29 29 // -------------------------------------------------------------------------- 30 30 // 31 31 // Class 32 // Name: FdGetLine33 // Purpose: Line based file descriptor reading34 // Created: 20 03/07/2432 // Name: GetLine 33 // Purpose: Common base class for line based file descriptor reading 34 // Created: 2011/04/22 35 35 // 36 36 // -------------------------------------------------------------------------- 37 class FdGetLine37 class GetLine 38 38 { 39 p ublic:40 FdGetLine(int fd);41 ~FdGetLine(); 39 protected: 40 GetLine(); 41 42 42 private: 43 FdGetLine(const FdGetLine &rToCopy);43 GetLine(const GetLine &rToCopy); 44 44 45 45 public: 46 std::string GetLine(bool Preprocess = false); 47 bool IsEOF() {return mEOF;} 46 virtual bool IsEOF() {return mEOF;} 48 47 int GetLineNumber() {return mLineNumber;} 49 48 50 // Call to detach, setting file pointer correctly to last bit read. 51 // Only works for lseek-able file descriptors. 52 void DetachFile(); 53 54 private: 55 char mBuffer[FDGETLINE_BUFFER_SIZE]; 56 int mFileHandle; 49 protected: 50 bool GetLineInternal(std::string &rOutput, 51 bool Preprocess = false, 52 int Timeout = IOStream::TimeOutInfinite); 53 virtual int ReadMore(int Timeout = IOStream::TimeOutInfinite) = 0; 54 virtual bool IsStreamDataLeft() = 0; 55 56 char mBuffer[GETLINE_BUFFER_SIZE]; 57 57 int mLineNumber; 58 58 int mBufferBegin; 59 59 int mBytesInBuffer; 60 60 bool mPendingEOF; 61 std::string mPendingString; 61 62 bool mEOF; 62 63 }; 63 64 64 #endif // FDGETLINE__H65 #endif // GETLINE__H 65 66 -
box/trunk/lib/common/IOStreamGetLine.cpp
r2883 r2935 14 14 #include "MemLeakFindOn.h" 15 15 16 // utility whitespace function17 inline bool iw(int c)18 {19 return (c == ' ' || c == '\t' || c == '\v' || c == '\f'); // \r, \n are already excluded20 }21 22 23 16 // -------------------------------------------------------------------------- 24 17 // … … 30 23 // -------------------------------------------------------------------------- 31 24 IOStreamGetLine::IOStreamGetLine(IOStream &Stream) 32 : mrStream(Stream), 33 mLineNumber(0), 34 mBufferBegin(0), 35 mBytesInBuffer(0), 36 mPendingEOF(false), 37 mEOF(false) 25 : mrStream(Stream) 38 26 { 39 27 } … … 67 55 bool IOStreamGetLine::GetLine(std::string &rOutput, bool Preprocess, int Timeout) 68 56 { 69 // EOF? 70 if(mEOF) {THROW_EXCEPTION(CommonException, GetLineEOF)} 57 return GetLineInternal(rOutput, Preprocess, Timeout); 58 } 59 60 61 // -------------------------------------------------------------------------- 62 // 63 // Function 64 // Name: IOStreamGetLine::ReadMore() 65 // Purpose: Read more bytes from the handle, possible the 66 // console, into mBuffer and return the number of 67 // bytes read, 0 on EOF or -1 on error. 68 // Created: 2011/04/22 69 // 70 // -------------------------------------------------------------------------- 71 int IOStreamGetLine::ReadMore(int Timeout) 72 { 73 int bytes = mrStream.Read(mBuffer, sizeof(mBuffer), Timeout); 71 74 72 // Initialise string to stored into 73 std::string r(mPendingString); 74 mPendingString.erase(); 75 76 bool foundLineEnd = false; 77 78 while(!foundLineEnd && !mEOF) 75 if(!mrStream.StreamDataLeft()) 79 76 { 80 // Use any bytes left in the buffer 81 while(mBufferBegin < mBytesInBuffer) 82 { 83 int c = mBuffer[mBufferBegin++]; 84 if(c == '\r') 85 { 86 // Ignore nasty Windows line ending extra chars 87 } 88 else if(c == '\n') 89 { 90 // Line end! 91 foundLineEnd = true; 92 break; 93 } 94 else 95 { 96 // Add to string 97 r += c; 98 } 99 100 // Implicit line ending at EOF 101 if(mBufferBegin >= mBytesInBuffer && mPendingEOF) 102 { 103 foundLineEnd = true; 104 } 105 } 106 107 // Check size 108 if(r.size() > IOSTREAMGETLINE_MAX_LINE_SIZE) 109 { 110 THROW_EXCEPTION(CommonException, GetLineTooLarge) 111 } 112 113 // Read more in? 114 if(!foundLineEnd && mBufferBegin >= mBytesInBuffer && !mPendingEOF) 115 { 116 int bytes = mrStream.Read(mBuffer, sizeof(mBuffer), Timeout); 117 118 // Adjust buffer info 119 mBytesInBuffer = bytes; 120 mBufferBegin = 0; 121 122 // EOF / closed? 123 if(!mrStream.StreamDataLeft()) 124 { 125 mPendingEOF = true; 126 } 127 128 // No data returned? 129 if(bytes == 0 && mrStream.StreamDataLeft()) 130 { 131 // store string away 132 mPendingString = r; 133 // Return false; 134 return false; 135 } 136 } 137 138 // EOF? 139 if(mPendingEOF && mBufferBegin >= mBytesInBuffer) 140 { 141 // File is EOF, and now we've depleted the buffer completely, so tell caller as well. 142 mEOF = true; 143 } 77 mPendingEOF = true; 144 78 } 145 79 146 if(!Preprocess) 147 { 148 rOutput = r; 149 return true; 150 } 151 else 152 { 153 // Check for comment char, but char before must be whitespace 154 int end = 0; 155 int size = r.size(); 156 while(end < size) 157 { 158 if(r[end] == '#' && (end == 0 || (iw(r[end-1])))) 159 { 160 break; 161 } 162 end++; 163 } 164 165 // Remove whitespace 166 int begin = 0; 167 while(begin < size && iw(r[begin])) 168 { 169 begin++; 170 } 171 172 if(end < size && !iw(r[end])) 173 { 174 end--; 175 } 176 177 while(end > begin && end < size && iw(r[end])) 178 { 179 end--; 180 } 181 182 // Return a sub string 183 rOutput = r.substr(begin, end - begin + 1); 184 return true; 185 } 80 return bytes; 186 81 } 187 82 -
box/trunk/lib/common/IOStreamGetLine.h
r2415 r2935 13 13 #include <string> 14 14 15 #include "GetLine.h" 15 16 #include "IOStream.h" 16 17 #ifdef BOX_RELEASE_BUILD18 #define IOSTREAMGETLINE_BUFFER_SIZE 102419 #else20 #define IOSTREAMGETLINE_BUFFER_SIZE 421 #endif22 23 // Just a very large upper bound for line size to avoid24 // people sending lots of data over sockets and causing memory problems.25 #define IOSTREAMGETLINE_MAX_LINE_SIZE (1024*256)26 17 27 18 // -------------------------------------------------------------------------- … … 33 24 // 34 25 // -------------------------------------------------------------------------- 35 class IOStreamGetLine 26 class IOStreamGetLine : public GetLine 36 27 { 37 28 public: … … 43 34 public: 44 35 bool GetLine(std::string &rOutput, bool Preprocess = false, int Timeout = IOStream::TimeOutInfinite); 45 bool IsEOF() {return mEOF;}46 int GetLineNumber() {return mLineNumber;}47 36 48 37 // Call to detach, setting file pointer correctly to last bit read. 49 38 // Only works for lseek-able file descriptors. 50 39 void DetachFile(); 40 41 virtual bool IsStreamDataLeft() 42 { 43 return mrStream.StreamDataLeft(); 44 } 51 45 52 46 // For doing interesting stuff with the remaining data... … … 56 50 void IgnoreBufferedData(int BytesToIgnore); 57 51 IOStream &GetUnderlyingStream() {return mrStream;} 52 53 protected: 54 int ReadMore(int Timeout = IOStream::TimeOutInfinite); 58 55 59 56 private: 60 char mBuffer[IOSTREAMGETLINE_BUFFER_SIZE];61 57 IOStream &mrStream; 62 int mLineNumber;63 int mBufferBegin;64 int mBytesInBuffer;65 bool mPendingEOF;66 bool mEOF;67 std::string mPendingString;68 58 }; 69 59
Note: See TracChangeset
for help on using the changeset viewer.
