aboutsummaryrefslogtreecommitdiff
path: root/pdstring+wchar/src/pdstringUtils.c
diff options
context:
space:
mode:
Diffstat (limited to 'pdstring+wchar/src/pdstringUtils.c')
-rw-r--r--pdstring+wchar/src/pdstringUtils.c239
1 files changed, 192 insertions, 47 deletions
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; bi<src->b_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;