blender-gdsimporter/gds/reader.py

129 lines
2.9 KiB
Python

from datetime import datetime
from .record import *
import abc
class ProgressGetter(object, metaclass=abc.ABCMeta):
@abc.abstractproperty
def current(self):
pass
@abc.abstractproperty
def total(self):
pass
@abc.abstractmethod
def progress(self):
raise NotImplementedError("getting the progess is not implemented")
class Reader(ProgressGetter):
# statistics
total = 0
@property
def current(self):
return float(self.stream.tell())
# returns the read progress in percent
def progress(self):
if self.total <= 0:
return 1.0
return self.current / self.total
def __init__(self, file):
self.stream = file
# find file size
self.stream.seek(0, 2)
self.total = self.stream.tell()
self.stream.seek(0, 0)
def skip(self, n):
self.stream.read(n)
def read_int(self):
temp = self.stream.read(4)
if len(temp) != 4:
return None
return int(temp[3]) | int(temp[2]) << 8 | int(temp[1]) << 16 | int(temp[0]) << 24
def read_short(self):
temp = self.stream.read(2)
if len(temp) != 2:
return None
return int(temp[1]) | int(temp[0]) << 8
def read_double(self):
temp = self.stream.read(8)
if len(temp) != 8:
return None
result = 0
for i in temp:
if int(i) != 0:
# read double
result = 1
for j in range(1,8):
result += float(temp[8-j])/(2**(j*8))
exp = int(temp[0]) & 0x7F
exp -= 64
result *= 16**exp
if int(temp[0]) & 0x80:
result += -1
return result
# double is Zero
return 0
def read_ascii(self, len):
return self.stream.read(len).decode("ASCII").strip()
def read_record(self):
result = Record()
try:
result.len = self.read_short()
result.ident = Records(self.read_short())
except ValueError:
return None
result.len -= 4 # remove record header len
return result
def read_date(self):
# date
year = self.read_short()
month = self.read_short()
day = self.read_short()
# time
hour = self.read_short()
minute = self.read_short()
second = self.read_short()
return datetime(year=year, month=month, day=day, hour=hour, minute=minute, second=second)
def read_coord(self):
X = self.read_int()
Y = self.read_int()
return (X,Y)
def read_coords(self, len):
len /= 8
result = []
while len > 0:
point = self.read_coord()
if not point:
return None
result.append(point)
len -= 1
return result