bug-mailutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bug-mailutils] RFC 2047 decoding function


From: Kidong Lee
Subject: [bug-mailutils] RFC 2047 decoding function
Date: Mon, 27 Jan 2003 18:22:49 +0900
User-agent: Mutt/1.4i

This is RFC 2047 decoding function.

In this function, It allocates the memory only one time(allocating size
is the same as encoded string), because it avoids calling realloc() repeatly
for performance.
It needs more memory sligntly, but performance is better than when calling
realloc() repeatly.

And I did not write character set conversion and RFC 2047 encode function
yet. Because I don't know when I will be able to add this.

It's not a form of patch. because I can't decide in which file I should
place this function.

I'm not sure whether I'm going along the right way. If not, I hope you
to modify it.


---

int
rfc2047_decode (const char* tocode, const char* fromstr, char** ptostr)
{
  int status = 0;
  char *start_position = NULL;

  start_position = strstr (fromstr, "=?");

  /* Memory allocation is happened only in this place */
  /* Assumes decoded text is shorter than encoded text */
  *ptostr = strdup(fromstr);
  if (*ptostr == NULL)
    return ENOMEM;

  if (start_position != NULL)
    {
      memset((void *) *ptostr, 0, strlen(fromstr));
      strncpy(*ptostr, fromstr, start_position - fromstr);
    }

  while (start_position != NULL)
    {
      char *fromcode = NULL;
      char *encoding_type = NULL;
      char *encoded_text = NULL;
      stream_t filter = NULL;
      stream_t in_stream = NULL;
      char *pbuffer = NULL;
      char filter_type[17];     /* length of "quoted-printalble" + 1 */
      int nbytes = 0;
      char *sp = NULL;
      char *end_position = NULL;

      fromcode = strtok_r (start_position + 2, "?", &sp);
      encoding_type = strtok_r (NULL, "?", &sp);
      encoded_text = strtok_r (NULL, "?", &sp);

      assert (fromcode != NULL && encoding_type != NULL
              && encoded_text != NULL);

      if (toupper (encoding_type[0]) == 'B')
        strcpy (filter_type, "base64");
      else if (toupper (encoding_type[0]) == 'Q')
        strcpy (filter_type, "quoted-printable");

      memory_stream_create (&in_stream, 0, 0);
      stream_write (in_stream, encoded_text, strlen (encoded_text), 0, NULL);
      filter_create (&filter, in_stream, filter_type, MU_FILTER_DECODE,
                     MU_STREAM_READ);

      pbuffer = (char *) calloc(strlen(encoded_text) + 1, sizeof (char));
      if (stream_read (filter, pbuffer, strlen (encoded_text), 0,
                  &nbytes) == 0 && nbytes)
        {
          /* TODO: Need to convert character set */
          strncat (*ptostr, pbuffer, nbytes);
        }
      assert(pbuffer != NULL);
      free(pbuffer);

      stream_close (in_stream);
      stream_close (filter);

      start_position = strstr (strtok_r (NULL, "\n", &sp), "=?");

      end_position = encoded_text + strlen(encoded_text) + 2;

      /* Copying unencoded text after encoded text */
      if (start_position != NULL && start_position > end_position)
        {
          int length = start_position - end_position;
          strncat(*ptostr, end_position, length);
        }
    }
  return status;
}





reply via email to

[Prev in Thread] Current Thread [Next in Thread]