BEGIN_NCBI_SCOPE CConn_IOStream::CConn_IOStream(const TConn_Pair& connpair, const STimeout* timeout, size_t buf_size, TConn_Flags flags, CT_CHAR_TYPE* ptr, size_t size) : CNcbiIostream(0), m_CSb(0) { auto_ptr<CConn_Streambuf> csb(new CConn_Streambuf(connpair.first, connpair.second, timeout, buf_size, flags, ptr, size)); CONN conn = csb->GetCONN(); if (conn) { SOCK s/*dummy*/; // CONN_Write(0 bytes) could have caused the same effect as GetSOCK (void) CONN_GetSOCK(conn, &s); // Prompt CONN to actually open if (CONN_Status(conn, eIO_Open) == eIO_Success) { init(csb.get()); m_CSb = csb.release(); return; } } init(0); // according to the standard (27.4.4.1.3), badbit is set here }
EIO_Status CConn_Streambuf::x_Close(bool close) { if (!m_Conn) return close ? eIO_Closed : eIO_Success; EIO_Status status; // flush only if some data pending if (pbase() < pptr()) { if ((status = CONN_Status(m_Conn, eIO_Write)) != eIO_Success) { m_Status = status; if (CONN_Status(m_Conn, eIO_Open) == eIO_Success) { _TRACE(x_Message("Close(): Cannot finalize implicitly" ", data loss may result")); } } else if (sync() != 0) status = m_Status != eIO_Success ? m_Status : eIO_Unknown; } else status = eIO_Success; setg(0, 0, 0); setp(0, 0); CONN c = m_Conn; m_Conn = 0; // NB: no re-entry if (close) { // here: not called from the close callback x_OnClose if (m_CbValid) { SCONN_Callback cb; CONN_SetCallback(c, eCONN_OnClose, &m_Cb, &cb); if ((void*) cb.func != (void*) x_OnClose || cb.data != this) CONN_SetCallback(c, eCONN_OnClose, &cb, 0); } if (m_Close && (m_Status = CONN_Close(c)) != eIO_Success) { _TRACE(x_Message("Close(): CONN_Close() failed")); if (status == eIO_Success) status = m_Status; } } else if (m_CbValid && m_Cb.func) { EIO_Status cbstat = m_Cb.func(c, eCONN_OnClose, m_Cb.data); if (cbstat != eIO_Success) status = cbstat; } return status; }
EIO_Status CConn_Streambuf::Status(EIO_Event direction) const { return direction == eIO_Close ? m_Status : m_Conn ? CONN_Status(m_Conn, direction) : eIO_Closed; }