void SNetStorageObjectRPC::Close() { if (m_State == eReady) return; CNetServerConnection conn_copy(m_Connection); m_Connection = NULL; if (m_State == eReading) { m_State = eReady; if (!m_EOF) { m_UTTPReader.Reset(); conn_copy->Close(); } } else { /* m_State == eWriting */ m_State = eReady; CSocket& sock = conn_copy->m_Socket; s_SendEndOfData(sock); CReadJsonFromSocket message_reader; s_TrapErrors(m_OriginalRequest, message_reader.ReadMessage(sock), sock, m_NetStorageRPC->m_Config.err_mode); } }
void SNetStorageObjectRPC::ReadConfirmation() { CSocket& sock = m_Connection->m_Socket; CJsonOverUTTPReader json_reader; try { size_t bytes_read; while (!json_reader.ReadMessage(m_UTTPReader)) { s_ReadSocket(sock, m_ReadBuffer, READ_BUFFER_SIZE, &bytes_read); m_UTTPReader.SetNewBuffer(m_ReadBuffer, bytes_read); } if (m_UTTPReader.GetNextEvent() != CUTTPReader::eEndOfBuffer) { NCBI_THROW_FMT(CNetStorageException, eIOError, "Extra bytes past confirmation message " "while reading " << m_Locator << " from " << sock.GetPeerAddress() << '.'); } } catch (...) { m_UTTPReader.Reset(); m_Connection->Close(); throw; } s_TrapErrors(m_OriginalRequest, json_reader.GetMessage(), sock, m_NetStorageRPC->m_Config.err_mode); }
ERW_Result SNetStorageObjectRPC::Read(void* buffer, size_t buf_size, size_t* bytes_read) { if (m_State == eWriting) { NCBI_THROW_FMT(CNetStorageException, eInvalidArg, "Cannot read a NetStorage file while writing to it"); } size_t bytes_read_local; if (m_State == eReady) { m_OriginalRequest = x_MkRequest("READ"); if (m_ReadBuffer == NULL) m_ReadBuffer = new char[READ_BUFFER_SIZE]; CNetServer server(*m_OwnService.Iterate(CNetService::eRandomize)); CJsonOverUTTPExecHandler json_over_uttp_sender(m_OriginalRequest); server->TryExec(json_over_uttp_sender); CSocket& sock = json_over_uttp_sender.GetConnection()->m_Socket; CJsonOverUTTPReader json_reader; try { do { s_ReadSocket(sock, m_ReadBuffer, READ_BUFFER_SIZE, &bytes_read_local); m_UTTPReader.SetNewBuffer(m_ReadBuffer, bytes_read_local); } while (!json_reader.ReadMessage(m_UTTPReader)); } catch (...) { m_UTTPReader.Reset(); sock.Close(); throw; } s_TrapErrors(m_OriginalRequest, json_reader.GetMessage(), sock, m_NetStorageRPC->m_Config.err_mode); m_Connection = json_over_uttp_sender.GetConnection(); m_CurrentChunkSize = 0; m_State = eReading; m_EOF = false; } char* buf_pos = reinterpret_cast<char*>(buffer); if (m_CurrentChunkSize >= buf_size) { if (buf_size > 0) { memcpy(buf_pos, m_CurrentChunk, buf_size); m_CurrentChunk += buf_size; m_CurrentChunkSize -= buf_size; } if (bytes_read != NULL) *bytes_read = buf_size; return eRW_Success; } if (m_CurrentChunkSize > 0) { memcpy(buf_pos, m_CurrentChunk, m_CurrentChunkSize); buf_pos += m_CurrentChunkSize; buf_size -= m_CurrentChunkSize; } size_t bytes_copied = m_CurrentChunkSize; m_CurrentChunkSize = 0; if (m_EOF) { if (bytes_read != NULL) *bytes_read = bytes_copied; return bytes_copied ? eRW_Success : eRW_Eof; } try { while (buf_size > 0) { switch (m_UTTPReader.GetNextEvent()) { case CUTTPReader::eChunkPart: case CUTTPReader::eChunk: m_CurrentChunk = m_UTTPReader.GetChunkPart(); m_CurrentChunkSize = m_UTTPReader.GetChunkPartSize(); if (m_CurrentChunkSize >= buf_size) { memcpy(buf_pos, m_CurrentChunk, buf_size); m_CurrentChunk += buf_size; m_CurrentChunkSize -= buf_size; if (bytes_read != NULL) *bytes_read = bytes_copied + buf_size; return eRW_Success; } memcpy(buf_pos, m_CurrentChunk, m_CurrentChunkSize); buf_pos += m_CurrentChunkSize; buf_size -= m_CurrentChunkSize; bytes_copied += m_CurrentChunkSize; m_CurrentChunkSize = 0; break; case CUTTPReader::eControlSymbol: if (m_UTTPReader.GetControlSymbol() != END_OF_DATA_MARKER) { NCBI_THROW_FMT(CNetStorageException, eIOError, "NetStorage API: invalid end-of-data-stream " "terminator: " << (int) m_UTTPReader.GetControlSymbol()); } m_EOF = true; ReadConfirmation(); if (bytes_read != NULL) *bytes_read = bytes_copied; return bytes_copied ? eRW_Success : eRW_Eof; case CUTTPReader::eEndOfBuffer: s_ReadSocket(m_Connection->m_Socket, m_ReadBuffer, READ_BUFFER_SIZE, &bytes_read_local); m_UTTPReader.SetNewBuffer(m_ReadBuffer, bytes_read_local); break; default: NCBI_THROW_FMT(CNetStorageException, eIOError, "NetStorage API: invalid UTTP status " "while reading " << m_Locator); } } if (bytes_read != NULL) *bytes_read = bytes_copied; return eRW_Success; } catch (...) { m_State = eReady; m_UTTPReader.Reset(); m_Connection->Close(); m_Connection = NULL; throw; } }