summaryrefslogtreecommitdiff
path: root/src/wii/filesystem.py
blob: 0d40fe9a7a4973c9b5fd625bd34e609933a0cd80 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import weakref

class WiiFSObject(object):
	def __init__(self):
		self._parent_ref = None
		self._name = ''
		self._low_name = ''
	
	@property
	def parent(self):
		ref = self._parent_ref
		return (ref() if ref else None)

	@parent.setter
	def parent(self, value):
		self._parent_ref = weakref.ref(value)
	
	@parent.deleter
	def parent(self):
		self._parent_ref = None
	

	@property
	def name(self):
		return self._name

	@name.setter
	def name(self, value):
		self._name = value
		self._low_name = value.lower()

	
	def unlinkFromParent(self):
		if self.parent == None:
			return

		if self.parent.isDirectory():
			self.parent.children.remove(self)

		del self.parent

	def isFile(self): return False
	def isDirectory(self): return False


class WiiFile(WiiFSObject):
	def __init__(self):
		WiiFSObject.__init__(self)
		self.data = None
	
	def isFile(self): return True


class WiiDirectory(WiiFSObject):
	def __init__(self):
		WiiFSObject.__init__(self)
		self.children = []
	
	def isDirectory(self): return True

	def findByName(self, name, recursive):
		return self._findByName(name.lower(), recursive)

	def _findByName(self, lowercase_name, recursive):
		for obj in self.children:
			if obj._low_name == lowercase_name:
				return obj

			if recursive and obj.isDirectory():
				tryThis = obj._findByName(lowercase_name, recursive)
				if tryThis:
					return tryThis

		return None

	def resolvePath(self, path, createIfNotExists=False):
		components = path.split('/')
		currentDir = self

		# special case: handle absolute paths
		if components[0] == '':
			while currentDir.parent:
				currentDir = currentDir.parent

			del components[0]

		while len(components) > 0:
			bit = components.pop(0)
			nextObj = None

			if bit == '.':
				nextObj = currentDir
			elif bit == '..':
				nextObj = currentDir.parent
			else:
				nextObj = currentDir.findByName(bit, False)

			if nextObj is None:
				if not createIfNotExists:
					print("failed to resolve path %s: missing component %s" % (path, bit))
					return None
				elif bit != '..':
					# we must create it!
					if len(components) == 0:
						nextObj = WiiFile()
					else:
						nextObj = WiiDirectory()

					nextObj.name = bit
					currentDir.addChild(nextObj)

			if len(components) == 0:
				return nextObj

			if not nextObj.isDirectory():
				print("failed to resolve path %s: component %s is not a directory" % (path, bit))
				return None

			# has to be a directory so just continue
			currentDir = nextObj

		print("wtf? %s" % path)
		return None

	def addChild(self, obj):
		if self.findByName(obj.name, False):
			return False

		obj.unlinkFromParent()
		self.children.append(obj)
		obj.parent = self

		return True