aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChloe Kudryavtsev <code@toast.bunkerlabs.net>2023-03-23 16:19:21 -0400
committerChloe Kudryavtsev <code@toast.bunkerlabs.net>2023-03-23 16:19:21 -0400
commit763d6089abdf6617725f9d77425047d641faa0bc (patch)
tree52c4515d03449b3507f3ff56f7aa017b90042290
parentnative: main: remove prefixes and rename module (diff)
all: implement mime-data-cb
-rw-r--r--jurl/mime.janet3
-rw-r--r--src/main.c2
-rw-r--r--src/mime.c66
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)
diff --git a/src/main.c b/src/main.c
index 3646bde..a322d99 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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,
diff --git a/src/mime.c b/src/mime.c
index 912c467..078d02f 100644
--- a/src/mime.c
+++ b/src/mime.c
@@ -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) {