You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
231 lines
8.2 KiB
Python
231 lines
8.2 KiB
Python
# -*- coding: utf-8 -*-
|
|
#
|
|
# Copyright © 2010 Eugeniy Meshcheryakov <eugen@debian.org>
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Lesser General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
from __future__ import absolute_import
|
|
from . import record, tags
|
|
|
|
class AbstractRecord(object):
|
|
def __init__(self, variable):
|
|
self.variable = variable
|
|
|
|
def read(self, instance, gen):
|
|
raise NotImplementedError
|
|
|
|
def save(self, instance, stream):
|
|
raise NotImplementedError
|
|
|
|
def __repr__(self):
|
|
return '<property: %s>'%self.variable
|
|
|
|
class SecondVar(object):
|
|
"""Class that simplifies second property support."""
|
|
def __init__(self, variable2):
|
|
self.variable2 = variable2
|
|
|
|
class SimpleRecord(AbstractRecord):
|
|
def __init__(self, variable, gds_record):
|
|
AbstractRecord.__init__(self, variable)
|
|
self.gds_record = gds_record
|
|
|
|
def read(self, instance, gen):
|
|
rec = gen.current
|
|
rec.check_tag(self.gds_record)
|
|
rec.check_size(1)
|
|
setattr(instance, self.variable, rec.data[0])
|
|
gen.read_next()
|
|
|
|
def save(self, instance, stream):
|
|
record.Record(self.gds_record, (getattr(instance, self.variable),)).save(stream)
|
|
|
|
class SimpleOptionalRecord(SimpleRecord):
|
|
def optional_read(self, instance, unused_gen, rec):
|
|
"""
|
|
Called when optional tag is found. `rec` contains that tag.
|
|
`gen` is advanced to next record befor calling this function.
|
|
"""
|
|
rec.check_size(1)
|
|
setattr(instance, self.variable, rec.data[0])
|
|
|
|
def read(self, instance, gen):
|
|
rec = gen.current
|
|
if rec.tag == self.gds_record:
|
|
gen.read_next()
|
|
self.optional_read(instance, gen, rec)
|
|
|
|
def save(self, instance, stream):
|
|
data = getattr(instance, self.variable, None)
|
|
if data is not None:
|
|
record.Record(self.gds_record, (data,)).save(stream)
|
|
|
|
class OptionalWholeRecord(SimpleOptionalRecord):
|
|
"""Class for records that need to store all data (not data[0])."""
|
|
def optional_read(self, instance, unused_gen, rec):
|
|
setattr(instance, self.variable, rec.data)
|
|
|
|
def save(self, instance, stream):
|
|
data = getattr(instance, self.variable, None)
|
|
if data is not None:
|
|
record.Record(self.gds_record, data).save(stream)
|
|
|
|
class PropertiesRecord(AbstractRecord):
|
|
def read(self, instance, gen):
|
|
rec = gen.current
|
|
props = []
|
|
while rec.tag == tags.PROPATTR:
|
|
rec.check_size(1)
|
|
propattr = rec.data[0]
|
|
rec = gen.read_next()
|
|
rec.check_tag(tags.PROPVALUE)
|
|
props.append((propattr, rec.data))
|
|
rec = gen.read_next()
|
|
setattr(instance, self.variable, props)
|
|
|
|
def save(self, instance, stream):
|
|
props = getattr(instance, self.variable)
|
|
if props:
|
|
for (propattr, propvalue) in props:
|
|
record.Record(tags.PROPATTR, (propattr,)).save(stream)
|
|
record.Record(tags.PROPVALUE, propvalue).save(stream)
|
|
|
|
class XYRecord(SimpleRecord):
|
|
def read(self, instance, gen):
|
|
rec = gen.current
|
|
rec.check_tag(self.gds_record)
|
|
setattr(instance, self.variable, rec.points)
|
|
gen.read_next()
|
|
|
|
def save(self, instance, stream):
|
|
pts = getattr(instance, self.variable)
|
|
record.Record(self.gds_record, points=pts).save(stream)
|
|
|
|
class StringRecord(SimpleRecord):
|
|
def read(self, instance, gen):
|
|
rec = gen.current
|
|
rec.check_tag(self.gds_record)
|
|
setattr(instance, self.variable, rec.data)
|
|
gen.read_next()
|
|
|
|
def save(self, instance, stream):
|
|
record.Record(self.gds_record, getattr(instance, self.variable)).save(stream)
|
|
|
|
class ColRowRecord(AbstractRecord, SecondVar):
|
|
def __init__(self, variable1, variable2):
|
|
AbstractRecord.__init__(self, variable1)
|
|
SecondVar.__init__(self, variable2)
|
|
|
|
def read(self, instance, gen):
|
|
rec = gen.current
|
|
rec.check_tag(tags.COLROW)
|
|
rec.check_size(2)
|
|
cols, rows = rec.data
|
|
setattr(instance, self.variable, cols)
|
|
setattr(instance, self.variable2, rows)
|
|
gen.read_next()
|
|
|
|
def save(self, instance, stream):
|
|
col = getattr(instance, self.variable)
|
|
row = getattr(instance, self.variable2)
|
|
record.Record(tags.COLROW, (col, row)).save(stream)
|
|
|
|
class TimestampsRecord(SimpleRecord, SecondVar):
|
|
def __init__(self, variable1, variable2, gds_record):
|
|
SimpleRecord.__init__(self, variable1, gds_record)
|
|
SecondVar.__init__(self, variable2)
|
|
|
|
def read(self, instance, gen):
|
|
rec = gen.current
|
|
rec.check_tag(self.gds_record)
|
|
mod_time, acc_time = rec.times
|
|
setattr(instance, self.variable, mod_time)
|
|
setattr(instance, self.variable2, acc_time)
|
|
gen.read_next()
|
|
|
|
def save(self, instance, stream):
|
|
mod_time = getattr(instance, self.variable)
|
|
acc_time = getattr(instance, self.variable2)
|
|
record.Record(self.gds_record, times=(mod_time, acc_time)).save(stream)
|
|
|
|
class STransRecord(OptionalWholeRecord):
|
|
mag = SimpleOptionalRecord('mag', tags.MAG)
|
|
angle = SimpleOptionalRecord('angle', tags.ANGLE)
|
|
|
|
def optional_read(self, instance, gen, rec):
|
|
setattr(instance, self.variable, rec.data)
|
|
self.mag.read(instance, gen)
|
|
self.angle.read(instance, gen)
|
|
|
|
def save(self, instance, stream):
|
|
data = getattr(instance, self.variable, None)
|
|
if data is not None:
|
|
OptionalWholeRecord.save(self, instance, stream)
|
|
self.mag.save(instance, stream)
|
|
self.angle.save(instance, stream)
|
|
|
|
class ACLRecord(SimpleOptionalRecord):
|
|
def optional_read(self, instance, unused_gen, rec):
|
|
setattr(instance, self.variable, rec.acls)
|
|
|
|
def save(self, instance, stream):
|
|
data = getattr(instance, self.variable, None)
|
|
if data:
|
|
record.Record(self.gds_record, acls=data).save(stream)
|
|
|
|
class FormatRecord(SimpleOptionalRecord, SecondVar):
|
|
def __init__(self, variable1, variable2, gds_record):
|
|
SimpleOptionalRecord.__init__(self, variable1, gds_record)
|
|
SecondVar.__init__(self, variable2)
|
|
|
|
def optional_read(self, instance, gen, rec):
|
|
SimpleOptionalRecord.optional_read(self, instance, gen, rec)
|
|
cur_rec = gen.curent
|
|
if cur_rec.tag == tags.MASK:
|
|
masks = []
|
|
while cur_rec.tag == tags.MASK:
|
|
masks.append(cur_rec.data)
|
|
cur_rec = gen.read_next()
|
|
cur_rec.check_tag(tags.ENDMASKS)
|
|
setattr(instance, self.variable2, masks)
|
|
gen.read_next()
|
|
|
|
def save(self, instance, stream):
|
|
fmt = getattr(instance, self.variable, None)
|
|
if fmt is not None:
|
|
SimpleOptionalRecord.save(self, instance, stream)
|
|
masks = getattr(instance, self.variable2, None)
|
|
if masks:
|
|
for mask in masks:
|
|
record.Record(tags.MASK, mask).save(stream)
|
|
record.Record(tags.ENDMASKS).save(stream)
|
|
|
|
class UnitsRecord(SimpleRecord, SecondVar):
|
|
def __init__(self, variable1, variable2, gds_record):
|
|
SimpleRecord.__init__(self, variable1, gds_record)
|
|
SecondVar.__init__(self, variable2)
|
|
|
|
def read(self, instance, gen):
|
|
rec = gen.current
|
|
rec.check_tag(self.gds_record)
|
|
rec.check_size(2)
|
|
unit1, unit2 = rec.data
|
|
setattr(instance, self.variable, unit1)
|
|
setattr(instance, self.variable2, unit2)
|
|
gen.read_next()
|
|
|
|
def save(self, instance, stream):
|
|
unit1 = getattr(instance, self.variable)
|
|
unit2 = getattr(instance, self.variable2)
|
|
record.Record(self.gds_record, (unit1, unit2)).save(stream)
|