2727except ImportError :
2828 import urllib as quote
2929
30+ # TODO DL Threshold for converting large Arrays in ROS-Messages?
31+ THRESH = 256
32+
3033class EntityAttribute ():
3134 """ Here the actual Conversion to the correct JSON-Format happens
3235 (no string is generated here). By initializing this class the given Object is
@@ -73,6 +76,7 @@ def __init__(self, _object, ipmd, concreteDataType=None, baseEntity=False):
7376 self .setPythonMetaData (ipmd , "complex" )
7477 # self.setConcreteMetaData(concreteDataType)
7578 elif objectType is str :
79+ # Thanks to ROS, Bytes are converted into
7680 self .type = "string"
7781 self .value = str (_object )
7882 # self.setConcreteMetaData(concreteDataType)
@@ -114,7 +118,7 @@ def __init__(self, _object, ipmd, concreteDataType=None, baseEntity=False):
114118 raise ValueError ("Cannot get attrs from {}" .format (str (_object )))
115119
116120 if hasattr (_object , '_type' ) and hasattr (_object , '_slot_types' ) and hasattr (_object , '__slots__' ): # ROS-Specific Type-Declaration
117- ### This is a special Class from ROS!
121+ ### This is a special CASE for ROS!!! !
118122 self .type = _object ._type .replace ("/" , "." ) # Needs to be replaced Fiware does not allow a '/'
119123 self .setPythonMetaData (ipmd , "class" )
120124 # Special Case 'Image-like'-Data in ROS (very long 'int8[]'- and 'uint8[]' - arrays)
@@ -123,14 +127,14 @@ def __init__(self, _object, ipmd, concreteDataType=None, baseEntity=False):
123127 for key , key_type in zip (_object .__slots__ , _object ._slot_types ):
124128 if key .startswith ('_' ):
125129 continue
126- if (key_type == 'int8[]' or key_type == 'uint8[]' ) and len (getattr (_object , key )) >= 256 :
130+ if ('int8[' in key_type or 'uint8[' in key_type ) and len (getattr (_object , key )) >= THRESH :
127131 # TODO DL 256 -> Threshold?
128132 # Generate Base64 String of the Array:
129133 tempDict [key ] = EntityAttribute (None , ipmd )
130134 tempDict [key ].type = "base64"
131135
132136 # Either generate unsigned or signed byte-array
133- if key_type == 'int8[]' :
137+ if 'int8[' in key_type :
134138 tempDict [key ].value = array .array ('b' , getattr (_object , key )).tostring ()
135139 else :
136140 tempDict [key ].value = array .array ('B' , getattr (_object , key )).tostring ()
@@ -145,8 +149,46 @@ def __init__(self, _object, ipmd, concreteDataType=None, baseEntity=False):
145149 else :
146150 innerConcreteMetaData = None
147151 if concreteDataType is not None and key in concreteDataType :
152+ # We have a special DatType for it
148153 innerConcreteMetaData = concreteDataType [key ]
149- tempDict [key ] = EntityAttribute (getattr (_object , key ), ipmd , innerConcreteMetaData )
154+ alreadySet = False # Boolean to check if data ist already set
155+ if "uint8[" in innerConcreteMetaData :
156+ # SPECIAL ROS CASE we have uint8[]-Array as a String or byte
157+ # See: http://wiki.ros.org/msg#Fields -> Array-Handling
158+ strangeObj = getattr (_object , key )
159+ toConvert = None
160+ if type (strangeObj ) is str :
161+ # Looks like ROS converted it for us into str!
162+ toConvert = array .array ("B" , strangeObj ).tolist ()
163+ if not self .python_version < (3 ,0 ) and type (strangeObj ) is bytes :
164+ # Looks like ROS converted it for us into bytes!
165+ toConvert = list (strangeObj )
166+ if toConvert is not None and len (toConvert ) >= THRESH :
167+ # TODO DL 256 -> Threshold?
168+ # Generate Base64 String of the Array:
169+ tempDict [key ] = EntityAttribute (None , ipmd )
170+ tempDict [key ].type = "base64"
171+
172+ # Generate unsigned or byte-array
173+ tempDict [key ].value = array .array ('B' , getattr (_object , key )).tostring ()
174+
175+ # Form that Byte-Array: generate Base64 String
176+ tempDict [key ].value = base64 .b64encode (tempDict [key ].value )
177+
178+ # Escape Special Characters:
179+ tempDict [key ].value = quote .quote (tempDict [key ].value )
180+ tempDict [key ].metadata = dict ()
181+ self .setConcreteMetaData (innerConcreteMetaData , tempDict [key ])
182+ alreadySet = True
183+
184+ else :
185+ # Something else we should convert
186+ toConvert = getattr (_object , key )
187+ if alreadySet is False :
188+ tempDict [key ] = EntityAttribute (toConvert , ipmd , innerConcreteMetaData )
189+ else :
190+ # Just get its child and convert it
191+ tempDict [key ] = EntityAttribute (getattr (_object , key ), ipmd , None )
150192 self .value = tempDict
151193 else :
152194 # Simple Class. Recursively retrieve the other values
0 commit comments