Source code for pdpy_lib.memory.struct

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# **************************************************************************** #
# This file is part of the pdpy project: https://github.com/pdpy-org
# Copyright (C) 2021 Fede Camara Halac
# **************************************************************************** #
""" Class Definitions for Pure Data's Data Structures """

from . import goparray
from ..core.base import Base
from ..utilities.exceptions import ArgumentException
from ..utilities.utils import log

__all__ = [ 'Struct' ]

[docs]class Struct(Base): """ An object containing a Pure Data 'struct' header """ def __init__(self, pd_lines=None, json=None, xml=None): self.__pdpy__ = self.__class__.__name__ self.order = [] super().__init__(pdtype='N', cls='struct') if json is not None: super().__populate__(self, json) elif xml is not None: # log(1,xml.findall('*')) self.name = xml.findtext('name') # iterate through the attributes based on the order # order will be updated as we go for k,_ in sorted(xml.attrib.items(), key=lambda i: i[1]): e = k[:-1] # remove the 's' x = xml.find(k) if k=='floats': for s in x.findall(e): self.addFloat(s.text) elif k=='symbols': for s in x.findall(e): self.addSymbol(s.text) elif k=='texts': for s in x.findall(e): self.addText(s.text) elif k=='arrays': for s in x.findall('goparray'): self.addArray(s.findtext('name'),s.findtext('template')) else: raise ArgumentException("Unknown attribute: {}".format(k)) elif pd_lines is not None: self.name = pd_lines[0] pd_lines = pd_lines[1:] i = 0 while i < len(pd_lines): if i >= len(pd_lines): break pd_type = pd_lines[i] pd_name = pd_lines[i + 1] if 'float' == pd_type: self.addFloat(pd_name) elif 'symbol' == pd_type: self.addSymbol(pd_name) elif 'text' == pd_type: self.addText(pd_name) elif 'array' == pd_type: array_name = pd_lines[i + 2] self.addArray(pd_name, array_name) i += 1 else: log(1, "Unparsed Struct Field #" + str(i)) log(1, self.name, pd_lines) self.__dumps__() i += 2 else: pass # raise ArgumentException("Struct: Incorrect arguments given")
[docs] def addFloat(self, pd_name): if not hasattr(self, 'float'): self.float = [] self.order.append('float') self.float.append(pd_name)
[docs] def addSymbol(self, pd_name): if not hasattr(self, 'symbol'): self.symbol = [] self.order.append('symbol') self.symbol.append(pd_name)
[docs] def addText(self, pd_name): if not hasattr(self, 'text'): self.text = [] self.order.append('text') self.text.append(pd_name)
[docs] def addArray(self, pd_name, array_name): """ Append an array structure with symbols for name and template """ if not hasattr(self, 'array'): self.array = [] self.order.append('array') self.array.append(goparray.GOPArray(json={ 'name' : pd_name, 'template' : array_name }))
[docs] def parse(self, data): """ Returns a list of scalar data structured by the corresponding struct """ _data = {} # log(1,"DATA",data) # data = list(filter(lambda x:x==' ',data)) if len(data) == 0: return None arr = None fs = data[0].split(' ') # log(1,'FS',fs) if len(data) >= 2: arr = data[1:] # log(1,'ARR',arr) if hasattr(self, 'float'): _data.update({ 'float': { f:self.__num__(v) for f,v in zip(self.float, fs[:len(self.float)]) } }) if hasattr(self, 'symbol'): # log(1, "SYMBOLS", self.symbol, fs) _data.update({ 'symbol': {f:v for f,v in zip(self.symbol, fs[len(self.float):])} }) # log(1, "DATA", _data) if arr is not None and hasattr(self, 'array'): for a in self.array: _, template = self.__parent__.getTemplate(a.template) if template is not None: if hasattr(template, 'float'): # fill the corresponding named arrays with float arrays _arr_obj = {} for val_list in arr: # zip key and value from template names and data float values for key, val in zip(template.float, val_list): if key in _arr_obj: _arr_obj[key].append(self.__num__(val)) else: _arr_obj[key] = [self.__num__(val)] _data.update({ 'array' : _arr_obj }) if hasattr(template, 'symbol'): # fill the corresponding named arrays with tring arrays _arr_obj = {} for val_list in arr: # zip key and value from template names and data string values for key, val in zip(template.symbol, val_list): if key in _arr_obj: _arr_obj[key].append(val) else: _arr_obj[key] = [val] _data.append(_arr_obj) if hasattr(template, 'array'): #TODO: implement this log(1,"DS recursion on arrays implemented") if len(_data): return _data
def __pd__(self): """ Returns the struct instruction for the pd file """ if not hasattr(self, 'name'): return self.__closeline__("X", "obj", self.position.__pd__() + " " + self.__cls__) s = self.name for a in getattr(self, 'order', []): arr = [] for x in getattr(self, a, []): if a == 'array': x = x.__pd__() else: x = a + ' ' + x arr.append(x) s += ' ' + ' '.join(arr) if arr else '' return super().__pd__(s) def __xml__(self): """ Return the XML Element for this object """ x = super().__xml__(self, attrib=('name')) for i,a in enumerate(getattr(self, 'order', [])): super().__update_attrib__(x, a + 's', i) xs = super().__element__(tag = a + 's') for e in getattr(self, a, []): if a == 'array': super().__subelement__(xs, e.__xml__()) else: super().__subelement__(xs, a, text=e) # update the parent elements super().__subelement__(x, xs) return x