/*
Binary_log_event* Binary_log_driver::parse_event(boost::asio::streambuf
                                                 &sbuff, Log_event_header
                                                 *header)
                                                 */
Binary_log_event* Binary_log_driver::parse_event(std::istream &is,
                                                 Log_event_header *header)
{
  Binary_log_event *parsed_event= 0;

  switch (header->type_code) {
    case TABLE_MAP_EVENT:
      parsed_event= proto_table_map_event(is, header);
      break;
    case QUERY_EVENT:
      parsed_event= proto_query_event(is, header);
      break;
    case INCIDENT_EVENT:
      parsed_event= proto_incident_event(is, header);
      break;
    case WRITE_ROWS_EVENT:
    case UPDATE_ROWS_EVENT:
    case DELETE_ROWS_EVENT:
    case WRITE_ROWS_EVENTv2:
    case UPDATE_ROWS_EVENTv2:
    case DELETE_ROWS_EVENTv2:
      parsed_event= proto_rows_event(is, header, m_format_desc_event);
      break;
    case ROTATE_EVENT:
      {
        Rotate_event *rot= proto_rotate_event(is, header);
        m_binlog_file_name= rot->binlog_file;
        m_binlog_offset= (unsigned long)rot->binlog_pos;
        parsed_event= rot;
      }
      break;
    case INTVAR_EVENT:
      parsed_event= proto_intvar_event(is, header);
      break;
    case USER_VAR_EVENT:
      parsed_event= proto_uservar_event(is, header);
      break;
    case FORMAT_DESCRIPTION_EVENT:
      parsed_event = proto_desc_event(is, header);
      break;
    case ROWS_QUERY_EVENT:
      parsed_event = proto_rows_query_event(is, header);
      break;
    default:
      {
        // Create a dummy driver.
        parsed_event= new Binary_log_event(header);
      }
  }

  return parsed_event;
}
/*
Binary_log_event* Binary_log_driver::parse_event(boost::asio::streambuf
                                                 &sbuff, Log_event_header
                                                 *header)
                                                 */
Binary_log_event* Binary_log_driver::parse_event(std::istream &is,
                                                 Log_event_header *header)
{
  Binary_log_event *parsed_event= 0;

  boost::uint32_t event_length= header->event_length;

  if (m_checksum_alg == BINLOG_CHECKSUM_ALG_CRC32) {
    event_length -= CHECKSUM_CRC32_SIGNATURE_LEN;
  }

  switch (header->type_code) {
    case TABLE_MAP_EVENT:
      parsed_event= proto_table_map_event(is, header, event_length);
      break;
    case QUERY_EVENT:
      parsed_event= proto_query_event(is, header, event_length);
      break;
    case INCIDENT_EVENT:
      parsed_event= proto_incident_event(is, header, event_length);
      break;
    case WRITE_ROWS_EVENT:
    case UPDATE_ROWS_EVENT:
    case DELETE_ROWS_EVENT:
      parsed_event= proto_rows_event(is, header, event_length);
      break;
    case ROTATE_EVENT:
      {
        Rotate_event *rot= proto_rotate_event(is, header, event_length);
        m_binlog_file_name= rot->binlog_file;
        m_binlog_offset= (unsigned long)rot->binlog_pos;
        parsed_event= rot;
      }
      break;
    case INTVAR_EVENT:
      parsed_event= proto_intvar_event(is, header, event_length);
      break;
    case USER_VAR_EVENT:
      parsed_event= proto_uservar_event(is, header, event_length);
      break;
    case FORMAT_DESCRIPTION_EVENT:
      {
        std::string buf;
        // The length of the payload is unknown until we get the common header
        // length which is stored in the stream itself.  So, read the stream to
        // the location where the common header length is stored.
        boost::uint32_t len = ST_COMMON_HEADER_LEN_OFFSET + 1;
        for (int i=0; i< len; i++)
        {
          char ch;
          is.get(ch);
          buf.push_back(ch);
          if (i == ST_COMMON_HEADER_LEN_OFFSET) {
            int common_header_len = ch;
            // Now we know the correct payload size.  update the length.
            len = header->event_length - common_header_len;
          }
        }
        is.seekg(-len, is.cur);
        m_checksum_alg= get_checksum_alg(buf.data(), len);
        parsed_event= new Binary_log_event(header);
      }
      break;
    default:
      {
        // Create a dummy driver.
        parsed_event= new Binary_log_event(header);
      }
  }

  return parsed_event;
}