'\" t .\" Title: zosc .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets vsnapshot .\" Date: 03/02/2024 .\" Manual: CZMQ Manual .\" Source: CZMQ 4.2.1 .\" Language: English .\" .TH "ZOSC" "3" "03/02/2024" "CZMQ 4\&.2\&.1" "CZMQ Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" zosc \- Class for work with Open Sound Control messages .SH "SYNOPSIS" .sp .nf // This is a draft class, and may change without notice\&. It is disabled in // stable builds by default\&. If you use this in applications, please ask // for it to be pushed to stable state\&. Use \-\-enable\-drafts to enable\&. #ifdef CZMQ_BUILD_DRAFT_API // *** Draft method, for development use, may change without warning *** // Create a new empty OSC message with the specified address string\&. CZMQ_EXPORT zosc_t * zosc_new (const char *address); // *** Draft method, for development use, may change without warning *** // Create a new OSC message from the specified zframe\&. Takes ownership of // the zframe\&. CZMQ_EXPORT zosc_t * zosc_fromframe (zframe_t *frame); // *** Draft method, for development use, may change without warning *** // Create a new zosc message from memory\&. Take ownership of the memory // and calling free on the data after construction\&. 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 the given format and arguments\&. // The format type tags are as follows: // i \- 32bit integer // h \- 64bit integer // f \- 32bit floating point number (IEEE) // d \- 64bit (double) floating point number // s \- string (NULL terminated) // t = timetag: an OSC timetag in NTP format (uint64_t) // S \- symbol // c \- char // m \- 4 byte midi packet (8 digits hexadecimal) // T \- TRUE (no value required) // F \- FALSE (no value required) // N \- NIL (no value required) // I \- Impulse (for triggers) or INFINITUM (no value required) // b \- binary blob CZMQ_EXPORT zosc_t * zosc_create (const char *address, const char *format, \&.\&.\&.); // *** Draft method, for development use, may change without warning *** // Destroy an OSC message CZMQ_EXPORT void zosc_destroy (zosc_t **self_p); // *** Draft method, for development use, may change without warning *** // Return chunk data size CZMQ_EXPORT size_t zosc_size (zosc_t *self); // *** Draft method, for development use, may change without warning *** // Return OSC chunk data\&. Caller does not own the data! CZMQ_EXPORT byte * zosc_data (zosc_t *self); // *** Draft method, for development use, may change without warning *** // Return the OSC address string CZMQ_EXPORT const char * zosc_address (zosc_t *self); // *** Draft method, for development use, may change without warning *** // Return the OSC format of the message\&. // i \- 32bit integer // h \- 64bit integer // f \- 32bit floating point number (IEEE) // d \- 64bit (double) floating point number // s \- string (NULL terminated) // t = timetag: an OSC timetag in NTP format (uint64_t) // S \- symbol // c \- char // m \- 4 byte midi packet (8 digits hexadecimal) // T \- TRUE (no value required) // F \- FALSE (no value required) // N \- NIL (no value required) // I \- Impulse (for triggers) or INFINITUM (no value required) // b \- binary blob CZMQ_EXPORT const char * zosc_format (zosc_t *self); // *** Draft method, for development use, may change without warning *** // Append data to the osc message\&. The format describes the data that // needs to be appended in the message\&. This essentially relocates all // data! // The format type tags are as follows: // i \- 32bit integer // h \- 64bit integer // f \- 32bit floating point number (IEEE) // d \- 64bit (double) floating point number // s \- string (NULL terminated) // t = timetag: an OSC timetag in NTP format (uint64_t) // S \- symbol // c \- char // m \- 4 byte midi packet (8 digits hexadecimal) // T \- TRUE (no value required) // F \- FALSE (no value required) // N \- NIL (no value required) // I \- Impulse (for triggers) or INFINITUM (no value required) // b \- binary blob CZMQ_EXPORT int zosc_append (zosc_t *self, const char *format, \&.\&.\&.); // *** Draft method, for development use, may change without warning *** // Retrieve the values provided by the given format\&. Note that zosc_retr // creates the objects and the caller must destroy them when finished\&. // The supplied pointers do not need to be initialized\&. Returns 0 if // successful, or \-1 if it failed to retrieve a value in which case the // pointers are not modified\&. If an argument pointer is NULL is skips the // value\&. See the format method for a detailed list op type tags for the // format string\&. CZMQ_EXPORT int zosc_retr (zosc_t *self, const char *format, \&.\&.\&.); // *** Draft method, for development use, may change without warning *** // Create copy of the message, as new chunk object\&. Returns a fresh zosc_t // object, or null if there was not enough heap memory\&. If chunk is null, // returns null\&. // Caller owns return value and must destroy it when done\&. CZMQ_EXPORT zosc_t * zosc_dup (zosc_t *self); // *** Draft method, for development use, may change without warning *** // Transform zosc into a zframe that can be sent in a message\&. // Caller owns return value and must destroy it when done\&. CZMQ_EXPORT zframe_t * zosc_pack (zosc_t *self); // *** Draft method, for development use, may change without warning *** // Transform zosc into a zframe that can be sent in a message\&. // Take ownership of the chunk\&. // Caller owns return value and must destroy it when done\&. CZMQ_EXPORT zframe_t * zosc_packx (zosc_t **self_p); // *** Draft method, for development use, may change without warning *** // Transform a zframe into a zosc\&. // Caller owns return value and must destroy it when done\&. CZMQ_EXPORT zosc_t * zosc_unpack (zframe_t *frame); // *** Draft method, for development use, may change without warning *** // Dump OSC message to stdout, for debugging and tracing\&. CZMQ_EXPORT void zosc_print (zosc_t *self); // *** Draft method, for development use, may change without warning *** // Probe the supplied object, and report if it looks like a zosc_t\&. CZMQ_EXPORT bool zosc_is (void *self); // *** Draft method, for development use, may change without warning *** // Return a pointer to the item at the head of the OSC data\&. // Sets the given char argument to the type tag of the data\&. // If the message is empty, returns NULL and the sets the // given char to NULL\&. CZMQ_EXPORT const void * zosc_first (zosc_t *self, char *type); // *** Draft method, for development use, may change without warning *** // Return the next item of the OSC message\&. If the list is empty, returns // NULL\&. To move to the start of the OSC message call zosc_first ()\&. CZMQ_EXPORT const void * zosc_next (zosc_t *self, char *type); // *** Draft method, for development use, may change without warning *** // Return a pointer to the item at the tail of the OSC message\&. // Sets the given char argument to the type tag of the data\&. If // the message is empty, returns NULL\&. CZMQ_EXPORT const void * zosc_last (zosc_t *self, char *type); // *** Draft method, for development use, may change without warning *** // Set the provided 32 bit integer from value at the current cursor position in the message\&. // If the type tag at the current position does not correspond it will fail and // return \-1\&. Returns 0 on success\&. CZMQ_EXPORT int zosc_pop_int32 (zosc_t *self, int *val); // *** Draft method, for development use, may change without warning *** // Set the provided 64 bit integer from the value at the current cursor position in the message\&. // If the type tag at the current position does not correspond it will fail and // return \-1\&. Returns 0 on success\&. CZMQ_EXPORT int zosc_pop_int64 (zosc_t *self, int64_t *val); // *** Draft method, for development use, may change without warning *** // Set the provided float from the value at the current cursor position in the message\&. // If the type tag at the current position does not correspond it will fail and // return \-1\&. Returns 0 on success\&. CZMQ_EXPORT int zosc_pop_float (zosc_t *self, float *val); // *** Draft method, for development use, may change without warning *** // Set the provided double from the value at the current cursor position in the message\&. // If the type tag at the current position does not correspond it will fail and // return \-1\&. Returns 0 on success\&. CZMQ_EXPORT int zosc_pop_double (zosc_t *self, double *val); // *** Draft method, for development use, may change without warning *** // Set the provided string from the value at the current cursor position in the message\&. // If the type tag at the current position does not correspond it will fail and // return \-1\&. Returns 0 on success\&. Caller owns the string! CZMQ_EXPORT int zosc_pop_string (zosc_t *self, char **val); // *** Draft method, for development use, may change without warning *** // Set the provided char from the value at the current cursor position in the message\&. // If the type tag at the current position does not correspond it will fail and // return \-1\&. Returns 0 on success\&. CZMQ_EXPORT int zosc_pop_char (zosc_t *self, char *val); // *** Draft method, for development use, may change without warning *** // Set the provided boolean from the type tag in the message\&. Booleans are not represented // in the data in the message, only in the type tag\&. If the type tag at the current // position does not correspond it will fail and return \-1\&. Returns 0 on success\&. CZMQ_EXPORT int zosc_pop_bool (zosc_t *self, bool *val); // *** Draft method, for development use, may change without warning *** // Set the provided 4 bytes (unsigned 32bit int) from the value at the current // cursor position in the message\&. If the type tag at the current position does // not correspond it will fail and return \-1\&. Returns 0 on success\&. CZMQ_EXPORT int zosc_pop_midi (zosc_t *self, uint32_t *val); // *** Draft method, for development use, may change without warning *** // Self test of this class\&. CZMQ_EXPORT void zosc_test (bool verbose); #endif // CZMQ_BUILD_DRAFT_API Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zosc\&.c\*(Aq\&. .fi .SH "DESCRIPTION" .sp zosc \- work with Open Sound Control messages .sp Please add \fI@discuss\fR section in \fI\&./\&.\&./src/zosc\&.c\fR\&. .SH "EXAMPLE" .PP \fBFrom zosc_test method\fR. .sp .if n \{\ .RS 4 .\} .nf // we need to have packets on the heap char *p1 = (char *)malloc(40); memcpy(p1, oscpacket, 40); zosc_t *self = zosc_frommem(p1, 40); assert (self); assert ( zosc_is( self )); assert(streq ( zosc_address(self), "/sample/address")); assert(streq ( zosc_format(self), "iTfs")); // check value uint32_t test = 0; bool b = false; float f = 0\&.f; char *s = "BLA"; zosc_retr(self, "iTfs", &test, &b, &f, &s); assert(test == 1); assert(b); assert(fabsf(f \- 3\&.14f) < FLT_EPSILON); // float equal assert(streq(s, "hello")); zstr_free(&s); zosc_destroy (&self); zframe_t *frame = zframe_new(oscpacket, 40); assert(frame); assert(zframe_size(frame) == 40); zosc_t *fosc = zosc_fromframe(frame); assert (fosc); assert(streq ( zosc_address(fosc), "/sample/address")); assert(streq ( zosc_format(fosc), "iTfs")); // test skipping retrieving values zosc_retr(fosc, "iTfs", NULL, NULL, NULL, NULL); char *fstr = ""; zosc_retr(fosc, "iTfs", NULL, NULL, NULL, &fstr); assert( streq(fstr, "hello") ); zstr_free(&fstr); zosc_destroy (&fosc); // to the heap, otherwise we can\*(Aqt destroy char *p2 = (char *)malloc(48); memcpy(p2, testpack, 48); zosc_t *testmsg = zosc_frommem(p2, 48); assert( testmsg ); assert(streq ( zosc_address(testmsg), "/test")); assert(streq ( zosc_format(testmsg), "ihTfds" ) ); // test duplicate zosc_t *testmsgdup = zosc_dup(NULL); assert( testmsgdup == NULL ); testmsgdup = zosc_dup(testmsg); assert( testmsgdup ); assert(streq ( zosc_address(testmsgdup), "/test")); assert(streq ( zosc_format(testmsgdup), "ihTfds" ) ); zosc_destroy(&testmsgdup); // check value int itest = \-1; int64_t ltest = \-1; bool btest = false; float ftest = \-1\&.f; double dtest = \-1\&.; char *stest; const char *format = zosc_format(testmsg); zosc_retr(testmsg, format, &itest, <est, &btest, &ftest, &dtest, &stest); assert( itest == 2 ); assert( ltest == 1844674407370 ); assert( btest ); assert( fabsf(ftest \- 3\&.14f) < FLT_EPSILON ); // float equal assert( fabs(dtest \- 3\&.1415926535897932) < DBL_EPSILON ); assert( streq(stest, "hello") ); zstr_free(&stest); zosc_destroy(&testmsg); // test constructing messages int64_t prez = 3; zosc_t* conm = zosc_create("/construct", "iihfdscF", \-2,2, prez, 3\&.14,6\&.283185307179586, "greetings", \*(Aqq\*(Aq); assert(conm); assert(streq(zosc_address(conm), "/construct")); assert(streq(zosc_format(conm), "iihfdscF")); if (verbose) zosc_print(conm); int x,y; int64_t z; float zz; double zzz; char *ss = "aliens"; char q = \*(Aqz\*(Aq; bool Ftest = true; zosc_retr(conm, "iihfdscF", &x, &y, &z, &zz, &zzz, &ss, &q, &Ftest); assert( x==\-2 ); assert( y==2 ); assert( z==3 ); assert( fabsf(zz\-3\&.14f) < FLT_EPSILON ); assert( fabs(zzz\-6\&.283185307179586) < DBL_EPSILON ); assert( streq( ss, "greetings") ); assert( q == \*(Aqq\*(Aq); assert( !Ftest ); zstr_free(&ss); // test iterating char type = \*(Aq0\*(Aq; const void *data = zosc_first(conm, &type); while ( data ) { if (verbose) zsys_info("type tag is %c", type); switch (type) { case(\*(Aqi\*(Aq): { int32_t test = 9; int rc = zosc_pop_int32(conm, &test); assert(rc == 0); assert( test == \-2 || test == 2); break; } case(\*(Aqh\*(Aq): { int32_t fail = 9; int rc = zosc_pop_int32(conm, &fail); // this will fail assert(rc == \-1); int64_t test = 9; rc = zosc_pop_int64(conm, &test); assert(rc == 0); assert( test == 3 ); break; } case(\*(Aqf\*(Aq): { float flt_v = 0\&.f; int rc = zosc_pop_float(conm, &flt_v); assert(rc == 0); assert( fabsf(flt_v\-3\&.14f) < FLT_EPSILON ); break; } case \*(Aqd\*(Aq: { double dbl_v = 0\&.; int rc = zosc_pop_double(conm, &dbl_v); assert(rc == 0); assert( fabs(dbl_v\-6\&.283185307179586) < DBL_EPSILON ); break; } case \*(Aqs\*(Aq: { char *str; int rc = zosc_pop_string(conm, &str); assert(rc == 0); assert(streq(str, "greetings")); zstr_free(&str); break; } case \*(Aqc\*(Aq: { char chr; int rc = zosc_pop_char(conm, &chr); assert(rc == 0); assert(chr == \*(Aqq\*(Aq); break; } case \*(AqF\*(Aq: { bool bl; int rc = zosc_pop_bool(conm, &bl); assert(rc == 0); assert( !bl ); break; } default: assert(0); } data = zosc_next(conm, &type); } // test append int64_t preal = \-80000; zosc_append(conm, "ih", \-200, preal); int ax,ay; int64_t az; float azz; double azzz; char *ass = "aliens"; char aq = \*(Aqz\*(Aq; bool aFtest = true; int ai = 0; int64_t al = 0; zosc_retr(conm, "iihfdscFih", &ax, &ay, &az, &azz, &azzz, &ass, &aq, &aFtest, &ai, &al); assert( ax==\-2 ); assert( ay==2 ); assert( az==3 ); assert( fabsf(azz\-3\&.14f) < FLT_EPSILON ); assert( fabs(azzz\-6\&.283185307179586) < DBL_EPSILON ); assert( streq( ass, "greetings") ); assert( aq == \*(Aqq\*(Aq); assert( !aFtest ); assert( ai==\-200 ); assert( al==\-80000 ); zstr_free(&ass); #ifdef ZMQ_DGRAM zsock_t *dgrams = zsock_new_dgram("udp://*:*"); assert (dgrams); zframe_t *t = zosc_pack(conm); zstr_sendm( dgrams, "127\&.0\&.0\&.1:7777" ); zframe_send( &t, dgrams, 0); zclock_sleep(10); // slow down, otherwise we\*(Aqve cleaned up before async send zsock_destroy( &dgrams ); #else int sockfd; struct sockaddr_in servaddr; // Creating socket file descriptor if ( (sockfd = (int)socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) { zsys_error("socket creation failed"); } memset(&servaddr, 0, sizeof(servaddr)); // Filling server information servaddr\&.sin_family = AF_INET; servaddr\&.sin_port = htons(7777); servaddr\&.sin_addr\&.s_addr = INADDR_ANY; #ifdef __WINDOWS__ sendto(sockfd, (const char *)zosc_data(conm), (int)zosc_size(conm), 0, (const struct sockaddr *) &servaddr, sizeof(servaddr)); #else sendto(sockfd, zosc_data(conm), zosc_size(conm), 0, (const struct sockaddr *) &servaddr, sizeof(servaddr)); #endif #endif zosc_destroy(&conm); #ifdef __WINDOWS__ zsys_shutdown(); #endif .fi .if n \{\ .RE .\} .sp .SH "AUTHORS" .sp The czmq manual was written by the authors in the AUTHORS file\&. .SH "RESOURCES" .sp Main web site: \m[blue]\fB\%\fR\m[] .sp Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> .SH "COPYRIGHT" .sp Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. .SH "NOTES" .IP " 1." 4 zeromq-dev@lists.zeromq.org .RS 4 \%mailto:zeromq-dev@lists.zeromq.org .RE