예제 #1
0
 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;
}
예제 #4
0
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;
}
예제 #5
0
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;
}
예제 #7
0
/** 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;
}