aboutsummaryrefslogtreecommitdiff
path: root/cyclone/hammer/testmess.c
diff options
context:
space:
mode:
Diffstat (limited to 'cyclone/hammer/testmess.c')
-rw-r--r--cyclone/hammer/testmess.c245
1 files changed, 245 insertions, 0 deletions
diff --git a/cyclone/hammer/testmess.c b/cyclone/hammer/testmess.c
new file mode 100644
index 0000000..a6e8fe4
--- /dev/null
+++ b/cyclone/hammer/testmess.c
@@ -0,0 +1,245 @@
+/* Copyright (c) 2002-2003 krzYszcz and others.
+ * For information on usage and redistribution, and for a DISCLAIMER OF ALL
+ * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+#include <string.h>
+#include "m_pd.h"
+
+#define TESTMESS_INISIZE 4 /* LATER rethink */
+#define TESTMESS_STACKSIZE 256
+
+typedef struct _testmess
+{
+ t_object x_ob;
+ t_symbol *x_method;
+ void (*x_messfun)(struct _testmess *, t_symbol *s, int, t_atom *);
+ int x_appendmode;
+ int x_size; /* as allocated */
+ int x_natoms; /* as used */
+ int x_tailwise; /* data is moved to the end of a buffer */
+ t_atom *x_message;
+ t_atom *x_messbuf;
+ t_atom x_messini[TESTMESS_INISIZE];
+} t_testmess;
+
+static t_class *testmess_class;
+
+static void testmess_setnatoms(t_testmess *x, int natoms)
+{
+ if (x->x_tailwise)
+ x->x_message = x->x_messbuf + x->x_size - natoms;
+ else
+ x->x_message = x->x_messbuf;
+ x->x_natoms = natoms;
+}
+
+static int testmess_makeroom(t_testmess *x, int natoms, int preserve)
+{
+ if (x->x_size < natoms)
+ {
+ int newsize = x->x_size * 2;
+ while (newsize < natoms) newsize *= 2;
+ post("makeroom %s %d %d %d", x->x_method->s_name,
+ preserve, natoms, newsize);
+ if (x->x_messbuf == x->x_messini)
+ {
+ if (!(x->x_messbuf =
+ (t_atom *)getbytes(newsize * sizeof(*x->x_messbuf))))
+ {
+ x->x_messbuf = x->x_messini;
+ testmess_setnatoms(x, preserve ? x->x_natoms : 0);
+ return (0);
+ }
+ x->x_size = newsize;
+ testmess_setnatoms(x, preserve ? x->x_natoms : 0);
+ if (x->x_natoms)
+ {
+ if (x->x_tailwise)
+ memcpy(x->x_message,
+ x->x_messini + TESTMESS_INISIZE - x->x_natoms,
+ x->x_natoms * sizeof(*x->x_message));
+ else
+ memcpy(x->x_message,
+ x->x_messini, x->x_natoms * sizeof(*x->x_message));
+ }
+ }
+ else
+ {
+ int oldsize = x->x_size;
+ if (!(x->x_messbuf =
+ (t_atom *)resizebytes(x->x_messbuf,
+ x->x_size * sizeof(*x->x_messbuf),
+ newsize * sizeof(*x->x_messbuf))))
+ {
+ x->x_messbuf = x->x_messini;
+ x->x_size = TESTMESS_INISIZE;
+ testmess_setnatoms(x, 0);
+ return (0);
+ }
+ x->x_size = newsize;
+ testmess_setnatoms(x, preserve ? x->x_natoms : 0);
+ if (x->x_natoms && x->x_tailwise)
+ memmove(x->x_message, x->x_messbuf + oldsize - x->x_natoms,
+ x->x_natoms * sizeof(*x->x_message));
+ }
+ }
+ return (1);
+}
+
+static void testmess_stackmess(t_testmess *x, t_symbol *s, int ac, t_atom *av)
+{
+ t_atom buf[TESTMESS_STACKSIZE];
+ int natoms = x->x_natoms;
+ if (x->x_appendmode)
+ {
+ int left = TESTMESS_STACKSIZE - ac;
+ if (left < 0) ac = TESTMESS_STACKSIZE, natoms = 0;
+ else if (natoms > left) natoms = left;
+ if (ac)
+ memcpy(buf, av, ac * sizeof(*buf));
+ if (natoms)
+ memcpy(buf + ac, x->x_message, natoms * sizeof(*buf));
+ }
+ else
+ {
+ int left = TESTMESS_STACKSIZE - natoms;
+ if (left < 0) natoms = TESTMESS_STACKSIZE, ac = 0;
+ else if (ac > left) ac = left;
+ if (natoms)
+ memcpy(buf, x->x_message, natoms * sizeof(*buf));
+ if (ac)
+ memcpy(buf + natoms, av, ac * sizeof(*buf));
+ }
+ outlet_anything(((t_object *)x)->ob_outlet, s, natoms + ac, buf);
+}
+
+static void testmess_heapmess(t_testmess *x, t_symbol *s, int ac, t_atom *av)
+{
+ int ntotal = x->x_natoms + ac;
+ t_atom *buf = getbytes(ntotal * sizeof(*buf));
+ if (buf)
+ {
+ if (x->x_appendmode)
+ {
+ if (ac)
+ memcpy(buf, av, ac * sizeof(*buf));
+ if (x->x_natoms)
+ memcpy(buf + ac, x->x_message, x->x_natoms * sizeof(*buf));
+ }
+ else
+ {
+ if (x->x_natoms)
+ memcpy(buf, x->x_message, x->x_natoms * sizeof(*buf));
+ if (ac)
+ memcpy(buf + x->x_natoms, av, ac * sizeof(*buf));
+ }
+ outlet_anything(((t_object *)x)->ob_outlet, s, ntotal, buf);
+ freebytes(buf, ntotal * sizeof(*buf));
+ }
+}
+
+static void testmess_premess(t_testmess *x, t_symbol *s, int ac, t_atom *av)
+{
+ int ntotal = x->x_natoms + ac;
+ if (testmess_makeroom(x, ntotal, 1))
+ {
+ t_atom *buf;
+ if (x->x_appendmode)
+ {
+ buf = x->x_messbuf + x->x_size - ntotal;
+ if (ac)
+ memcpy(buf, av, ac * sizeof(*buf));
+ }
+ else
+ {
+ buf = x->x_messbuf;
+ if (ac)
+ memcpy(buf + x->x_natoms, av, ac * sizeof(*buf));
+ }
+ outlet_anything(((t_object *)x)->ob_outlet, s, ntotal, buf);
+ }
+}
+
+static void testmess_bang(t_testmess *x)
+{
+ if (x->x_natoms)
+ x->x_messfun(x, &s_list, 0, 0);
+}
+
+static void testmess_float(t_testmess *x, t_float f)
+{
+ t_atom at;
+ SETFLOAT(&at, f);
+ x->x_messfun(x, (x->x_natoms ? &s_list : &s_float), 1, &at);
+}
+
+static void testmess_symbol(t_testmess *x, t_symbol *s)
+{
+ x->x_messfun(x, s, 0, 0);
+}
+
+static void testmess_anything(t_testmess *x, t_symbol *s, int ac, t_atom *av)
+{
+ x->x_messfun(x, s, ac, av);
+}
+
+static void testmess_set(t_testmess *x, t_floatarg f1, t_floatarg f2)
+{
+ int natoms = (int)f1;
+ if (natoms > 0 && testmess_makeroom(x, natoms * 2, 0))
+ {
+ t_atom *ap;
+ int i = (int)f2;;
+ testmess_setnatoms(x, natoms);
+ ap = x->x_message;
+ while (natoms--)
+ {
+ SETFLOAT(ap, i);
+ i++; ap++;
+ }
+ }
+}
+
+static void testmess_free(t_testmess *x)
+{
+ if (x->x_messbuf != x->x_messini)
+ freebytes(x->x_messbuf, x->x_size * sizeof(*x->x_messbuf));
+}
+
+static void *testmess_new(t_symbol *s, t_floatarg f)
+{
+ t_testmess *x = (t_testmess *)pd_new(testmess_class);
+ x->x_appendmode = 1;
+ x->x_tailwise = 0;
+ if (s == gensym("stack"))
+ x->x_method = s, x->x_messfun = testmess_stackmess;
+ else if (s == gensym("heap"))
+ x->x_method = s, x->x_messfun = testmess_heapmess;
+ else
+ {
+ x->x_method = gensym("prealloc");
+ x->x_messfun = testmess_premess;
+ x->x_tailwise = x->x_appendmode;
+ }
+ x->x_size = TESTMESS_INISIZE;
+ x->x_messbuf = x->x_messini;
+ outlet_new((t_object *)x, &s_anything);
+ testmess_setnatoms(x, 0);
+ testmess_set(x, f, 0);
+ return (x);
+}
+
+void testmess_setup(void)
+{
+ testmess_class = class_new(gensym("testmess"),
+ (t_newmethod)testmess_new,
+ (t_method)testmess_free,
+ sizeof(t_testmess), 0,
+ A_DEFFLOAT, A_DEFSYM, 0);
+ class_addbang(testmess_class, testmess_bang);
+ class_addfloat(testmess_class, testmess_float);
+ class_addsymbol(testmess_class, testmess_symbol);
+ class_addanything(testmess_class, testmess_anything);
+ class_addmethod(testmess_class, (t_method)testmess_set,
+ gensym("set"), A_FLOAT, A_DEFFLOAT, 0);
+}