[gmime-devel] resetting stream after g_mime_object_write_to_stream



I'm using gmime-2.6 on Arch Linux to manipulate a basic multipart file. Under a particular combination of actions I am no longer able to read data from the streams obtained from the content objects of individual parts:

#include <gmime/gmime.h>
#include <stdio.h>
#include <errno.h>

static void each_part(GMimeObject *up, GMimeObject *part, gpointer user_data) {
if(GMIME_IS_PART(part)) {
GMimeDataWrapper* dw = g_mime_part_get_content_object(GMIME_PART(part));
 GMimeStream* ms = g_mime_data_wrapper_get_stream(dw);
 gint64 l = g_mime_stream_length(ms);
 char* s = malloc(g_mime_stream_length(ms));
 gint64 r = g_mime_stream_read(ms, s, l);
 g_mime_stream_reset(ms);
printf("content object is %lld bytes long, read %lld bytes (%s)\n", l, r, strerror(errno));
 errno = 0;
}
}

int main(int argc, char** argv) {
g_mime_init(0);
FILE* fp = fopen(argv[1], "rb");
GMimeStream* gfs = g_mime_stream_file_new(fp);
GMimeParser* parser = g_mime_parser_new_with_stream(gfs);
GMimeMessage* message = g_mime_parser_construct_message(parser);
#if 1
FILE* f2 = fopen(argv[2], "wb");
GMimeStream* fs = g_mime_stream_file_new(f2);

g_mime_object_write_to_stream(GMIME_OBJECT(g_mime_message_get_mime_part(message)), fs);
g_mime_stream_flush(fs);
g_mime_stream_reset(fs);
g_object_unref(fs);
#endif
        

g_mime_multipart_foreach(GMIME_MULTIPART(g_mime_message_get_mime_part(message)), each_part, NULL);

g_mime_multipart_foreach(GMIME_MULTIPART(g_mime_message_get_mime_part(message)), each_part, NULL);
}



This outputs:

content object is 391 bytes long, read -1 bytes (Invalid argument)
content object is 22442 bytes long, read -1 bytes (Invalid argument)
content object is 406625 bytes long, read -1 bytes (Invalid argument)
content object is 391 bytes long, read 391 bytes (Success)
content object is 22442 bytes long, read 22442 bytes (Success)
content object is 406625 bytes long, read 406625 bytes (Success)

If I disable the #ifdef section:

content object is 391 bytes long, read 391 bytes (Success)
content object is 22442 bytes long, read 22442 bytes (Success)
content object is 406625 bytes long, read 406625 bytes (Success)
content object is 391 bytes long, read 391 bytes (Success)
content object is 22442 bytes long, read 22442 bytes (Success)
content object is 406625 bytes long, read 406625 bytes (Success)

If I disable the #ifdef section AND comment out gmime_stream_reset(ms):

content object is 391 bytes long, read 391 bytes (Success)
content object is 22442 bytes long, read 22442 bytes (Success)
content object is 406625 bytes long, read 406625 bytes (Success)
content object is 391 bytes long, read -1 bytes (Invalid argument)
content object is 22442 bytes long, read -1 bytes (Invalid argument)
content object is 406625 bytes long, read -1 bytes (Invalid argument)

This leaves me to believe the g_mime_stream_reset is necessary probably to reset some internal pointers, and they are not reset in the call to g_mime_object_write_to_stream. Note that neither the presence or order of the g_mime_stream_flush(fs), g_mime_stream_reset(fs) and g_object_unref(fs) calls make any difference to the results of this test.

Sorry for the verbosity, I had trouble making this example any more minimal.



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