Package PyFoam :: Package Basics :: Module DataStructures
[hide private]
[frames] | no frames]

Source Code for Module PyFoam.Basics.DataStructures

  1  """Data structures in Foam-Files that can't be directly represented by Python-Structures""" 
  2   
  3  from __future__ import division 
  4   
  5  from copy import deepcopy 
  6  import math 
  7  import re 
  8   
  9  # import FoamFileGenerator in the end to avoid circular dependencies 
 10   
 11  from PyFoam.ThirdParty.six import integer_types,PY3,string_types 
 12   
 13  if PY3: 
14 - def cmp(a,b):
15 if a<b: 16 return -1 17 elif a==b: 18 return 0 19 else: 20 return 1
21
22 -class FoamDataType(object):
23 - def __repr__(self):
24 return "'"+str(self)+"'"
25
26 - def __eq__(self,other):
27 """Implementation to make __cmp__ work again in Python3 28 29 Implementing this method means that these objects are not hashable. 30 But that is OK 31 """ 32 return self.__cmp__(other)==0
33
34 - def __lt__(self,other):
35 "Implementation to make __cmp__ work again in Python3" 36 return self.__cmp__(other)<0
37
38 - def __ne__(self,other):
39 return self.__cmp__(other)!=0
40
41 - def __gt__(self,other):
42 return self.__cmp__(other)>0
43
44 - def __ge__(self,other):
45 return self.__cmp__(other)>=0
46
47 - def __le__(self,other):
48 return self.__cmp__(other)<=0
49
50 -class Field(FoamDataType):
51 - def __init__(self,val,name=None):
52 self.val=val 53 self.name=name 54 if type(val) in[list,UnparsedList,BinaryList]: 55 self.uniform=False 56 elif self.name==None: 57 self.uniform=True 58 else: 59 raise TypeError("Type",type(val),"of value",val,"can not be used to determine uniformity")
60
61 - def __str__(self):
62 result="" 63 if self.uniform: 64 result+="uniform " 65 else: 66 result+="nonuniform " 67 if self.name: 68 result+=self.name+" " 69 70 result+=str( 71 PyFoam.Basics.FoamFileGenerator.FoamFileGenerator( 72 self.val, 73 longListThreshold=-1, 74 useFixedType=False 75 )) 76 return result
77
78 - def __cmp__(self,other):
79 if other==None or type(other)!=Field: 80 return 1 81 if self.uniform!=other.uniform: 82 return cmp(self.uniform,other.uniform) 83 elif self.name!=other.name: 84 return cmp(self.name,other.name) 85 else: 86 return cmp(self.val,other.val)
87
88 - def __getitem__(self,key):
89 assert(not self.uniform) 90 return self.val[key]
91
92 - def __setitem__(self,key,value):
93 assert(not self.uniform) 94 self.val[key]=value
95
96 - def isUniform(self):
97 return self.uniform
98
99 - def isBinary(self):
100 return type(self.val)==BinaryList
101
102 - def binaryString(self):
103 return "nonuniform "+self.name+" <BINARY DATA>"
104
105 - def value(self):
106 return self.val
107
108 - def setUniform(self,data):
109 self.val=data 110 self.uniform=True 111 self.name=None
112
113 -class Dimension(FoamDataType):
114 - def __init__(self,*dims):
115 assert(len(dims)==7) 116 self.dims=list(dims)
117
118 - def __str__(self):
119 result="[ " 120 for v in self.dims: 121 result+=str(v)+" " 122 result+="]" 123 return result
124
125 - def __cmp__(self,other):
126 if other==None: 127 return 1 128 return cmp(self.dims,other.dims)
129
130 - def __getitem__(self,key):
131 return self.dims[key]
132
133 - def __setitem__(self,key,value):
134 self.dims[key]=value
135
136 -class FixedLength(FoamDataType):
137 - def __init__(self,vals):
138 self.vals=vals[:]
139
140 - def __str__(self):
141 return "("+" ".join(["%g"%v for v in self.vals])+")"
142
143 - def __cmp__(self,other):
144 if other==None or not issubclass(type(other),FixedLength): 145 return 1 146 return cmp(self.vals,other.vals)
147
148 - def __getitem__(self,key):
149 return self.vals[key]
150
151 - def __setitem__(self,key,value):
152 self.vals[key]=value
153
154 - def __len__(self):
155 return len(self.vals)
156
157 -class Vector(FixedLength):
158 - def __init__(self,x,y,z):
159 FixedLength.__init__(self,[x,y,z])
160
161 - def __add__(self,y):
162 x=self 163 if type(y)==Vector: 164 return Vector(x[0]+y[0],x[1]+y[1],x[2]+y[2]) 165 elif type(y) in integer_types+(float,): 166 return Vector(x[0]+y,x[1]+y,x[2]+y) 167 else: 168 return NotImplemented
169
170 - def __radd__(self,y):
171 x=self 172 if type(y) in integer_types+(float,): 173 return Vector(x[0]+y,x[1]+y,x[2]+y) 174 else: 175 return NotImplemented
176
177 - def __sub__(self,y):
178 x=self 179 if type(y)==Vector: 180 return Vector(x[0]-y[0],x[1]-y[1],x[2]-y[2]) 181 elif type(y) in integer_types+(float,): 182 return Vector(x[0]-y,x[1]-y,x[2]-y) 183 else: 184 return NotImplemented
185
186 - def __rsub__(self,y):
187 x=self 188 if type(y) in integer_types+(float,): 189 return Vector(y-x[0],y-x[1],y-x[2]) 190 else: 191 return NotImplemented
192
193 - def __mul__(self,y):
194 x=self 195 if type(y)==Vector: 196 return Vector(x[0]*y[0],x[1]*y[1],x[2]*y[2]) 197 elif type(y) in integer_types+(float,): 198 return Vector(x[0]*y,x[1]*y,x[2]*y) 199 else: 200 return NotImplemented
201
202 - def __rmul__(self,y):
203 x=self 204 if type(y) in integer_types+(float,): 205 return Vector(y*x[0],y*x[1],y*x[2]) 206 else: 207 return NotImplemented
208
209 - def __div__(self,y):
210 x=self 211 if type(y)==Vector: 212 return Vector(x[0]/y[0],x[1]/y[1],x[2]/y[2]) 213 elif type(y) in integer_types+(float,): 214 return Vector(x[0]/y,x[1]/y,x[2]/y) 215 else: 216 return NotImplemented
217
218 - def __truediv__(self,y):
219 return self.__div__(y)
220
221 - def __xor__(self,y):
222 x=self 223 if type(y)==Vector: 224 return Vector(x[1]*y[2]-x[2]*y[1], 225 x[2]*y[0]-x[0]*y[2], 226 x[0]*y[1]-x[1]*y[0]) 227 else: 228 return NotImplemented
229
230 - def __abs__(self):
231 x=self 232 return math.sqrt(x[0]*x[0]+x[1]*x[1]+x[2]*x[2])
233
234 - def __neg__(self):
235 x=self 236 return Vector(-x[0],-x[1],-x[2])
237
238 - def __pos__(self):
239 x=self 240 return Vector( x[0], x[1], x[2])
241
242 -class Tensor(FixedLength):
243 - def __init__(self,v1,v2,v3,v4,v5,v6,v7,v8,v9):
244 FixedLength.__init__(self,[v1,v2,v3,v4,v5,v6,v7,v8,v9])
245
246 -class SymmTensor(FixedLength):
247 - def __init__(self,v1,v2,v3,v4,v5,v6):
248 FixedLength.__init__(self,[v1,v2,v3,v4,v5,v6])
249
250 -class BoolProxy(object):
251 """Wraps a boolean parsed from a file. Optionally stores a textual 252 representation 253 """ 254 255 TrueStrings=["on", 256 "yes", 257 "true", 258 # "y" # this breaks parsing certain files 259 ] 260 FalseStrings=[ 261 "off", 262 "no", 263 "false", 264 # "n", # this breaks parsing certain files 265 "none", 266 "invalid" 267 ] 268
269 - def __init__(self,val=None,textual=None):
270 if val==None and textual==None: 271 raise TypeError("'BoolProxy' initialized without values") 272 elif val==None: 273 if textual in BoolProxy.TrueStrings: 274 self.val=True 275 elif textual in BoolProxy.FalseStrings: 276 self.val=False 277 else: 278 raise TypeError(str(textual)+" not in "+str(BoolProxy.TrueStrings) 279 +" or "+str(BoolProxy.TrueStrings)) 280 else: 281 if val not in [True,False]: 282 raise TypeError(str(val)+" is not a boolean") 283 self.val=val 284 self.textual=textual 285 if self.textual: 286 if self.val: 287 if self.textual not in BoolProxy.TrueStrings: 288 raise TypeError(self.textual+" not in " 289 +str(BoolProxy.TrueStrings)) 290 else: 291 if self.textual not in BoolProxy.FalseStrings: 292 raise TypeError(self.textual+" not in " 293 +str(BoolProxy.FalseStrings))
294
295 - def __nonzero__(self):
296 return self.val
297 298 # for Python 3
299 - def __bool__(self):
300 return self.val
301
302 - def __str__(self):
303 if self.textual==None: 304 if self.val: 305 return "yes" 306 else: 307 return "no" 308 else: 309 return self.textual
310
311 - def __eq__(self,o):
312 if type(o) in [bool,BoolProxy]: 313 return self.val==o 314 elif isinstance(o,string_types): 315 if self.textual==o: 316 return True 317 else: 318 try: 319 return self.val==BoolProxy(textual=o) 320 except TypeError: 321 return False 322 else: 323 raise TypeError("Can't compare BoolProxy with "+str(type(o)))
324
325 -class DictRedirection(object):
326 """This class is in charge of handling redirections to other directories"""
327 - def __init__(self,fullCopy,reference,name):
328 self._fullCopy=fullCopy 329 self._reference=reference 330 self._name=name
331
332 - def useAsRedirect(self):
333 self._fullCopy=None
334
335 - def getContent(self):
336 result=self._fullCopy 337 self._fullCopy=None 338 return result
339
340 - def __call__(self):
341 return self._reference
342
343 - def __str__(self):
344 return "$"+self._name
345
346 - def __float__(self):
347 return float(self._reference)
348
349 -class DictProxy(dict):
350 """A class that acts like a dictionary, but preserves the order 351 of the entries. Used to beautify the output""" 352
353 - def __init__(self):
354 dict.__init__(self) 355 self._order=[] 356 self._decoration={} 357 self._regex=[] 358 self._redirects=[]
359
360 - def __setitem__(self,key,value):
361 isRegex=False 362 if type(key)==str: 363 if key[0]=='"' and key[-1]=='"': 364 isRegex=True 365 if isRegex: 366 exp=re.compile(key[1:-1]) 367 self._regex=[(key,exp,value)]+self._regex 368 else: 369 dict.__setitem__(self,key,value) 370 if key not in self._order or isRegex: 371 self._order.append(key)
372
373 - def __getitem__(self,key):
374 try: 375 return dict.__getitem__(self,key) 376 except KeyError: 377 for k,e,v in self._regex: 378 if e.match(key): 379 return v 380 for r in self._redirects: 381 try: 382 return r()[key] 383 except KeyError: 384 pass 385 386 raise KeyError(key)
387
388 - def __delitem__(self,key):
389 dict.__delitem__(self,key) 390 self._order.remove(key) 391 if key in self._decoration: 392 del self._decoration[key]
393
394 - def __deepcopy__(self,memo):
395 new=DictProxy() 396 for k in self._order: 397 if type(k)==DictRedirection: 398 new.addRedirection(k) 399 else: 400 try: 401 new[k]=deepcopy(self[k],memo) 402 except KeyError: 403 new[k]=deepcopy(self.getRegexpValue(k),memo) 404 405 return new
406
407 - def __contains__(self,key):
408 if dict.__contains__(self,key): 409 return True 410 else: 411 for k,e,v in self._regex: 412 if e.match(key): 413 return True 414 for r in self._redirects: 415 if key in r(): 416 return True 417 418 return False
419
420 - def __enforceString(self,v,toString):
421 if not isinstance(v,string_types) and toString: 422 r=str(v) 423 if isinstance(v,(list,dict)): 424 r='"'+r+'"' 425 return r 426 else: 427 return v
428
429 - def update(self,other=None,toString=False,**kwargs):
430 """Emulate the regular update of dict""" 431 if other: 432 if hasattr(other,"keys"): 433 for k in other.keys(): 434 self[k]=self.__enforceString(other[k],toString) 435 else: 436 for k,v in other: 437 self[k]=self.__enforceString(v,toString) 438 for k in kwargs: 439 self[k]=self.__enforceString(kwargs[k],toString)
440
441 - def keys(self):
442 return [x for x in self._order if type(x)!=DictRedirection]
443
444 - def __str__(self):
445 first=True 446 result="{" 447 for k in self.keys(): 448 v=self[k] 449 if first: 450 first=False 451 else: 452 result+=", " 453 result+="%s: %s" % (repr(k),repr(v)) 454 result+="}" 455 return result
456
457 - def addDecoration(self,key,text):
458 if key in self: 459 if key not in self._decoration: 460 self._decoration[key]="" 461 self._decoration[key]+=text
462
463 - def getDecoration(self,key):
464 if key in self._decoration: 465 return " \t"+self._decoration[key] 466 else: 467 return ""
468
469 - def getRegexpValue(self,key):
470 for k,e,v in self._regex: 471 if k==key: 472 return v 473 raise KeyError(key)
474
475 - def addRedirection(self,redir):
476 self._order.append(redir) 477 redir.useAsRedirect() 478 self._redirects.append(redir)
479
480 -class TupleProxy(list):
481 """Enables Tuples to be manipulated""" 482
483 - def __init__(self,tup=()):
484 list.__init__(self,tup)
485
486 -class Unparsed(object):
487 """A class that encapsulates an unparsed string""" 488
489 - def __init__(self,data):
490 self.data=data
491
492 - def __str__(self):
493 return self.data
494
495 - def __hash__(self):
496 return hash(self.data)
497
498 - def __lt__(self,other):
499 return self.data<other.data
500
501 -class BinaryBlob(Unparsed):
502 """Represents a part of the file with binary data in it"""
503 - def __init__(self,data):
504 Unparsed.__init__(self,data)
505
506 -class Codestream(str):
507 """A class that encapsulates an codestream string""" 508
509 - def __str__(self):
510 return "#{" + str.__str__(self) + "#}"
511
512 -class UnparsedList(object):
513 """A class that encapsulates a list that was not parsed for 514 performance reasons""" 515
516 - def __init__(self,lngth,data):
517 self.data=data 518 self.length=lngth
519
520 - def __len__(self):
521 return self.length
522
523 - def __cmp__(self,other):
524 return cmp(self.data,other.data)
525
526 - def __eq__(self,other):
527 return self.data==other.data
528
529 - def __lt__(self,other):
530 return self.data<other.data
531
532 -class BinaryList(UnparsedList):
533 """A class that represents a list that is saved as binary data""" 534
535 - def __init__(self,lngth,data):
536 UnparsedList.__init__(self,lngth,data)
537
538 -def makePrimitiveString(val):
539 """Make strings of types that might get written to a directory""" 540 if isinstance(val,(Dimension,FixedLength,BoolProxy)): 541 return str(val) 542 else: 543 return val
544 545 # Moved to the end to avoid circular dependencies 546 import PyFoam.Basics.FoamFileGenerator 547 548 # Should work with Python3 and Python2 549