-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
1,112 additions
and
812 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
# dataFile.py | ||
# Copyright (c) 2014 Michael Zahniser | ||
# Copyright (C) 2017 Frederick W. Goy IV | ||
# | ||
# This program is a derivative of the source code from the Endless Sky | ||
# project, which is licensed under the GNU GPLv3. | ||
# | ||
# Endless Sky source: https://github.com/endless-sky/endless-sky | ||
# | ||
# | ||
# This program is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU General Public License as published by | ||
# the Free Software Foundation, either version 3 of the License, or | ||
# (at your option) any later version. | ||
# | ||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU General Public License | ||
# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
|
||
|
||
from dataNode import DataNode | ||
|
||
import os | ||
import io | ||
|
||
|
||
|
||
def Back(sequence): | ||
return sequence[(len(sequence) - 1)] | ||
|
||
|
||
|
||
class DataFile(object): | ||
def __init__(self, path=""): | ||
if not path or not path.endswith(".txt"): | ||
return [] | ||
|
||
self.root = DataNode() | ||
self.Load(path) | ||
|
||
|
||
def Begin(self): | ||
return self.root.Begin() | ||
|
||
|
||
def End(self): | ||
return self.root.End() | ||
|
||
|
||
def Load(self, path): | ||
result = [] | ||
try: | ||
path = os.path.normpath(path) | ||
|
||
with io.open(path, "rb") as newFile: | ||
for line in newFile: | ||
result.append(line) | ||
|
||
except (IOError, OSError) as error: | ||
message = error.strerror + " " + error.filename | ||
print(message) | ||
|
||
if not result: | ||
return result | ||
|
||
if Back(result) != "\n": | ||
if Back(Back(result)) != "\n": | ||
result[len(result) - 1] += "\n" | ||
result.append("\n") | ||
else: | ||
result.append("\n") | ||
|
||
self.Parse(result) | ||
|
||
self.root.tokens.append("file") | ||
self.root.tokens.append(path) | ||
|
||
|
||
def Parse(self, data): | ||
stack = [self.root] | ||
whiteStack = [-1] | ||
for line in data: | ||
it = 0 | ||
white = 0 | ||
while line[it].isspace() and line[it] != "\n": | ||
white += 1 | ||
it += 1 | ||
|
||
if line[it] == "#" or line[it] == "\n": | ||
continue | ||
|
||
while Back(whiteStack) >= white: | ||
whiteStack.pop() | ||
stack.pop() | ||
|
||
node = DataNode() | ||
Back(stack).Append(node) | ||
|
||
stack.append(node) | ||
whiteStack.append(white) | ||
|
||
while line[it] != "\n": | ||
endQuote = line[it] | ||
isQuoted = False | ||
if endQuote == '"' or endQuote == '`': | ||
isQuoted = True | ||
it += 1 | ||
|
||
token = "" | ||
if isQuoted: | ||
while line[it] != "\n" and line[it] != endQuote: | ||
token += line[it] | ||
it += 1 | ||
it += 1 | ||
|
||
else: | ||
while not line[it].isspace(): | ||
token += line[it] | ||
it += 1 | ||
|
||
if token: | ||
node.tokens.append(token) | ||
|
||
if line[it] != "\n": | ||
while line[it].isspace() and line[it] != "\n": | ||
it += 1 | ||
|
||
if line[it] == "#": | ||
break | ||
|
||
|
||
def Append(self, node): | ||
self.root.Append(node) | ||
|
||
|
||
def Remove(self, node): | ||
self.root.Remove(node) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
# dataNode.py | ||
# Copyright (c) 2014 Michael Zahniser | ||
# Copyright (C) 2017 Frederick W. Goy IV | ||
# | ||
# This program is a derivative of the source code from the Endless Sky | ||
# project, which is licensed under the GNU GPLv3. | ||
# | ||
# Endless Sky source: https://github.com/endless-sky/endless-sky | ||
# | ||
# | ||
# This program is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU General Public License as published by | ||
# the Free Software Foundation, either version 3 of the License, or | ||
# (at your option) any later version. | ||
# | ||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU General Public License | ||
# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
|
||
|
||
class DataNode(object): | ||
def __init__(self, parent=None, children=None, tokens=None): | ||
self.parent = parent | ||
self.children = children or [] | ||
self.tokens = tokens or [] | ||
|
||
|
||
def Size(self): | ||
return len(self.tokens) | ||
|
||
|
||
def Token(self, index): | ||
return self.tokens[index] | ||
|
||
|
||
def Value(self, index): | ||
if not self.IsNumber(index): | ||
message = "Cannot convert token at " + str(index) + " to a number." | ||
print(message) | ||
return 0. | ||
|
||
token = self.tokens[index] | ||
|
||
hasDecimalPoint = False | ||
hasExponent = False | ||
for it in token: | ||
if it == ".": | ||
hasDecimalPoint = True | ||
elif it == "e" or it == "E": | ||
hasExponent = True | ||
|
||
if hasDecimalPoint or hasExponent: | ||
return float(token) | ||
else: | ||
return int(token) | ||
|
||
|
||
def IsNumber(self, index): | ||
if index >= len(self.tokens) or not self.tokens[index]: | ||
return False | ||
|
||
token = self.tokens[index] | ||
|
||
hasDecimalPoint = False | ||
hasExponent = False | ||
isLeading = True | ||
for it in token: | ||
if isLeading: | ||
isLeading = False | ||
if it == "-" or it == "+": | ||
continue | ||
|
||
if it == ".": | ||
if hasDecimalPoint or hasExponent: | ||
return False | ||
|
||
hasDecimalPoint = True | ||
|
||
elif it == "e" or it == "E": | ||
if hasExponent: | ||
return False | ||
|
||
hasExponent = True | ||
isLeading = True | ||
|
||
elif not it.isdigit(): | ||
return False | ||
|
||
return True | ||
|
||
|
||
def HasChildren(self): | ||
if self.children: | ||
return True | ||
|
||
return False | ||
|
||
|
||
def HasToken(self, token, deep=False): | ||
match = False | ||
if token in self.tokens: | ||
match = True | ||
|
||
if not match and deep: | ||
for node in self.Begin(): | ||
if match: | ||
break | ||
|
||
match = node.HasToken(token, deep=True) | ||
|
||
return match | ||
|
||
|
||
def Begin(self): | ||
for it in self.children[:]: | ||
yield it | ||
|
||
|
||
def BeginFlat(self): | ||
for it in self.Begin(): | ||
yield it | ||
|
||
for itb in it.BeginFlat(): | ||
yield itb | ||
|
||
|
||
def End(self): | ||
for it in reversed(self.children)[:]: | ||
yield it | ||
|
||
|
||
def Append(self, node): | ||
node.parent = self | ||
self.children.append(node) | ||
|
||
|
||
def Remove(self, node): | ||
node.parent = None | ||
self.children.remove(node) | ||
|
||
|
||
def Copy(self): | ||
newTokens = [] | ||
for token in self.tokens: | ||
newTokens.append(token) | ||
|
||
newNode = DataNode(tokens=newTokens) | ||
if self.HasChildren(): | ||
for node in self.Begin(): | ||
newNode.Append(node.Copy()) | ||
|
||
return newNode | ||
|
||
|
||
def Delete(self): | ||
if self.parent: | ||
self.parent.Remove(self) | ||
else: | ||
self.parent = None | ||
|
||
self.tokens = None | ||
|
||
for node in self.Begin(): | ||
node.Delete() | ||
|
||
self.children = None | ||
|
Oops, something went wrong.