diff options
| author | 2023-03-23 16:19:21 -0400 | |
|---|---|---|
| committer | 2023-03-23 16:19:21 -0400 | |
| commit | 763d6089abdf6617725f9d77425047d641faa0bc (patch) | |
| tree | 52c4515d03449b3507f3ff56f7aa017b90042290 | |
| parent | native: main: remove prefixes and rename module (diff) | |
all: implement mime-data-cb
| -rw-r--r-- | jurl/mime.janet | 3 | ||||
| -rw-r--r-- | src/main.c | 2 | ||||
| -rw-r--r-- | src/mime.c | 66 |
3 files changed, 66 insertions, 5 deletions
diff --git a/jurl/mime.janet b/jurl/mime.janet index 7b199b3..2bb8c2f 100644 --- a/jurl/mime.janet +++ b/jurl/mime.janet @@ -18,11 +18,12 @@ :encoder encoder}] (some-do handle name native/mime-name) (some-do handle data native/mime-data) - (some-do handle data-cb native/mime-data-cb) (some-do handle filedata native/mime-filedata) (some-do handle filename native/mime-filename) (some-do handle mimetype native/mime-type) (some-do handle encoder native/mime-encoder) + (when (some? data-cb) + (native/mime-data-cb handle ;data-cb)) (when (some? amime) (:attach amime handle)) (when (some? headers) @@ -83,7 +83,7 @@ JANET_FN(jurl_mime_data, "Set a string or buffer as the data source for the mimepart"); JANET_FN(jurl_mime_data_cb, - "(mime-data-cb part (fn ...))", + "(mime-data-cb part datasize (fn [mode size|offset &opt position]))", "Set a callback as the data source for the mimepart"); JANET_FN(jurl_mime_filedata, @@ -77,10 +77,70 @@ JANET_CFUN(jurl_mime_data) { return jurl_geterror(ret); } -// TODO +static size_t readfunc(char *buffer, size_t size, size_t nitems, void *arg) { + JanetFunction *fun = (JanetFunction*)arg; + size_t realsize = size * nitems; + + Janet argv[2] = { janet_ckeywordv("read"), + janet_wrap_integer(realsize), }; + Janet res = janet_call(fun, 2, argv); + if (janet_checktype(res, JANET_NIL)) return 0; + JanetByteView bytes; + if (!janet_bytes_view(res, &bytes.bytes, &bytes.len)) { + janet_panic("could not open bytesview in readfunc"); + } + + size_t actualsize = realsize > bytes.len ? bytes.len : realsize; + memcpy(buffer, bytes.bytes, actualsize); + + return realsize; +} + +static int seekfunc(void *arg, curl_off_t offset, int origin) { + JanetFunction *fun = (JanetFunction*)arg; + char *pos; + switch (origin) { + case SEEK_SET: + pos = "set"; + break; + case SEEK_CUR: + pos = "cur"; + break; + case SEEK_END: + pos = "end"; + break; + default: + janet_panicf("unrecognized origin in seekfunc: %d", origin); + } + + Janet argv[3] = { janet_ckeywordv("seek"), + janet_wrap_integer(offset), + janet_ckeywordv(pos), }; + Janet res = janet_call(fun, 3, argv); + + if (janet_keyeq(res, "ok")) { + return CURL_SEEKFUNC_OK; + } else if (janet_keyeq(res, "fail")) { + return CURL_SEEKFUNC_FAIL; + } else if (janet_keyeq(res, "cantseek")) { + return CURL_SEEKFUNC_CANTSEEK; + } else { + janet_panicf("unrecognized return in seekfunc: %v", res); + } + + return CURL_SEEKFUNC_CANTSEEK; // unreachable +} + +// (callback :read size) +// (callback :seek offset :set | :cur | :end) JANET_CFUN(jurl_mime_data_cb) { - janet_panic("not implemented"); - return janet_wrap_nil(); // unreachable + janet_fixarity(argc, 3); + curl_mimepart *part = (curl_mimepart*)janet_getpointer(argv, 0); + curl_off_t size = janet_getinteger64(argv, 1); + JanetFunction *fun = janet_getfunction(argv, 2); + + CURLcode res = curl_mime_data_cb(part, size, readfunc, seekfunc, NULL, fun); + return jurl_geterror(res); } JANET_CFUN(jurl_mime_filedata) { |
