From 9f6510850e3782a22b0ac282161f5e1e7413f3f2 Mon Sep 17 00:00:00 2001 From: Bryan Jurish Date: Sun, 25 Jan 2009 22:16:17 +0000 Subject: + got 'wchars' objects working svn path=/trunk/externals/moocow/; revision=10638 --- pdstring+wchar/src/pdstringUtils.c | 239 +++++++++++++++++++++++++++++-------- 1 file changed, 192 insertions(+), 47 deletions(-) (limited to 'pdstring+wchar/src/pdstringUtils.c') diff --git a/pdstring+wchar/src/pdstringUtils.c b/pdstring+wchar/src/pdstringUtils.c index b07f760..2596422 100644 --- a/pdstring+wchar/src/pdstringUtils.c +++ b/pdstring+wchar/src/pdstringUtils.c @@ -105,7 +105,9 @@ typedef struct _pdstring_atoms { * Initialization *=====================================================================*/ -//-- bytes +/*--------------------------------------------------------------------- + * bytes + */ static void pdstring_bytes_clear(t_pdstring_bytes *b) { if (b->b_alloc) freebytes(b->b_buf, (b->b_alloc)*sizeof(unsigned char)); @@ -125,7 +127,9 @@ static void pdstring_bytes_init(t_pdstring_bytes *b, size_t n) pdstring_bytes_realloc(b,n); } -//-- wchars +/*--------------------------------------------------------------------- + * wchars + */ static void pdstring_wchars_clear(t_pdstring_wchars *w) { if (w->w_alloc) freebytes(w->w_buf, (w->w_alloc)*sizeof(wchar_t)); @@ -145,7 +149,9 @@ static void pdstring_wchars_init(t_pdstring_wchars *w, size_t n) pdstring_wchars_realloc(w,n); } -//-- atoms +/*--------------------------------------------------------------------- + * atoms + */ static void pdstring_atoms_clear(t_pdstring_atoms *a) { if (a->a_alloc) freebytes(a->a_buf, (a->a_alloc)*sizeof(t_atom)); @@ -171,35 +177,67 @@ static void pdstring_atoms_init(t_pdstring_atoms *a, size_t n) *=====================================================================*/ /*-------------------------------------------------------------------- - * pdstring_atoms2bytes() - * + always appends a final NUL byte to *dst_buf, even if src_argv doesn't contain one - * + returns number of bytes actually written to *dst_buf, __including__ implicit trailing NUL + * pdstring_any2bytes() + * + x is used for error reporting + * + uses x_binbuf for conversion + * + selector sel is added to binbuf too, if it is none of {NULL, &s_float, &s_list, &s_} + * + x_binbuf may be NULL, in which case a temporary t_binbuf is created and used + * - in this case, output bytes are copied into *dst, reallocating if required + * + if x_binbuf is given and non-NULL, dst may be NULL. + * - if dst is non-NULL, its values will be clobbered by those returned by + * binbuf_gettext() */ -static int pdstring_atoms2bytes(t_pdstring_bytes *dst, //-- destination byte buffer - t_pdstring_atoms *src, //-- source t_atom float list - t_float x_eos) //-- EOS byte value: stop if reached (negative ~ 0) +static void pdstring_any2bytes(void *x, t_pdstring_bytes *dst, t_symbol *sel, t_pdstring_atoms *src, t_binbuf *x_binbuf) { - t_atom *argv = src->a_buf; - int argc = src->a_len; - unsigned char *s; - int new_len=0; + int bb_is_tmp=0; - /*-- re-allocate? --*/ - if (dst->b_alloc <= (argc+1)) - pdstring_bytes_realloc(dst, argc + 1 + PDSTRING_BYTES_GET); + //-- create temporary binbuf? + if (!x_binbuf) { + x_binbuf = binbuf_new(); + bb_is_tmp = 1; + } - /*-- get byte string --*/ - for (s=dst->b_buf, new_len=0; argc > 0; argc--, argv++, s++, new_len++) - { - *s = atom_getfloat(argv); - if ((x_eos<0 && !*s) || (*s==x_eos)) { break; } /*-- hack: truncate at first EOS char --*/ - } - *s = '\0'; /*-- always append terminating NUL */ - dst->b_len = new_len; + //-- prepare binbuf + binbuf_clear(x_binbuf); - return new_len+1; + //-- binbuf_add(): selector + if (sel && sel != &s_float && sel != &s_list && sel != &s_) { + t_atom a; + SETSYMBOL((&a), sel); + binbuf_add(x_binbuf, 1, &a); + } + + //-- binbuf_add(): src atoms + binbuf_add(x_binbuf, src->a_len, src->a_buf); + + //-- output: get text string + if (bb_is_tmp) { + //-- temporary binbuf: copy text + char *text; + int len; + binbuf_gettext(x_binbuf, &text, &len); + + //-- reallocate? + if ( dst->b_alloc < len ) + pdstring_bytes_realloc(dst, len + PDSTRING_BYTES_GET); + + //-- copy + memcpy(dst->b_buf, text, len*sizeof(char)); + dst->b_len = len; + + //-- cleanup + binbuf_free(x_binbuf); + if (text) freebytes(text,len); + } + else if (dst) { + //-- permanent binbuf: clobber dst + pdstring_bytes_clear(dst); + binbuf_gettext(x_binbuf, ((char**)((void*)(&dst->b_buf))), &dst->b_len); + dst->b_alloc = dst->b_len; + } } + /*-------------------------------------------------------------------- * pdstring_bytes2any() * + uses x_binbuf for conversion @@ -209,7 +247,7 @@ static int pdstring_atoms2bytes(t_pdstring_bytes *dst, //-- destination byte buf * - if dst is non-NULL, its values will be clobbered by those returned by * binbuf_getnatom() and binbuf_getvec() */ -static void pdstring_bytes2any(t_pdstring_atoms *dst, t_pdstring_bytes *src, t_binbuf *x_binbuf) +static void pdstring_bytes2any(void *x, t_pdstring_atoms *dst, t_pdstring_bytes *src, t_binbuf *x_binbuf) { int bb_is_tmp=0; @@ -235,7 +273,6 @@ static void pdstring_bytes2any(t_pdstring_atoms *dst, t_pdstring_bytes *src, t_b if ( dst->a_alloc < argc ) pdstring_atoms_realloc(dst, argc + PDSTRING_ATOMS_GET); - //-- copy memcpy(dst->a_buf, argv, argc*sizeof(t_atom)); dst->a_len = argc; @@ -251,44 +288,152 @@ static void pdstring_bytes2any(t_pdstring_atoms *dst, t_pdstring_bytes *src, t_b } } + /*-------------------------------------------------------------------- - * pdstring_bytes2wchars() + * pdstring_atoms2bytes() + * + always appends a final NUL byte to *dst_buf, even if src_argv doesn't contain one + * + returns number of bytes actually written to *dst_buf, __including__ implicit trailing NUL */ -static int pdstring_bytes2wchars(t_pdstring_wchars *dst, t_pdstring_bytes *src) +static int pdstring_atoms2bytes(void *x, t_pdstring_bytes *dst, t_pdstring_atoms *src, t_float x_eos) { - /* - //-- get required length - int nwc=0, size; + t_atom *argv = src->a_buf; + int argc = src->a_len; unsigned char *s; - for (s=src->b_buf, size=src->b_len, nwc=0; size>0; nwc++) { - int csize = mblen(s,size); - if (csize < 0) { - error("pdstring_bytes2wchars(): could not compute length for byte-string \"%s\" - skipping a byte!"); - s++; - continue; + int new_len=0; + + /*-- re-allocate? --*/ + if (dst->b_alloc <= (argc+1)) + pdstring_bytes_realloc(dst, argc + 1 + PDSTRING_BYTES_GET); + + /*-- get byte string --*/ + for (s=dst->b_buf, new_len=0; argc > 0; argc--, argv++, s++, new_len++) + { + *s = atom_getfloat(argv); + if ((x_eos<0 && !*s) || (*s==x_eos)) { break; } /*-- hack: truncate at first EOS char --*/ } - s += csize; - } - */ + *s = '\0'; /*-- always append terminating NUL */ + dst->b_len = new_len; + + return new_len+1; +} + +/*-------------------------------------------------------------------- + * pdstring_atoms2wchars() + * + always appends a final NUL wchar_t to dst->w_buf, even if src->a_buf doesn't contain one + * + returns number of bytes actually written to dst->w_buf, __including__ implicit trailing NUL + * + but dst->w_len does NOT include implicit trailing NUL + */ +static int pdstring_atoms2wchars(void *x, t_pdstring_wchars *dst, t_pdstring_atoms *src, t_float x_eos) +{ + t_atom *argv = src->a_buf; + int argc = src->a_len; + int new_len=0; + wchar_t *s; + + /*-- re-allocate? --*/ + if (dst->w_alloc <= (argc+1)) + pdstring_wchars_realloc(dst, argc + 1 + PDSTRING_WCHARS_GET); + + /*-- get wchar_t string --*/ + for (s=dst->w_buf, new_len=0; argc > 0; argc--, argv++, s++, new_len++) + { + *s = atom_getfloat(argv); + if ((x_eos<0 && !*s) || (*s==x_eos)) { break; } /*-- hack: truncate at first EOS char --*/ + } + *s = L'\0'; /*-- always append terminating NUL */ + dst->w_len = new_len; + + return new_len+1; +} + + +/*-------------------------------------------------------------------- + * pdstring_bytes2wchars() + */ +static int pdstring_bytes2wchars(void *x, t_pdstring_wchars *dst, t_pdstring_bytes *src) +{ + size_t bi, wi; //-- re-allocate? if ( dst->w_alloc < src->b_len ) pdstring_wchars_realloc(dst, src->b_len + PDSTRING_WCHARS_GET); //-- convert - size_t newlen = mbstowcs(dst->w_buf, (char*)src->b_buf, src->b_len); - if (newlen==((size_t)-1)) { - error("pdstring_bytes2wchars(): could not convert multibyte string \"%s\"", src->b_buf); + //PDSDEBUG(post("\nbytes2wchars[dst=%p,src=%p]: init", dst,src);) + mbtowc(NULL,NULL,0); //-- re-initialize conversion state for mbtowc() + for (bi=0,wi=0; bib_len; wi++) { + int nbytes = mbtowc(dst->w_buf+wi, (char*)(src->b_buf+bi), src->b_len-bi); + if (nbytes <= 0) { + if (nbytes < 0) { + pd_error(x,"pdstring_bytes2wchars(): malformed byte string \"%s\" at char '%c' - copying literal byte", src->b_buf, src->b_buf[bi]); + } + dst->w_buf[wi] = src->b_buf[bi]; + nbytes = 1; + } + bi += nbytes; + //PDSDEBUG(post("bytes2wchars[dst=%p,src=%p]: loop[bi=%d,wi=%d,src=%s]: nbytes=%d,wc=%u", dst,src, bi,wi,src, nbytes,dst->w_buf[wi])); + } + dst->w_len = wi; + return wi; +} + +/*-------------------------------------------------------------------- + * pdstring_wchars2bytes() + */ +static int pdstring_wchars2bytes(void *x, t_pdstring_bytes *dst, t_pdstring_wchars *src) +{ + size_t bi, wi; + + //-- re-allocate? + if ( dst->b_alloc < src->w_len * MB_CUR_MAX ) + pdstring_bytes_realloc(dst, src->w_len * MB_CUR_MAX + PDSTRING_WCHARS_GET); + + //-- convert + for (bi=0,wi=0; wi < src->w_len; wi++) { + int nbytes = wctomb((char*)dst->b_buf+bi, src->w_buf[wi]); + if (nbytes <= 0) { + if (nbytes < 0) { + pd_error(x,"pdstring_wchars2bytes(): malformed wide string \"%S\" at wchar_t '%C' - forcing literal value", src->w_buf, src->w_buf[wi]); + } + dst->b_buf[bi] = src->w_buf[wi]; + nbytes = 1; + } + bi += nbytes; } - dst->w_len = newlen; + dst->b_len = bi; + return bi; +} + - return (newlen < src->b_len ? newlen : newlen+1); +/*-------------------------------------------------------------------- + * pdstring_bytes2atoms() + * + implicitly appends x_eos if >= 0 and != PDSTRING_EOS_NONE + */ +static void pdstring_bytes2atoms(void *x, t_pdstring_atoms *dst, t_pdstring_bytes *src, t_float x_eos) +{ + int i; + + //-- re-allocate? + if ( dst->a_alloc <= src->b_len ) + pdstring_atoms_realloc(dst, src->b_len + 1 + PDSTRING_ATOMS_GET); + + //-- convert + for (i=0; i < src->b_len; i++) { + SETFLOAT((dst->a_buf+i), src->b_buf[i]); + } + dst->a_len = src->b_len; + + //-- append eos atom? + if (x_eos >= 0 && x_eos != PDSTRING_EOS_NONE) { + SETFLOAT(dst->a_buf+dst->a_len, x_eos); + dst->a_len++; + } } /*-------------------------------------------------------------------- * pdstring_wchars2atoms() */ -static void pdstring_wchars2atoms(t_pdstring_atoms *dst, t_pdstring_wchars *src) +static void pdstring_wchars2atoms(void *x, t_pdstring_atoms *dst, t_pdstring_wchars *src) { int i; -- cgit v1.2.1