summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ffi.c36
-rw-r--r--ffi.h2
-rw-r--r--lib.c24
-rw-r--r--lib.h2
4 files changed, 62 insertions, 2 deletions
diff --git a/ffi.c b/ffi.c
index 7d51327a..8b3f30db 100644
--- a/ffi.c
+++ b/ffi.c
@@ -73,7 +73,7 @@ val array_s, zarray_s;
val struct_s;
-val str_d_s, wstr_s, wstr_d_s;
+val str_d_s, wstr_s, wstr_d_s, bstr_s, bstr_d_s;
val buf_d_s;
@@ -622,6 +622,32 @@ static val ffi_wstr_d_get(struct txr_ffi_type *tft, mem_t *src, val self)
return p ? string_own(p) : nil;
}
+static void ffi_bstr_put(struct txr_ffi_type *tft, val s, mem_t *dst,
+ val self)
+{
+ if (s == nil) {
+ *coerce(unsigned char **, dst) = 0;
+ } else {
+ const wchar_t *ws = c_str(s);
+ unsigned char *u8s = chk_strdup_8bit(ws);
+ *coerce(unsigned char **, dst) = u8s;
+ }
+}
+
+static val ffi_bstr_get(struct txr_ffi_type *tft, mem_t *src, val self)
+{
+ unsigned char *p = *coerce(unsigned char **, src);
+ return p ? string_8bit(p) : nil;
+}
+
+static val ffi_bstr_d_get(struct txr_ffi_type *tft, mem_t *src, val self)
+{
+ unsigned char *p = *coerce(unsigned char **, src);
+ val ret = p ? string_8bit(p) : nil;
+ free(p);
+ return ret;
+}
+
static void ffi_buf_put(struct txr_ffi_type *tft, val buf, mem_t *dst,
val self)
{
@@ -1442,6 +1468,12 @@ static void ffi_init_types(void)
ffi_typedef(wstr_d_s, make_ffi_type_builtin(wstr_d_s, str_s,
sizeof (mem_t *), &ffi_type_pointer,
ffi_wstr_d_put, ffi_wstr_d_get));
+ ffi_typedef(bstr_s, make_ffi_type_builtin(bstr_s, str_s,
+ sizeof (mem_t *), &ffi_type_pointer,
+ ffi_bstr_put, ffi_bstr_get));
+ ffi_typedef(bstr_d_s, make_ffi_type_builtin(bstr_d_s, str_s,
+ sizeof (mem_t *), &ffi_type_pointer,
+ ffi_bstr_put, ffi_bstr_d_get));
{
val iter;
@@ -1802,6 +1834,8 @@ void ffi_init(void)
str_d_s = intern(lit("str-d"), user_package);
wstr_s = intern(lit("wstr"), user_package);
wstr_d_s = intern(lit("wstr-d"), user_package);
+ bstr_s = intern(lit("bstr"), user_package);
+ bstr_d_s = intern(lit("bstr-d"), user_package);
buf_d_s = intern(lit("buf-d"), user_package);
ptr_in_s = intern(lit("ptr-in"), user_package);
ptr_out_s = intern(lit("ptr-out"), user_package);
diff --git a/ffi.h b/ffi.h
index 3f9f421d..c598044f 100644
--- a/ffi.h
+++ b/ffi.h
@@ -41,7 +41,7 @@ extern val array_s, zarray_s;
extern val struct_s;
-extern val str_d_s, wstr_s, wstr_d_s;
+extern val str_d_s, wstr_s, wstr_d_s, bstr_s, bstr_d_s;
extern val buf_d_s;
diff --git a/lib.c b/lib.c
index a38ac973..86485e3c 100644
--- a/lib.c
+++ b/lib.c
@@ -2673,6 +2673,21 @@ char *chk_strdup_utf8(const char *str)
return copy;
}
+unsigned char *chk_strdup_8bit(const wchar_t *str)
+{
+ size_t nchar = wcslen(str) + 1, i;
+ unsigned char *copy = coerce(unsigned char *, chk_malloc(nchar));
+ for (i = 0; i < nchar; i++) {
+ if (str[i] < 0 || str[i] > 255) {
+ free(copy);
+ uw_throwf(error_s, lit("cannot coerce ~s to 8 bit"),
+ string(str), nao);
+ }
+ copy[i] = str[i];
+ }
+ return copy;
+}
+
mem_t *chk_copy_obj(mem_t *orig, size_t size)
{
mem_t *copy = chk_malloc(size);
@@ -3276,6 +3291,15 @@ val string_utf8(const char *str)
return obj;
}
+val string_8bit(const unsigned char *str)
+{
+ size_t l = strlen(coerce(const char *, str)), i;
+ wchar_t *wstr = chk_wmalloc(l + 1);
+ for (i = 0; i <= l; i++)
+ wstr[i] = str[i];
+ return string_own(wstr);
+}
+
val mkstring(val len, val ch)
{
size_t l = c_num(len);
diff --git a/lib.h b/lib.h
index 5c74abf5..4875ef2a 100644
--- a/lib.h
+++ b/lib.h
@@ -605,6 +605,7 @@ mem_t *chk_manage_vec(mem_t *old, size_t oldfilled, size_t newfilled,
wchar_t *chk_wmalloc(size_t nwchar);
wchar_t *chk_strdup(const wchar_t *str);
char *chk_strdup_utf8(const char *str);
+unsigned char *chk_strdup_8bit(const wchar_t *str);
mem_t *chk_copy_obj(mem_t *orig, size_t size);
val cons(val car, val cdr);
val make_lazy_cons(val func);
@@ -724,6 +725,7 @@ val maskv(struct args *bits);
val string_own(wchar_t *str);
val string(const wchar_t *str);
val string_utf8(const char *str);
+val string_8bit(const unsigned char *str);
val mkstring(val len, val ch);
val mkustring(val len); /* must initialize immediately with init_str! */
val init_str(val str, const wchar_t *);