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
00028 schema_tag = ""
00029 mo = re.search(r"^(\+|-)(.*)",name)
00030 if mo: (schema_tag,name) = mo.groups()
00031
00032
00033
00034 if self.__mode == "r":
00035 self.__ReadItem()
00036
00037
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
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
00055
00056 else:
00057
00058
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
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
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