static gboolean
gst_curl_base_sink_event (GstBaseSink * bsink, GstEvent * event)
{
  GstCurlBaseSink *sink = GST_CURL_BASE_SINK (bsink);
  GstCurlBaseSinkClass *klass = GST_CURL_BASE_SINK_GET_CLASS (sink);

  switch (event->type) {
    case GST_EVENT_EOS:
      GST_DEBUG_OBJECT (sink, "received EOS");
      gst_curl_base_sink_transfer_thread_close (sink);
      gst_curl_base_sink_wait_for_response (sink);
      break;
    case GST_EVENT_CAPS:
      if (klass->set_mime_type) {
        GstCaps *caps;
        gst_event_parse_caps (event, &caps);
        klass->set_mime_type (sink, caps);
      }
      break;
    default:
      break;
  }

  return GST_BASE_SINK_CLASS (parent_class)->event (bsink, event);
}
static gboolean
gst_curl_base_sink_stop (GstBaseSink * bsink)
{
  GstCurlBaseSink *sink = GST_CURL_BASE_SINK (bsink);

  gst_curl_base_sink_transfer_thread_close (sink);
  if (sink->fdset != NULL) {
    gst_poll_free (sink->fdset);
    sink->fdset = NULL;
  }

  return TRUE;
}
static gboolean
gst_curl_smtp_sink_event (GstBaseSink * bsink, GstEvent * event)
{
  GstCurlBaseSink *bcsink = GST_CURL_BASE_SINK (bsink);
  GstCurlSmtpSink *sink = GST_CURL_SMTP_SINK (bsink);

  switch (event->type) {
    case GST_EVENT_EOS:
      GST_DEBUG_OBJECT (sink, "received EOS");
      gst_curl_base_sink_set_live (bcsink, FALSE);

      GST_OBJECT_LOCK (sink);
      sink->eos = TRUE;
      GST_OBJECT_UNLOCK (sink);

      if (sink->base64_chunk != NULL)
        add_final_boundary_unlocked (sink);

      gst_curl_base_sink_transfer_thread_notify_unlocked (bcsink);

      GST_OBJECT_LOCK (sink);
      if (sink->base64_chunk != NULL && bcsink->flow_ret == GST_FLOW_OK) {
        gst_curl_smtp_sink_wait_for_transfer_end_unlocked (sink);
      }
      GST_OBJECT_UNLOCK (sink);

      gst_curl_base_sink_transfer_thread_close (bcsink);

      break;

    default:
      break;
  }

  return GST_BASE_SINK_CLASS (parent_class)->event (bsink, event);
}
static gboolean
gst_curl_smtp_sink_event (GstBaseSink * bsink, GstEvent * event)
{
  GstCurlBaseSink *bcsink = GST_CURL_BASE_SINK (bsink);
  GstCurlSmtpSink *sink = GST_CURL_SMTP_SINK (bsink);

  GByteArray *array;
  gchar *boundary_end;

  switch (event->type) {
    case GST_EVENT_EOS:
      GST_DEBUG_OBJECT (sink, "received EOS");
      gst_curl_base_sink_set_live (bcsink, FALSE);

      GST_OBJECT_LOCK (sink);
      sink->eos = TRUE;
      GST_OBJECT_UNLOCK (sink);

      if (sink->base64_chunk != NULL) {
        gsize len;
        gint save, state;
        gchar *data_out;

        array = sink->base64_chunk->chunk_array;
        g_assert (array);

        GST_DEBUG ("adding final boundary");

        /* it will need up to 5 bytes if line-breaking is enabled
         * additional byte is needed for <CR> as it is not automatically added by glib */
        data_out = g_malloc (6);
        save = sink->base64_chunk->save;
        state = sink->base64_chunk->state;
        len = g_base64_encode_close (TRUE, data_out, &state, &save);
        /* workaround */
        data_out[len - 1] = '\r';
        data_out[len] = '\n';
        /* +1 for CR */
        g_byte_array_append (array, (guint8 *) data_out, (guint) (len + 1));
        g_free (data_out);

        boundary_end = g_strdup_printf ("\r\n%s\r\n", BOUNDARY_STRING_END);
        g_byte_array_append (array, (guint8 *) boundary_end,
            strlen (boundary_end));
        g_free (boundary_end);
      }

      gst_curl_base_sink_transfer_thread_notify_unlocked (bcsink);

      GST_OBJECT_LOCK (sink);
      if (sink->base64_chunk != NULL && bcsink->flow_ret == GST_FLOW_OK) {
        gst_curl_smtp_sink_wait_for_transfer_end_unlocked (sink);
      }
      GST_OBJECT_UNLOCK (sink);

      gst_curl_base_sink_transfer_thread_close (bcsink);

      break;

    default:
      break;
  }

  return GST_BASE_SINK_CLASS (parent_class)->event (bsink, event);
}