mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 02:15:10 +00:00 
			
		
		
		
	 8a99a8aa89
			
		
	
	
		8a99a8aa89
		
	
	
	
	
		
			
			resource files with various inheritence rules, parsers, etc. pythonprefs uses this to create a single uniform interface to all relevant python preferences.
		
			
				
	
	
		
			219 lines
		
	
	
	
		
			5.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			219 lines
		
	
	
	
		
			5.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #
 | |
| # General parser/loaders for preferences files and such
 | |
| #
 | |
| import Res
 | |
| import macfs
 | |
| import struct
 | |
| import MACFS
 | |
| 
 | |
| READ=1
 | |
| READWRITE=3
 | |
| Error = "Preferences.Error"
 | |
| 
 | |
| debug = 0
 | |
| 
 | |
| class NullLoader:
 | |
| 	def __init__(self, data=None):
 | |
| 		self.data = data
 | |
| 		
 | |
| 	def load(self):
 | |
| 		if self.data is None:
 | |
| 			raise Error, "No default given"
 | |
| 		return self.data
 | |
| 		
 | |
| 	def save(self, data):
 | |
| 		raise Error, "Cannot save to default value"
 | |
| 		
 | |
| 	def delete(self, deep=0):
 | |
| 		if debug:
 | |
| 			print 'Attempt to delete default value'
 | |
| 		raise Error, "Cannot delete default value"
 | |
| 		
 | |
| _defaultdefault = NullLoader()
 | |
| 		
 | |
| class ResLoader:
 | |
| 	def __init__(self, filename, resid, resnum=None, resname=None, default=_defaultdefault):
 | |
| 		self.filename = filename
 | |
| 		self.fss = macfs.FSSpec(self.filename)
 | |
| 		self.resid = resid
 | |
| 		self.resnum = resnum
 | |
| 		self.resname = resname
 | |
| 		self.default = default
 | |
| 		self.data = None
 | |
| 		
 | |
| 	def load(self):
 | |
| 		oldrh = Res.CurResFile()
 | |
| 		try:
 | |
| 			rh = Res.FSpOpenResFile(self.fss, READ)
 | |
| 		except Res.Error:
 | |
| 			self.data = self.default.load()
 | |
| 			return self.data
 | |
| 		try:
 | |
| 			if self.resname:
 | |
| 				handle = Res.Get1NamedResource(self.resid, self.resname)
 | |
| 			else:
 | |
| 				handle = Res.Get1Resource(self.resid, self.resnum)
 | |
| 		except Res.Error:
 | |
| 			self.data = self.default.load()
 | |
| 		else:
 | |
| 			if debug:
 | |
| 				print 'Loaded', (self.resid, self.resnum, self.resname), 'from', self.fss.as_pathname()
 | |
| 			self.data = handle.data
 | |
| 		Res.CloseResFile(rh)
 | |
| 		Res.UseResFile(oldrh)
 | |
| 		return self.data
 | |
| 		
 | |
| 	def save(self, data):
 | |
| 		if self.data is None or self.data != data:
 | |
| 			oldrh = Res.CurResFile()
 | |
| 			rh = Res.FSpOpenResFile(self.fss, READWRITE)
 | |
| 			try:
 | |
| 				handle = Res.Get1Resource(self.resid, self.resnum)
 | |
| 			except Res.Error:
 | |
| 				handle = Res.Resource(data)
 | |
| 				handle.AddResource(self.resid, self.resnum, '')
 | |
| 				if debug:
 | |
| 					print 'Added', (self.resid, self.resnum), 'to', self.fss.as_pathname()
 | |
| 			else:
 | |
| 				handle.data = data
 | |
| 				handle.ChangedResource()
 | |
| 				if debug:
 | |
| 					print 'Changed', (self.resid, self.resnum), 'in', self.fss.as_pathname()
 | |
| 			Res.CloseResFile(rh)
 | |
| 			Res.UseResFile(oldrh)
 | |
| 			
 | |
| 	def delete(self, deep=0):
 | |
| 		if debug:
 | |
| 			print 'Deleting in', self.fss.as_pathname(), `self.data`, deep
 | |
| 		oldrh = Res.CurResFile()
 | |
| 		rh = Res.FSpOpenResFile(self.fss, READWRITE)
 | |
| 		try:
 | |
| 			handle = Res.Get1Resource(self.resid, self.resnum)
 | |
| 		except Res.Error:
 | |
| 			if 	deep:
 | |
| 				if debug: print 'deep in', self.default
 | |
| 				self.default.delete(1)
 | |
| 		else:
 | |
| 			handle.RemoveResource()
 | |
| 			if debug:
 | |
| 				print 'Deleted', (self.resid, self.resnum), 'from', self.fss.as_pathname()
 | |
| 		self.data = None
 | |
| 		Res.CloseResFile(rh)
 | |
| 		Res.UseResFile(oldrh)
 | |
