Changeset: a999c79cabb2 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/a999c79cabb2 Modified Files: common/stream/mapi_stream.c common/stream/stream.h Branch: copyintobinary Log Message:
Implement mapi_request_download diffs (170 lines): diff --git a/common/stream/mapi_stream.c b/common/stream/mapi_stream.c --- a/common/stream/mapi_stream.c +++ b/common/stream/mapi_stream.c @@ -24,15 +24,15 @@ discard(stream *s) } } -struct mapi_recv_upload { +struct mapi_filetransfer { stream *from_client; // set to NULL after sending MAPI_PROMPT3 stream *to_client; // set to NULL when client sends empty }; static ssize_t -recv_upload_read(stream *restrict s, void *restrict buf, size_t elmsize, size_t cnt) +upload_read(stream *restrict s, void *restrict buf, size_t elmsize, size_t cnt) { - struct mapi_recv_upload *state = s->stream_data.p; + struct mapi_filetransfer *state = s->stream_data.p; if (state->from_client == NULL) { assert(s->eof); @@ -69,9 +69,9 @@ recv_upload_read(stream *restrict s, voi } static void -recv_upload_close(stream *s) +upload_close(stream *s) { - struct mapi_recv_upload *state = s->stream_data.p; + struct mapi_filetransfer *state = s->stream_data.p; stream *from = state->from_client; if (from) @@ -79,25 +79,48 @@ recv_upload_close(stream *s) stream *to = state->to_client; mnstr_write(to, PROMPT3, strlen(PROMPT3), 1); - mnstr_flush(to, MNSTR_FLUSH_ALL); + mnstr_flush(to, MNSTR_FLUSH_DATA); +} + +static ssize_t +download_write(stream *restrict s, const void *restrict buf, size_t elmsize, size_t cnt) +{ + struct mapi_filetransfer *state = s->stream_data.p; + stream *to = state->to_client; + return to->write(to, buf, elmsize, cnt); } static void -recv_upload_destroy(stream *s) +download_close(stream *s) { - struct mapi_recv_upload *state = s->stream_data.p; + struct mapi_filetransfer *state = s->stream_data.p; + + stream *to = state->to_client; + stream *from = state->from_client; + if (to) + mnstr_flush(to, MNSTR_FLUSH_DATA); + if (from) + discard(from); +} + +static void +destroy(stream *s) +{ + struct mapi_filetransfer *state = s->stream_data.p; free(state); destroy_stream(s); } -stream* -mapi_request_upload(const char *filename, bool binary, bstream *bs, stream *ws) +static stream* +setup_transfer(const char *req, const char *filename, bstream *bs, stream *ws) { const char *msg = NULL; stream *s = NULL; - struct mapi_recv_upload *state = NULL; + struct mapi_filetransfer *state = NULL; ssize_t nwritten; + ssize_t nread; + bool ok; while (!bs->eof) bstream_next(bs); @@ -105,10 +128,7 @@ mapi_request_upload(const char *filename assert(isa_block_stream(ws)); assert(isa_block_stream(rs)); - if (binary) - nwritten = mnstr_printf(ws, "%srb %s\n", PROMPT3, filename); - else - nwritten = mnstr_printf(ws, "%sr 0 %s\n", PROMPT3, filename); + nwritten = mnstr_printf(ws, PROMPT3 "%s %s\n", req, filename); if (nwritten <= 0) { msg = mnstr_peek_error(ws); goto end; @@ -119,7 +139,9 @@ mapi_request_upload(const char *filename } char buf[256]; - if (mnstr_readline(rs, buf, sizeof(buf)) != 1 || buf[0] != '\n') { + nread = mnstr_readline(rs, buf, sizeof(buf)); + ok = (nread == 0 || (nread == 1 && buf[0] == '\n')); + if (!ok) { msg = buf; discard(rs); goto end; @@ -139,10 +161,6 @@ mapi_request_upload(const char *filename state->from_client = rs; state->to_client = ws; s->stream_data.p = state; - s->binary= binary; - s->read = recv_upload_read; - s->close = recv_upload_close; - s->destroy = recv_upload_destroy; end: if (msg) { mnstr_destroy(s); @@ -152,3 +170,36 @@ end: return s; } } + +stream* +mapi_request_upload(const char *filename, bool binary, bstream *bs, stream *ws) +{ + const char *req = binary ? "rb" : "r 0"; + stream *s = setup_transfer(req, filename, bs, ws); + if (s == NULL) + return NULL; + + s->binary = binary; + s->read = upload_read; + s->close = upload_close; + s->destroy = destroy; + + return s; +} + +stream* +mapi_request_download(const char *filename, bool binary, bstream *bs, stream *ws) +{ + const char *req = binary ? "wb" : "w"; + stream *s = setup_transfer(req, filename, bs, ws); + if (s == NULL) + return NULL; + + s->binary = binary; + s->readonly = false; + s->write = download_write; + s->close = download_close; + s->destroy = destroy; + + return s; +} diff --git a/common/stream/stream.h b/common/stream/stream.h --- a/common/stream/stream.h +++ b/common/stream/stream.h @@ -265,5 +265,6 @@ stream_export stream *stream_fwf_create( stream_export stream *create_text_stream(stream *s); stream_export stream *mapi_request_upload(const char *filename, bool binary, bstream *rs, stream *ws); +stream_export stream *mapi_request_download(const char *filename, bool binary, bstream *rs, stream *ws); #endif /*_STREAM_H_*/ _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org