diff options
-rw-r--r-- | ffi.c | 36 | ||||
-rw-r--r-- | ffi.h | 2 | ||||
-rw-r--r-- | lib.c | 24 | ||||
-rw-r--r-- | lib.h | 2 |
4 files changed, 62 insertions, 2 deletions
@@ -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); @@ -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; @@ -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); @@ -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 *); |