📄 strbuffer.cpp
字号:
{ // cache pos char* pos = m_CurrentPos; for ( ;; ) { size_t c = m_DataEndPos - pos; if ( c >= count ) { // all data is already in buffer -> skip it m_CurrentPos = pos + count; return; } else { count -= c; m_CurrentPos = pos += c; pos = FillBuffer(pos); } }}void CIStreamBuffer::SkipEndOfLine(char lastChar) THROWS1((CIOException)){ _ASSERT(lastChar == '\n' || lastChar == '\r'); _ASSERT(m_CurrentPos > m_Buffer && m_CurrentPos[-1] == lastChar); m_Line++; char nextChar; try { nextChar = PeekChar(); } catch ( CEofException& /* ignored */ ) { return; } // lastChar either '\r' or \n' // if nextChar is compliment, skip it if ( (lastChar + nextChar) == ('\r' + '\n') ) SkipChar();}size_t CIStreamBuffer::ReadLine(char* buff, size_t size) THROWS1((CIOException)){ size_t count = 0; try { while ( size > 0 ) { char c = *buff++ = GetChar(); count++; size--; switch ( c ) { case '\r': // replace leading '\r' by '\n' buff[-1] = '\n'; if ( PeekChar() == '\n' ) SkipChar(); return count; case '\n': if ( PeekChar() == '\r' ) SkipChar(); return count; } } return count; } catch ( CEofException& /*ignored*/ ) { return count; }}void CIStreamBuffer::BadNumber(void){ m_Error = "bad number";// THROW1_TRACE(runtime_error, "bad number in line " + NStr::UIntToString(GetLine())); NCBI_THROW(CIOException,eRead, "bad number in line " + NStr::UIntToString(GetLine()));}void CIStreamBuffer::SetStreamOffset(size_t pos){ m_Input->Seekg(pos); m_BufferOffset = pos; m_DataEndPos = m_Buffer; m_CurrentPos = m_Buffer; m_Line = 1;}Int4 CIStreamBuffer::GetInt4(void){ bool sign; char c = GetChar(); switch ( c ) { case '-': sign = true; c = GetChar(); break; case '+': sign = false; c = GetChar(); break; default: sign = false; break; } if ( c < '0' || c > '9' ) BadNumber(); Int4 n = c - '0'; for ( ;; ) { c = PeekCharNoEOF(); if ( c < '0' || c > '9' ) break; SkipChar(); // TODO: check overflow n = n * 10 + (c - '0'); } if ( sign ) return -n; else return n;}Uint4 CIStreamBuffer::GetUint4(void){ char c = GetChar(); if ( c == '+' ) c = GetChar(); if ( c < '0' || c > '9' ) BadNumber(); Uint4 n = c - '0'; for ( ;; ) { c = PeekCharNoEOF(); if ( c < '0' || c > '9' ) break; SkipChar(); // TODO: check overflow n = n * 10 + (c - '0'); } return n;}Int8 CIStreamBuffer::GetInt8(void) THROWS1((CIOException)){ bool sign; char c = GetChar(); switch ( c ) { case '-': sign = true; c = GetChar(); break; case '+': sign = false; c = GetChar(); break; default: sign = false; break; } if ( c < '0' || c > '9' ) BadNumber(); Int8 n = c - '0'; for ( ;; ) { c = PeekCharNoEOF(); if ( c < '0' || c > '9' ) break; SkipChar(); // TODO: check overflow n = n * 10 + (c - '0'); } if ( sign ) return -n; else return n;}Uint8 CIStreamBuffer::GetUint8(void) THROWS1((CIOException)){ char c = GetChar(); if ( c == '+' ) c = GetChar(); if ( c < '0' || c > '9' ) BadNumber(); Uint8 n = c - '0'; for ( ;; ) { c = PeekCharNoEOF(); if ( c < '0' || c > '9' ) break; SkipChar(); // TODO: check overflow n = n * 10 + (c - '0'); } return n;}COStreamBuffer::COStreamBuffer(CNcbiOstream& out, bool deleteOut) THROWS1((bad_alloc)) : m_Output(out), m_DeleteOutput(deleteOut), m_Error(0), m_IndentLevel(0), m_BufferOffset(0), m_Buffer(new char[KInitialBufferSize]), m_CurrentPos(m_Buffer), m_BufferEnd(m_Buffer + KInitialBufferSize), m_Line(1), m_LineLength(0), m_BackLimit(0), m_UseIndentation(true){}COStreamBuffer::~COStreamBuffer(void){ try { Close(); } catch ( exception& exc ) { ERR_POST(Warning << "~COStreamBuffer: exception while closing: " << exc.what()); } delete[] m_Buffer;}void COStreamBuffer::Close(void){ if ( m_Output ) { Flush(); if ( m_DeleteOutput ) delete &m_Output; m_DeleteOutput = false; } m_Error = 0; m_IndentLevel = 0; m_CurrentPos = m_Buffer; m_Line = 1; m_LineLength = 0;}void COStreamBuffer::FlushBuffer(bool fullBuffer) THROWS1((CIOException)){ size_t used = GetUsedSpace(); size_t count; size_t leave; if ( fullBuffer ) { count = used; leave = 0; } else { leave = m_BackLimit; if ( used < leave ) return; // none to flush count = used - leave; } if ( count != 0 ) { if ( !m_Output.write(m_Buffer, count) ) { m_Error = "write fault";// THROW1_TRACE(CIOException, "write fault"); NCBI_THROW(CIOException,eWrite,m_Error); } if ( leave != 0 ) { memmove(m_Buffer, m_Buffer + count, leave); m_CurrentPos -= count; } else { m_CurrentPos = m_Buffer; } m_BufferOffset += count; }}void COStreamBuffer::Flush(void) THROWS1((CIOException)){ FlushBuffer(); IOS_BASE::iostate state = m_Output.rdstate(); m_Output.clear(); try { if ( !m_Output.flush() ) { NCBI_THROW(CIOException,eFlush,"COStreamBuffer::Flush: failed"); } } catch (...) { m_Output.clear(state); throw; } m_Output.clear(state);}char* COStreamBuffer::DoReserve(size_t count) THROWS1((CIOException, bad_alloc)){ FlushBuffer(false); size_t usedSize = m_CurrentPos - m_Buffer; size_t needSize = usedSize + count; size_t bufferSize = m_BufferEnd - m_Buffer; if ( bufferSize < needSize ) { // realloc too small buffer do { bufferSize = BiggerBufferSize(bufferSize); } while ( bufferSize < needSize ); if ( usedSize == 0 ) { delete[] m_Buffer; m_CurrentPos = m_Buffer = new char[bufferSize]; m_BufferEnd = m_Buffer + bufferSize; } else { char* oldBuffer = m_Buffer; m_Buffer = new char[bufferSize]; m_BufferEnd = m_Buffer + bufferSize; memcpy(m_Buffer, oldBuffer, usedSize); delete[] oldBuffer; m_CurrentPos = m_Buffer + usedSize; } } return m_CurrentPos;}void COStreamBuffer::PutInt4(Int4 v) THROWS1((CIOException, bad_alloc)){ const size_t BSIZE = (sizeof(v)*CHAR_BIT) / 3 + 2; char b[BSIZE]; char* pos = b + BSIZE; if ( v == 0 ) { *--pos = '0'; } else { Uint4 uv = v; bool sign = v < 0; if ( sign ) uv = -v; do { *--pos = char('0' + (uv % 10)); uv /= 10; } while ( uv ); if ( sign ) *--pos = '-'; } PutString(pos, b + BSIZE - pos);}void COStreamBuffer::PutUint4(Uint4 v) THROWS1((CIOException, bad_alloc)){ const size_t BSIZE = (sizeof(v)*CHAR_BIT) / 3 + 2; char b[BSIZE]; char* pos = b + BSIZE; if ( v == 0 ) { *--pos = '0'; } else { do { *--pos = char('0' + (v % 10)); v /= 10; } while ( v ); } PutString(pos, b + BSIZE - pos);}void COStreamBuffer::PutInt8(Int8 v) THROWS1((CIOException, bad_alloc)){ const size_t BSIZE = (sizeof(v)*CHAR_BIT) / 3 + 2; char b[BSIZE]; char* pos = b + BSIZE; if ( v == 0 ) { *--pos = '0'; } else { bool sign = v < 0; if ( sign ) v = -v; do { *--pos = char('0' + (v % 10)); v /= 10; } while ( v ); if ( sign ) *--pos = '-'; } PutString(pos, b + BSIZE - pos);}void COStreamBuffer::PutUint8(Uint8 v) THROWS1((CIOException, bad_alloc)){ const size_t BSIZE = (sizeof(v)*CHAR_BIT) / 3 + 2; char b[BSIZE]; char* pos = b + BSIZE; if ( v == 0 ) { *--pos = '0'; } else { do { *--pos = char('0' + (v % 10)); v /= 10; } while ( v ); } PutString(pos, b + BSIZE - pos);}void COStreamBuffer::PutEolAtWordEnd(size_t lineLength) THROWS1((CIOException, bad_alloc)){ Reserve(1); size_t linePos = m_LineLength; char* pos = m_CurrentPos; bool goodPlace = false; while ( pos > m_Buffer && linePos > 0 ) { --pos; --linePos; if ( linePos <= lineLength && (isspace(*pos) || *pos == '\'') ) { goodPlace = true; break; } else if ( *pos == '\n' || *pos == '"' ) { // no suitable space found break; } } // Prevent insertion of more than one '\n' if (pos > m_Buffer && *(pos-1) == '\n') { goodPlace = false; } if ( !goodPlace ) { // no suitable space found if ( linePos < lineLength ) { pos += lineLength - linePos; linePos = lineLength; } // assure we will not break double "" while ( pos > m_Buffer && *(pos - 1) == '"' ) { --pos; --linePos; } if ( pos == m_Buffer ) { // it's possible that we already put some " before... while ( pos < m_CurrentPos && *pos == '"' ) { ++pos; ++linePos; } } } // split there // insert '\n' size_t count = m_CurrentPos - pos; memmove(pos + 1, pos, count); m_LineLength = count; ++m_CurrentPos; *pos = '\n'; ++m_Line;}void COStreamBuffer::Write(const char* data, size_t dataLength) THROWS1((CIOException, bad_alloc)){ while ( dataLength > 0 ) { size_t available = GetAvailableSpace(); if ( available == 0 ) { FlushBuffer(false); available = GetAvailableSpace(); } if ( available >= dataLength ) break; // current chunk will fit in buffer memcpy(m_CurrentPos, data, available); m_CurrentPos += available; data += available; dataLength -= available; } memcpy(m_CurrentPos, data, dataLength); m_CurrentPos += dataLength;}void COStreamBuffer::Write(CByteSourceReader& reader) THROWS1((CIOException, bad_alloc)){ for ( ;; ) { size_t available = GetAvailableSpace(); if ( available == 0 ) { FlushBuffer(false); available = GetAvailableSpace(); } size_t count = reader.Read(m_CurrentPos, available); if ( count == 0 ) { if ( reader.EndOfData() ) return; else// THROW1_TRACE(CIOException, "buffer read fault"); NCBI_THROW(CIOException,eRead,"buffer read fault"); } m_CurrentPos += count; }}END_NCBI_SCOPE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -