OSC: Properly encode/decode special characters in osc paths.

This commit is contained in:
Jonathan Moore Liles 2012-06-04 22:58:57 -07:00
parent 0fba0747fc
commit d249bb9bbd
5 changed files with 134 additions and 37 deletions

View File

@ -41,6 +41,8 @@
#include "OSC/Endpoint.H" #include "OSC/Endpoint.H"
#include "string_util.h"
Module *Module::_copied_module_empty = 0; Module *Module::_copied_module_empty = 0;
@ -243,12 +245,11 @@ Module::Port::generate_osc_path ()
else else
asprintf( &path, "/strip/%s/%s/%s", module()->chain()->name(), p->module()->label(), p->name() ); 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. char *s = escape_url( path );
for ( int i = strlen( path ); i--; )
{ free( path );
if ( path[i] == ' ' || path[i] == ',' )
path[i] = '_'; path = s;
}
return path; return path;
} }

85
nonlib/string_util.C Normal file
View File

@ -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 <string.h>
#include <stdio.h>
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 );
}

21
nonlib/string_util.h Normal file
View File

@ -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 );

View File

@ -40,6 +40,8 @@ using namespace std;
#include <unistd.h> // for symlink() #include <unistd.h> // for symlink()
#include "string_util.h"
Audio_Sequence::Audio_Sequence ( Track *track, const char *name ) : Sequence( track ) 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 void
Audio_Sequence::handle_widget_change ( nframes_t start, nframes_t length ) Audio_Sequence::handle_widget_change ( nframes_t start, nframes_t length )
{ {
@ -280,7 +253,7 @@ Audio_Sequence::handle ( int m )
return 0; return 0;
} }
deurlify( file ); unescape_url( file );
printf( "pasted file \"%s\"\n", file ); printf( "pasted file \"%s\"\n", file );

View File

@ -34,6 +34,8 @@ using std::list;
#include "OSC/Endpoint.H" #include "OSC/Endpoint.H"
#include "string_util.h"
bool Control_Sequence::draw_with_gradient = true; bool Control_Sequence::draw_with_gradient = true;
@ -234,6 +236,12 @@ Control_Sequence::mode ( Mode m )
{ {
char *path; char *path;
asprintf( &path, "/track/%s/control/%i", track()->name(), track()->ncontrols() ); 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 ); _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 ) ) sig->parameter_limits().max == 1.0 ) )
return; 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 ), peer_menu->add( s, 0, NULL, (void*)( sig ),
FL_MENU_TOGGLE | FL_MENU_TOGGLE |
( _osc_output->is_connected_to( sig ) ? FL_MENU_VALUE : 0 ) ); ( _osc_output->is_connected_to( sig ) ? FL_MENU_VALUE : 0 ) );
free( path );
free( s ); free( s );
connect_osc(); connect_osc();