diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-05-04 21:19:13 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-05-04 21:19:13 -0700 |
commit | 7f841abd8218c68f8d69fe798b8d5e9d322b4de8 (patch) | |
tree | 0e334842c9c4e9f47b7c9f0174edd50e0c10c28b | |
parent | 33c229bbbbf75ab8b3f048579eb2b7a63acaae7d (diff) | |
download | txr-7f841abd8218c68f8d69fe798b8d5e9d322b4de8.tar.gz txr-7f841abd8218c68f8d69fe798b8d5e9d322b4de8.tar.bz2 txr-7f841abd8218c68f8d69fe798b8d5e9d322b4de8.zip |
ffi: map (array n bchar) to Lisp string.
* ffi.c (struct txr_ffi_type): New bitfield flag, bchar_conv.
(ffi_array_in, ffi_array_get): Handle bchar_conv.
(ffi_type_compile): Set bchar_conv flag for array of bchar.
* lib.c (string_8bit_size): New function.
* lib.h (string_8bit_size): Declared.
-rw-r--r-- | ffi.c | 26 | ||||
-rw-r--r-- | lib.c | 9 | ||||
-rw-r--r-- | lib.h | 1 |
3 files changed, 36 insertions, 0 deletions
@@ -96,6 +96,7 @@ struct txr_ffi_type { unsigned null_term : 1; unsigned char_conv : 1; unsigned wchar_conv : 1; + unsigned bchar_conv : 1; void (*put)(struct txr_ffi_type *, val obj, mem_t *dst, val self); val (*get)(struct txr_ffi_type *, mem_t *src, val self); val (*in)(struct txr_ffi_type *, mem_t *src, val obj, val self); @@ -959,6 +960,19 @@ static val ffi_array_in(struct txr_ffi_type *tft, mem_t *src, val vec, } } vec = if3(vec, replace(vec, str, zero, t), str); + } else if (tft->bchar_conv) { + val str; + + if (nelem == 0) { + str = null_string; + } else { + const unsigned char *chptr = coerce(const unsigned char *, src); + if (chptr[tft->size - 1] == 0) + str = string_8bit(chptr); + else + str = string_8bit_size(chptr, tft->size); + } + vec = if3(vec, replace(vec, str, zero, t), str); } else { ucnum offs = 0; struct txr_ffi_type *etft = ffi_type_struct(eltype); @@ -1060,6 +1074,16 @@ static val ffi_array_get(struct txr_ffi_type *tft, mem_t *src, val self) return init_str(ustr, wchptr); } } + } else if (tft->bchar_conv) { + if (nelem == 0) { + return null_string; + } else { + const unsigned char *chptr = coerce(const unsigned char *, src); + if (chptr[tft->size - 1] == 0) + return string_8bit(chptr); + else + return string_8bit_size(chptr, tft->size); + } } else { cnum znelem = if3(tft->null_term && nelem > 0, nelem - 1, nelem); val vec = vector(num_fast(znelem), nil); @@ -1295,6 +1319,8 @@ val ffi_type_compile(val syntax) tft->char_conv = 1; else if (eltype_syntax == wchar_s) tft->wchar_conv = 1; + else if (eltype_syntax == bchar_s) + tft->bchar_conv = 1; return type; } } else if (sym == ptr_in_s) { @@ -3300,6 +3300,15 @@ val string_8bit(const unsigned char *str) return string_own(wstr); } +val string_8bit_size(const unsigned char *str, size_t sz) +{ + size_t i; + wchar_t *wstr = chk_wmalloc(sz); + for (i = 0; i < sz; i++) + wstr[i] = str[i]; + return string_own(wstr); +} + val mkstring(val len, val ch) { size_t l = c_num(len); @@ -726,6 +726,7 @@ 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 string_8bit_size(const unsigned char *str, size_t sz); val mkstring(val len, val ch); val mkustring(val len); /* must initialize immediately with init_str! */ val init_str(val str, const wchar_t *); |