[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [bug-mailutils] RFC 2047 decoding function
From: |
Alain Magloire |
Subject: |
Re: [bug-mailutils] RFC 2047 decoding function |
Date: |
Tue, 28 Jan 2003 10:49:26 -0500 (EST) |
>
> 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.
>
since it seems to be independent, I would be better in its own file.
Say rfc2047.c 8-)
Is that the final version or you are planning to work on it more?
> ---
>
> 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;
> }