From 2fca84eeb6f1079b1f8a0723f5d2b176aa1b62e3 Mon Sep 17 00:00:00 2001 From: Bryan Jurish Date: Sat, 24 Jan 2009 22:43:09 +0000 Subject: + added basic pdstringUtils.c, bytes2wchars.c svn path=/trunk/externals/moocow/; revision=10617 --- pdstring+wchar/src/pdstringUtils.c | 307 +++++++++++++++++++++++++++++++++++++ 1 file changed, 307 insertions(+) create mode 100644 pdstring+wchar/src/pdstringUtils.c (limited to 'pdstring+wchar/src/pdstringUtils.c') diff --git a/pdstring+wchar/src/pdstringUtils.c b/pdstring+wchar/src/pdstringUtils.c new file mode 100644 index 0000000..b07f760 --- /dev/null +++ b/pdstring+wchar/src/pdstringUtils.c @@ -0,0 +1,307 @@ +/* -*- Mode: C -*- */ +/*=============================================================================*\ + * File: pdstringUtils.c + * Author: Bryan Jurish + * Description: pdstring: common utilities + * + * 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_C +#define PDSTRING_UTILS_C + +#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_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(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) +{ + 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_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(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_bytes2wchars() + */ +static int pdstring_bytes2wchars(t_pdstring_wchars *dst, t_pdstring_bytes *src) +{ + /* + //-- get required length + int nwc=0, size; + 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; + } + s += csize; + } + */ + + //-- 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); + } + dst->w_len = newlen; + + return (newlen < src->b_len ? newlen : newlen+1); +} + +/*-------------------------------------------------------------------- + * pdstring_wchars2atoms() + */ +static void pdstring_wchars2atoms(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_C */ -- cgit v1.2.1