GBSIOHelper.py

Go to the documentation of this file.
00001 import re
00002 import pickle
00003 
00004 from GBSLogger import Log, logger 
00005 
00006 class GBSIOHelper :
00007     """I/O Helper class"""
00008 
00009     def __init__(self,file_name,mode):
00010         self.__file  = None
00011         self.__mode  = mode
00012         self.__ClearCache()
00013         if mode != "r" and mode != "w":
00014             print "GBSIOHelper: Bad I/O mode " + str(mode)  + " on " + str(file_name)
00015             raise IOError
00016         self.__file = open(file_name,mode)
00017 
00018     def __call__(self,name,type,value=""): return self.DoIO(name,type,value)
00019 
00020 
00021     def DoIO(self,name,type,value=""):
00022         if self.__file == None: raise IOError
00023         if type != "s" and type != "i" and type != "f" and type != "p":
00024             Log(self,logger.ERROR,"GBSIOHelper: Bad I/O type " + str(type) + " on " + str(self.__file))
00025             raise IOError
00026 
00027         #  Check for schema evolution tags '+' and '-'
00028         schema_tag = ""
00029         mo = re.search(r"^(\+|-)(.*)",name)
00030         if mo: (schema_tag,name) = mo.groups()
00031 
00032         ###   Reading   ###
00033         
00034         if self.__mode == "r":
00035             self.__ReadItem()
00036 
00037             # Deal with matching names but tolerate case differences.
00038             if name.lower() == self.__name.lower():
00039                 if type != self.__type:
00040                     Log(self,logger.ERROR,"GBSIOHelper: Type mismatch on name: '" + str(name)\
00041                     + "', found type '" + str(self.__type) + "' but expecting type '"\
00042                     + str(type) + "' in " + str(self.__file))
00043                     raise IOError
00044                 value = self.__value
00045                 self.__ClearCache()
00046                 return value
00047 
00048             # Mismatch is O.K. if schema evolution is active
00049             if schema_tag: return value
00050             Log(self,logger.ERROR,"GBSIOHelper: Found name: '" + str(self.__name) + "', but expecting '"\
00051                 + str(name) + "' on " + str(self.__file))
00052             raise IOError
00053 
00054         ###   Writing   ###
00055         
00056         else:
00057 
00058             # Schema evolution: don't write dropped names
00059             if schema_tag == "-": return value
00060             return self.__WriteItem(name,type,value)
00061 
00062     def Close(self):
00063 
00064         """If reading, check that all the data has been read."""
00065         if self.__mode == "r":
00066             line = self.__file.readline()
00067             if line:
00068                 Log(self,logger.ERROR,"GBSIOHelper: File " + str(self.__file)\
00069                     + " has extra data:-\n" + str(line) + " after I/O complete.'")
00070                 raise IOError
00071         self.__file.close()
00072 
00073         
00074     ######  Private Methods (not user callable)  ######
00075 
00076     def __ClearCache(self):
00077 
00078         """Clear internally cached value (only used for reading)."""
00079         
00080         self.__name  = None
00081         self.__type  = None
00082         self.__value = None
00083 
00084     def __ReadItem(self):
00085 
00086         """Read item if not already in cache."""
00087         if self.__name: return
00088 
00089         line = self.__file.readline()
00090         if not line:
00091             Log(self,logger.ERROR,"GBSIOHelper: EOF on " + str(self.__file))
00092             raise IOError
00093         mo = re.search(r"(.)\s*(.*?):\s+(.*)",line)
00094         if not mo:
00095             Log(self,logger.ERROR,"GBSIOHelper: Malformed data:" + str(line)\
00096                 + " on " + str(self.__file))
00097             raise IOError
00098         (self.__type,self.__name,self.__value) = mo.groups()
00099         if   self.__type == "s": pass
00100         elif self.__type == "i": self.__value = int(self.__value)
00101         elif self.__type == "f": self.__value = float(self.__value)
00102         elif self.__type == "p":
00103             self.__value = pickle.load(self.__file)
00104             self.__file.readline()
00105         else:
00106             Log(self,logger.ERROR,"GBSIOHelper: Bad type: '" + str(self.__type) + "' reading line:" + str(line)\
00107                 + " on " + str(self.__file))
00108             raise IOError
00109     
00110 
00111     def __WriteItem(self,name,type,value):
00112 
00113         """Write item to file."""
00114 
00115         self.__file.write(type + name.rjust(30) + ":   ")
00116         if   type != "p":
00117             # For strings, replace any '\n' by ' ' before storing
00118             if   type == "s":
00119                 p = re.compile('(\n)')
00120                 value = p.sub(' ',value)
00121             self.__file.write(str(value) + "\n")
00122         else:
00123             self.__file.write("\n")
00124             pickle.dump(value,self.__file)
00125             self.__file.write("\n")
00126         return value
00127 
00128             
00129 
00130 
00131 
00132 def TestIOHelper():
00133     ioh = GBSIOHelper("TestIOHelper.state","w")
00134     ioh("A String","s","This is a string")
00135     ioh.DoIO("An integer","i",42)
00136     ioh.DoIO("A floating point","f",3.14159)
00137     ioh.DoIO("A list","p",["abc",123,456.0])
00138     ioh.DoIO("A tuple","p",("xyz",111,222.0))
00139     ioh.DoIO("A second list","p",["abc",123,456.0])
00140     ioh.DoIO("A second tuple","p",("xyz",111,222.0))
00141     ioh.Close()
00142     del ioh
00143     ioh = GBSIOHelper("TestIOHelper.state","r")
00144 
00145     value = ioh("A String","s")
00146     print value
00147     value = ioh.DoIO("An integer","i")
00148     print value
00149     value = ioh.DoIO("A floating point","f")
00150     print value
00151     value =  ioh.DoIO("A list","p")
00152     print value
00153     value =  ioh.DoIO("A tuple","p")
00154     print value
00155     value =  ioh.DoIO("A second list","p")
00156     print value
00157     value =  ioh.DoIO("A second tuple","p")
00158     print value
00159     ioh.Close()
00160     del ioh
00161 
00162     
00163     
00164            
00165            
00166            
00167             
00168 
00169 

Generated on Fri Mar 5 09:25:41 2010 for gbs by  doxygen 1.4.7