1 # Copyright 2012 GRNET S.A. All rights reserved.
3 # Redistribution and use in source and binary forms, with or
4 # without modification, are permitted provided that the following
7 # 1. Redistributions of source code must retain the above
8 # copyright notice, this list of conditions and the following
11 # 2. Redistributions in binary form must reproduce the above
12 # copyright notice, this list of conditions and the following
13 # disclaimer in the documentation and/or other materials
14 # provided with the distribution.
16 # THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 # POSSIBILITY OF SUCH DAMAGE.
29 # The views and conclusions contained in the software and
30 # documentation are those of the authors and should not be
31 # interpreted as representing official policies, either expressed
32 # or implied, of GRNET S.A.
35 from collections import OrderedDict
37 from kamaki.clients.commissioning.utils.ordereddict import OrderedDict
38 from itertools import chain
39 from cStringIO import StringIO
41 ARGMAP_MAGIC = '[=ARGMAP=]'
44 class arguments(object):
45 __slots__ = ('args', 'kw')
47 def __init__(self, *args, **kwargs):
48 self.args = list(args)
50 kwitems = kw.pop('kwitems', None)
51 if kwitems is not None:
57 return str(self.args) + '+' + str(self.kw)
60 return repr(self.args) + '+' + repr(self.kw)
62 def __getitem__(self, key):
63 if (isinstance(key, int)
64 or isinstance(key, long)
65 or isinstance(key, slice)):
70 def __setitem__(self, key, value):
71 if (isinstance(key, int)
72 or isinstance(key, long)
73 or isinstance(key, slice)):
74 self.args[key] = value
78 def __delitem__(self, key):
79 if (isinstance(key, int)
80 or isinstance(key, long)
81 or isinstance(key, slice)):
87 for item in self.args:
93 return list(self.iteritems())
96 return self.kw.iterkeys()
101 def itervalues(self):
102 return chain(self.args, self.kw.itervalues())
105 return list(self.itervalues)
107 def append(self, value):
108 self.args.append(value)
111 def argmap_encode(obj, output):
116 if isinstance(obj, basestring):
119 if isinstance(obj, unicode):
120 obj = obj.encode('utf-8')
124 end = obj.find(start) + 1
127 output(obj[start:end] + '"')
133 if isinstance(obj, int) or isinstance(obj, long):
137 if hasattr(obj, 'iteritems'):
140 for k, v in obj.iteritems():
151 if hasattr(obj, '__iter__'):
162 m = "Unsupported type '%s'" % (type(obj))
166 def argmap_decode(inputf, s=None):
167 if isinstance(inputf, str):
168 inputf = StringIO(inputf).read
189 item, s = argmap_decode_args(inputf)
199 def argmap_decode_atom(inputf):
202 m = "Invalid atom '%s'" % (s,)
207 def argmap_decode_args(inputf):
220 args.append(ARGMAP_MAGIC)
225 atom, s = argmap_decode_atom(inputf)
228 value, s = argmap_decode(inputf)
237 m = "EOF while scanning for ']'"
242 key, s = argmap_decode(inputf, s=s)
245 def argmap_check(obj):
246 if hasattr(obj, 'keys') and callable(obj.keys):
247 # this could cover both cases
248 return ARGMAP_MAGIC in obj
249 if hasattr(obj, '__len__'):
251 return length and obj[length - 1] == ARGMAP_MAGIC
255 def argmap_unzip_dict(argmap):
256 if not hasattr(argmap, 'keys'):
257 m = "argmap unzip dict: not a dict"
259 if ARGMAP_MAGIC not in argmap:
260 m = "argmap unzip dict: magic not found"
262 args = argmap.pop(None, [])
263 kw = OrderedDict(argmap)
268 def argmap_unzip_list(argmap):
269 if not argmap or argmap.pop() != ARGMAP_MAGIC:
270 m = "argmap unzip list: magic not found"
284 def argmap_unzip(argmap):
285 if hasattr(argmap, 'keys'):
286 return argmap_unzip_dict(argmap)
287 elif hasattr(argmap, '__iter__'):
288 return argmap_unzip_list(argmap)
290 m = "argmap: cannot unzip type %s" % (type(argmap),)
294 def argmap_zip_list(args, kw):
295 return [(None, a) for a in args] + kw.items() + [ARGMAP_MAGIC]
298 def argmap_zip_dict(args, kw):
299 argmap = OrderedDict()
301 argmap[ARGMAP_MAGIC] = ARGMAP_MAGIC
302 argmap[None] = list(args) + (argmap[None] if None in argmap else [])
305 argmap_zip = argmap_zip_list
308 def argmap_list_to_dict(argmap):
309 args, kw = argmap_unzip_list(argmap)
310 kw[ARGMAP_MAGIC] = ARGMAP_MAGIC
315 def argmap_dict_to_list(argmap):
316 args, kw = argmap_unzip_dict(argmap)
317 return args + kw.items() + [ARGMAP_MAGIC]
320 def argmap_unpack_list(argmap):
321 kw = argmap_list_to_dict(argmap)
327 def argmap_unpack_dict(argmap):
328 if hasattr(argmap, 'keys') and callable(argmap.keys):
329 return argmap_dict_to_list(argmap)[:-1]