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/configure | 2 +- pdstring+wchar/configure.ac | 2 +- pdstring+wchar/src/Makefile.am | 30 ++- pdstring+wchar/src/Makefile.in | 45 +++- pdstring+wchar/src/any2bytes-help.pd | 4 +- pdstring+wchar/src/any2bytes.c | 108 ++------ pdstring+wchar/src/any2wchars-help.pd | 37 +++ pdstring+wchar/src/any2wchars.pd | 10 + pdstring+wchar/src/bytes2any.c | 9 +- pdstring+wchar/src/bytes2wchars-help.pd | 46 ++++ pdstring+wchar/src/bytes2wchars-test.pd | 16 +- pdstring+wchar/src/bytes2wchars.c | 8 +- pdstring+wchar/src/pdstring-help.pd | 82 ++++-- pdstring+wchar/src/pdstring.c | 2 + pdstring+wchar/src/pdstringUtils.c | 239 +++++++++++++---- pdstring+wchar/src/pdstringUtils.h | 452 ++++++++++++++++++++++++++++++++ pdstring+wchar/src/wchars2any-help.pd | 42 +++ pdstring+wchar/src/wchars2any.pd | 12 + pdstring+wchar/src/wchars2bytes-help.pd | 44 ++++ pdstring+wchar/src/wchars2bytes-test.pd | 46 ++++ pdstring+wchar/src/wchars2bytes.c | 157 +++++++++++ 21 files changed, 1209 insertions(+), 184 deletions(-) create mode 100644 pdstring+wchar/src/any2wchars-help.pd create mode 100644 pdstring+wchar/src/any2wchars.pd create mode 100644 pdstring+wchar/src/bytes2wchars-help.pd create mode 100644 pdstring+wchar/src/pdstringUtils.h create mode 100644 pdstring+wchar/src/wchars2any-help.pd create mode 100644 pdstring+wchar/src/wchars2any.pd create mode 100644 pdstring+wchar/src/wchars2bytes-help.pd create mode 100644 pdstring+wchar/src/wchars2bytes-test.pd create mode 100644 pdstring+wchar/src/wchars2bytes.c (limited to 'pdstring+wchar') diff --git a/pdstring+wchar/configure b/pdstring+wchar/configure index d4be0f4..9787a42 100755 --- a/pdstring+wchar/configure +++ b/pdstring+wchar/configure @@ -3543,7 +3543,7 @@ esac ##------- PD externals: hack EXEEXT? PD_LIB_EXTERNALS="pdstring" -PD_OBJ_EXTERNALS="any2bytes bytes2any bytes2wchars" +PD_OBJ_EXTERNALS="any2bytes bytes2any bytes2wchars wchars2bytes" # Check whether --enable-object-externals was given. if test "${enable_object_externals+set}" = set; then diff --git a/pdstring+wchar/configure.ac b/pdstring+wchar/configure.ac index cca35f6..aa2af8d 100644 --- a/pdstring+wchar/configure.ac +++ b/pdstring+wchar/configure.ac @@ -88,7 +88,7 @@ esac ##------- PD externals: hack EXEEXT? PD_LIB_EXTERNALS="pdstring" -PD_OBJ_EXTERNALS="any2bytes bytes2any bytes2wchars" +PD_OBJ_EXTERNALS="any2bytes bytes2any bytes2wchars wchars2bytes" AC_ARG_ENABLE(object-externals, AC_HELP_STRING([--enable-object-externals], [Whether to build single-object externals (default=no)]), diff --git a/pdstring+wchar/src/Makefile.am b/pdstring+wchar/src/Makefile.am index 69e2efb..7f8df55 100644 --- a/pdstring+wchar/src/Makefile.am +++ b/pdstring+wchar/src/Makefile.am @@ -33,27 +33,41 @@ pdexterns_PROGRAMS = @PD_OBJECT_EXTERNALS@ EXTRA_PROGRAMS = \ pdstring \ any2bytes \ - bytes2any + bytes2any \ + bytes2wchars \ + wchars2bytes ## --- patches -pdexterns_DATA = +pdexterns_DATA = \ + any2wchars.pd \ + wchars2any.pd ## --- documentation pddoc_DATA = \ pdstring-help.pd \ any2bytes-help.pd \ - bytes2any-help.pd + bytes2any-help.pd \ + bytes2wchars-help.pd \ + wchars2bytes-help.pd \ + any2wchars-help.pd \ + wchars2any-help.pd #----------------------------------------------------------------------- # sources #----------------------------------------------------------------------- -pdstring_SOURCES = pdstring.c mooPdUtils.h +any2bytes_SOURCES = any2bytes.c mooPdUtils.h pdstringUtils.h -any2bytes_SOURCES = any2bytes.c mooPdUtils.h +bytes2any_SOURCES = bytes2any.c mooPdUtils.h pdstringUtils.h -bytes2any_SOURCES = bytes2any.c mooPdUtils.h +bytes2wchars_SOURCES = bytes2wchars.c mooPdUtils.h pdstringUtils.h + +wchars2bytes_SOURCES = wchars2bytes.c mooPdUtils.h pdstringUtils.h + +pdstring_SOURCES = pdstring.c mooPdUtils.h pdstringUtils.h + +pdstring.$(OBJECT): $(any2bytes_SOURCES) $(bytes2any_SOURCES) $(bytes2wchars_SOURCES) $(wchars2bytes_SOURCES) #----------------------------------------------------------------------- # external compilation : flags @@ -78,6 +92,10 @@ bytes2any_LDFLAGS = $(LFLAGS) any2bytes_LDFLAGS = $(LFLAGS) +bytes2wchars_LDFLAGS = $(LFLAGS) + +wchars2bytes_LDFLAGS = $(LFLAGS) + #----------------------------------------------------------------------- # Variables: cleanup #----------------------------------------------------------------------- diff --git a/pdstring+wchar/src/Makefile.in b/pdstring+wchar/src/Makefile.in index 5f5b1ae..265ee20 100644 --- a/pdstring+wchar/src/Makefile.in +++ b/pdstring+wchar/src/Makefile.in @@ -51,7 +51,7 @@ PRE_UNINSTALL = : POST_UNINSTALL = : pdexterns_PROGRAMS = @PD_OBJECT_EXTERNALS@ EXTRA_PROGRAMS = pdstring$(EXEEXT) any2bytes$(EXEEXT) \ - bytes2any$(EXEEXT) + bytes2any$(EXEEXT) bytes2wchars$(EXEEXT) wchars2bytes$(EXEEXT) subdir = src SUBDIRS = DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ @@ -73,9 +73,15 @@ any2bytes_LDADD = $(LDADD) am_bytes2any_OBJECTS = bytes2any.$(OBJEXT) bytes2any_OBJECTS = $(am_bytes2any_OBJECTS) bytes2any_LDADD = $(LDADD) +am_bytes2wchars_OBJECTS = bytes2wchars.$(OBJEXT) +bytes2wchars_OBJECTS = $(am_bytes2wchars_OBJECTS) +bytes2wchars_LDADD = $(LDADD) am_pdstring_OBJECTS = pdstring.$(OBJEXT) pdstring_OBJECTS = $(am_pdstring_OBJECTS) pdstring_LDADD = $(LDADD) +am_wchars2bytes_OBJECTS = wchars2bytes.$(OBJEXT) +wchars2bytes_OBJECTS = $(am_wchars2bytes_OBJECTS) +wchars2bytes_LDADD = $(LDADD) DEFAULT_INCLUDES = -I. -I$(srcdir) -I. depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles @@ -84,9 +90,11 @@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(any2bytes_SOURCES) $(bytes2any_SOURCES) \ - $(pdstring_SOURCES) + $(bytes2wchars_SOURCES) $(pdstring_SOURCES) \ + $(wchars2bytes_SOURCES) DIST_SOURCES = $(any2bytes_SOURCES) $(bytes2any_SOURCES) \ - $(pdstring_SOURCES) + $(bytes2wchars_SOURCES) $(pdstring_SOURCES) \ + $(wchars2bytes_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-exec-recursive install-info-recursive \ @@ -204,19 +212,28 @@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ SUFFIXES = .@PDEXT@ -pdexterns_DATA = +pdexterns_DATA = \ + any2wchars.pd \ + wchars2any.pd + pddoc_DATA = \ pdstring-help.pd \ any2bytes-help.pd \ - bytes2any-help.pd + bytes2any-help.pd \ + bytes2wchars-help.pd \ + wchars2bytes-help.pd \ + any2wchars-help.pd \ + wchars2any-help.pd #----------------------------------------------------------------------- # sources #----------------------------------------------------------------------- -pdstring_SOURCES = pdstring.c mooPdUtils.h -any2bytes_SOURCES = any2bytes.c mooPdUtils.h -bytes2any_SOURCES = bytes2any.c mooPdUtils.h +any2bytes_SOURCES = any2bytes.c mooPdUtils.h pdstringUtils.h +bytes2any_SOURCES = bytes2any.c mooPdUtils.h pdstringUtils.h +bytes2wchars_SOURCES = bytes2wchars.c mooPdUtils.h pdstringUtils.h +wchars2bytes_SOURCES = wchars2bytes.c mooPdUtils.h pdstringUtils.h +pdstring_SOURCES = pdstring.c mooPdUtils.h pdstringUtils.h #GLIB_IFLAGS = @GLIB_IFLAGS@ #GLIB_LFLAGS = @GLIB_LFLAGS@ @@ -225,6 +242,8 @@ AM_CFLAGS = $(OFLAGS) $(WFLAGS) $(AFLAGS) pdstring_LDFLAGS = $(LFLAGS) bytes2any_LDFLAGS = $(LFLAGS) any2bytes_LDFLAGS = $(LFLAGS) +bytes2wchars_LDFLAGS = $(LFLAGS) +wchars2bytes_LDFLAGS = $(LFLAGS) #----------------------------------------------------------------------- # Variables: cleanup @@ -338,9 +357,15 @@ any2bytes$(EXEEXT): $(any2bytes_OBJECTS) $(any2bytes_DEPENDENCIES) bytes2any$(EXEEXT): $(bytes2any_OBJECTS) $(bytes2any_DEPENDENCIES) @rm -f bytes2any$(EXEEXT) $(LINK) $(bytes2any_LDFLAGS) $(bytes2any_OBJECTS) $(bytes2any_LDADD) $(LIBS) +bytes2wchars$(EXEEXT): $(bytes2wchars_OBJECTS) $(bytes2wchars_DEPENDENCIES) + @rm -f bytes2wchars$(EXEEXT) + $(LINK) $(bytes2wchars_LDFLAGS) $(bytes2wchars_OBJECTS) $(bytes2wchars_LDADD) $(LIBS) pdstring$(EXEEXT): $(pdstring_OBJECTS) $(pdstring_DEPENDENCIES) @rm -f pdstring$(EXEEXT) $(LINK) $(pdstring_LDFLAGS) $(pdstring_OBJECTS) $(pdstring_LDADD) $(LIBS) +wchars2bytes$(EXEEXT): $(wchars2bytes_OBJECTS) $(wchars2bytes_DEPENDENCIES) + @rm -f wchars2bytes$(EXEEXT) + $(LINK) $(wchars2bytes_LDFLAGS) $(wchars2bytes_OBJECTS) $(wchars2bytes_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -350,7 +375,9 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/any2bytes.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bytes2any.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bytes2wchars.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdstring.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wchars2bytes.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @@ -682,6 +709,8 @@ uninstall-info: uninstall-info-recursive uninstall-pdexternsPROGRAMS +pdstring.$(OBJECT): $(any2bytes_SOURCES) $(bytes2any_SOURCES) $(bytes2wchars_SOURCES) $(wchars2bytes_SOURCES) + maintainer-clean-local: rm -rf autom4te.cache diff --git a/pdstring+wchar/src/any2bytes-help.pd b/pdstring+wchar/src/any2bytes-help.pd index 215a27f..ef0ce17 100644 --- a/pdstring+wchar/src/any2bytes-help.pd +++ b/pdstring+wchar/src/any2bytes-help.pd @@ -10,10 +10,10 @@ #X text 188 103 anything can be converted to a list...; #X text 190 147 ... but "float" selector is silently dropped; #X msg 25 104 A B C; -#X text 193 312 First argument: initial buffer size (length of object-local +#X text 182 312 First argument: initial buffer size (length of object-local text buffer). This should get re-allocated when necessary. Specify 0 (zero) to use the default value.; -#X text 195 367 Second argument: initial EOS character. See above. +#X text 184 367 Second argument: initial EOS character. See above. ; #X text 320 458 Bryan Jurish ; #X text 19 439 SEE ALSO:; diff --git a/pdstring+wchar/src/any2bytes.c b/pdstring+wchar/src/any2bytes.c index 4500ee3..c2b2425 100644 --- a/pdstring+wchar/src/any2bytes.c +++ b/pdstring+wchar/src/any2bytes.c @@ -32,7 +32,7 @@ #endif #include "mooPdUtils.h" -#include "pdstringUtils.c" +#include "pdstringUtils.h" /* black magic */ #ifdef NT @@ -62,14 +62,12 @@ static t_class *any2bytes_class; typedef struct _any2bytes { t_object x_obj; - int x_alloc; - int x_argc; - t_float x_eos; //-- EOS character to add (<0 for none) - char *x_text; - t_atom *x_argv; - t_binbuf *x_binbuf; - t_inlet *x_eos_in; - t_outlet *x_outlet; + t_pdstring_bytes x_bytes; //-- byte buffer + t_pdstring_atoms x_atoms; //-- atom buffer (for output) + t_float x_eos; //-- EOS character to add (<0 for none) + t_binbuf *x_binbuf; + t_inlet *x_eos_in; + t_outlet *x_outlet; } t_any2bytes; @@ -87,82 +85,31 @@ static char *any2bytes_banner = "any2bytes: pdstring version " PACKAGE_VERSION " */ static void any2bytes_anything(t_any2bytes *x, t_symbol *sel, int argc, t_atom *argv) { - t_atom *ap; - unsigned char *s, *s_max; - int len; - - A2SDEBUG(post("-------any2bytes_anything(%p,...)---------", x)); - - /*-- set up binbuf --*/ - A2SDEBUG(post("any2bytes[%p]: binbuf_clear()", x)); - binbuf_clear(x->x_binbuf); - - /*-- binbuf_add(): selector --*/ - if (sel != &s_float && sel != &s_list && sel != &s_) { - t_atom a; - A2SDEBUG(post("any2bytes[%p]: binbuf_add(): selector: '%s'", x, sel->s_name)); - SETSYMBOL((&a), sel); - binbuf_add(x->x_binbuf, 1, &a); - } - A2SDEBUG(else { post("any2bytes[%p]: selector: '%s': IGNORED", x, sel->s_name); }); - - /*-- binbuf_add(): arg list --*/ - A2SDEBUG(post("any2bytes[%p]: binbuf_add(): arg list", x)); - binbuf_add(x->x_binbuf, argc, argv); - A2SDEBUG(post("any2bytes[%p]: binbuf_print: ", x)); - A2SDEBUG(binbuf_print(x->x_binbuf)); - - A2SDEBUG(post("any2bytes[%p]: binbuf_gettext()", x)); - binbuf_gettext(x->x_binbuf, &(x->x_text), &len); - A2SDEBUG(post("any2bytes[%p]: binbuf_gettext() = \"%s\" ; len=%d", x, x->x_text, len)); - /*text[len] = 0;*/ /*-- ? avoid errors: "free(): invalid next size(fast): 0x..." */ - - /*-- get output atom-list length --*/ - x->x_argc = len; - if (x->x_eos >= 0) { x->x_argc++; } - A2SDEBUG(post("any2bytes[%p]: argc=%d", x, x->x_argc)); - - /*-- (re-)allocate (maybe) --*/ - if (x->x_alloc < x->x_argc) { - A2SDEBUG(post("any2bytes[%p]: reallocate(%d->%d)", x, x->x_alloc, x->x_argc)); - freebytes(x->x_argv, x->x_alloc*sizeof(t_atom)); - x->x_argv = (t_atom*)getbytes(x->x_argc * sizeof(t_atom)); - x->x_alloc = x->x_argc; - } - - /*-- atom buffer: binbuf text --*/ - A2SDEBUG(post("any2bytes[%p]: atom buffer: for {...}", x)); - ap = x->x_argv; - s_max = ((unsigned char *)x->x_text)+len; - for (s=((unsigned char *)x->x_text); s < s_max; s++, ap++) { - A2SDEBUG(post("any2bytes[%p]: atom buffer[%d]: SETFLOAT(a,%d='%c')", x, (ap-x->x_argv), *s, *s)); - SETFLOAT(ap,*s); - } - A2SDEBUG(post("any2bytes: atom buffer: DONE")); - - /*-- add EOS character (maybe) --*/ - if (x->x_eos >= 0) { SETFLOAT(ap, ((int)x->x_eos)); } - - A2SDEBUG(post("any2bytes: outlet_list(..., %d, ...)", x->x_argc)); - outlet_list(x->x_outlet, &s_list, x->x_argc, x->x_argv); + //-- convert any -> bytes -> atoms + t_pdstring_atoms arg_atoms = {argv,argc,0}; + pdstring_bytes_clear(&x->x_bytes); + pdstring_any2bytes(x, &x->x_bytes, sel, &arg_atoms, x->x_binbuf); + pdstring_bytes2atoms(x, &x->x_atoms, &x->x_bytes, x->x_eos); + + //-- output + outlet_list(x->x_outlet, &s_list, x->x_atoms.a_len, x->x_atoms.a_buf); } - /*-------------------------------------------------------------------- * new */ static void *any2bytes_new(MOO_UNUSED t_symbol *sel, int argc, t_atom *argv) { t_any2bytes *x = (t_any2bytes *)pd_new(any2bytes_class); + int bufsize = ANY2BYTES_DEFAULT_BUFLEN; //-- defaults - x->x_eos = 0; - x->x_alloc = ANY2BYTES_DEFAULT_BUFLEN; + x->x_eos = 0; //-- args: 0: bufsize if (argc > 0) { - int bufsize = atom_getintarg(0, argc, argv); - if (bufsize > 0) { x->x_alloc = bufsize; } + int initial_bufsize = atom_getintarg(0, argc, argv); + if (initial_bufsize > 0) { bufsize = initial_bufsize; } } //-- args: 1: eos if (argc > 1) { @@ -170,9 +117,8 @@ static void *any2bytes_new(MOO_UNUSED t_symbol *sel, int argc, t_atom *argv) } //-- allocate - x->x_text = getbytes(x->x_alloc*sizeof(char)); - x->x_argc = 0; - x->x_argv = (t_atom *)getbytes(x->x_alloc*sizeof(t_atom)); + pdstring_bytes_init(&x->x_bytes, 0); //-- x_bytes gets clobbered by binbuf_gettext() + pdstring_atoms_init(&x->x_atoms, bufsize); x->x_binbuf = binbuf_new(); //-- inlets @@ -182,7 +128,7 @@ static void *any2bytes_new(MOO_UNUSED t_symbol *sel, int argc, t_atom *argv) x->x_outlet = outlet_new(&x->x_obj, &s_list); //-- report - A2SDEBUG(post("any2bytes_new(): x=%p, alloc=%d, eos=%d, text=%p, argv=%p, binbuf=%p", x, x->x_alloc, x->x_eos, x->x_text, x->x_argv, x->x_binbuf)); + A2SDEBUG(post("any2bytes_new(): x=%p, eos=%d, binbuf=%p", x, x->x_eos, x->x_binbuf)); return (void *)x; } @@ -192,14 +138,8 @@ static void *any2bytes_new(MOO_UNUSED t_symbol *sel, int argc, t_atom *argv) */ static void any2bytes_free(t_any2bytes *x) { - if (x->x_text) { - freebytes(x->x_text, x->x_alloc*sizeof(char)); - x->x_text = NULL; - } - if (x->x_argv) { - freebytes(x->x_argv, x->x_alloc*sizeof(t_atom)); - x->x_argv = NULL; - } + pdstring_bytes_clear(&x->x_bytes); + pdstring_atoms_clear(&x->x_atoms); binbuf_free(x->x_binbuf); inlet_free(x->x_eos_in); outlet_free(x->x_outlet); diff --git a/pdstring+wchar/src/any2wchars-help.pd b/pdstring+wchar/src/any2wchars-help.pd new file mode 100644 index 0000000..3ed9e63 --- /dev/null +++ b/pdstring+wchar/src/any2wchars-help.pd @@ -0,0 +1,37 @@ +#N canvas 72 8 636 478 10; +#X msg 109 197 0; +#X msg 77 197 -1; +#X text 19 47 INLETS:; +#X text 31 61 1 - pd messages; +#X text 247 49 OUTLETS:; +#X floatatom 44 147 8 0 0 0 - - -; +#X symbolatom 34 125 10 0 0 0 - - -; +#X text 189 125 ... no special handling for symbols; +#X text 188 103 anything can be converted to a list...; +#X text 190 147 ... but "float" selector is silently dropped; +#X msg 25 104 A B C; +#X text 182 312 First argument: initial buffer size (length of object-local +text buffer). This should get re-allocated when necessary. Specify +0 (zero) to use the default value.; +#X text 320 458 Bryan Jurish ; +#X text 19 439 SEE ALSO:; +#X msg 139 197 42; +#X text 31 75 2 - EOS character (float); +#X obj 100 438 pdstring; +#X obj 25 314 any2wchars 128 -1; +#X obj 25 400 print any2wchars-help; +#X text 21 29 SYNTAX: any2wchars [INITIAL_BUFSIZE [EOS_CHAR]]; +#X text 49 5 any2wchars : convert pd messages to a list of wchar_t +values; +#X text 263 63 1 - lists of wchar_t-valued floats; +#X text 184 194 The second inlet is as for [any2bytes]; +#X text 184 367 Second argument: initial EOS character. See [any2bytes]. +; +#X obj 168 438 locale; +#X connect 0 0 17 1; +#X connect 1 0 17 1; +#X connect 5 0 17 0; +#X connect 6 0 17 0; +#X connect 10 0 17 0; +#X connect 14 0 17 1; +#X connect 17 0 18 0; diff --git a/pdstring+wchar/src/any2wchars.pd b/pdstring+wchar/src/any2wchars.pd new file mode 100644 index 0000000..a531952 --- /dev/null +++ b/pdstring+wchar/src/any2wchars.pd @@ -0,0 +1,10 @@ +#N canvas 398 18 328 196 10; +#X obj 54 20 inlet; +#X obj 154 20 inlet; +#X obj 54 62 any2bytes \$1 \$2; +#X obj 54 134 outlet; +#X obj 54 90 bytes2wchars \$1; +#X connect 0 0 2 0; +#X connect 1 0 2 1; +#X connect 2 0 4 0; +#X connect 4 0 3 0; diff --git a/pdstring+wchar/src/bytes2any.c b/pdstring+wchar/src/bytes2any.c index 81f28bd..e4b3715 100644 --- a/pdstring+wchar/src/bytes2any.c +++ b/pdstring+wchar/src/bytes2any.c @@ -32,7 +32,7 @@ #endif #include "mooPdUtils.h" -#include "pdstringUtils.c" +#include "pdstringUtils.h" /* black magic */ #ifdef NT @@ -87,8 +87,8 @@ typedef struct _bytes2any static void bytes2any_atoms(t_bytes2any *x, int argc, t_atom *argv) { t_pdstring_atoms src = {argv,argc,argc}; - pdstring_atoms2bytes(&(x->x_bytes), &src, x->x_eos); - pdstring_bytes2any(NULL, &(x->x_bytes), x->x_binbuf); + pdstring_atoms2bytes(x, &(x->x_bytes), &src, x->x_eos); + pdstring_bytes2any(x, NULL, &(x->x_bytes), x->x_binbuf); int x_argc; t_atom *x_argv; @@ -183,8 +183,7 @@ static void *bytes2any_new(MOO_UNUSED t_symbol *sel, int argc, t_atom *argv) */ static void bytes2any_free(t_bytes2any *x) { - if (x->x_bytes.b_buf) - freebytes(x->x_bytes.b_buf, x->x_bytes.b_alloc*sizeof(unsigned char)); + pdstring_bytes_clear(&x->x_bytes); binbuf_free(x->x_binbuf); inlet_free(x->x_eos_in); outlet_free(x->x_outlet_done); diff --git a/pdstring+wchar/src/bytes2wchars-help.pd b/pdstring+wchar/src/bytes2wchars-help.pd new file mode 100644 index 0000000..3d3d0b6 --- /dev/null +++ b/pdstring+wchar/src/bytes2wchars-help.pd @@ -0,0 +1,46 @@ +#N canvas 610 14 566 410 10; +#X text 81 5 bytes2wchars : convert bytes to wide characters; +#X text 11 27 SYNTAX: bytes2wchars [INITIAL_BUFSIZE]; +#X text 11 46 INLETS:; +#X text 241 48 OUTLETS:; +#X text 19 62 1 - byte-valued float lists; +#X text 257 62 1 - wchar_t-valued float lists; +#X obj 24 310 bytes2wchars; +#X obj 24 334 print bytes2wchars-help; +#X msg 24 95 97 32 98 32 99; +#X msg 41 227 228 246 252; +#X msg 71 159 C; +#X text 69 129 8-bit values are interpreted according to the current +locale's LC_CTYPE category: here are some examples:; +#N canvas 0 0 338 182 locale_LC_CTYPE 0; +#X obj 48 124 locale; +#X obj 48 36 inlet; +#X obj 48 64 symbol; +#X msg 48 92 set LC_CTYPE \$1; +#X text 57 143 + requires the "locale" external; +#X connect 1 0 2 0; +#X connect 2 0 3 0; +#X connect 3 0 0 0; +#X restore 103 190 pd locale_LC_CTYPE; +#X msg 45 255 195 164 195 182 195 188; +#X text 219 253 ... the same string encoded in UTF-8; +#X text 205 387 Bryan Jurish ; +#X text 11 371 SEE ALSO:; +#X obj 26 388 pdstring; +#X obj 93 388 locale; +#X text 11 355 BUGS: float representation is only safe up to 24-bit +values; +#X msg 103 159 en_DK.ISO-8859-1; +#X msg 225 159 en_DK.UTF-8; +#X text 145 97 Values <= 127 are unchanged; +#X msg 49 281 207 128 206 180; +#X text 217 225 ISO-8859-1 bytes "ä \, ö \, ü"; +#X text 219 283 "&pi &delta" in UTF-8; +#X connect 6 0 7 0; +#X connect 8 0 6 0; +#X connect 9 0 6 0; +#X connect 10 0 12 0; +#X connect 13 0 6 0; +#X connect 20 0 12 0; +#X connect 21 0 12 0; +#X connect 23 0 6 0; diff --git a/pdstring+wchar/src/bytes2wchars-test.pd b/pdstring+wchar/src/bytes2wchars-test.pd index b5d3706..faeaea1 100644 --- a/pdstring+wchar/src/bytes2wchars-test.pd +++ b/pdstring+wchar/src/bytes2wchars-test.pd @@ -1,4 +1,4 @@ -#N canvas 96 10 578 300 10; +#N canvas 600 24 578 300 10; #X obj 114 136 bytes2wchars; #X obj 138 168 print wchars; #X obj 285 238 locale; @@ -13,15 +13,16 @@ #X floatatom 116 204 5 0 0 0 - - -; #X msg 41 61 195 182; #X text 39 23 ö \;; -#X text 95 41 latin1; -#X text 99 59 utf8; #X msg 159 61 197 147; #X text 155 23 &oelig \;; #X msg 159 39 339; #X msg 245 37 960; #X msg 245 59 207 128; #X text 245 21 &pi \;; -#X msg 337 63 207 128 197 147 195 182 0; +#X obj 353 136 loadbang; +#X text 97 41 ucs-4; +#X text 99 59 utf-8; +#X msg 337 63 207 128 0 197 147 0 195 182 0; #X connect 0 0 1 0; #X connect 0 0 11 0; #X connect 2 0 9 0; @@ -33,8 +34,9 @@ #X connect 8 0 5 0; #X connect 10 0 0 0; #X connect 12 0 0 0; +#X connect 14 0 0 0; #X connect 16 0 0 0; +#X connect 17 0 0 0; #X connect 18 0 0 0; -#X connect 19 0 0 0; -#X connect 20 0 0 0; -#X connect 22 0 0 0; +#X connect 20 0 7 0; +#X connect 23 0 0 0; diff --git a/pdstring+wchar/src/bytes2wchars.c b/pdstring+wchar/src/bytes2wchars.c index 185a3cb..7fbbc99 100644 --- a/pdstring+wchar/src/bytes2wchars.c +++ b/pdstring+wchar/src/bytes2wchars.c @@ -34,7 +34,7 @@ #endif #include "mooPdUtils.h" -#include "pdstringUtils.c" +#include "pdstringUtils.h" /* black magic */ #ifdef NT @@ -81,9 +81,9 @@ static void bytes2wchars_atoms(t_bytes2wchars *x, int argc, t_atom *argv) t_pdstring_atoms src = {argv,argc,0}; /*-- convert atoms -> bytes -> wchars -> atoms --*/ - pdstring_atoms2bytes(&x->x_bytes, &src, PDSTRING_EOS_NONE); - pdstring_bytes2wchars(&x->x_wchars, &x->x_bytes); - pdstring_wchars2atoms(&x->x_atoms, &x->x_wchars); //-- TODO + pdstring_atoms2bytes (x, &x->x_bytes, &src, PDSTRING_EOS_NONE); + pdstring_bytes2wchars(x, &x->x_wchars, &x->x_bytes); + pdstring_wchars2atoms(x, &x->x_atoms, &x->x_wchars); } diff --git a/pdstring+wchar/src/pdstring-help.pd b/pdstring+wchar/src/pdstring-help.pd index 12e6d42..9e3e0c3 100644 --- a/pdstring+wchar/src/pdstring-help.pd +++ b/pdstring+wchar/src/pdstring-help.pd @@ -1,11 +1,26 @@ -#N canvas 191 76 563 311 10; -#X text 258 284 Bryan Jurish ; +#N canvas 163 18 501 441 10; +#X text 196 400 Bryan Jurish ; +#X text 54 3 [pdstring] library : byte and wide-character strings; +#X obj 51 76 bytes2any; +#X obj 51 52 any2bytes; +#X text 148 77 convert byte strings to pd messages; +#X text 148 53 convert pd messages to byte strings; +#X obj 45 142 bytes2wchars; +#X text 147 143 convert byte strings to wide character strings; +#X obj 45 168 wchars2bytes; +#X text 148 169 convert wide character strings to byte strings; +#X text 22 121 BYTES <-> WIDE CHARACTERS; +#X text 26 33 BYTES <-> PD MESSAGES; +#X text 20 211 WIDE CHARACTERS <-> PD MESSAGES; +#X text 145 233 convert pd messages to wide character strings; +#X text 146 259 convert wide character strings to pd messages; +#X text 18 369 SEE ALSO:; +#N canvas 0 0 584 308 pdstring-bytes 0; #X floatatom 56 81 8 0 0 0 - - -; #X symbolatom 46 59 10 0 0 0 - - -; #X text 201 59 ... no special handling for symbols; #X text 200 37 anything can be converted to a list...; #X floatatom 54 178 4 0 0 0 - - -; -#X text 213 230 string2any converts ASCII lists to Pd messages...; #X text 202 81 ... but "float" selector is silently dropped; #N canvas 0 0 448 335 ascii-table 0; #X obj 162 144 f 0; @@ -37,23 +52,52 @@ #X connect 10 0 11 0; #X connect 10 1 11 0; #X connect 12 0 5 0; -#X restore 249 144 pd ascii-table; -#X msg 249 121 bang; -#X text 361 143 know your charset; +#X restore 289 156 pd ascii-table; +#X msg 289 133 bang; #X msg 37 38 A B C; #X msg 55 199 list 49 50 51; -#X text 54 3 any2string \, string2any : ASCII conversions in [pdstring] -lib; -#X obj 37 108 any2bytes; -#X obj 37 230 bytes2any; #X obj 58 139 print any2bytes-out; +#X obj 37 108 any2bytes; #X obj 37 254 print bytes2any-out; -#X connect 1 0 14 0; -#X connect 2 0 14 0; -#X connect 5 0 15 0; -#X connect 9 0 8 0; -#X connect 11 0 14 0; -#X connect 12 0 15 0; -#X connect 14 0 15 0; -#X connect 14 0 16 0; -#X connect 15 0 17 0; +#X obj 37 230 bytes2any; +#X text 289 173 ... know your character set; +#X text 213 230 bytes2any converts byte lists to Pd messages...; +#X connect 0 0 11 0; +#X connect 1 0 11 0; +#X connect 4 0 13 0; +#X connect 7 0 6 0; +#X connect 8 0 11 0; +#X connect 9 0 13 0; +#X connect 11 0 10 0; +#X connect 11 0 13 0; +#X connect 13 0 12 0; +#X restore 87 368 pd pdstring-bytes; +#N canvas 0 0 584 308 pdstring-wchars 0; +#X floatatom 56 81 8 0 0 0 - - -; +#X symbolatom 46 59 10 0 0 0 - - -; +#X text 201 59 ... no special handling for symbols; +#X text 200 37 anything can be converted to a list...; +#X floatatom 54 178 4 0 0 0 - - -; +#X text 202 81 ... but "float" selector is silently dropped; +#X msg 37 38 A B C; +#X msg 55 199 list 49 50 51; +#X obj 37 254 print wchars2any-out; +#X text 213 230 wchars2any converts wchar lists to Pd messages...; +#X obj 58 139 print any2wchars-out; +#X obj 37 108 any2wchars; +#X obj 37 230 wchars2any; +#X connect 0 0 11 0; +#X connect 1 0 11 0; +#X connect 4 0 12 0; +#X connect 6 0 11 0; +#X connect 7 0 12 0; +#X connect 11 0 10 0; +#X connect 11 0 12 0; +#X connect 12 0 8 0; +#X restore 217 368 pd pdstring-wchars; +#X obj 43 232 any2wchars; +#X obj 43 258 wchars2any; +#X obj 355 368 locale; +#X text 18 303 NOTE:; +#X text 26 319 Wide character support requires locale support to be +enabled \, e.g. by the [locale] external.; diff --git a/pdstring+wchar/src/pdstring.c b/pdstring+wchar/src/pdstring.c index bea27b1..907d16d 100644 --- a/pdstring+wchar/src/pdstring.c +++ b/pdstring+wchar/src/pdstring.c @@ -58,6 +58,7 @@ typedef struct _pdstring # include "any2bytes.c" # include "bytes2any.c" # include "bytes2wchars.c" +# include "wchars2bytes.c" #endif /*-------------------------------------------------------------------- @@ -90,6 +91,7 @@ void pdstring_setup(void) any2bytes_setup_guts(); bytes2any_setup_guts(); bytes2wchars_setup_guts(); + wchars2bytes_setup_guts(); #endif pdstring_class = class_new(gensym("pdstring"), 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; diff --git a/pdstring+wchar/src/pdstringUtils.h b/pdstring+wchar/src/pdstringUtils.h new file mode 100644 index 0000000..85a72a5 --- /dev/null +++ b/pdstring+wchar/src/pdstringUtils.h @@ -0,0 +1,452 @@ +/* -*- Mode: C -*- */ +/*=============================================================================*\ + * File: pdstringUtils.h + * Author: Bryan Jurish + * Description: pdstring: common utilities (static include) + * + * Copyright (c) 2009 Bryan Jurish. + * + * For information on usage and redistribution, and for a DISCLAIMER OF ALL + * WARRANTIES, see the file "COPYING", in this distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *=============================================================================*/ + +#ifndef PDSTRING_UTILS_H +#define PDSTRING_UTILS_H + +#include +#include +#include +#include "mooPdUtils.h" + +/*===================================================================== + * Debugging + *=====================================================================*/ +#define PDSTRING_UTILS_DEBUG 1 +//#undef PDSTRING_UTILS_DEBUG + +#ifdef PDSTRING_UTILS_DEBUG +# define PDSDEBUG(x) x +#else +# define PDSDEBUG(x) +#endif + +/*===================================================================== + * Constants + *=====================================================================*/ + +/* PDSTRING_EOS_NONE + * + "safe" float value to use as x_eos if no truncation is desired + */ +#define PDSTRING_EOS_NONE 1e38f + +/* PDSTRING_DEFAULT_BUFLEN + * + common default buffer length + */ +#define PDSTRING_DEFAULT_BUFLEN 256 + +/* PDSTRING_DEFAULT_GET + * + common default buffer grow length + */ +#define PDSTRING_DEFAULT_GET 256 + +/* PDSTRING_BYSTES_GET + * + number of extra bytes to get when buffer must grow + */ +#define PDSTRING_BYTES_GET PDSTRING_DEFAULT_GET +#define PDSTRING_WCHARS_GET PDSTRING_DEFAULT_GET +#define PDSTRING_ATOMS_GET PDSTRING_DEFAULT_GET + +/*===================================================================== + * Structures & Types + *=====================================================================*/ + +/* t_pdstring_bytes + * + a byte-string buffer + */ +typedef struct _pdstring_bytes { + unsigned char *b_buf; //-- byte-string buffer + int b_len; //-- current length of b_buf + size_t b_alloc; //-- allocated size of b_buf +} t_pdstring_bytes; + +/* t_pdstring_wchars + * + a wide character buffer + */ +typedef struct _pdstring_wchars { + wchar_t *w_buf; //-- wide character buffer + int w_len; //-- current length of w_buf + size_t w_alloc; //-- allocated size of w_buf +} t_pdstring_wchars; + +/* t_pdstring_atoms + * + an atom-list buffer + */ +typedef struct _pdstring_atoms { + t_atom *a_buf; //-- t_atom buffer (aka argv) + int a_len; //-- current length of a_buf (aka argc) + size_t a_alloc; //-- allocated size of a_buf +} t_pdstring_atoms; + +/*===================================================================== + * Initialization + *=====================================================================*/ + +/*--------------------------------------------------------------------- + * bytes + */ +static void pdstring_bytes_clear(t_pdstring_bytes *b) +{ + if (b->b_alloc) freebytes(b->b_buf, (b->b_alloc)*sizeof(unsigned char)); + b->b_buf = NULL; + b->b_len = 0; + b->b_alloc = 0; +} +static void pdstring_bytes_realloc(t_pdstring_bytes *b, size_t n) +{ + pdstring_bytes_clear(b); + b->b_buf = n ? (unsigned char*)getbytes(n*sizeof(unsigned char)) : NULL; + b->b_alloc = n; +} +static void pdstring_bytes_init(t_pdstring_bytes *b, size_t n) +{ + pdstring_bytes_clear(b); + pdstring_bytes_realloc(b,n); +} + +/*--------------------------------------------------------------------- + * wchars + */ +static void pdstring_wchars_clear(t_pdstring_wchars *w) +{ + if (w->w_alloc) freebytes(w->w_buf, (w->w_alloc)*sizeof(wchar_t)); + w->w_buf = NULL; + w->w_len = 0; + w->w_alloc = 0; +} +static void pdstring_wchars_realloc(t_pdstring_wchars *w, size_t n) +{ + pdstring_wchars_clear(w); + w->w_buf = n ? (wchar_t*)getbytes(n*sizeof(wchar_t)) : NULL; + w->w_alloc = n; +} +static void pdstring_wchars_init(t_pdstring_wchars *w, size_t n) +{ + pdstring_wchars_clear(w); + pdstring_wchars_realloc(w,n); +} + +/*--------------------------------------------------------------------- + * atoms + */ +static void pdstring_atoms_clear(t_pdstring_atoms *a) +{ + if (a->a_alloc) freebytes(a->a_buf, (a->a_alloc)*sizeof(t_atom)); + a->a_buf = NULL; + a->a_len = 0; + a->a_alloc = 0; +} +static void pdstring_atoms_realloc(t_pdstring_atoms *a, size_t n) +{ + pdstring_atoms_clear(a); + a->a_buf = n ? (t_atom*)getbytes(n*sizeof(t_atom)) : NULL; + a->a_alloc = n; +} +static void pdstring_atoms_init(t_pdstring_atoms *a, size_t n) +{ + pdstring_atoms_clear(a); + pdstring_atoms_realloc(a,n); +} + + +/*===================================================================== + * Utilities + *=====================================================================*/ + +/*-------------------------------------------------------------------- + * 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 void pdstring_any2bytes(void *x, t_pdstring_bytes *dst, t_symbol *sel, t_pdstring_atoms *src, t_binbuf *x_binbuf) +{ + int bb_is_tmp=0; + + //-- create temporary binbuf? + if (!x_binbuf) { + x_binbuf = binbuf_new(); + bb_is_tmp = 1; + } + + //-- prepare binbuf + binbuf_clear(x_binbuf); + + //-- 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 + * + x_binbuf may be NULL, in which case a temporary t_binbuf is created and used + * - in this case, output atoms 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_getnatom() and binbuf_getvec() + */ +static void pdstring_bytes2any(void *x, t_pdstring_atoms *dst, t_pdstring_bytes *src, t_binbuf *x_binbuf) +{ + int bb_is_tmp=0; + + //-- create temporary binbuf? + if (!x_binbuf) { + x_binbuf = binbuf_new(); + bb_is_tmp = 1; + } + + //-- populate binbuf + binbuf_clear(x_binbuf); + binbuf_text(x_binbuf, (char*)src->b_buf, src->b_len); + //PDSDEBUG(post("bytes2any[dst=%p,src=%p,bb=%p]: binbuf_print: ", dst,src,x_binbuf)); + //PDSDEBUG(binbuf_print(x_binbuf)); + + //-- populate atom list + if (bb_is_tmp) { + //-- temporary binbuf: copy atoms + t_atom *argv = binbuf_getvec(x_binbuf); + int argc = binbuf_getnatom(x_binbuf); + + //-- reallocate? + 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; + + //-- cleanup + binbuf_free(x_binbuf); + } + else if (dst) { + //-- permanent binbuf: clobber dst + dst->a_buf = binbuf_getvec(x_binbuf); + dst->a_len = binbuf_getnatom(x_binbuf); + dst->a_alloc = 0; //-- don't try to free this + } +} + + +/*-------------------------------------------------------------------- + * 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_atoms2bytes(void *x, t_pdstring_bytes *dst, t_pdstring_atoms *src, t_float x_eos) +{ + t_atom *argv = src->a_buf; + int argc = src->a_len; + unsigned char *s; + 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 = '\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 + //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 character (%u) - bashing to byte", src->w_buf[wi]); + } + dst->b_buf[bi] = src->w_buf[wi]; + nbytes = 1; + } + bi += nbytes; + } + dst->b_len = bi; + return bi; +} + + +/*-------------------------------------------------------------------- + * 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(void *x, t_pdstring_atoms *dst, t_pdstring_wchars *src) +{ + int i; + + //-- re-allocate? + if ( dst->a_alloc < src->w_len ) + pdstring_atoms_realloc(dst, src->w_len + PDSTRING_ATOMS_GET); + + //-- convert + for (i=0; i < src->w_len; i++) { + SETFLOAT((dst->a_buf+i), src->w_buf[i]); + } + dst->a_len = src->w_len; +} + + +#endif /* PDSTRING_UTILS_H */ diff --git a/pdstring+wchar/src/wchars2any-help.pd b/pdstring+wchar/src/wchars2any-help.pd new file mode 100644 index 0000000..d57343e --- /dev/null +++ b/pdstring+wchar/src/wchars2any-help.pd @@ -0,0 +1,42 @@ +#N canvas 101 18 612 604 10; +#X text 13 52 INLETS:; +#X text 309 54 OUTLETS:; +#X text 325 68 1 - pd messages; +#X text 325 82 2 - bang on done; +#X msg 24 113 97 32 98 32 99; +#X msg 39 135 97 0 98 0 99; +#X msg 92 206 0; +#X msg 60 206 -1; +#X msg 124 206 32; +#X text 163 350 First argument: initial buffer size (length of object-local +text buffer). This should get re-allocated when necessary. Specify +0 (zero) to use the default value.; +#X text 165 405 Second argument: initial EOS character. See above. +; +#X text 159 477 Right outlet gives a bang after the entire input list +has been processed.; +#X text 189 531 Parsed pd messages are sent to the left outlet.; +#X text 306 580 Bryan Jurish ; +#X text 27 83 2 - EOS character (float); +#X text 161 121 lists of floats are converted to pd messages.; +#X text 168 161 ... selector is ignored ...; +#X text 21 571 SEE ALSO:; +#X obj 102 570 pdstring; +#X text 13 30 SYNTAX: wchars2any [INITIAL_BUFSIZE [EOS_CHAR]]; +#X obj 131 454 print wchars2any-help-done; +#X obj 24 529 print wchars2any-help; +#X msg 54 161 StringThing 97; +#X obj 24 350 wchars2any 128 0; +#X text 59 7 wchars2any : convert lists of wchar_t values to pd messages +; +#X text 27 68 1 - wchar_t-valued float lists; +#X text 166 202 The second inlet is as for [bytes2any]; +#X obj 169 570 locale; +#X connect 4 0 23 0; +#X connect 5 0 23 0; +#X connect 6 0 23 1; +#X connect 7 0 23 1; +#X connect 8 0 23 1; +#X connect 22 0 23 0; +#X connect 23 0 21 0; +#X connect 23 1 20 0; diff --git a/pdstring+wchar/src/wchars2any.pd b/pdstring+wchar/src/wchars2any.pd new file mode 100644 index 0000000..63bdc26 --- /dev/null +++ b/pdstring+wchar/src/wchars2any.pd @@ -0,0 +1,12 @@ +#N canvas 398 276 384 218 10; +#X obj 68 22 inlet; +#X obj 221 22 inlet; +#X obj 68 112 bytes2any \$1 \$2; +#X obj 68 73 wchars2bytes \$1; +#X obj 68 146 outlet; +#X obj 168 146 outlet; +#X connect 0 0 3 0; +#X connect 1 0 2 1; +#X connect 2 0 4 0; +#X connect 2 1 5 0; +#X connect 3 0 2 0; diff --git a/pdstring+wchar/src/wchars2bytes-help.pd b/pdstring+wchar/src/wchars2bytes-help.pd new file mode 100644 index 0000000..b892bea --- /dev/null +++ b/pdstring+wchar/src/wchars2bytes-help.pd @@ -0,0 +1,44 @@ +#N canvas 66 8 522 426 10; +#X text 11 46 INLETS:; +#X text 269 48 OUTLETS:; +#X text 283 64 1 - byte-valued float lists; +#X text 21 62 1 - wchar_t-valued float lists; +#X msg 24 95 97 32 98 32 99; +#X msg 45 229 228 246 252; +#X msg 71 159 C; +#N canvas 0 0 338 182 locale_LC_CTYPE 0; +#X obj 48 124 locale; +#X obj 48 36 inlet; +#X obj 48 64 symbol; +#X msg 48 92 set LC_CTYPE \$1; +#X text 57 143 + requires the "locale" external; +#X connect 1 0 2 0; +#X connect 2 0 3 0; +#X connect 3 0 0 0; +#X restore 103 190 pd locale_LC_CTYPE; +#X text 213 393 Bryan Jurish ; +#X text 9 377 SEE ALSO:; +#X obj 24 394 pdstring; +#X obj 91 394 locale; +#X text 11 355 BUGS: float representation is only safe up to 24-bit +values; +#X text 81 5 wchars2bytes : convert wide characters to (multiple) bytes +; +#X text 11 27 SYNTAX: wchars2bytes [INITIAL_BUFSIZE]; +#X msg 103 159 en_DK.ISO-8859-1; +#X msg 225 159 en_DK.UTF-8; +#X text 69 129 Greater values are interpreted according to the current +locale's LC_CTYPE category: here are some examples:; +#X text 145 97 Values <= 127 are unchanged; +#X msg 47 260 960 948; +#X text 157 229 "ä ö ü" \, ISO-8859-1 safe; +#X text 159 259 "&pi &delta" \, not ISO-8859-1 safe; +#X obj 24 310 wchars2bytes; +#X obj 24 334 print wchars2bytes-help; +#X connect 4 0 22 0; +#X connect 5 0 22 0; +#X connect 6 0 7 0; +#X connect 15 0 7 0; +#X connect 16 0 7 0; +#X connect 19 0 22 0; +#X connect 22 0 23 0; diff --git a/pdstring+wchar/src/wchars2bytes-test.pd b/pdstring+wchar/src/wchars2bytes-test.pd new file mode 100644 index 0000000..2a5bcc5 --- /dev/null +++ b/pdstring+wchar/src/wchars2bytes-test.pd @@ -0,0 +1,46 @@ +#N canvas 376 34 606 300 10; +#X obj 114 136 bytes2wchars; +#X obj 138 168 print wchars; +#X obj 323 222 locale; +#X msg 323 149 get; +#X msg 359 199 set LC_CTYPE \$1; +#X obj 359 178 symbol; +#X msg 359 147 C; +#X msg 393 147 en_US.ISO-8859-1; +#X msg 515 147 en_US.UTF-8; +#X obj 322 246 print locale; +#X msg 37 41 246; +#X floatatom 56 178 5 0 0 0 - - -; +#X msg 37 61 195 182; +#X text 35 23 ö \;; +#X msg 159 61 197 147; +#X text 155 23 &oelig \;; +#X msg 159 39 339; +#X msg 245 37 960; +#X msg 245 59 207 128; +#X text 245 21 &pi \;; +#X obj 391 120 loadbang; +#X text 93 41 ucs-4; +#X text 95 59 utf-8; +#X msg 325 61 207 128 0 197 147 0 195 182 0; +#X obj 114 198 wchars2bytes; +#X obj 112 226 print bytes; +#X connect 0 0 1 0; +#X connect 0 0 11 0; +#X connect 0 0 24 0; +#X connect 2 0 9 0; +#X connect 3 0 2 0; +#X connect 4 0 2 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 5 0; +#X connect 8 0 5 0; +#X connect 10 0 0 0; +#X connect 12 0 0 0; +#X connect 14 0 0 0; +#X connect 16 0 0 0; +#X connect 17 0 0 0; +#X connect 18 0 0 0; +#X connect 20 0 7 0; +#X connect 23 0 0 0; +#X connect 24 0 25 0; diff --git a/pdstring+wchar/src/wchars2bytes.c b/pdstring+wchar/src/wchars2bytes.c new file mode 100644 index 0000000..8c6f74d --- /dev/null +++ b/pdstring+wchar/src/wchars2bytes.c @@ -0,0 +1,157 @@ +/* -*- Mode: C -*- */ +/*=============================================================================*\ + * File: wchars2bytes.c + * Author: Bryan Jurish + * Description: convert wchar_t-valued atom lists to byte-valued atom lists + * + * Copyright (c) 2009 Bryan Jurish. + * + * For information on usage and redistribution, and for a DISCLAIMER OF ALL + * WARRANTIES, see the file "COPYING", in this distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *=============================================================================*/ + +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "mooPdUtils.h" +#include "pdstringUtils.h" + +/* black magic */ +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + +/*-------------------------------------------------------------------- + * DEBUG + *--------------------------------------------------------------------*/ + +/*===================================================================== + * Constants + *=====================================================================*/ +static char *wchars2bytes_banner = "wchars2bytes: pdstring version " PACKAGE_VERSION " by Bryan Jurish"; + +#define WCHARS2BYTES_DEFAULT_BUFLEN PDSTRING_DEFAULT_BUFLEN + +/*===================================================================== + * Structures and Types: any2string + *=====================================================================*/ + +static t_class *wchars2bytes_class; + +typedef struct _wchars2bytes +{ + t_object x_obj; + t_pdstring_wchars x_wchars; //-- wide character buffer + t_pdstring_bytes x_bytes; //-- byte buffer + t_pdstring_atoms x_atoms; //-- atoms to output + t_outlet *x_outlet; +} t_wchars2bytes; + + +/*===================================================================== + * Methods + *=====================================================================*/ + +/*-------------------------------------------------------------------- + * anything + */ +static void wchars2bytes_anything(t_wchars2bytes *x, MOO_UNUSED t_symbol *sel, int argc, t_atom *argv) +{ + //-- convert arg_atoms -> wchars -> bytes -> atoms + t_pdstring_atoms arg_atoms = {argv,argc,0}; + pdstring_atoms2wchars(x, &x->x_wchars, &arg_atoms, PDSTRING_EOS_NONE); + pdstring_wchars2bytes(x, &x->x_bytes, &x->x_wchars); + pdstring_bytes2atoms (x, &x->x_atoms, &x->x_bytes, PDSTRING_EOS_NONE); + + //-- output + outlet_anything(x->x_outlet, &s_list, x->x_atoms.a_len, x->x_atoms.a_buf); +} + + +/*-------------------------------------------------------------------- + * new + */ +static void *wchars2bytes_new(MOO_UNUSED t_symbol *sel, int argc, t_atom *argv) +{ + t_wchars2bytes *x = (t_wchars2bytes *)pd_new(wchars2bytes_class); + int bufsize = PDSTRING_DEFAULT_BUFLEN; + + //-- args: 0: bufsize + if (argc > 0) { + int initial_bufsize = atom_getintarg(0,argc,argv); + if (initial_bufsize > 0) bufsize = initial_bufsize; + } + + //-- allocate + pdstring_wchars_init(&x->x_wchars, bufsize); + pdstring_bytes_init (&x->x_bytes, bufsize); + pdstring_atoms_init (&x->x_atoms, bufsize); + + //-- outlets + x->x_outlet = outlet_new(&x->x_obj, &s_list); + + return (void *)x; +} + +/*-------------------------------------------------------------------- + * free + */ +static void wchars2bytes_free(t_wchars2bytes *x) +{ + pdstring_wchars_clear(&x->x_wchars); + pdstring_bytes_clear(&x->x_bytes); + pdstring_atoms_clear(&x->x_atoms); + outlet_free(x->x_outlet); + return; +} + +/*-------------------------------------------------------------------- + * setup: guts + */ +void wchars2bytes_setup_guts(void) +{ + //-- class + wchars2bytes_class = class_new(gensym("wchars2bytes"), + (t_newmethod)wchars2bytes_new, + (t_method)wchars2bytes_free, + sizeof(t_wchars2bytes), + CLASS_DEFAULT, + A_GIMME, //-- initial_bufsize + 0); + + //-- methods + class_addanything(wchars2bytes_class, (t_method)wchars2bytes_anything); + + //-- help symbol + //class_sethelpsymbol(wchars2bytes_class, gensym("wchars2bytes-help.pd")); //-- breaks pd-extended help lookup +} + +/*-------------------------------------------------------------------- + * setup + */ +void wchars2bytes_setup(void) +{ + post(wchars2bytes_banner); + wchars2bytes_setup_guts(); +} -- cgit v1.2.1