Skip to content
Snippets Groups Projects
Commit 7e521bcd authored by Emlyn Corrin's avatar Emlyn Corrin
Browse files

Support Arrays

parent 7768cb15
Branches
No related tags found
No related merge requests found
...@@ -33,8 +33,11 @@ class OscMessage(object): ...@@ -33,8 +33,11 @@ class OscMessage(object):
if type_tag.startswith(','): if type_tag.startswith(','):
type_tag = type_tag[1:] type_tag = type_tag[1:]
params = []
param_stack = [params]
# Parse each parameter given its type. # Parse each parameter given its type.
for param in type_tag: for param in type_tag:
have_val = True
if param == "i": # Integer. if param == "i": # Integer.
val, index = osc_types.get_int(self._dgram, index) val, index = osc_types.get_int(self._dgram, index)
elif param == "f": # Float. elif param == "f": # Float.
...@@ -49,11 +52,25 @@ class OscMessage(object): ...@@ -49,11 +52,25 @@ class OscMessage(object):
val = True val = True
elif param == "F": # False. elif param == "F": # False.
val = False val = False
elif param == "[": # Array start.
a = []
param_stack[-1].append(a)
param_stack.append(a)
have_val = False
elif param == "]": # Array stop.
if len(param_stack) < 2:
raise ParseError('Unexpected closing bracket in type tag: {0}'.format(type_tag))
param_stack.pop()
have_val = False
# TODO: Support more exotic types as described in the specification. # TODO: Support more exotic types as described in the specification.
else: else:
logging.warning('Unhandled parameter type: {0}'.format(param)) logging.warning('Unhandled parameter type: {0}'.format(param))
continue continue
self._parameters.append(val) if have_val:
param_stack[-1].append(val)
if len(param_stack) != 1:
raise ParseError('Missing closing bracket in type tag: {0}'.format(type_tag))
self._parameters = params
except osc_types.ParseError as pe: except osc_types.ParseError as pe:
raise ParseError('Found incorrect datagram, ignoring it', pe) raise ParseError('Found incorrect datagram, ignoring it', pe)
......
...@@ -19,6 +19,9 @@ class OscMessageBuilder(object): ...@@ -19,6 +19,9 @@ class OscMessageBuilder(object):
ARG_TYPE_TRUE = "T" ARG_TYPE_TRUE = "T"
ARG_TYPE_FALSE = "F" ARG_TYPE_FALSE = "F"
ARG_TYPE_ARRAY_START = "["
ARG_TYPE_ARRAY_STOP = "]"
_SUPPORTED_ARG_TYPES = ( _SUPPORTED_ARG_TYPES = (
ARG_TYPE_FLOAT, ARG_TYPE_INT, ARG_TYPE_BLOB, ARG_TYPE_STRING, ARG_TYPE_RGBA, ARG_TYPE_TRUE, ARG_TYPE_FALSE) ARG_TYPE_FLOAT, ARG_TYPE_INT, ARG_TYPE_BLOB, ARG_TYPE_STRING, ARG_TYPE_RGBA, ARG_TYPE_TRUE, ARG_TYPE_FALSE)
...@@ -46,6 +49,16 @@ class OscMessageBuilder(object): ...@@ -46,6 +49,16 @@ class OscMessageBuilder(object):
"""Returns the (type, value) arguments list of this message.""" """Returns the (type, value) arguments list of this message."""
return self._args return self._args
def valid_type(self, arg_type):
if arg_type in self._SUPPORTED_ARG_TYPES:
return True
elif isinstance(arg_type, list):
for a in arg_type:
if not self.valid_type(a):
return False
return True
return False
def add_arg(self, arg_value, arg_type=None): def add_arg(self, arg_value, arg_type=None):
"""Add a typed argument to this message. """Add a typed argument to this message.
...@@ -56,10 +69,27 @@ class OscMessageBuilder(object): ...@@ -56,10 +69,27 @@ class OscMessageBuilder(object):
Raises: Raises:
- ValueError: if the type is not supported. - ValueError: if the type is not supported.
""" """
if arg_type and arg_type not in self._SUPPORTED_ARG_TYPES: if arg_type and not self.valid_type(arg_type):
raise ValueError( raise ValueError(
'arg_type must be one of {}'.format(self._SUPPORTED_ARG_TYPES)) 'arg_type must be one of {}'.format(self._SUPPORTED_ARG_TYPES))
if not arg_type: if not arg_type:
arg_type = self.get_arg_type(arg_value)
if isinstance(arg_type, list):
self._args.append((self.ARG_TYPE_ARRAY_START, None))
for v, t in zip(arg_value, arg_type):
self.add_arg(v, t)
self._args.append((self.ARG_TYPE_ARRAY_STOP, None))
else:
self._args.append((arg_type, arg_value))
def get_arg_type(self, arg_value):
"""Guess the type of a value.
Args:
- arg_value: The value to guess the type of.
Raises:
- ValueError: if the type is not supported.
"""
if isinstance(arg_value, str): if isinstance(arg_value, str):
arg_type = self.ARG_TYPE_STRING arg_type = self.ARG_TYPE_STRING
elif isinstance(arg_value, bytes): elif isinstance(arg_value, bytes):
...@@ -72,9 +102,11 @@ class OscMessageBuilder(object): ...@@ -72,9 +102,11 @@ class OscMessageBuilder(object):
arg_type = self.ARG_TYPE_TRUE arg_type = self.ARG_TYPE_TRUE
elif arg_value == False: elif arg_value == False:
arg_type = self.ARG_TYPE_FALSE arg_type = self.ARG_TYPE_FALSE
elif isinstance(arg_value, list):
arg_type = [self.get_arg_type(v) for v in arg_value]
else: else:
raise ValueError('Infered arg_value type is not supported') raise ValueError('Infered arg_value type is not supported')
self._args.append((arg_type, arg_value)) return arg_type
def build(self): def build(self):
"""Builds an OscMessage from the current state of this builder. """Builds an OscMessage from the current state of this builder.
...@@ -110,7 +142,10 @@ class OscMessageBuilder(object): ...@@ -110,7 +142,10 @@ class OscMessageBuilder(object):
dgram += osc_types.write_blob(value) dgram += osc_types.write_blob(value)
elif arg_type == self.ARG_TYPE_RGBA: elif arg_type == self.ARG_TYPE_RGBA:
dgram += osc_types.write_rgba(value) dgram += osc_types.write_rgba(value)
elif arg_type == self.ARG_TYPE_TRUE or arg_type == self.ARG_TYPE_FALSE: elif arg_type in (self.ARG_TYPE_TRUE,
self.ARG_TYPE_FALSE,
self.ARG_TYPE_ARRAY_START,
self.ARG_TYPE_ARRAY_STOP):
continue continue
else: else:
raise BuildError('Incorrect parameter type found {}'.format( raise BuildError('Incorrect parameter type found {}'.format(
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment