1# -*- coding: utf-8 -*- 2# 3# Copyright © 2010 Eugeniy Meshcheryakov <eugen@debian.org> 4# 5# This program is free software: you can redistribute it and/or modify 6# it under the terms of the GNU Lesser General Public License as published by 7# the Free Software Foundation, either version 3 of the License, or 8# (at your option) any later version. 9# 10# This program is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13# GNU Lesser General Public License for more details. 14# 15# You should have received a copy of the GNU Lesser General Public License 16# along with this program. If not, see <http://www.gnu.org/licenses/>. 17""" 18:mod:`gdsii.structure` --- interface to a GDSII structure 19========================================================= 20 21This module contains class that represents a GDSII structure. 22 23.. moduleauthor:: Eugeniy Meshcheryakov <eugen@debian.org> 24""" 25from __future__ import absolute_import 26from . import elements, record, tags, _records 27from datetime import datetime 28 29_STRNAME = _records.StringRecord('name', tags.STRNAME) 30_BGNSTR = _records.TimestampsRecord('mod_time', 'acc_time', tags.BGNSTR) 31_STRCLASS = _records.SimpleOptionalRecord('strclass', tags.STRCLASS) 32 33class Structure(list): 34 """ 35 GDSII structure class. This class is derived for :class:`list` and can 36 contain one or more elements from :mod:`gdsii.elements`. 37 38 GDS syntax for the structure: 39 .. productionlist:: 40 structure: BGNSTR 41 : STRNAME 42 : [STRCLASS] 43 : {`element`}* 44 : ENDSTR 45 """ 46 _gds_objs = (_BGNSTR, _STRNAME, _STRCLASS) 47 48 def __init__(self, name, mod_time=None, acc_time=None): 49 """ 50 Initialize the structure. 51 `mod_time` and `acc_time` are set to current UTC time by default. 52 """ 53 list.__init__(self) 54 self.name = name 55 self.mod_time = mod_time if mod_time is not None else datetime.utcnow() 56 self.acc_time = acc_time if acc_time is not None else datetime.utcnow() 57 58 def _init_optional(self): 59 """Initialize optional attributes to None.""" 60 self.strclass = None 61 62 @classmethod 63 def _load(cls, gen): 64 self = cls.__new__(cls) 65 list.__init__(self) 66 self._init_optional() 67 68 for obj in self._gds_objs: 69 obj.read(self, gen) 70 71 # read elements till ENDSTR 72 while gen.current.tag != tags.ENDSTR: 73 self.append(elements._Base._load(gen)) 74 return self 75 76 def _save(self, stream): 77 for obj in self._gds_objs: 78 obj.save(self, stream) 79 for elem in self: 80 elem._save(stream) 81 record.Record(tags.ENDSTR).save(stream) 82 83 def __repr__(self): 84 return '<Structure: %s>' % self.name.decode() 85