Ejemplo n.º 1
0
long
fish_sound_comments_encode (FishSound * fsound, unsigned char * buf,
			    long length)
{
  char * c = (char *)buf;
  const FishSoundComment * comment;
  int nb_fields = 0, vendor_length = 0;
  unsigned long actual_length = 0, remaining = length, field_length;

  /* Vendor string */
  if (fsound->vendor)
    vendor_length = fs_comment_len (fsound->vendor);
  if (accum_length (&actual_length, 4 + vendor_length) == 0)
    return 0;

  /* user comment list length */
  if (accum_length (&actual_length, 4) == 0)
    return 0;

  for (comment = fish_sound_comment_first (fsound); comment;
       comment = fish_sound_comment_next (fsound, comment)) {
    /* [size]"name" */
    if (accum_length (&actual_length, 4 + fs_comment_len (comment->name)) == 0)
      return 0;
    if (comment->value) {
      /* "=value" */
      if (accum_length (&actual_length, 1 + fs_comment_len (comment->value)) == 0)
        return 0;
    }

    debug_printf (1, "%s = %s", comment->name, comment->value);

    nb_fields++;
  }

  /* framing bit */
  if (accum_length (&actual_length, 1) == 0)
    return 0;

  /* NB. actual_length is not modified from here onwards */

  if (buf == NULL) return actual_length;

  remaining -= 4;
  if (remaining <= 0) return actual_length;
  writeint (c, 0, vendor_length);
  c += 4;

  if (fsound->vendor) {
    field_length = fs_comment_len (fsound->vendor);
    memcpy (c, fsound->vendor, MIN (field_length, remaining));
    c += field_length; remaining -= field_length;
    if (remaining <= 0) return actual_length;
  }

  remaining -= 4;
  if (remaining <= 0) return actual_length;
  writeint (c, 0, nb_fields);
  c += 4;

  for (comment = fish_sound_comment_first (fsound); comment;
       comment = fish_sound_comment_next (fsound, comment)) {

    field_length = fs_comment_len (comment->name);     /* [size]"name" */
    if (comment->value)
      field_length += 1 + fs_comment_len (comment->value); /* "=value" */

    remaining -= 4;
    if (remaining <= 0) return actual_length;
    writeint (c, 0, field_length);
    c += 4;

    field_length = fs_comment_len (comment->name);
    memcpy (c, comment->name, MIN (field_length, remaining));
    c += field_length; remaining -= field_length;
    if (remaining <= 0) return actual_length;

    if (comment->value) {
      remaining --;
      if (remaining <= 0) return actual_length;
      *c = '=';
      c++;

      field_length = fs_comment_len (comment->value);
      memcpy (c, comment->value, MIN (field_length, remaining));
      c += field_length; remaining -= field_length;
      if (remaining <= 0) return actual_length;
    }
  }

  if (remaining <= 0) return actual_length;
  *c = 0x01;

  return actual_length;
}
long
oggz_comments_encode (OGGZ * oggz, long serialno,
                      unsigned char * buf, long length)
{
  oggz_stream_t * stream;
  char * c = (char *)buf;
  const OggzComment * comment;
  int nb_fields = 0, vendor_length = 0;
  unsigned long actual_length = 0, remaining = length, field_length;

  /* Deal with sign of length first */
  if (length < 0) return 0;

  stream = oggz_get_stream (oggz, serialno);
  if (stream == NULL) return OGGZ_ERR_BAD_SERIALNO;

  /* Vendor string */
  if (stream->vendor)
    vendor_length = oggz_comment_len (stream->vendor);
  if (accum_length (&actual_length, 4 + vendor_length) == 0)
    return 0;
#ifdef DEBUG
  printf ("oggz_comments_encode: vendor = %s\n", stream->vendor);
#endif

  /* user comment list length */
  if (accum_length (&actual_length, 4) == 0)
    return 0;


  for (comment = oggz_comment_first (oggz, serialno); comment;
       comment = oggz_comment_next (oggz, serialno, comment)) {
    /* [size]"name" */
    if (accum_length (&actual_length, 4 + oggz_comment_len (comment->name)) == 0)
      return 0;
    if (comment->value) {
      /* "=value" */
      if (accum_length (&actual_length, 1 + oggz_comment_len (comment->value)) == 0)
        return 0;
    }

#ifdef DEBUG
    printf ("oggz_comments_encode: %s = %s\n",
	    comment->name, comment->value);
#endif

    nb_fields++;
  }

  /* framing bit */
  if (accum_length (&actual_length, 1) == 0)
    return 0;

  /* NB. actual_length is not modified from here onwards */

  if (buf == NULL) return actual_length;

  remaining -= 4;
  if (remaining <= 0) return actual_length;
  writeint (c, 0, vendor_length);
  c += 4;

  if (stream->vendor) {
    field_length = oggz_comment_len (stream->vendor);
    memcpy (c, stream->vendor, MIN (field_length, remaining));
    c += field_length; remaining -= field_length;
    if (remaining <= 0) return actual_length;
  }

  remaining -= 4;
  if (remaining <= 0) return actual_length;
  writeint (c, 0, nb_fields);
  c += 4;

  for (comment = oggz_comment_first (oggz, serialno); comment;
       comment = oggz_comment_next (oggz, serialno, comment)) {

    field_length = oggz_comment_len (comment->name);     /* [size]"name" */
    if (comment->value)
      field_length += 1 + oggz_comment_len (comment->value); /* "=value" */

    remaining -= 4;
    if (remaining <= 0) return actual_length;
    writeint (c, 0, field_length);
    c += 4;

    field_length = oggz_comment_len (comment->name);
    memcpy (c, comment->name, MIN (field_length, remaining));
    c += field_length; remaining -= field_length;
    if (remaining <= 0) return actual_length;

    if (comment->value) {
      remaining --;
      if (remaining <= 0) return actual_length;
      *c = '=';
      c++;

      field_length = oggz_comment_len (comment->value);
      memcpy (c, comment->value, MIN (field_length, remaining));
      c += field_length; remaining -= field_length;
      if (remaining <= 0) return actual_length;
    }
  }

  if (remaining <= 0) return actual_length;
  *c = 0x01;

  return actual_length;
}