diff --git a/api/python_cffi.slurp b/api/python_cffi.slurp index e888e469e..6f2532a65 100644 --- a/api/python_cffi.slurp +++ b/api/python_cffi.slurp @@ -4647,6 +4647,11 @@ zosc_t * zosc_t * zosc_frommem (char *data, size_t size); +// Create a new zosc message from a string. This the same syntax as +// zosc_create but written as a single line string. +zosc_t * + zosc_fromstring (const char *oscstring); + // Create a new zosc message from the given format and arguments. // The format type tags are as follows: // i - 32bit integer @@ -4750,6 +4755,10 @@ zframe_t * zosc_t * zosc_unpack (zframe_t *frame); +// Return a string describing the the OSC message. The returned string must be freed by the caller. +char * + zosc_dump (zosc_t *self); + // Dump OSC message to stdout, for debugging and tracing. void zosc_print (zosc_t *self); diff --git a/api/zosc.api b/api/zosc.api index 2567fce46..a8d68b5a2 100644 --- a/api/zosc.api +++ b/api/zosc.api @@ -49,6 +49,12 @@ + + Create a new zosc message from a string. This the same syntax as + zosc_create but written as a single line string. + + + Create a new zosc message from the given format and arguments. The format type tags are as follows: @@ -168,6 +174,11 @@ + + Return a string describing the the OSC message. The returned string must be freed by the caller. + + + Dump OSC message to stdout, for debugging and tracing. diff --git a/bindings/jni/czmq-jni/src/main/c/org_zeromq_czmq_Zosc.c b/bindings/jni/czmq-jni/src/main/c/org_zeromq_czmq_Zosc.c index febfb3fde..e3ae54ab1 100644 --- a/bindings/jni/czmq-jni/src/main/c/org_zeromq_czmq_Zosc.c +++ b/bindings/jni/czmq-jni/src/main/c/org_zeromq_czmq_Zosc.c @@ -37,6 +37,15 @@ Java_org_zeromq_czmq_Zosc__1_1frommem (JNIEnv *env, jclass c, jbyteArray data, j return frommem_; } +JNIEXPORT jlong JNICALL +Java_org_zeromq_czmq_Zosc__1_1fromstring (JNIEnv *env, jclass c, jstring oscstring) +{ + char *oscstring_ = (char *) (*env)->GetStringUTFChars (env, oscstring, NULL); + jlong fromstring_ = (jlong) (intptr_t) zosc_fromstring (oscstring_); + (*env)->ReleaseStringUTFChars (env, oscstring, oscstring_); + return fromstring_; +} + JNIEXPORT jlong JNICALL Java_org_zeromq_czmq_Zosc__1_1create (JNIEnv *env, jclass c, jstring address, jstring format) { @@ -133,6 +142,15 @@ Java_org_zeromq_czmq_Zosc__1_1unpack (JNIEnv *env, jclass c, jlong frame) return unpack_; } +JNIEXPORT jstring JNICALL +Java_org_zeromq_czmq_Zosc__1_1dump (JNIEnv *env, jclass c, jlong self) +{ + char *dump_ = (char *) zosc_dump ((zosc_t *) (intptr_t) self); + jstring return_string_ = (*env)->NewStringUTF (env, dump_); + zstr_free (&dump_); + return return_string_; +} + JNIEXPORT void JNICALL Java_org_zeromq_czmq_Zosc__1_1print (JNIEnv *env, jclass c, jlong self) { diff --git a/bindings/jni/czmq-jni/src/main/java/org/zeromq/czmq/Zosc.java b/bindings/jni/czmq-jni/src/main/java/org/zeromq/czmq/Zosc.java index b1e3ac588..72383f9f2 100644 --- a/bindings/jni/czmq-jni/src/main/java/org/zeromq/czmq/Zosc.java +++ b/bindings/jni/czmq-jni/src/main/java/org/zeromq/czmq/Zosc.java @@ -54,6 +54,14 @@ public static Zosc frommem (byte [] data, long size) { return new Zosc (__frommem (data, size)); } /* + Create a new zosc message from a string. This the same syntax as + zosc_create but written as a single line string. + */ + native static long __fromstring (String oscstring); + public static Zosc fromstring (String oscstring) { + return new Zosc (__fromstring (oscstring)); + } + /* Create a new zosc message from the given format and arguments. The format type tags are as follows: i - 32bit integer @@ -195,6 +203,13 @@ public static Zosc unpack (Zframe frame) { return new Zosc (__unpack (frame.self)); } /* + Return a string describing the the OSC message. The returned string must be freed by the caller. + */ + native static String __dump (long self); + public String dump () { + return __dump (self); + } + /* Dump OSC message to stdout, for debugging and tracing. */ native static void __print (long self); diff --git a/bindings/lua_ffi/czmq_ffi.lua b/bindings/lua_ffi/czmq_ffi.lua index af688b481..8025e3466 100644 --- a/bindings/lua_ffi/czmq_ffi.lua +++ b/bindings/lua_ffi/czmq_ffi.lua @@ -4642,6 +4642,11 @@ zosc_t * zosc_t * zosc_frommem (char *data, size_t size); +// Create a new zosc message from a string. This the same syntax as +// zosc_create but written as a single line string. +zosc_t * + zosc_fromstring (const char *oscstring); + // Create a new zosc message from the given format and arguments. // The format type tags are as follows: // i - 32bit integer @@ -4745,6 +4750,10 @@ zframe_t * zosc_t * zosc_unpack (zframe_t *frame); +// Return a string describing the the OSC message. The returned string must be freed by the caller. +char * + zosc_dump (zosc_t *self); + // Dump OSC message to stdout, for debugging and tracing. void zosc_print (zosc_t *self); diff --git a/bindings/nodejs/README.md b/bindings/nodejs/README.md index cb5523e5b..2e2368e86 100644 --- a/bindings/nodejs/README.md +++ b/bindings/nodejs/README.md @@ -5208,6 +5208,12 @@ zosc my_zosc.unpack (Zframe) Transform a zframe into a zosc. +``` +string my_zosc.dump () +``` + +Return a string describing the the OSC message. The returned string must be freed by the caller. + ``` nothing my_zosc.print () ``` diff --git a/bindings/nodejs/binding.cc b/bindings/nodejs/binding.cc index 25f212c71..eb9c426e7 100644 --- a/bindings/nodejs/binding.cc +++ b/bindings/nodejs/binding.cc @@ -9679,6 +9679,7 @@ NAN_MODULE_INIT (Zosc::Init) { Nan::SetPrototypeMethod (tpl, "pack", _pack); Nan::SetPrototypeMethod (tpl, "packx", _packx); Nan::SetPrototypeMethod (tpl, "unpack", _unpack); + Nan::SetPrototypeMethod (tpl, "dump", _dump); Nan::SetPrototypeMethod (tpl, "print", _print); Nan::SetPrototypeMethod (tpl, "popInt32", _pop_int32); Nan::SetPrototypeMethod (tpl, "popInt64", _pop_int64); @@ -9840,6 +9841,12 @@ NAN_METHOD (Zosc::_unpack) { } } +NAN_METHOD (Zosc::_dump) { + Zosc *zosc = Nan::ObjectWrap::Unwrap (info.Holder ()); + char *result = (char *) zosc_dump (zosc->self); + info.GetReturnValue ().Set (Nan::New (result).ToLocalChecked ()); +} + NAN_METHOD (Zosc::_print) { Zosc *zosc = Nan::ObjectWrap::Unwrap (info.Holder ()); zosc_print (zosc->self); diff --git a/bindings/nodejs/binding.h b/bindings/nodejs/binding.h index 6c02146fa..82aa43a73 100644 --- a/bindings/nodejs/binding.h +++ b/bindings/nodejs/binding.h @@ -1130,6 +1130,7 @@ class Zosc: public Nan::ObjectWrap { static NAN_METHOD (_pack); static NAN_METHOD (_packx); static NAN_METHOD (_unpack); + static NAN_METHOD (_dump); static NAN_METHOD (_print); static NAN_METHOD (_pop_int32); static NAN_METHOD (_pop_int64); diff --git a/bindings/python/czmq/_czmq_ctypes.py b/bindings/python/czmq/_czmq_ctypes.py index 03cd8413f..3aea44304 100644 --- a/bindings/python/czmq/_czmq_ctypes.py +++ b/bindings/python/czmq/_czmq_ctypes.py @@ -9559,6 +9559,8 @@ def test(verbose): lib.zosc_fromframe.argtypes = [zframe_p] lib.zosc_frommem.restype = zosc_p lib.zosc_frommem.argtypes = [c_void_p, c_size_t] +lib.zosc_fromstring.restype = zosc_p +lib.zosc_fromstring.argtypes = [c_char_p] lib.zosc_create.restype = zosc_p lib.zosc_create.argtypes = [c_char_p, c_char_p] lib.zosc_size.restype = c_size_t @@ -9581,6 +9583,8 @@ def test(verbose): lib.zosc_packx.argtypes = [POINTER(zosc_p)] lib.zosc_unpack.restype = zosc_p lib.zosc_unpack.argtypes = [zframe_p] +lib.zosc_dump.restype = POINTER(c_char) +lib.zosc_dump.argtypes = [zosc_p] lib.zosc_print.restype = None lib.zosc_print.argtypes = [zosc_p] lib.zosc_is.restype = c_bool @@ -9695,6 +9699,14 @@ def frommem(data, size): """ return Zosc(lib.zosc_frommem(data, size), True) + @staticmethod + def fromstring(oscstring): + """ + Create a new zosc message from a string. This the same syntax as +zosc_create but written as a single line string. + """ + return Zosc(lib.zosc_fromstring(oscstring), True) + @staticmethod def create(address, format, *args): """ @@ -9819,6 +9831,12 @@ def unpack(frame): """ return Zosc(lib.zosc_unpack(frame), True) + def dump(self): + """ + Return a string describing the the OSC message. The returned string must be freed by the caller. + """ + return return_fresh_string(lib.zosc_dump(self._as_parameter_)) + def print(self): """ Dump OSC message to stdout, for debugging and tracing. diff --git a/bindings/python_cffi/czmq_cffi/Zosc.py b/bindings/python_cffi/czmq_cffi/Zosc.py index 7eed6f8af..d733e6f38 100644 --- a/bindings/python_cffi/czmq_cffi/Zosc.py +++ b/bindings/python_cffi/czmq_cffi/Zosc.py @@ -61,6 +61,14 @@ def frommem(data, size): """ return utils.lib.zosc_frommem(data, size) + @staticmethod + def fromstring(oscstring): + """ + Create a new zosc message from a string. This the same syntax as + zosc_create but written as a single line string. + """ + return utils.lib.zosc_fromstring(utils.to_bytes(oscstring)) + @staticmethod def create(address, format, *format_args): """ @@ -185,6 +193,12 @@ def unpack(frame): """ return utils.lib.zosc_unpack(frame._p) + def dump(self): + """ + Return a string describing the the OSC message. The returned string must be freed by the caller. + """ + return utils.lib.zosc_dump(self._p) + def print_py(self): """ Dump OSC message to stdout, for debugging and tracing. diff --git a/bindings/python_cffi/czmq_cffi/cdefs.py b/bindings/python_cffi/czmq_cffi/cdefs.py index 7ee491dc4..a87b7e5e0 100644 --- a/bindings/python_cffi/czmq_cffi/cdefs.py +++ b/bindings/python_cffi/czmq_cffi/cdefs.py @@ -4649,6 +4649,11 @@ zosc_t * zosc_frommem (char *data, size_t size); +// Create a new zosc message from a string. This the same syntax as +// zosc_create but written as a single line string. +zosc_t * + zosc_fromstring (const char *oscstring); + // Create a new zosc message from the given format and arguments. // The format type tags are as follows: // i - 32bit integer @@ -4752,6 +4757,10 @@ zosc_t * zosc_unpack (zframe_t *frame); +// Return a string describing the the OSC message. The returned string must be freed by the caller. +char * + zosc_dump (zosc_t *self); + // Dump OSC message to stdout, for debugging and tracing. void zosc_print (zosc_t *self); diff --git a/bindings/qml/src/QmlZosc.cpp b/bindings/qml/src/QmlZosc.cpp index d8e5aa158..7830a8344 100644 --- a/bindings/qml/src/QmlZosc.cpp +++ b/bindings/qml/src/QmlZosc.cpp @@ -99,6 +99,15 @@ QmlZframe *QmlZosc::pack () { return retQ_; }; +/// +// Return a string describing the the OSC message. The returned string must be freed by the caller. +QString QmlZosc::dump () { + char *retStr_ = zosc_dump (self); + QString retQStr_ = QString (retStr_); + free (retStr_); + return retQStr_; +}; + /// // Dump OSC message to stdout, for debugging and tracing. void QmlZosc::print () { @@ -254,6 +263,15 @@ QmlZosc *QmlZoscAttached::frommem (char *data, size_t size) { return qmlSelf; }; +/// +// Create a new zosc message from a string. This the same syntax as +// zosc_create but written as a single line string. +QmlZosc *QmlZoscAttached::fromstring (const QString &oscstring) { + QmlZosc *qmlSelf = new QmlZosc (); + qmlSelf->self = zosc_fromstring (oscstring.toUtf8().data()); + return qmlSelf; +}; + /// // Create a new zosc message from the given format and arguments. // The format type tags are as follows: diff --git a/bindings/qml/src/QmlZosc.h b/bindings/qml/src/QmlZosc.h index 4dcd33c21..8842ccfb2 100644 --- a/bindings/qml/src/QmlZosc.h +++ b/bindings/qml/src/QmlZosc.h @@ -91,6 +91,9 @@ public slots: // Transform zosc into a zframe that can be sent in a message. QmlZframe *pack (); + // Return a string describing the the OSC message. The returned string must be freed by the caller. + QString dump (); + // Dump OSC message to stdout, for debugging and tracing. void print (); @@ -185,6 +188,10 @@ public slots: // and calling free on the data after construction. QmlZosc *frommem (char *data, size_t size); + // Create a new zosc message from a string. This the same syntax as + // zosc_create but written as a single line string. + QmlZosc *fromstring (const QString &oscstring); + // Create a new zosc message from the given format and arguments. // The format type tags are as follows: // i - 32bit integer diff --git a/bindings/qt/src/qzosc.cpp b/bindings/qt/src/qzosc.cpp index 54f57add6..025eef292 100644 --- a/bindings/qt/src/qzosc.cpp +++ b/bindings/qt/src/qzosc.cpp @@ -38,6 +38,14 @@ QZosc* QZosc::frommem (char *data, size_t size, QObject *qObjParent) return new QZosc (zosc_frommem (data, size), qObjParent); } +/// +// Create a new zosc message from a string. This the same syntax as +// zosc_create but written as a single line string. +QZosc* QZosc::fromstring (const QString &oscstring, QObject *qObjParent) +{ + return new QZosc (zosc_fromstring (oscstring.toUtf8().data()), qObjParent); +} + /// // Destroy an OSC message QZosc::~QZosc () @@ -126,6 +134,16 @@ QZosc * QZosc::unpack (QZframe *frame) return rv; } +/// +// Return a string describing the the OSC message. The returned string must be freed by the caller. +QString QZosc::dump () +{ + char *retStr_ = zosc_dump (self); + QString rv = QString (retStr_); + zstr_free (&retStr_); + return rv; +} + /// // Dump OSC message to stdout, for debugging and tracing. void QZosc::print () diff --git a/bindings/qt/src/qzosc.h b/bindings/qt/src/qzosc.h index ffcc79a20..f62f7ac65 100644 --- a/bindings/qt/src/qzosc.h +++ b/bindings/qt/src/qzosc.h @@ -28,6 +28,10 @@ class QT_CZMQ_EXPORT QZosc : public QObject // and calling free on the data after construction. static QZosc* frommem (char *data, size_t size, QObject *qObjParent = 0); + // Create a new zosc message from a string. This the same syntax as + // zosc_create but written as a single line string. + static QZosc* fromstring (const QString &oscstring, QObject *qObjParent = 0); + // Destroy an OSC message ~QZosc (); @@ -72,6 +76,9 @@ class QT_CZMQ_EXPORT QZosc : public QObject // Transform a zframe into a zosc. static QZosc * unpack (QZframe *frame); + // Return a string describing the the OSC message. The returned string must be freed by the caller. + QString dump (); + // Dump OSC message to stdout, for debugging and tracing. void print (); diff --git a/bindings/ruby/lib/czmq/ffi.rb b/bindings/ruby/lib/czmq/ffi.rb index b978063de..54d927ef1 100644 --- a/bindings/ruby/lib/czmq/ffi.rb +++ b/bindings/ruby/lib/czmq/ffi.rb @@ -989,6 +989,7 @@ def self.attach_function(name, *rest) attach_function :zosc_new, [:string], :pointer, **opts attach_function :zosc_fromframe, [:pointer], :pointer, **opts attach_function :zosc_frommem, [:pointer, :size_t], :pointer, **opts + attach_function :zosc_fromstring, [:string], :pointer, **opts attach_function :zosc_create, [:string, :string, :varargs], :pointer, **opts attach_function :zosc_destroy, [:pointer], :void, **opts attach_function :zosc_size, [:pointer], :size_t, **opts @@ -1001,6 +1002,7 @@ def self.attach_function(name, *rest) attach_function :zosc_pack, [:pointer], :pointer, **opts attach_function :zosc_packx, [:pointer], :pointer, **opts attach_function :zosc_unpack, [:pointer], :pointer, **opts + attach_function :zosc_dump, [:pointer], :pointer, **opts attach_function :zosc_print, [:pointer], :void, **opts attach_function :zosc_is, [:pointer], :bool, **opts attach_function :zosc_first, [:pointer, :pointer], :pointer, **opts diff --git a/bindings/ruby/lib/czmq/ffi/zosc.rb b/bindings/ruby/lib/czmq/ffi/zosc.rb index d0fcb0cba..b7d04d202 100644 --- a/bindings/ruby/lib/czmq/ffi/zosc.rb +++ b/bindings/ruby/lib/czmq/ffi/zosc.rb @@ -124,6 +124,15 @@ def self.frommem(data, size) __new ptr end + # Create a new zosc message from a string. This the same syntax as + # zosc_create but written as a single line string. + # @param oscstring [String, #to_s, nil] + # @return [CZMQ::Zosc] + def self.fromstring(oscstring) + ptr = ::CZMQ::FFI.zosc_fromstring(oscstring) + __new ptr + end + # Create a new zosc message from the given format and arguments. # The format type tags are as follows: # i - 32bit integer @@ -307,6 +316,17 @@ def self.unpack(frame) result end + # Return a string describing the the OSC message. The returned string must be freed by the caller. + # + # @return [::FFI::AutoPointer] + def dump() + raise DestroyedError unless @ptr + self_p = @ptr + result = ::CZMQ::FFI.zosc_dump(self_p) + result = ::FFI::AutoPointer.new(result, LibC.method(:free)) + result + end + # Dump OSC message to stdout, for debugging and tracing. # # @return [void] diff --git a/include/zosc.h b/include/zosc.h index 21bb16c69..22500efa4 100644 --- a/include/zosc.h +++ b/include/zosc.h @@ -42,6 +42,12 @@ CZMQ_EXPORT zosc_t * CZMQ_EXPORT zosc_t * zosc_frommem (char *data, size_t size); +// *** Draft method, for development use, may change without warning *** +// Create a new zosc message from a string. This the same syntax as +// zosc_create but written as a single line string. +CZMQ_EXPORT zosc_t * + zosc_fromstring (const char *oscstring); + // *** Draft method, for development use, may change without warning *** // Create a new zosc message from the given format and arguments. // The format type tags are as follows: @@ -161,6 +167,12 @@ CZMQ_EXPORT zframe_t * CZMQ_EXPORT zosc_t * zosc_unpack (zframe_t *frame); +// *** Draft method, for development use, may change without warning *** +// Return a string describing the the OSC message. The returned string must be freed by the caller. +// Caller owns return value and must destroy it when done. +CZMQ_EXPORT char * + zosc_dump (zosc_t *self); + // *** Draft method, for development use, may change without warning *** // Dump OSC message to stdout, for debugging and tracing. CZMQ_EXPORT void diff --git a/src/zosc.c b/src/zosc.c index b9a02828a..71ae996e0 100644 --- a/src/zosc.c +++ b/src/zosc.c @@ -269,6 +269,110 @@ zosc_frommem (char *data, size_t size) return self; } + +zosc_t * +zosc_fromstring (const char *oscstr) +{ + // split spaces + char *input = strdup(oscstr); + char *address = strtok(input, " "); + if (address == NULL) + { + // no spaces return + zstr_free(&input); + return NULL; + } + char *format = strtok(NULL, " "); + if (format == NULL) + { + // no format + zstr_free(&input); + return NULL; + } + zosc_t *oscm = zosc_new(address); + int i = 0; + char type = *format; + while( type != 0 ) + { + char *value = NULL; + if (type != 'F' && type != 'T' ) + { + value = strtok(NULL, " "); + if (value == NULL) + goto error; + } + + switch (type) + { + case('i'): + { + int32_t v = atoi(value); + zosc_append(oscm, "i", v); + break; + } + case('h'): + { + int64_t v = atol(value); + zosc_append(oscm, "h", v); + break; + } + case('f'): + { + float v = (float)atof(value); + zosc_append(oscm, "f", v); + break; + } + case('d'): + { + double v = atof(value); + zosc_append(oscm, "d", v); + break; + } + case('s'): + { + zosc_append(oscm, "s", value); + break; + } + case('c'): + { + zosc_append(oscm, "c", value[0]); + break; + } + case('m'): + { + // TODO midi + //zosc_append(oscm, "m", value); + break; + } + case('F'): + { + zosc_append(oscm, "F", NULL); + break; + } + case('T'): + { + zosc_append(oscm, "T", NULL); + break; + } + default: + { + zsys_info("type tag is %c", type); + break; + } + } + i++; // get next character + type = *(format+i); + } + zstr_free(&input); + return oscm; + +error: + zstr_free(&input); + zosc_destroy(&oscm); + return NULL; +} + + zosc_t * zosc_create (const char *address, const char *format, ...) { @@ -590,15 +694,16 @@ zosc_unpack (zframe_t *frame) } // Dump OSC message to stdout, for debugging and tracing. -void -zosc_print (zosc_t *self) +char * +zosc_dump (zosc_t *self) { assert(self); assert(self->format); + char *out = (char *)malloc(1024); size_t needle = self->data_begin; int i=0; - fprintf(stdout, "%s %s", self->address, self->format); + sprintf(out, "%s %s", self->address, self->format); while(self->format[i]) { switch (self->format[i]) @@ -607,14 +712,14 @@ zosc_print (zosc_t *self) { void *data = zchunk_data( self->chunk ) + needle; int32_t int_v = (int32_t)ntohl(*(uint32_t *)data); - fprintf(stdout, " %i", int_v); + sprintf(out, "%s %i", out, int_v); needle += sizeof (uint32_t); break; } case 'h': { uint64_t int_v = ntohll(*(uint64_t*)(zchunk_data( self->chunk ) + (needle * sizeof (char) ))); - fprintf(stdout, " %ld", (long)int_v); + sprintf(out, "%s %ld", out, (long)int_v); needle += sizeof (uint64_t); break; } @@ -622,7 +727,7 @@ zosc_print (zosc_t *self) { uint32_t flt_v = ntohl(*(uint32_t*)(zchunk_data( self->chunk ) + needle)); float *v = (float *)&flt_v; // hackish - fprintf(stdout, " %.6f", (double)*v); + sprintf(out, "%s %.6f", out, (double)*v); needle += sizeof (float); break; } @@ -630,7 +735,7 @@ zosc_print (zosc_t *self) { uint64_t dbl_v = ntohll(*(uint64_t*)(zchunk_data( self->chunk ) + needle)); double *v = (double *)&dbl_v; - fprintf(stdout, " %f", *v); + sprintf(out, "%s %f", out, *v); needle += sizeof (double); break; } @@ -638,7 +743,7 @@ zosc_print (zosc_t *self) { // not sure if the double pointer is the way to go char *str = (char*)(zchunk_data( self->chunk ) + needle); - fprintf(stdout, " %s", str); + sprintf(out, "%s %s", out, str); size_t l = strlen((char*)(zchunk_data( self->chunk ) + needle)); needle += l + 1; needle = (needle + 3) & (size_t)~0x03; @@ -650,26 +755,26 @@ zosc_print (zosc_t *self) { char chr = (*(char*)(zchunk_data( self->chunk ) + needle + 3)); - fprintf(stdout, " %c", chr); + sprintf(out, "%s %c", out, chr); needle += sizeof (int); // advance multitude of 4! break; } case 'm': { uint32_t midi = ntohl(*(uint32_t *)(zchunk_data( self->chunk ) + needle)); - fprintf(stdout, " 0x%08x", midi); + sprintf(out, "%s 0x%08x", out, midi); needle += sizeof (uint32_t); break; } case 'T': { // value only determined based on the format! - fprintf(stdout, " True"); + //sprintf(out, "%s True", out); break; } case 'F': { - fprintf(stdout, " False"); + //sprintf(out, "%s False", out); break; } case 'N': // never used??? @@ -685,9 +790,18 @@ zosc_print (zosc_t *self) } i++; } - fprintf(stdout, "\n"); + return out; +} + +void +zosc_print (zosc_t *self) +{ + char *s = zosc_dump(self); + zsys_debug("%s", s); + zstr_free(&s); } + bool zosc_is (void *self) { @@ -1036,6 +1150,35 @@ zosc_test (bool verbose) zstr_free(&stest); zosc_destroy(&testmsg); + // test contructing from string + zosc_t* strm = zosc_fromstring("/stringmsg ihfdscF 32 64 1.100000 3.140000 hello q"); + assert(strm); + assert(streq(zosc_address(strm), "/stringmsg")); + assert(streq(zosc_format(strm), "ihfdscF")); + char *sd = zosc_dump(strm); + assert(streq(sd, "/stringmsg ihfdscF 32 64 1.100000 3.140000 hello q")); + zstr_free(&sd); + { + int32_t test = 0; + int64_t test64 = 0; + float testf = 0.0f; + double testd = 0.0; + char * tests = "robots"; + char c = 'a'; + bool b = true; + zosc_retr(strm, zosc_format(strm), &test, &test64, &testf, &testd, &tests, &c, &b); + assert( test == 32 ); + assert( test64 == 64 ); + assert( fabsf(testf-1.1f) < FLT_EPSILON ); + assert( fabs(testd-3.14) < DBL_EPSILON ); + assert( streq(tests, "hello") ); + zstr_free( &tests ); + assert( c == 'q' ); + } + // test print + zosc_print(strm); + zosc_destroy(&strm); + // test constructing messages int64_t prez = 3; zosc_t* conm = zosc_create("/construct", "iihfdscF", -2,2, prez, 3.14,6.283185307179586, "greetings", 'q');