From a8d65409decc86cf8d9f9ebadea28be551b3a4d2 Mon Sep 17 00:00:00 2001 From: Not Zed Date: Tue, 5 Dec 2000 11:50:32 +0000 Subject: stream_flush does make sense for a substream afterall (if you have a 2000-12-05 Not Zed * camel-seekable-substream.c (stream_flush): stream_flush does make sense for a substream afterall (if you have a stream_write). (stream_write): Implement this. (stream_seek): Change the STREAM_END behaviour to be more sane. if bounded go from the end of the bound, if unbounded, go from the end of the parent stream. * camel-stream-mem.c (stream_read): Dont return error if reading past the end of data, just return 0. * camel-stream-fs.c (camel_stream_fs_init): Initialise the stream to be unbound. (stream_seek): Fix the logic when seeking from the end of an unbounded stream. (camel_stream_fs_new_with_fd): If the fd is invalid (-1), then return NULL immediately. (stream_seek): Range check a SEEK_END so it fits within bound_start. 2000-12-01 Not Zed * tests/lib/folders.c (test_folder_basic): New test to perform basic store operations on folders (taken from folders/test1). (test_folder_message_ops): Tkane the guts out of folders/test2. svn path=/trunk/; revision=6790 --- camel/ChangeLog | 27 +++++++ camel/camel-seekable-substream.c | 81 +++++++++++++------ camel/camel-stream-fs.c | 11 ++- camel/camel-stream-mem.c | 13 ++- camel/providers/local/camel-local-summary.c | 1 - camel/tests/Makefile.am | 2 +- camel/tests/lib/Makefile.am | 4 +- camel/tests/stream/Makefile.am | 21 +++++ camel/tests/stream/test1.c | 119 ++++++++++++++++++++++++++++ camel/tests/stream/test2.c | 53 +++++++++++++ camel/tests/stream/test3.c | 104 ++++++++++++++++++++++++ 11 files changed, 397 insertions(+), 39 deletions(-) create mode 100644 camel/tests/stream/Makefile.am create mode 100644 camel/tests/stream/test1.c create mode 100644 camel/tests/stream/test2.c create mode 100644 camel/tests/stream/test3.c diff --git a/camel/ChangeLog b/camel/ChangeLog index de60e747e3..6e04660b28 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,30 @@ +2000-12-05 Not Zed + + * camel-seekable-substream.c (stream_flush): stream_flush does + make sense for a substream afterall (if you have a stream_write). + (stream_write): Implement this. + (stream_seek): Change the STREAM_END behaviour to be more sane. + if bounded go from the end of the bound, if unbounded, go from the + end of the parent stream. + + * camel-stream-mem.c (stream_read): Dont return error if reading + past the end of data, just return 0. + + * camel-stream-fs.c (camel_stream_fs_init): Initialise the stream + to be unbound. + (stream_seek): Fix the logic when seeking from the end of an + unbounded stream. + (camel_stream_fs_new_with_fd): If the fd is invalid (-1), then + return NULL immediately. + (stream_seek): Range check a SEEK_END so it fits within + bound_start. + +2000-12-01 Not Zed + + * tests/lib/folders.c (test_folder_basic): New test to perform + basic store operations on folders (taken from folders/test1). + (test_folder_message_ops): Tkane the guts out of folders/test2. + 2000-12-04 Jeffrey Stedfast * providers/smtp/camel-smtp-transport.c (smtp_connect): i18n-ize diff --git a/camel/camel-seekable-substream.c b/camel/camel-seekable-substream.c index 9b197f97bd..ad1a01eef6 100644 --- a/camel/camel-seekable-substream.c +++ b/camel/camel-seekable-substream.c @@ -132,14 +132,12 @@ camel_seekable_substream_new_with_seekable_stream_and_bounds (CamelSeekableStrea static gboolean parent_reset (CamelSeekableSubstream *seekable_substream, CamelSeekableStream *parent) { - CamelSeekableStream *seekable_stream = - CAMEL_SEEKABLE_STREAM (seekable_substream); + CamelSeekableStream *seekable_stream = CAMEL_SEEKABLE_STREAM (seekable_substream); if (camel_seekable_stream_tell (parent) == seekable_stream->position) return TRUE; - return camel_seekable_stream_seek (parent, seekable_stream->position, CAMEL_STREAM_SET) - == seekable_stream->position; + return camel_seekable_stream_seek (parent, seekable_stream->position, CAMEL_STREAM_SET) == seekable_stream->position; } static int @@ -147,8 +145,7 @@ stream_read (CamelStream *stream, char *buffer, unsigned int n) { CamelSeekableStream *parent; CamelSeekableStream *seekable_stream = CAMEL_SEEKABLE_STREAM (stream); - CamelSeekableSubstream *seekable_substream = - CAMEL_SEEKABLE_SUBSTREAM (stream); + CamelSeekableSubstream *seekable_substream = CAMEL_SEEKABLE_SUBSTREAM (stream); int v; if (n == 0) @@ -183,20 +180,47 @@ stream_read (CamelStream *stream, char *buffer, unsigned int n) static int stream_write (CamelStream *stream, const char *buffer, unsigned int n) { - /* NOT VALID ON SEEKABLE SUBSTREAM */ - /* Well, it's entirely valid, just not implemented */ - g_warning ("CamelSeekableSubstream:: seekable substream doesn't " - "have a write method yet?\n"); - return -1; + CamelSeekableStream *parent; + CamelSeekableStream *seekable_stream = CAMEL_SEEKABLE_STREAM(stream); + CamelSeekableSubstream *seekable_substream = CAMEL_SEEKABLE_SUBSTREAM(stream); + int v; + + if (n == 0) + return 0; + + parent = seekable_substream->parent_stream; + + /* Go to our position in the parent stream. */ + if (!parent_reset (seekable_substream, parent)) { + stream->eos = TRUE; + return 0; + } + + /* Compute how many bytes should be written. */ + if (seekable_stream->bound_end != CAMEL_STREAM_UNBOUND) + n = MIN (seekable_stream->bound_end - seekable_stream->position, n); + + if (n == 0) { + stream->eos = TRUE; + return 0; + } + + v = camel_stream_write((CamelStream *)parent, buffer, n); + + /* ignore <0 - it's an error, let the caller deal */ + if (v > 0) + seekable_stream->position += v; + + return v; + } static int stream_flush (CamelStream *stream) { - /* NOT VALID ON SEEKABLE SUBSTREAM */ - g_warning ("CamelSeekableSubstream:: seekable substream doesn't " - "have a flush method\n"); - return -1; + CamelSeekableSubstream *sus = (CamelSeekableSubstream *)stream; + + return camel_stream_flush(sus->parent_stream); } static int @@ -209,9 +233,8 @@ stream_close (CamelStream *stream) static gboolean eos (CamelStream *stream) { - CamelSeekableSubstream *seekable_substream = - CAMEL_SEEKABLE_SUBSTREAM (stream); - CamelSeekableStream *seekable_stream = CAMEL_SEEKABLE_STREAM (stream); + CamelSeekableSubstream *seekable_substream = CAMEL_SEEKABLE_SUBSTREAM(stream); + CamelSeekableStream *seekable_stream = CAMEL_SEEKABLE_STREAM(stream); CamelSeekableStream *parent; gboolean eos; @@ -235,9 +258,8 @@ static off_t stream_seek (CamelSeekableStream *seekable_stream, off_t offset, CamelStreamSeekPolicy policy) { - CamelSeekableSubstream *seekable_substream = - CAMEL_SEEKABLE_SUBSTREAM (seekable_stream); - CamelStream *stream = CAMEL_STREAM (seekable_stream); + CamelSeekableSubstream *seekable_substream = CAMEL_SEEKABLE_SUBSTREAM(seekable_stream); + CamelStream *stream = CAMEL_STREAM(seekable_stream); off_t real_offset = 0; stream->eos = FALSE; @@ -252,11 +274,18 @@ stream_seek (CamelSeekableStream *seekable_stream, off_t offset, break; case CAMEL_STREAM_END: - real_offset = camel_seekable_stream_seek (seekable_substream->parent_stream, - offset, - CAMEL_STREAM_END); - if (real_offset == -1) - return -1; + if (seekable_stream->bound_end == CAMEL_STREAM_UNBOUND) { + real_offset = camel_seekable_stream_seek(seekable_substream->parent_stream, + offset, + CAMEL_STREAM_END); + if (real_offset != -1) { + if (real_offsetbound_start) + real_offset = seekable_stream->bound_start; + seekable_stream->position = real_offset; + } + return real_offset; + } + real_offset = seekable_stream->bound_end + offset; break; } diff --git a/camel/camel-stream-fs.c b/camel/camel-stream-fs.c index 17c6b98e08..59082ec531 100644 --- a/camel/camel-stream-fs.c +++ b/camel/camel-stream-fs.c @@ -69,6 +69,7 @@ camel_stream_fs_init (gpointer object, gpointer klass) CamelStreamFs *stream = CAMEL_STREAM_FS (object); stream->fd = -1; + ((CamelSeekableStream *)stream)->bound_end = CAMEL_STREAM_UNBOUND; } static void @@ -114,6 +115,9 @@ camel_stream_fs_new_with_fd (int fd) CamelStreamFs *stream_fs; off_t offset; + if (fd == -1) + return NULL; + stream_fs = CAMEL_STREAM_FS (camel_object_new (camel_stream_fs_get_type ())); stream_fs->fd = fd; offset = lseek (fd, 0, SEEK_CUR); @@ -271,10 +275,13 @@ stream_seek (CamelSeekableStream *stream, off_t offset, CamelStreamSeekPolicy po real = stream->position + offset; break; case CAMEL_STREAM_END: - if (stream->bound_end != CAMEL_STREAM_UNBOUND) { + if (stream->bound_end == CAMEL_STREAM_UNBOUND) { real = lseek(stream_fs->fd, offset, SEEK_END); - if (real != -1) + if (real != -1) { + if (realbound_start) + real = stream->bound_start; stream->position = real; + } return real; } real = stream->bound_end + offset; diff --git a/camel/camel-stream-mem.c b/camel/camel-stream-mem.c index 0c07a2759f..b9012bcccb 100644 --- a/camel/camel-stream-mem.c +++ b/camel/camel-stream-mem.c @@ -163,11 +163,10 @@ stream_read (CamelStream *stream, char *buffer, size_t n) nread = MIN (n, camel_stream_mem->buffer->len - seekable->position); if (nread > 0) { - memcpy (buffer, camel_stream_mem->buffer->data + - seekable->position, nread); + memcpy (buffer, camel_stream_mem->buffer->data + seekable->position, nread); seekable->position += nread; } else - nread = -1; + nread = 0; return nread; } @@ -186,12 +185,10 @@ stream_write (CamelStream *stream, const char *buffer, size_t n) #warning "g_byte_arrays use g_malloc and so are totally unsuitable for this object" #endif if (seekable->position == stream_mem->buffer->len) { - stream_mem->buffer = - g_byte_array_append (stream_mem->buffer, (const guint8 *)buffer, nwrite); + g_byte_array_append(stream_mem->buffer, (const guint8 *)buffer, nwrite); } else { - g_byte_array_set_size (stream_mem->buffer, - nwrite + stream_mem->buffer->len); - memcpy (stream_mem->buffer->data + seekable->position, buffer, nwrite); + g_byte_array_set_size(stream_mem->buffer, nwrite + stream_mem->buffer->len); + memcpy(stream_mem->buffer->data + seekable->position, buffer, nwrite); } seekable->position += nwrite; diff --git a/camel/providers/local/camel-local-summary.c b/camel/providers/local/camel-local-summary.c index 5e47ee35c3..1377ff43a8 100644 --- a/camel/providers/local/camel-local-summary.c +++ b/camel/providers/local/camel-local-summary.c @@ -347,7 +347,6 @@ camel_local_summary_write_headers(int fd, struct _header_raw *header, char *xevl while (header) { if (strcmp(header->name, "X-Evolution")) { - printf("writing header: '%s'\n", header->name); len = fprintf(out, "%s:%s\n", header->name, header->value); if (len == -1) { fclose(out); diff --git a/camel/tests/Makefile.am b/camel/tests/Makefile.am index 327f75816d..f604cb81a1 100644 --- a/camel/tests/Makefile.am +++ b/camel/tests/Makefile.am @@ -1,4 +1,4 @@ SUBDIRS = lib \ - message folder + message folder stream diff --git a/camel/tests/lib/Makefile.am b/camel/tests/lib/Makefile.am index a87dc59bf6..aef91a1253 100644 --- a/camel/tests/lib/Makefile.am +++ b/camel/tests/lib/Makefile.am @@ -7,7 +7,9 @@ libcameltest_a_SOURCES = \ camel-test.c camel-test.h \ messages.c messages.h \ addresses.c addresses.h \ - folders.c folders.h + folders.c folders.h \ + streams.c streams.h + diff --git a/camel/tests/stream/Makefile.am b/camel/tests/stream/Makefile.am new file mode 100644 index 0000000000..d16f8aaa55 --- /dev/null +++ b/camel/tests/stream/Makefile.am @@ -0,0 +1,21 @@ + +INCLUDES = -I$(top_srcdir)/intl -I$(top_srcdir) -I$(top_srcdir)/camel \ + -I$(includedir) \ + -I$(top_srcdir)/camel/tests/lib \ + -DG_LOG_DOMAIN=\"evolution-tests\" + +LDADD = \ + $(top_builddir)/camel/libcamel.la \ + $(top_builddir)/e-util/libeutil.la \ + $(top_builddir)/libibex/libibex.la \ + $(GNOME_LIBDIR) \ + $(top_builddir)/camel/tests/lib/libcameltest.a \ + $(GNOMEUI_LIBS) $(INTLLIBS) $(EXTRA_GNOME_LIBS) + +check_PROGRAMS = \ + test1 test2 test3 + +TESTS = test1 test2 test3 + + + diff --git a/camel/tests/stream/test1.c b/camel/tests/stream/test1.c new file mode 100644 index 0000000000..452d45274f --- /dev/null +++ b/camel/tests/stream/test1.c @@ -0,0 +1,119 @@ +/* + test ... camelstreamfs */ + +#include "camel-test.h" +#include "streams.h" + +#include +#include +#include + +#include "camel/camel-stream-fs.h" + +int main(int argc, char **argv) +{ + CamelSeekableStream *ss = NULL; + int i; + int fd = -1; + struct stat st; + int size; + char buffer[1024]; + + camel_test_init(argc, argv); + + camel_test_start("CamelStream fs, open, seek, read, write, eos"); + for (i=0;i<2;i++) { + + (void)unlink("stream.txt"); + + push("trying to open a nonexistant stream, method %d", i); + switch(i) { + case 0: + ss = (CamelSeekableStream *)camel_stream_fs_new_with_name("stream.txt", O_RDWR, 0); + break; + case 1: + fd = open("stream.txt", O_RDWR, 0); + ss = (CamelSeekableStream *)camel_stream_fs_new_with_fd(fd); + break; + } + check(ss == NULL && errno == ENOENT); + check(stat("stream.txt", &st) == -1 && errno == ENOENT); + pull(); + + push("Creating stream using method %d", i); + switch(i) { + case 0: + ss = (CamelSeekableStream *)camel_stream_fs_new_with_name("stream.txt", O_CREAT|O_RDWR|O_TRUNC, 0600); + fd = ((CamelStreamFs *)ss)->fd; + break; + case 1: + fd = open("stream.txt", O_CREAT|O_RDWR|O_TRUNC, 0600); + ss = (CamelSeekableStream *)camel_stream_fs_new_with_fd(fd); + break; + } + check(ss != NULL); + check(stat("stream.txt", &st) == 0 && (st.st_mode&0777) == 0600 && S_ISREG(st.st_mode) && st.st_size == 0); + pull(); + + test_stream_seekable_writepart(ss); + test_stream_seekable_readpart(ss); + + push("getting filesize"); + check(stat("stream.txt", &st) == 0 && (st.st_mode&0777) == 0600 && S_ISREG(st.st_mode)); + size = st.st_size; + pull(); + + push("checking close closes"); + check_unref(ss, 1); + check(close(fd) == -1); + pull(); + + push("re-opening stream"); + switch(i) { + case 0: + ss = (CamelSeekableStream *)camel_stream_fs_new_with_name("stream.txt", O_RDWR, 0); + fd = ((CamelStreamFs *)ss)->fd; + break; + case 1: + fd = open("stream.txt", O_RDWR, 0); + ss = (CamelSeekableStream *)camel_stream_fs_new_with_fd(fd); + break; + } + check(ss != NULL); + check(stat("stream.txt", &st) == 0 && (st.st_mode&0777) == 0600 && S_ISREG(st.st_mode) && st.st_size == size); + + test_stream_seekable_readpart(ss); + + check_unref(ss, 1); + check(close(fd) == -1); + pull(); + + push("re-opening stream with truncate"); + switch(i) { + case 0: + ss = (CamelSeekableStream *)camel_stream_fs_new_with_name("stream.txt", O_RDWR|O_TRUNC, 0); + fd = ((CamelStreamFs *)ss)->fd; + break; + case 1: + fd = open("stream.txt", O_RDWR|O_TRUNC, 0); + ss = (CamelSeekableStream *)camel_stream_fs_new_with_fd(fd); + break; + } + check(ss != NULL); + check(stat("stream.txt", &st) == 0 && (st.st_mode&0777) == 0600 && S_ISREG(st.st_mode) && st.st_size == 0); + + /* read has to return 0 before eos is set */ + check(camel_stream_read(CAMEL_STREAM(ss), buffer, 1) == 0); + check(camel_stream_eos(CAMEL_STREAM(ss))); + + check_unref(ss, 1); + check(close(fd) == -1); + pull(); + + (void)unlink("stream.txt"); + } + + camel_test_end(); + + return 0; +} diff --git a/camel/tests/stream/test2.c b/camel/tests/stream/test2.c new file mode 100644 index 0000000000..02ad88e95c --- /dev/null +++ b/camel/tests/stream/test2.c @@ -0,0 +1,53 @@ +/* + test ... camelstreammem */ + +#include "camel-test.h" +#include "streams.h" + +#include +#include +#include + +#include "camel/camel-stream-mem.h" + +int main(int argc, char **argv) +{ + CamelSeekableStream *ss = NULL; + int i; + int fd = -1; + struct stat st; + int size; + char buffer[1024]; + GByteArray *ba; + + camel_test_init(argc, argv); + + camel_test_start("CamelStream mem, create, seek, read, write, eos"); + for (i=0;i<3;i++) { + + push("Creating stream using method %d", i); + switch(i) { + case 0: + ss = (CamelSeekableStream *)camel_stream_mem_new(); + break; + case 1: + ba = g_byte_array_new(); + ss = (CamelSeekableStream *)camel_stream_mem_new_with_byte_array(ba); + break; + case 2: + ss = (CamelSeekableStream *)camel_stream_mem_new_with_buffer("", 0); + break; + } + check(ss != NULL); + + test_stream_seekable_writepart(ss); + test_stream_seekable_readpart(ss); + + check_unref(ss, 1); + pull(); + } + + camel_test_end(); + + return 0; +} diff --git a/camel/tests/stream/test3.c b/camel/tests/stream/test3.c new file mode 100644 index 0000000000..b870a7773e --- /dev/null +++ b/camel/tests/stream/test3.c @@ -0,0 +1,104 @@ +/* + test ... camelseekablesubstream */ + +#include "camel-test.h" +#include "streams.h" + +#include +#include +#include + +#include "camel/camel-stream-mem.h" +#include "camel/camel-stream-fs.h" +#include "camel/camel-seekable-substream.h" + +#define ARRAY_LEN(x) (sizeof(x)/sizeof(x[0])) + +struct { + off_t lower, upper; +} ranges[] = { + { 3, 10241 }, + { 0, 1024 }, + { 0, 0 }, + { 0, 1 }, + { 0, 2 }, + { 0, 3 }, + { 0, 7 }, + { 1, 8 }, + { 1, 9 }, + { 10245, 10300 }, + { 0, CAMEL_STREAM_UNBOUND }, +/* { 1, CAMEL_STREAM_UNBOUND }, + { 2, CAMEL_STREAM_UNBOUND }, + { 3, CAMEL_STREAM_UNBOUND }, these take too long to run + { 7, CAMEL_STREAM_UNBOUND },*/ + { 10245, CAMEL_STREAM_UNBOUND }, +}; + +int main(int argc, char **argv) +{ + CamelSeekableStream *ss = NULL; + int i, j; + CamelSeekableSubstream *sus, *sus2; + + camel_test_init(argc, argv); + + camel_test_start("CamelSeekableSubstream, mem backing"); + for (j=0;j