| 
 | |
| class AnyResLoader:
 | |
| 	def __init__(self, resid, resnum=None, resname=None, default=_defaultdefault):
 | |
| 		self.resid = resid
 | |
| 		self.resnum = resnum
 | |
| 		self.resname = resname
 | |
| 		self.default = default
 | |
| 		self.data = None
 | |
| 		
 | |
| 	def load(self):
 | |
| 		try:
 | |
| 			if self.resname:
 | |
| 				handle = Res.GetNamedResource(self.resid, self.resname)
 | |
| 			else:
 | |
| 				handle = Res.GetResource(self.resid, self.resnum)
 | |
| 		except Res.Error:
 | |
| 			self.data = self.default.load()
 | |
| 		else:
 | |
| 			self.data = handle.data
 | |
| 		return self.data
 | |
| 		
 | |
| 	def save(self, data):
 | |
| 		raise Error, "Cannot save AnyResLoader preferences"
 | |
| 					
 | |
| 	def delete(self, deep=0):
 | |
| 		raise Error, "Cannot delete AnyResLoader preferences"
 | |
| 			
 | |
| class StructLoader:
 | |
| 	def __init__(self, format, loader):
 | |
| 		self.format = format
 | |
| 		self.loader = loader
 | |
| 		
 | |
| 	def load(self):
 | |
| 		data = self.loader.load()
 | |
| 		return struct.unpack(self.format, data)
 | |
| 		
 | |
| 	def save(self, data):
 | |
| 		data = apply(struct.pack, (self.format,)+data)
 | |
| 		self.loader.save(data)
 | |
| 		
 | |
| 	def delete(self, deep=0):
 | |
| 		self.loader.delete(deep)
 | |
| 		
 | |
| class PstringLoader:
 | |
| 	def __init__(self, loader):
 | |
| 		self.loader = loader
 | |
| 		
 | |
| 	def load(self):
 | |
| 		data = self.loader.load()
 | |
| 		len = ord(data[0])
 | |
| 		return data[1:1+len]
 | |
| 		
 | |
| 	def save(self, data):
 | |
| 		if len(data) > 255:
 | |
| 			raise Error, "String too big for pascal-style"
 | |
| 		self.loader.save(chr(len(data))+data)
 | |
| 		
 | |
| 	def delete(self, deep=0):
 | |
| 		self.loader.delete(deep)
 | |
| 		
 | |
| class VersionLoader(StructLoader):
 | |
| 	def load(self):
 | |
| 		while 1:
 | |
| 			data = self.loader.load()
 | |
| 			if debug:
 | |
| 				print 'Versionloader:', `data`
 | |
| 			try:
 | |
| 				rv = struct.unpack(self.format, data)
 | |
| 				rv = self.versioncheck(rv)
 | |
| 				return rv
 | |
| 			except (struct.error, Error):
 | |
| 				self.delete(1)
 | |
| 				
 | |
| 	def versioncheck(self, data):
 | |
| 		return data
 | |
| 		
 | |
| class StrListLoader:
 | |
| 	def __init__(self, loader):
 | |
| 		self.loader = loader
 | |
| 		
 | |
| 	def load(self):
 | |
| 		data = self.loader.load()
 | |
| 		num, = struct.unpack('h', data[:2])
 | |
| 		data = data[2:]
 | |
| 		rv = []
 | |
| 		for i in range(num):
 | |
| 			strlen = ord(data[0])
 | |
| 			if strlen < 0: strlen = strlen + 256
 | |
| 			str = data[1:strlen+1]
 | |
| 			data = data[strlen+1:]
 | |
| 			rv.append(str)
 | |
| 		return rv
 | |
| 
 | |
| 	def save(self, list):
 | |
| 		rv = struct.pack('h', len(list))
 | |
| 		for str in list:
 | |
| 			rv = rv + chr(len(str)) + str
 | |
| 		self.loader.save(rv)
 | |
| 		
 | |
| 	def delete(self, deep=0):
 | |
| 		self.loader.delete(deep)
 | |
| 
 | |
| def preferencefile(filename, creator=None, type=None):
 | |
| 	create = creator != None and type != None
 | |
| 	vrefnum, dirid = macfs.FindFolder(MACFS.kOnSystemDisk, 'pref', create)
 | |
| 	fss = macfs.FSSpec((vrefnum, dirid, filename))
 | |
| 	oldrf = Res.CurResFile()
 | |
| 	if create:
 | |
| 		try:
 | |
| 			rh = Res.FSpOpenResFile(fss, READ)
 | |
| 		except Res.Error:
 | |
| 			Res.FSpCreateResFile(fss, creator, type, MACFS.smAllScripts)
 | |
| 		else:
 | |
| 			Res.CloseResFile(rh)
 | |
| 			Res.UseResFile(oldrf)
 | |
| 	return fss
 | |
| 	
 |