diff options
| author | kr.angelov <kr.angelov@gmail.com> | 2012-01-20 13:41:10 +0000 |
|---|---|---|
| committer | kr.angelov <kr.angelov@gmail.com> | 2012-01-20 13:41:10 +0000 |
| commit | 2eee382a62a909d5a3f2f5eda94f30fe68fd5335 (patch) | |
| tree | b0b0d513535895f244214aebf6358e172b8dce6d /src/runtime/c/gu/write.c | |
| parent | b9728357126f8b9a6311cca17d9f0dcc2a7bfb9b (diff) | |
initial import of the C runtime
Diffstat (limited to 'src/runtime/c/gu/write.c')
| -rw-r--r-- | src/runtime/c/gu/write.c | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/src/runtime/c/gu/write.c b/src/runtime/c/gu/write.c new file mode 100644 index 000000000..69573fb0d --- /dev/null +++ b/src/runtime/c/gu/write.c @@ -0,0 +1,174 @@ +#include <gu/write.h> + + +size_t +gu_utf32_write(const GuUCS* src, size_t len, GuWriter* wtr, GuExn* err) +{ + return gu_utf32_out_utf8(src, len, &wtr->out_, err); +} + + +void +gu_vprintf(const char* fmt, va_list args, GuWriter* wtr, GuExn* err) +{ + GuPool* tmp_pool = gu_local_pool(); + char* str = gu_vasprintf(fmt, args, tmp_pool); + gu_puts(str, wtr, err); + gu_pool_free(tmp_pool); +} + +void +gu_printf(GuWriter* wtr, GuExn* err, const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + gu_vprintf(fmt, args, wtr, err); + va_end(args); +} + + +GuWriter* +gu_new_utf8_writer(GuOut* utf8_out, GuPool* pool) +{ + GuOutStream* stream = gu_out_proxy_stream(utf8_out, pool); + GuWriter* wtr = gu_new(GuWriter, pool); + wtr->out_ = gu_init_out(stream); + return wtr; +} + + +#if 0 +#ifdef GU_UCS_WCHAR +#include <stdlib.h> +#include <wchar.h> +static const mbstate_t gu_init_mbstate; // implicitly initialized to zero +#endif + +typedef struct GuLocaleWriter GuLocaleWriter; + +struct GuLocaleWriter { + GuOutWriter owtr; +#ifdef GU_UCS_WCHAR + mbstate_t ps; + size_t mb_cur_max; +#endif +}; + +size_t +gu_locale_writer_write(GuWriter* wtr, const uint8_t* utf8_src, size_t sz, + GuExn* err) +{ + GuLocaleWriter* lwtr = (GuLocaleWriter*) wtr; + size_t done = 0; + static const size_t bufsize = 256; +#ifdef GU_UCS_WCHAR + size_t margin = lwtr->mb_cur_max; +#else + size_t margin = 1; +#endif + GuOut* out = lwtr->owtr.out; + if (gu_out_is_buffered(out)) { + while (done < sz) { + size_t dst_sz; + uint8_t* dst = gu_out_begin_span(out, &dst_sz); + if (!dst) { + break; + } + if (dst_sz <= margin) { + gu_out_end_span(out, 0); + break; + } + size_t end = dst_sz - margin; + const uint8_t* + size_t n = done; + while (n < sz && dst_i <= end) { +#ifdef GU_UCS_WCHAR + GuUCS ucs = gu_ + wchar_t wc = src[n]; + size_t nb = wcrtomb((char*) p, wc, &lwtr->ps); +#else + *p = (uint8_t) gu_ucs_char(buf[n], err); + size_t nb = 1; + if (!gu_ok(err)) { + gu_exn_clear(err); + nb = (size_t) -1; + } +#endif + if (nb == (size_t) -1) { + *p++ = (uint8_t) '?'; + } else { + p += nb; + } + + } + for ( + + } + + + + } + + uint8_t cbuf[256]; + while (done < size && gu_ok(err)) { + uint8_t* p = cbuf; + uint8_t* edge = &cbuf[bufsize - margin]; + size_t n; + for (n = done; p <= edge && n < size; n++) { +#ifdef GU_UCS_WCHAR + wchar_t wc = buf[n]; + size_t nb = wcrtomb((char*) p, wc, &lwtr->ps); +#else + *p = (uint8_t) gu_ucs_char(buf[n], err); + size_t nb = 1; + if (!gu_ok(err)) { + gu_exn_clear(err); + nb = (size_t) -1; + } +#endif + if (nb == (size_t) -1) { + *p++ = (uint8_t) '?'; + } else { + p += nb; + } + } + gu_out_bytes(lwtr->owtr.out, cbuf, p - cbuf, err); + if (gu_ok(err)) { + done = n; + } + } + return done; +} + +GuWriter* +gu_locale_writer(GuOut* out, GuPool* pool) +{ + GuLocaleWriter* lwtr = gu_new_s( + pool, GuLocaleWriter, + .wtr.out.output = gu_locale_writer_output, + .wtr.out.flush = gu_locale_writer_flush, + .out = out); +#ifdef GU_UCS_WCHAR + lwtr->ps = gu_init_mbstate; + lwtr->mb_cur_max = MB_CUR_MAX; +#endif + return (GuWriter*) lwtr; +} + +#endif + +extern inline void +gu_ucs_write(GuUCS ucs, GuWriter* wtr, GuExn* err); + +extern inline void +gu_writer_flush(GuWriter* wtr, GuExn* err); + +extern inline void +gu_putc(char c, GuWriter* wtr, GuExn* err); + +extern inline void +gu_puts(const char* str, GuWriter* wtr, GuExn* err); + +extern inline size_t +gu_utf8_write(const uint8_t* src, size_t sz, GuWriter* wtr, GuExn* err); + |
