From d249bb9bbd282c664a2cf344c3b86ffbf6126550 Mon Sep 17 00:00:00 2001 From: Jonathan Moore Liles Date: Mon, 4 Jun 2012 22:58:57 -0700 Subject: [PATCH] OSC: Properly encode/decode special characters in osc paths. --- mixer/src/Module.C | 13 ++--- nonlib/string_util.C | 85 +++++++++++++++++++++++++++++++++ nonlib/string_util.h | 21 ++++++++ timeline/src/Audio_Sequence.C | 33 ++----------- timeline/src/Control_Sequence.C | 19 +++++++- 5 files changed, 134 insertions(+), 37 deletions(-) create mode 100644 nonlib/string_util.C create mode 100644 nonlib/string_util.h diff --git a/mixer/src/Module.C b/mixer/src/Module.C index aadbd4f..f28f8f5 100644 --- a/mixer/src/Module.C +++ b/mixer/src/Module.C @@ -41,6 +41,8 @@ #include "OSC/Endpoint.H" +#include "string_util.h" + Module *Module::_copied_module_empty = 0; @@ -243,12 +245,11 @@ Module::Port::generate_osc_path () else asprintf( &path, "/strip/%s/%s/%s", module()->chain()->name(), p->module()->label(), p->name() ); - // Hack to keep spaces out of OSC URL... Probably need to handle other special characters similarly. - for ( int i = strlen( path ); i--; ) - { - if ( path[i] == ' ' || path[i] == ',' ) - path[i] = '_'; - } + char *s = escape_url( path ); + + free( path ); + + path = s; return path; } diff --git a/nonlib/string_util.C b/nonlib/string_util.C new file mode 100644 index 0000000..cb4f349 --- /dev/null +++ b/nonlib/string_util.C @@ -0,0 +1,85 @@ + +/*******************************************************************************/ +/* Copyright (C) 2012 Jonathan Moore Liles */ +/* */ +/* 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; see the file COPYING. If not,write to the Free Software */ +/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/*******************************************************************************/ + +#include +#include + +void unescape_url ( char *url ) +{ + char *r, *w; + + r = w = url; + + for ( ; *r; r++, w++ ) + { + if ( *r == '%' ) + { + char data[3] = { *(r + 1), *(r + 2), 0 }; + + int c; + + sscanf( data, "%2X", &c ); + + *w = c; + + r += 2; + } + else + *w = *r; + } + + *w = 0; +} + +char *escape_url ( const char *url ) +{ + const char *s; + char *w; + + char r[1024]; + + s = url; + + w = r; + + for ( ; *s && w < r + sizeof( r ); s++, w++ ) + { + switch ( *s ) + { + case ' ': + case '<': + case '>': + case '%': + case '#': + case '*': + case ',': + sprintf( w, "%%%2X", *s ); + w += 2; + break; + default: + *w = *s; + break; + + } + } + + *w = 0; + + return strdup( r ); +} diff --git a/nonlib/string_util.h b/nonlib/string_util.h new file mode 100644 index 0000000..1a43254 --- /dev/null +++ b/nonlib/string_util.h @@ -0,0 +1,21 @@ + +/*******************************************************************************/ +/* Copyright (C) 2012 Jonathan Moore Liles */ +/* */ +/* 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; see the file COPYING. If not,write to the Free Software */ +/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/*******************************************************************************/ + +void unescape_url ( char *url ); +char * escape_url ( const char *url ); diff --git a/timeline/src/Audio_Sequence.C b/timeline/src/Audio_Sequence.C index b7a31c4..ad0ea7b 100644 --- a/timeline/src/Audio_Sequence.C +++ b/timeline/src/Audio_Sequence.C @@ -40,6 +40,8 @@ using namespace std; #include // for symlink() +#include "string_util.h" + Audio_Sequence::Audio_Sequence ( Track *track, const char *name ) : Sequence( track ) @@ -130,35 +132,6 @@ Audio_Sequence::set ( Log_Entry &e ) } -static -void -deurlify ( char *url ) -{ - char *r, *w; - - r = w = url; - - for ( ; *r; r++, w++ ) - { - if ( *r == '%' ) - { - char data[3] = { *(r + 1), *(r + 2), 0 }; - - int c; - - sscanf( data, "%2X", &c ); - - *w = c; - - r += 2; - } - else - *w = *r; - } - - *w = 0; -} - void Audio_Sequence::handle_widget_change ( nframes_t start, nframes_t length ) { @@ -280,7 +253,7 @@ Audio_Sequence::handle ( int m ) return 0; } - deurlify( file ); + unescape_url( file ); printf( "pasted file \"%s\"\n", file ); diff --git a/timeline/src/Control_Sequence.C b/timeline/src/Control_Sequence.C index acb162a..8a47132 100644 --- a/timeline/src/Control_Sequence.C +++ b/timeline/src/Control_Sequence.C @@ -34,6 +34,8 @@ using std::list; #include "OSC/Endpoint.H" +#include "string_util.h" + bool Control_Sequence::draw_with_gradient = true; @@ -234,6 +236,12 @@ Control_Sequence::mode ( Mode m ) { char *path; asprintf( &path, "/track/%s/control/%i", track()->name(), track()->ncontrols() ); + + char *s = escape_url( path ); + + free( path ); + + path = s; _osc_output = timeline->osc->add_signal( path, OSC::Signal::Output, 0, 1, 0, NULL, NULL ); @@ -536,12 +544,21 @@ Control_Sequence::peer_callback( const char *name, const OSC::Signal *sig ) sig->parameter_limits().max == 1.0 ) ) return; - asprintf( &s, "%s/%s%s", peer_prefix, name, sig->path() ); + + assert( sig->path() ); + + char *path = strdup( sig->path() ); + + unescape_url( path ); + + asprintf( &s, "%s/%s%s", peer_prefix, name, path ); peer_menu->add( s, 0, NULL, (void*)( sig ), FL_MENU_TOGGLE | ( _osc_output->is_connected_to( sig ) ? FL_MENU_VALUE : 0 ) ); + free( path ); + free( s ); connect_osc();