def _parse_datagram(self): try: self._address_regexp, index = osc_types.get_string(self._dgram, 0) if not self._dgram[index:]: # No params is legit, just return now. return # Get the parameters types. type_tag, index = osc_types.get_string(self._dgram, index) if type_tag.startswith(','): type_tag = type_tag[1:] params = [] param_stack = [params] # Parse each parameter given its type. for param in type_tag: if param == "i": # Integer. val, index = osc_types.get_int(self._dgram, index) elif param == "f": # Float. val, index = osc_types.get_float(self._dgram, index) elif param == "d": # Double. val, index = osc_types.get_float(self._dgram, index) elif param == "s": # String. val, index = osc_types.get_string(self._dgram, index) elif param == "b": # Blob. val, index = osc_types.get_blob(self._dgram, index) elif param == "r": # RGBA. val, index = osc_types.get_rgba(self._dgram, index) elif param == "T": # True. val = True elif param == "F": # False. val = False elif param == "[": # Array start. array = [] param_stack[-1].append(array) param_stack.append(array) elif param == "]": # Array stop. if len(param_stack) < 2: raise ParseError( 'Unexpected closing bracket in type tag: {0}'. format(type_tag)) param_stack.pop() # TODO: Support more exotic types as described in the specification. else: logging.warning( 'Unhandled parameter type: {0}'.format(param)) continue if param not in "[]": 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: raise ParseError('Found incorrect datagram, ignoring it', pe)
def _parse_datagram(self): self._address_regexp, index = osc_types.get_string(self._dgram, 0) if not self._dgram[index:]: # No params is legit, just return now. return # Get the parameters types. type_tag, index = osc_types.get_string(self._dgram, index) if type_tag.startswith(','): type_tag = type_tag[1:] # Parse each parameter given its type. for param in type_tag: if param == "i": # Integer. val, index = osc_types.get_int(self._dgram, index) elif param == "f": # Float. val, index = osc_types.get_float(self._dgram, index) elif param == "s": # String. val, index = osc_types.get_string(self._dgram, index) elif param == "b": # Blob. val, index = osc_types.get_blob(self._dgram, index) elif param == "T": # True. val = True elif param == "F": # False. val = False # TODO: Support more exotic types as described in the specification. else: logging.getLogger().warning('Unhandled parameter type: {0}'.format(param)) continue self._parameters.append(val)
def _parse_datagram(self): try: self._address_regexp, index = osc_types.get_string(self._dgram, 0) if not self._dgram[index:]: # No params is legit, just return now. return # Get the parameters types. type_tag, index = osc_types.get_string(self._dgram, index) if type_tag.startswith(','): type_tag = type_tag[1:] # Parse each parameter given its type. for param in type_tag: if param == "i": # Integer. val, index = osc_types.get_int(self._dgram, index) elif param == "f": # Float. val, index = osc_types.get_float(self._dgram, index) elif param == "s": # String. val, index = osc_types.get_string(self._dgram, index) elif param == "b": # Blob. val, index = osc_types.get_blob(self._dgram, index) elif param == "T": # True. val = True elif param == "F": # False. val = False # TODO: Support more exotic types as described in the specification. else: logging.warning( 'Unhandled parameter type: {0}'.format(param)) continue self._parameters.append(val) except osc_types.ParseError as pe: raise ParseError('Found incorrect datagram, ignoring it', pe)
def _parse_datagram(self): try: self._address_regexp, index = osc_types.get_string(self._dgram, 0) if not self._dgram[index:]: # No params is legit, just return now. return # Get the parameters types. type_tag, index = osc_types.get_string(self._dgram, index) if type_tag.startswith(','): type_tag = type_tag[1:] # Parse each parameter given its type. for param in type_tag: if param == "i": # Integer. val, index = osc_types.get_int(self._dgram, index) elif param == "f": # Float. val, index = osc_types.get_float(self._dgram, index) elif param == "s": # String. val, index = osc_types.get_string(self._dgram, index) elif param == "b": # Blob. val, index = osc_types.get_blob(self._dgram, index) # TODO: Support more exotic types as described in the specification. elif param == 0: # We've reached the end of the param string, finish now. return else: logging.warning('Unhandled parameter type: {0}'.format(param)) continue self._parameters.append(val) except osc_types.ParseError as pe: raise ParseError('Found incorrect datagram, ignoring it', pe)
def test_get_float(self): cases = { b"\x00\x00\x00\x00": (0.0, 4), b"?\x80\x00\x00'": (1.0, 4), b'@\x00\x00\x00': (2.0, 4), b"\x00\x00\x00\x00GARBAGE": (0.0, 4), } for dgram, expected in cases.items(): self.assertAlmostEqual(expected, osc_types.get_float(dgram, 0))
def _parse_datagram(self): try: self._address_regexp, index = osc_types.get_string(self._dgram, 0) if not self._dgram[index:]: # No params is legit, just return now. return # Get the parameters types. type_tag, index = osc_types.get_string(self._dgram, index) if type_tag.startswith(','): type_tag = type_tag[1:] params = [] param_stack = [params] # Parse each parameter given its type. for param in type_tag: if param == "i": # Integer. val, index = osc_types.get_int(self._dgram, index) elif param == "f": # Float. val, index = osc_types.get_float(self._dgram, index) elif param == "d": # Double. val, index = osc_types.get_double(self._dgram, index) elif param == "s": # String. val, index = osc_types.get_string(self._dgram, index) elif param == "b": # Blob. val, index = osc_types.get_blob(self._dgram, index) elif param == "r": # RGBA. val, index = osc_types.get_rgba(self._dgram, index) elif param == "m": # MIDI. val, index = osc_types.get_midi(self._dgram, index) elif param == "t": # osc time tag: val, index = osc_types.get_ttag(self._dgram, index) elif param == "T": # True. val = True elif param == "F": # False. val = False elif param == "[": # Array start. array = [] param_stack[-1].append(array) param_stack.append(array) elif param == "]": # Array stop. if len(param_stack) < 2: raise ParseError('Unexpected closing bracket in type tag: {0}'.format(type_tag)) param_stack.pop() # TODO: Support more exotic types as described in the specification. else: logging.warning('Unhandled parameter type: {0}'.format(param)) continue if param not in "[]": 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: raise ParseError('Found incorrect datagram, ignoring it', pe)
def __parse_sc_blob(data): '''Parses the blob from a SuperCollider osc message''' TYPE_TAG_MARKER = ord(b',') TYPE_TAG_START = 4 NUM_SIZE = 4 INT_TAG = ord(b'i') bytes2type = { ord(b'i'): lambda data: osc_types.get_int(data, 0), ord(b'f'): lambda data: osc_types.get_float(data, 0), ord(b's'): lambda data: osc_types.get_string(data, 0), } def __get_aligned_pos(pos): return NUM_SIZE * int(np.ceil((pos)/NUM_SIZE)) def __parse_list(data): list_size, _ = bytes2type[INT_TAG](data) type_tag_offset = __get_aligned_pos(list_size + 2) type_tag_end = TYPE_TAG_START + type_tag_offset type_tag = data[TYPE_TAG_START + 1: TYPE_TAG_START + 1 + list_size] value_list = [] idx = type_tag_end for t in type_tag: value, num_bytes = bytes2type[t](data[idx:]) value_list.append(value) idx += num_bytes return value_list, list_size def __parse_sc_msg(data): list_size, _ = bytes2type[INT_TAG](data) msg_size = __get_aligned_pos(NUM_SIZE + list_size) sc_list, _ = __parse_list(data[NUM_SIZE: msg_size]) return sc_list, msg_size bytes2type[ord(b'b')] = __parse_sc_msg def __parse_bundle(data): bundle_size = len(data) lists = [] idx = 16 # skip header while idx < bundle_size: sc_list, list_size = __parse_sc_msg(data[idx:]) lists.append(sc_list) idx += list_size return lists, bundle_size if data[TYPE_TAG_START] == TYPE_TAG_MARKER: return __parse_list(data)[0] elif data[:8] == b'#bundle\x00': return __parse_bundle(data)[0] else: return data
def test_datagram_too_short_pads(self): dgram = b'\x00' * 2 self.assertEqual((0, 4), osc_types.get_float(dgram, 0))
def parse_sclang_blob(data): '''Parses the blob from a SuperCollider osc message''' TYPE_TAG_MARKER = ord(b',') TYPE_TAG_START = 4 NUM_SIZE = 4 INT_TAG = ord(b'i') bytes2type = { ord(b'i'): lambda data: osc_types.get_int(data, 0), ord(b'f'): lambda data: osc_types.get_float(data, 0), ord(b's'): lambda data: osc_types.get_string(data, 0), ord(b'N'): lambda data: (None, 0), ord(b'I'): lambda data: (np.inf, 0), ord(b'T'): lambda data: (True, 0), ord(b'F'): lambda data: (False, 0) } def _get_aligned_pos(pos): return NUM_SIZE * int(np.ceil((pos) / NUM_SIZE)) def _parse_list(data): logging.debug("[ start parsing list: {}".format(data)) list_size, _ = bytes2type[INT_TAG](data) type_tag_offset = _get_aligned_pos(list_size + 2) type_tag_end = TYPE_TAG_START + type_tag_offset type_tag = data[TYPE_TAG_START + 1:TYPE_TAG_START + 1 + list_size] value_list = [] idx = type_tag_end for t in type_tag: try: value, num_bytes = bytes2type[t](data[idx:]) except KeyError: raise Exception('type tag "{}" not understood'.format(chr(t))) logging.debug("new value {}".format(value)) value_list.append(value) idx += num_bytes logging.debug("resulting list {}".format(value_list)) logging.debug("] end parsing list") return value_list, idx def _parse_sc_msg(data): logging.debug(">> parse sc msg: {}".format(data)) msg_size, _ = bytes2type[INT_TAG](data) logging.debug("msg size {}".format(msg_size)) data = data[NUM_SIZE:] if data[:8] == b'#bundle\x00': logging.debug("found bundle") msgs, bundle_size = _parse_bundle(data) return msgs, bundle_size + NUM_SIZE elif data[TYPE_TAG_START] == TYPE_TAG_MARKER: logging.debug("found list") value_list, list_size = _parse_list(data[:msg_size]) return value_list, list_size + NUM_SIZE else: raise Exception("Datagram not recognized") bytes2type[ord(b'b')] = _parse_sc_msg def _parse_bundle(data): logging.debug("## start parsing bundle: {}".format(data)) msgs = [] msg_count = ord(data[8 + 3:8 + 4]) - ord("\x80") bundle_size = 16 # skip header logging.debug("msg count {}".format(msg_count)) while msg_count > 0: sc_msg, msg_size = _parse_sc_msg(data[bundle_size:]) msgs.append(sc_msg) bundle_size += msg_size msg_count -= 1 logging.debug("msgs left {}".format(msg_count)) bundle_size = _get_aligned_pos(bundle_size) logging.debug("parsed bytes {}".format(data[:bundle_size])) logging.debug("msgs {}".format(msgs)) logging.debug("## end parsing bundle ") return msgs, bundle_size try: if len(data) > TYPE_TAG_START + 1: if data[TYPE_TAG_START] == TYPE_TAG_MARKER: return _parse_list(data)[0] elif data[:8] == b'#bundle\x00': return _parse_bundle(data)[0] except Exception as e: logging.warning('Ignoring Exception:\n{}\nreturning blob'.format(e)) return data