diff options
-rw-r--r-- | src/common/util/Atom.h | 123 | ||||
-rw-r--r-- | src/common/util/LibloAtom.h | 73 | ||||
-rw-r--r-- | src/common/util/Makefile.am | 4 |
3 files changed, 199 insertions, 1 deletions
diff --git a/src/common/util/Atom.h b/src/common/util/Atom.h new file mode 100644 index 00000000..6cb001e1 --- /dev/null +++ b/src/common/util/Atom.h @@ -0,0 +1,123 @@ +/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard. + * + * Ingen 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. + * + * Ingen 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 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., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef ATOM_H +#define ATOM_H + +#include <cassert> +#include <cstring> +#include <lo/lo.h> + + +/** An OSC atom (fundamental data types OSC messages are composed of). + */ +class Atom { +public: + enum Type { + NIL, + INT, + FLOAT, + STRING, + BLOB + }; + + Atom() : _type(NIL), _blob_val(0) {} + Atom(int32_t val) : _type(INT), _int_val(val) {} + Atom(float val) : _type(FLOAT), _float_val(val) {} + Atom(const char* val) : _type(STRING), _string_val(strdup(val)) {} + + Atom(void* val) : _type(BLOB), _blob_size(sizeof(val)), _blob_val(malloc(_blob_size)) + { memcpy(_blob_val, val, sizeof(_blob_size)); } + + ~Atom() + { + if (_type == STRING) + free(_string_val); + else if (_type == BLOB) + free(_blob_val); + } + + // Gotta love C++ boilerplate: + + Atom(const Atom& copy) + : _type(copy._type) + , _blob_size(copy._blob_size) + { + switch (_type) { + case NIL: _blob_val = 0; break; + case INT: _int_val = copy._int_val; break; + case FLOAT: _float_val = copy._float_val; break; + case STRING: _string_val = strdup(copy._string_val); break; + + case BLOB: _blob_val = malloc(_blob_size); + memcpy(_blob_val, copy._blob_val, _blob_size); + break; + + default: break; + } + } + + Atom& operator=(const Atom& other) + { + if (_type == BLOB) + free(_blob_val); + else if (_type == STRING) + free(_string_val); + + _type = other._type; + _blob_size = other._blob_size; + + switch (_type) { + case NIL: _blob_val = 0; break; + case INT: _int_val = other._int_val; break; + case FLOAT: _float_val = other._float_val; break; + case STRING: _string_val = strdup(other._string_val); break; + + case BLOB: _blob_val = malloc(_blob_size); + memcpy(_blob_val, other._blob_val, _blob_size); + break; + + default: break; + } + return *this; + } + + /** Type of this atom. Always check this before attempting to get the + * value - attempting to get the incorrectly typed value is a fatal error. + */ + Type type() const { return _type; } + + inline int32_t get_int32() const { assert(_type == INT); return _int_val; } + inline float get_float() const { assert(_type == FLOAT); return _float_val; } + inline const char* get_string() const { assert(_type == STRING); return _string_val; } + inline const void* get_blob() const { assert(_type == BLOB); return _blob_val; } + + inline operator bool() const { return (_type != NIL); } + +private: + Type _type; + + size_t _blob_size; ///< always a multiple of 32 + + union { + int32_t _int_val; + float _float_val; + char* _string_val; + void* _blob_val; + }; +}; + +#endif // ATOM_H diff --git a/src/common/util/LibloAtom.h b/src/common/util/LibloAtom.h new file mode 100644 index 00000000..02a469fe --- /dev/null +++ b/src/common/util/LibloAtom.h @@ -0,0 +1,73 @@ +/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard. + * + * Ingen 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. + * + * Ingen 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 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., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LIBLO_ATOM_H +#define LIBLO_ATOM_H + +#include <lo/lo.h> +#include "util/Atom.h" + + +/** Support for serializing an Atom to/from liblo messages. + * + * (Here to prevent a unnecessary liblo dependency on Atom). + */ +class LibloAtom { +public: + static void lo_message_add_atom(lo_message m, const Atom& atom) { + switch (atom.type()) { + //case NIL: + // (see below) + //break; + case Atom::INT: + lo_message_add_int32(m, atom.get_int32()); + break; + case Atom::FLOAT: + lo_message_add_float(m, atom.get_float()); + break; + case Atom::STRING: + lo_message_add_string(m, atom.get_string()); + break; + case Atom::BLOB: + // FIXME: is this okay? what does liblo do? + lo_message_add_blob(m, const_cast<void*>(atom.get_blob())); + break; + default: // This catches Atom::Type::NIL too + lo_message_add_nil(m); + break; + } + } + + static Atom lo_arg_to_atom(char type, lo_arg* arg) { + switch (type) { + case 'i': + return Atom(arg->i); + case 'f': + return Atom(arg->f); + case 's': + return Atom(&arg->s); + //case 'b' + // FIXME: How to get a blob from a lo_arg? + //return Atom(arg->b); + default: + return Atom(); + } + } + +}; + + +#endif // LIBLO_ATOM_H diff --git a/src/common/util/Makefile.am b/src/common/util/Makefile.am index dfa7ce2d..46bc3691 100644 --- a/src/common/util/Makefile.am +++ b/src/common/util/Makefile.am @@ -2,4 +2,6 @@ EXTRA_DIST = \ CountedPtr.h \ Path.h \ Queue.h \ - Semaphore.h + Semaphore.h \ + Atom.h \ + LibloAtom.h |