Ejemplo n.º 1
0
static int
MimeMultipartAlternative_create_child(MimeObject *obj)
{
  MimeMultipart *mult = (MimeMultipart *) obj;
  MimeMultipartAlternative *malt = (MimeMultipartAlternative *) obj;

  bool displayable =
    MimeMultipartAlternative_display_part_p (obj, mult->hdrs);

  MimeMultipartAlternative_flush_children(obj, false, displayable);
  
  mult->state = MimeMultipartPartFirstLine;
  int32_t i = malt->pending_parts++;
  if (malt->pending_parts > malt->max_parts) {
    malt->max_parts = malt->pending_parts;
    malt->buffered_hdrs = (MimeHeaders **)
      PR_REALLOC(malt->buffered_hdrs, malt->max_parts *
                 sizeof *malt->buffered_hdrs);
    if (! malt->buffered_hdrs)
      return MIME_OUT_OF_MEMORY;
    malt->part_buffers = (MimePartBufferData **)
      PR_REALLOC(malt->part_buffers, malt->max_parts *
                 sizeof *malt->part_buffers);
    if (! malt->part_buffers)
      return MIME_OUT_OF_MEMORY;
  }
  
  malt->buffered_hdrs[i] = MimeHeaders_copy(mult->hdrs);
  if (!malt->buffered_hdrs[i])
    return MIME_OUT_OF_MEMORY;
  malt->part_buffers[i] = MimePartBufferCreate();
  if (!malt->part_buffers[i])
    return MIME_OUT_OF_MEMORY;
  return 0;
}
Ejemplo n.º 2
0
static int
MimeMultipartAlternative_flush_children(MimeObject *obj,
                                        bool finished,
                                        bool next_is_displayable)
{
  /*
    Possible states:

    1. Cache contains nothing: do nothing.

    2. Finished, and the cache contains one displayable body followed
       by zero or more non-displayable bodies:

    3. Finished, and the cache contains one non-displayable body:
       create it with output off.

    4. Not finished, and the cache contains one displayable body
       followed by zero or more non-displayable bodies, and the new
       body we're about to create is displayable: create all cached
       bodies with output off.

    5. Not finished, and the cache contains one displayable body
       followed by zero or more non-displayable bodies, and the new
       body we're about to create is non-displayable: do nothing.

    6. Not finished, and the cache contains one non-displayable body:
       create it with output off.
  */
  MimeMultipartAlternative *malt = (MimeMultipartAlternative *) obj;
  bool have_displayable, do_flush, do_display;

  /* Case 1 */
  if (! malt->pending_parts)
    return 0;

  have_displayable =
    MimeMultipartAlternative_display_part_p(obj, malt->buffered_hdrs[0]);
  
  if (finished && have_displayable) {
    /* Case 2 */
    do_flush = true;
    do_display = true;
  }
  else if (finished && ! have_displayable) {
    /* Case 3 */
    do_flush = true;
    do_display = false;
  }
  else if (! finished && have_displayable && next_is_displayable) {
    /* Case 4 */
    do_flush = true;
    do_display = false;
  }
  else if (! finished && have_displayable && ! next_is_displayable) {
    /* Case 5 */
    do_flush = false;
    do_display = false;
  }
  else if (! finished && ! have_displayable) {
    /* Case 6 */
    do_flush = true;
    do_display = false;
  }
  else {
    NS_ERROR("mimemalt.cpp: logic error in flush_children");
    return -1;
  }
  
  if (do_flush) {
    int32_t i;
    for (i = 0; i < malt->pending_parts; i++) {
      MimeMultipartAlternative_display_cached_part(obj,
                                                   malt->buffered_hdrs[i],
                                                   malt->part_buffers[i],
                                                   do_display && (i == 0));
      MimeHeaders_free(malt->buffered_hdrs[i]);
      MimePartBufferDestroy(malt->part_buffers[i]);
    }
    malt->pending_parts = 0;
  }
  return 0;
}