void decode(thinger_message& message, size_t size){ size_t start_read = bytes_read(); while(size-(bytes_read()-start_read)>0) { protoson::pb_wire_type wire_type; uint32_t field_number; pb_decode_tag(wire_type, field_number); switch (wire_type) { case protoson::length_delimited:{ uint32_t size = pb_decode_varint32(); pb_skip(size); } break; case protoson::varint: { switch (field_number) { case thinger_message::SIGNAL_FLAG: message.set_signal_flag((thinger_message::signal_flag)pb_decode_varint32()); break; case thinger_message::STREAM_ID: message.set_stream_id(pb_decode_varint32()); break; default: pb_skip_varint(); break; } break; } case protoson::pson_type: switch(field_number){ case thinger_message::RESOURCE: protoson::pson_decoder::decode(message.get_resources()); break; case thinger_message::PSON_PAYLOAD: protoson::pson_decoder::decode(((protoson::pson&) message)); break; default: break; } break; case protoson::fixed_32: pb_skip(4); break; case protoson::fixed_64: pb_skip(8); break; default: break; } } }
vpr::Uint32 SocketDatagramImplBSD::recvfrom(void* msg, const vpr::Uint32 length, vpr::InetAddr& from, const vpr::Interval& timeout) { vpr::Uint32 bytes_read(0); #if defined(VPR_OS_IRIX) || defined(VPR_OS_HPUX) int fromlen; #else socklen_t fromlen; #endif // If not readable within timeout interval throw exception. if ( ! mHandle->isReadable(timeout) ) { std::ostringstream msg_stream; msg_stream << "Timeout occured while trying to read from " << mHandle->getName(); throw TimeoutException(msg_stream.str(), VPR_LOCATION); } ssize_t bytes; mBlockingFixed = true; fromlen = from.size(); bytes = ::recvfrom(mHandle->mFdesc, msg, length, 0, reinterpret_cast<sockaddr*>(&from.mAddr), &fromlen); if ( bytes == -1 ) { if ( errno == EAGAIN && ! isBlocking() ) { throw WouldBlockException("Would block while reading.", VPR_LOCATION); } else { std::ostringstream ss; ss << "[vpr::SocketDatagramImplBSD::recvfrom()] ERROR: Could not " << "read from socket (" << mRemoteAddr << "): " << strerror(errno); throw SocketException(ss.str(), VPR_LOCATION); } } else if ( bytes == 0 ) { throw SocketException("Socket not connected."); } else { bytes_read = bytes; } return bytes_read; }
// Read the specified number of bytes from the file handle into the given // bufer. vpr::Uint32 FileHandleImplUNIX::read_i(void* buffer, const vpr::Uint32 length, const vpr::Interval& timeout) { vpr::Uint32 bytes_read(0); // If not readable within timeout interval throw exception. if ( ! isReadable(timeout) ) { std::ostringstream msg_stream; msg_stream << "Timeout occured while trying to read from " << mName; throw TimeoutException(msg_stream.str(), VPR_LOCATION); } const ssize_t bytes = ::read(mFdesc, buffer, length); // Error: Something went wrong while attempting to read from the file. if ( bytes < 0 ) { if ( errno == EAGAIN && ! mBlocking ) { throw WouldBlockException("Would block while reading.", VPR_LOCATION); } else // "real" error, so throw IO Exception { std::ostringstream msg_stream; msg_stream << "Error reading from " << mName << ":" << strerror(errno); throw IOException(msg_stream.str(), VPR_LOCATION); } } // If 0 bytes were read and an error was returned, we throw. // Note: If bytes == 0 and no error (and socket) then that means the other // side shut down cleanly. else if ( 0 == bytes && 0 != errno ) { vprDEBUG(vprDBG_ERROR, vprDBG_WARNING_LVL) << "[vpr::FileHandleImplUNIX::read_i()] Nothing read from " << mName << ": " << strerror(errno) << std::endl << vprDEBUG_FLUSH; // XXX: Failure status may not be exactly what we want to return. std::ostringstream msg_stream; msg_stream << "Nothing read from " << mName << ": " << strerror(errno); throw IOException(msg_stream.str(), VPR_LOCATION); } else { bytes_read = bytes; } return bytes_read; }
bool clIndexerProtocol::ReadReply(clNamedPipe* conn, clIndexerReply& reply) { // first we read sizeof(size_t) to get the actual data size size_t buff_len(0); size_t actual_read(0); if ( !conn->read((void*)&buff_len, sizeof(buff_len), &actual_read, 10000) ) { fprintf(stderr, "ERROR: ReadReply: Failed to read from the pipe, reason: %d\n", conn->getLastError()); return false; } if (actual_read != sizeof(buff_len)) { fprintf(stderr, "ERROR: ReadReply: Protocol error: expected %lu bytes, got %u. reason: %d\n", sizeof(buff_len), (unsigned int)actual_read, conn->getLastError()); return false; } if ((buff_len / (1024*1024)) > 15) { // Dont read buffers larger than 15MB... return false; } char *data = new char[buff_len]; CharDeleter deleter(data); int bytes_left(buff_len); size_t bytes_read(0); while (bytes_left > 0) { if ( !conn->read(data+bytes_read, bytes_left, &actual_read, 10000) ) { fprintf(stderr, "ERROR: Protocol error: expected %u bytes, got %u\n", (unsigned int)buff_len, (unsigned int)actual_read); return false; } bytes_left -= actual_read; bytes_read += actual_read; } reply.fromBinary(data); return true; }
bool clIndexerProtocol::ReadRequest(clNamedPipe* conn, clIndexerRequest& req) { // first we read sizeof(size_t) to get the actual data size size_t buff_len(0); size_t actual_read(0); if ( !conn->read((void*)&buff_len, sizeof(buff_len), &actual_read, -1) ) { fprintf(stderr, "ERROR: Failed to read from the pipe, reason: %d\n", conn->getLastError()); return false; } if (actual_read != sizeof(buff_len)) { fprintf(stderr, "ERROR: Protocol error: expected %lu bytes, got %u\n", sizeof(buff_len), (unsigned int)actual_read); return false; } if(buff_len == 0) return false; char *data = new char[buff_len]; CharDeleter deleter(data); int bytes_left(buff_len); size_t bytes_read(0); while (bytes_left > 0) { if ( !conn->read(data+bytes_read, bytes_left, &actual_read, -1) ) { fprintf(stderr, "ERROR: [%s] Protocol error: expected %u bytes, got %u\n", __PRETTY_FUNCTION__, (unsigned int)buff_len, (unsigned int)actual_read); return false; } bytes_left -= actual_read; bytes_read += actual_read; } req.fromBinary(data); return true; }
// Read exactly the specified number of bytes from the file handle into the // given buffer. This is based on the readn() function given on pages 51-2 of // _Effective TCP/IP Programming_ by Jon D. Snader. vpr::Uint32 FileHandleImplUNIX::readn_i(void* buffer, const vpr::Uint32 buffer_size, const vpr::Interval& timeout) { if ( vpr::Interval::NoTimeout != timeout ) { vprDEBUG(vprDBG_ALL,vprDBG_WARNING_LVL) << "Timeout not supported\n" << vprDEBUG_FLUSH; //TODO: InvalidArgumentException instead, but this will require // adding it as an acceptable exception to throw. throw IOException("Timeout not supported by readn.", VPR_LOCATION); } vpr::Uint32 bytes_read(0); size_t bytes_left = buffer_size; while ( bytes_left > 0 ) { vprDEBUG(vprDBG_ALL, vprDBG_HVERB_LVL) << "[vpr::FileHandleImplUNIX::readn_i()] Reading " << bytes_left << " bytes from file handle " << mFdesc << std::endl << vprDEBUG_FLUSH; const ssize_t bytes = ::read(mFdesc, buffer, bytes_left); vprDEBUG_NEXT(vprDBG_ALL, vprDBG_HVERB_LVL) << "Read " << bytes << " bytes from file handle " << mFdesc << std::endl << vprDEBUG_FLUSH; // Read error. if ( bytes < 0 ) { // Restart the read process if we were interrupted by the OS. if ( EINTR == errno ) { continue; } // Restart the read process if socket is non-blocking and no // data was immediately available. else if ( EAGAIN == errno ) { continue; } // Otherwise, we have an error situation, so return failure status. else { std::ostringstream msg_stream; msg_stream << "Error reading from " << mName << ": " << strerror(errno); throw IOException(msg_stream.str(), VPR_LOCATION); } } // We have read EOF, so there is nothing more to read. At this point, // bytes_read contains an accurate count of the bytes read so far // (posisbly less than buffer_size). else if ( bytes == 0 ) { vprDEBUG(vprDBG_ALL, vprDBG_HVERB_LVL) << "[vpr::FileHandleImplUNIX::readn_i()] Read EOF with " << bytes_left << " bytes left to read from file handle " << mFdesc << " and " << bytes_read << " bytes read in total." << std::endl << vprDEBUG_FLUSH; std::ostringstream ss; ss << "Read EOF with " << bytes_left << " bytes left to read from file handle " << mFdesc << " and " << bytes_read << " bytes read in total."; throw EOFException(ss.str(), VPR_LOCATION); } else { buffer = (void*) ((char*) buffer + bytes); bytes_left -= bytes; bytes_read += bytes; } } return bytes_read; }
/** Find an arbitrary number of delimited strings at the end of a file. This * function provides the core of our last-lines-loader implementation. * * @param fd File descriptor to operate on. This must be opened for reading. * * @param bytes Delimiter sequence. * * @param bytes_length Number of significant bytes in @p bytes. * * @param count Number of tail sequences to find. * * @param out Destination string array. */ static inline size_t find_tail_sequences(int fd, const char* bytes, size_t bytes_length, size_t count, wxArrayString& out) { size_t count_added ( 0 ); /* We overlap the file reads a little to avoid splitting (and thus missing) the delimiter sequence. */ const size_t read_overlap ( bytes_length - 1 ); const size_t read_size ( BUFSIZ ); const off_t log_length ( lseek(fd, 0, SEEK_END) ); bool have_last_pos ( false ); char buf[read_size]; off_t last_found_pos ( 0 ); off_t last_read_position ( log_length + read_overlap ); /* We read `read_size'-byte blocks of the file, starting at the end and working backwards. */ while ( count_added < count && last_read_position > 0 ) { off_t read_position ( next_read_position(last_read_position, read_size, read_overlap) ); size_t bytes_read ( pread(fd, buf, std::min(static_cast<off_t>(read_size), last_read_position - read_position), read_position) ); /* In each block, we search for `bytes', starting at the end. */ for ( ssize_t i = bytes_read - read_overlap - 1; i >= 0; i-- ) { if ( !strncmp((buf + i), bytes, bytes_length) ) { off_t this_found_pos ( read_position + i ); if ( have_last_pos && count_added < count ) { size_t line_length ( last_found_pos - this_found_pos - bytes_length ); if ( line_length > 0 ) { char* source ( NULL ); if ( last_found_pos >= read_position + (off_t) bytes_read ) { source = new char[ line_length + 1]; memset(source, 0, line_length + 1); if ( pread(fd, source, line_length, this_found_pos + bytes_length) < (ssize_t) line_length ) { wxLogWarning(_T("ChatLog::find_tail_sequences: Read-byte count less than expected")); } } else { source = buf + i + bytes_length; } if ( strncmp(source, "##", 2) != 0 ) { out.Insert(wxString(L'\0', 0), 0); wxLogMessage(_T("ChatLog::find_tail_sequences: fetching write buffer for %lu bytes"), sizeof(wxChar) * (line_length + 1)); #if !defined(HAVE_WX28) || defined(SL_QT_MODE) wxStringBufferLength outzero_buf(out[0], sizeof(wxChar) * (line_length + 1)); wxConvUTF8.ToWChar(outzero_buf, line_length, source); outzero_buf.SetLength(line_length); #else wxConvUTF8.MB2WC(out[0].GetWriteBuf(sizeof(wxChar) * (line_length + 1)), source, line_length); out[0].UngetWriteBuf(line_length); #endif ++count_added; } if ( last_found_pos >= read_position + (off_t) bytes_read ) delete[] source; if ( count_added >= count ) i = -1; /* short-circuit the `for' loop. */ } } last_found_pos = this_found_pos; have_last_pos = true; i -= bytes_length - 1; } } last_read_position = read_position; } return count_added; }