remove old version of gds parser
This commit is contained in:
		
							parent
							
								
									ac8949f3bb
								
							
						
					
					
						commit
						1cf790d1d0
					
				
							
								
								
									
										1
									
								
								gds/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								gds/.gitignore
									
									
									
									
										vendored
									
									
								
							@ -1 +0,0 @@
 | 
				
			|||||||
__pycache__
 | 
					 | 
				
			||||||
@ -1,7 +0,0 @@
 | 
				
			|||||||
from .library import Library
 | 
					 | 
				
			||||||
from .structure import Structure
 | 
					 | 
				
			||||||
from .elements import *
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from .record import *
 | 
					 | 
				
			||||||
from .reader import Reader
 | 
					 | 
				
			||||||
from .parser import *
 | 
					 | 
				
			||||||
							
								
								
									
										116
									
								
								gds/elements.py
									
									
									
									
									
								
							
							
						
						
									
										116
									
								
								gds/elements.py
									
									
									
									
									
								
							@ -1,116 +0,0 @@
 | 
				
			|||||||
from enum import Enum
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Transformation(object):
 | 
					 | 
				
			||||||
    def __init__(self):
 | 
					 | 
				
			||||||
        self.mirror_x = 0
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
        self.absolute_rotation = 0
 | 
					 | 
				
			||||||
        self.absolute_magnification = 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.zoom = 1
 | 
					 | 
				
			||||||
        self.rotation = 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Element(object):
 | 
					 | 
				
			||||||
    def __init__(self):
 | 
					 | 
				
			||||||
        self.elflags = 0
 | 
					 | 
				
			||||||
        self.plex    = 0
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
class Drawable(object):
 | 
					 | 
				
			||||||
    def __init__(self):
 | 
					 | 
				
			||||||
        self.layer   = 0
 | 
					 | 
				
			||||||
        self.datatype = 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Boundary(Element, Drawable):
 | 
					 | 
				
			||||||
    def __init__(self):
 | 
					 | 
				
			||||||
        self.points = []
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
class Path(Element, Drawable):
 | 
					 | 
				
			||||||
    class Styles(Enum):
 | 
					 | 
				
			||||||
        SQUARE_ENDS  = 0
 | 
					 | 
				
			||||||
        ROUNDED_ENDS = 1
 | 
					 | 
				
			||||||
        OFFSET_ENDS  = 2
 | 
					 | 
				
			||||||
        CUSTOM_END   = 4
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    def __init__(self):
 | 
					 | 
				
			||||||
        self.extendEnd = [0,0] # extend past start and end    
 | 
					 | 
				
			||||||
        self.width     = 0
 | 
					 | 
				
			||||||
        self.pathStyle = Path.Styles.SQUARE_ENDS
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
        self.points = []
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Text(Element, Drawable):
 | 
					 | 
				
			||||||
    class VJust(Enum):
 | 
					 | 
				
			||||||
        Top    = 0
 | 
					 | 
				
			||||||
        Middle = 1
 | 
					 | 
				
			||||||
        Bottom = 2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    class HJust(Enum):
 | 
					 | 
				
			||||||
        Left   = 0
 | 
					 | 
				
			||||||
        Center = 1
 | 
					 | 
				
			||||||
        Right  = 2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self):
 | 
					 | 
				
			||||||
        # text info
 | 
					 | 
				
			||||||
        self.string = ""
 | 
					 | 
				
			||||||
        self.position = (0,0)
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        # presentation
 | 
					 | 
				
			||||||
        self.fontnumber               = 0
 | 
					 | 
				
			||||||
        self.verticalJustification    = Text.VJust.Top
 | 
					 | 
				
			||||||
        self.horizontalJustification  = Text.HJust.Left
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # optional path info
 | 
					 | 
				
			||||||
        self.pathStype = Path.Styles.SQUARE_ENDS
 | 
					 | 
				
			||||||
        self.pathWidth = 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.transformation = Transformation()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
class Box(Element, Drawable):
 | 
					 | 
				
			||||||
    def __init__(self):
 | 
					 | 
				
			||||||
        self.points = []
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class SRef(Element):
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    A Structure Reference defines a single instance of a different structure in 
 | 
					 | 
				
			||||||
    the structure we call parent here
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    def __init__(self):
 | 
					 | 
				
			||||||
        self.position = (0,0)
 | 
					 | 
				
			||||||
        self.structure = ""
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        self.transformation  = Transformation()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.parent = None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class ARef(SRef):
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    An Array Reference is similar to the SRef, but it defines the instances in a grid
 | 
					 | 
				
			||||||
    with size instances spaces evenly between the bound coordinates
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    with:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    v1 = bounds[0] - position
 | 
					 | 
				
			||||||
    v2 = bounds[1] - position
 | 
					 | 
				
			||||||
    i  = xth instance index
 | 
					 | 
				
			||||||
    j  = yth instance index
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    this will result in an array like this:
 | 
					 | 
				
			||||||
        j\i | 0               |  1                        | ... | size[0]
 | 
					 | 
				
			||||||
        ----+-----------------+---------------------------+-----+--------------------
 | 
					 | 
				
			||||||
        0   | (position)      |  (position + v1)          | ... | (bounds[0])
 | 
					 | 
				
			||||||
        1   | (position + v2) |  (position + v1*i + v2*j) | ... | (bounds[0] + v2)
 | 
					 | 
				
			||||||
      ...   | ...             |  ...                      | ... | ...
 | 
					 | 
				
			||||||
    size[1] | (bounds[2])     |  (bounds[2] + v1)         | ... | (bounds[0] + bounds[1])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    def __init__(self):
 | 
					 | 
				
			||||||
        super(ARef, self).__init__()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # positions of last instance in X and Y direction
 | 
					 | 
				
			||||||
        self.bounds = [(0,0), (0,0)]
 | 
					 | 
				
			||||||
        # number of instances in X and Y direction
 | 
					 | 
				
			||||||
        self.size   = (0,0)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@ -1,81 +0,0 @@
 | 
				
			|||||||
from datetime import datetime
 | 
					 | 
				
			||||||
from .elements import SRef
 | 
					 | 
				
			||||||
from .reader import ProgressGetter
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Library(object):
 | 
					 | 
				
			||||||
    def __init__(self):
 | 
					 | 
				
			||||||
        self.version = 0
 | 
					 | 
				
			||||||
        self.name = "NONAME"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.last_access = datetime.now()
 | 
					 | 
				
			||||||
        self.last_mod    = datetime.now()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # unit setup
 | 
					 | 
				
			||||||
        self.units_per_dbunit = 1
 | 
					 | 
				
			||||||
        self.meters_per_unit  = 1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.structures = {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    class LinkError(Exception):
 | 
					 | 
				
			||||||
        element = None
 | 
					 | 
				
			||||||
        pass
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    normalizes given coordinate according to library units
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    def normalize_coord(self, coord, to_meters=False):
 | 
					 | 
				
			||||||
        fact = self.units_per_dbunit
 | 
					 | 
				
			||||||
        if to_meters:
 | 
					 | 
				
			||||||
            fact *= self.meters_per_unit
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        return (coord[0] * fact, coord[1] * fact)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def link_refs(self, root, progress_callback=None):
 | 
					 | 
				
			||||||
        for ref in root.references:
 | 
					 | 
				
			||||||
            if isinstance(ref.structure, str):
 | 
					 | 
				
			||||||
                try:
 | 
					 | 
				
			||||||
                    element.structure = self.structures[ref.structure]
 | 
					 | 
				
			||||||
                except KeyError:
 | 
					 | 
				
			||||||
                    err = LinkError("dangeling sref (structure {} is not defined in library)".format(ref.structure))
 | 
					 | 
				
			||||||
                    err.element = root
 | 
					 | 
				
			||||||
                    raise err
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
        return root
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def link_all_refs(self, progress_callback=None):
 | 
					 | 
				
			||||||
        class Progress(ProgressGetter):
 | 
					 | 
				
			||||||
            total   = 0
 | 
					 | 
				
			||||||
            current = 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            def __init__(self, lib):
 | 
					 | 
				
			||||||
                for key, value in lib.structures.items():
 | 
					 | 
				
			||||||
                    self.total += len(value.references)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            def progress(self):
 | 
					 | 
				
			||||||
                return float(self.current) / self.total
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            def inc(self):
 | 
					 | 
				
			||||||
                self.current += 1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        count = Progress(self)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for key, value in self.structures.items():
 | 
					 | 
				
			||||||
            for element in value.references:             
 | 
					 | 
				
			||||||
                if isinstance(element.structure, str):
 | 
					 | 
				
			||||||
                    # try to resolve link
 | 
					 | 
				
			||||||
                    try:
 | 
					 | 
				
			||||||
                        ref = self.structures[element.structure]
 | 
					 | 
				
			||||||
                        element.structure = ref
 | 
					 | 
				
			||||||
                    except KeyError:
 | 
					 | 
				
			||||||
                        err = LinkError("dangeling sref (structure {} is not defined in library)".format(element.structure))
 | 
					 | 
				
			||||||
                        err.element = element
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                        raise err
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                count.inc()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if progress_callback:
 | 
					 | 
				
			||||||
                    progress_callback(count)
 | 
					 | 
				
			||||||
                    
 | 
					 | 
				
			||||||
                    
 | 
					 | 
				
			||||||
							
								
								
									
										407
									
								
								gds/parser.py
									
									
									
									
									
								
							
							
						
						
									
										407
									
								
								gds/parser.py
									
									
									
									
									
								
							@ -1,407 +0,0 @@
 | 
				
			|||||||
from . import *
 | 
					 | 
				
			||||||
from enum import Enum
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class errors(Enum):
 | 
					 | 
				
			||||||
    UNEXPECTED_EOF   = "unexpected EOF"
 | 
					 | 
				
			||||||
    EXPECTED_HEADER  = "expected file header"    
 | 
					 | 
				
			||||||
    EXPECTED_BGNLIB  = "expected beginning of library"
 | 
					 | 
				
			||||||
    EXPECTED_LIBNAME = "Library name is missing"
 | 
					 | 
				
			||||||
    EXPECTED_ENDMASK = "MASK records was not terminated by ENDMASK"
 | 
					 | 
				
			||||||
    EXPECTED_STRNAME = "encountered nameless structure"
 | 
					 | 
				
			||||||
    EXPECTED_UNITS   = "no unit record in file"
 | 
					 | 
				
			||||||
    EXPECTED_LAYER   = "expected a layer record in element"
 | 
					 | 
				
			||||||
    EXPECTED_POINTS  = "expected coordinates for element"
 | 
					 | 
				
			||||||
    EXPECTED_POINT   = "expected coordinate for element"
 | 
					 | 
				
			||||||
    EXPECTED_DATATYPE = "expected datatype"
 | 
					 | 
				
			||||||
    EXPECTED_ENDEL   = "end of element is missing"
 | 
					 | 
				
			||||||
    EXPECTED_TEXTTYPE = "expected TEXTTYPE"
 | 
					 | 
				
			||||||
    EXPECTED_STRING   = "textelement is missing text"
 | 
					 | 
				
			||||||
    EXPECTED_BOXTYPE  = "expected BOXTYPE"
 | 
					 | 
				
			||||||
    EXPECTED_SNAME    = "expected SNAME"
 | 
					 | 
				
			||||||
    EXPECTED_COLROW   = "expected COLROW"
 | 
					 | 
				
			||||||
    AREF_MISSING_POINTS = "aref needs three points"
 | 
					 | 
				
			||||||
    INVALID_PATHTYPE = "pathtype must be in range [0,2]"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Warnings(Enum):
 | 
					 | 
				
			||||||
    EXPECTED_ENDLIB  = "missing end of library"
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
class ParserError(Exception):
 | 
					 | 
				
			||||||
    pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Parser(Reader):
 | 
					 | 
				
			||||||
    def __init__(self, file, progress_callback=None):
 | 
					 | 
				
			||||||
        super(Parser, self).__init__(file)
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        self._token = None
 | 
					 | 
				
			||||||
        self.progress_callback = progress_callback
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        # parser state
 | 
					 | 
				
			||||||
        self.Library = Library()
 | 
					 | 
				
			||||||
        self.current_structure = None
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    @property
 | 
					 | 
				
			||||||
    def token(self):
 | 
					 | 
				
			||||||
        return self._token
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    @token.setter
 | 
					 | 
				
			||||||
    def token(self, t):
 | 
					 | 
				
			||||||
        self._token = t
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def next_token(self, throw=False):
 | 
					 | 
				
			||||||
        self.token = self.read_record()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if not self.token and throw:
 | 
					 | 
				
			||||||
            raise ParserError(errors.UNEXPECTED_EOF)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # if self.token:
 | 
					 | 
				
			||||||
        #     print(self.token.ident.name)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return self.token
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def parse_lib(self):
 | 
					 | 
				
			||||||
        # read header  
 | 
					 | 
				
			||||||
        if not self.next_token() or self.token.ident != Records.HEADER:
 | 
					 | 
				
			||||||
            raise ParserError(errors.EXPECTED_HEADER)
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        self.Library.version = self.read_short()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # must see BGNLIB
 | 
					 | 
				
			||||||
        if not self.next_token() or self.token.ident != Records.BGNLIB:
 | 
					 | 
				
			||||||
            raise ParserError(errors.EXPECTED_BGNLIB)
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        self.Library.last_mod    = self.read_date()
 | 
					 | 
				
			||||||
        self.Library.last_access = self.read_date()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if not self.next_token() or self.token.ident != Records.LIBNAME:
 | 
					 | 
				
			||||||
            raise ParserError(errors.EXPECTED_LIBNAME)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.Library.name = self.read_ascii(self.token.len)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # read optional records
 | 
					 | 
				
			||||||
        while self.next_token():
 | 
					 | 
				
			||||||
            if self.token.ident  == Records.REFLIBS or    \
 | 
					 | 
				
			||||||
                self.token.ident == Records.FONTS or     \
 | 
					 | 
				
			||||||
                self.token.ident == Records.ATTRTABLE or \
 | 
					 | 
				
			||||||
                self.token.ident == Records.GENERATIONS:
 | 
					 | 
				
			||||||
                # skip these records
 | 
					 | 
				
			||||||
                self.skip(self.token.len)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            elif self.token.ident == Records.FORMAT:
 | 
					 | 
				
			||||||
                self.skip(self.token.len)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                # look for optional mask
 | 
					 | 
				
			||||||
                while self.next_token().ident == Records.MASK:
 | 
					 | 
				
			||||||
                    self.skip(self.token.len)
 | 
					 | 
				
			||||||
                                   
 | 
					 | 
				
			||||||
                if self.token.ident != Records.ENDMASK:
 | 
					 | 
				
			||||||
                    raise ParserError(errors.EXPECTED_ENDMASK)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                # continue
 | 
					 | 
				
			||||||
                break
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if self.token.ident != Records.UNITS:
 | 
					 | 
				
			||||||
            raise ParserError(errors.EXPECTED_UNITS)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # read units
 | 
					 | 
				
			||||||
        self.Library.units_per_dbunit = self.read_double()
 | 
					 | 
				
			||||||
        self.Library.meters_per_unit  = self.read_double()
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        while self.next_token() and self.parse_structure():
 | 
					 | 
				
			||||||
            pass
 | 
					 | 
				
			||||||
       
 | 
					 | 
				
			||||||
        if self.token.ident != Records.ENDLIB:
 | 
					 | 
				
			||||||
            print(Warnings.EXPECTED_ENDLIB.value)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # tell callback that the process completed
 | 
					 | 
				
			||||||
        if self.progress_callback:
 | 
					 | 
				
			||||||
            self.progress_callback(self)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def parse_structure(self):
 | 
					 | 
				
			||||||
        self.structure = Structure()
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        if self.token.ident != Records.BGNSTR:
 | 
					 | 
				
			||||||
            return False
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.structure.last_mod = self.read_date()
 | 
					 | 
				
			||||||
        self.structure.last_access = self.read_date()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # read sname
 | 
					 | 
				
			||||||
        if not self.next_token() or self.token.ident != Records.STRNAME:
 | 
					 | 
				
			||||||
            raise ParserError(errors.EXPECTED_STRNAME)
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        self.structure.name = self.read_ascii(self.token.len)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        while self.next_token() and self.token.ident != Records.ENDSTR:
 | 
					 | 
				
			||||||
            if self.token.ident == Records.BOUNDARY:
 | 
					 | 
				
			||||||
                self.parse_boundary()
 | 
					 | 
				
			||||||
            elif self.token.ident == Records.PATH:
 | 
					 | 
				
			||||||
                self.parse_path()
 | 
					 | 
				
			||||||
            elif self.token.ident == Records.TEXT:
 | 
					 | 
				
			||||||
                self.parse_text()
 | 
					 | 
				
			||||||
            elif self.token.ident == Records.SREF:
 | 
					 | 
				
			||||||
                self.parse_sref()
 | 
					 | 
				
			||||||
            elif self.token.ident == Records.AREF:
 | 
					 | 
				
			||||||
                self.parse_aref()
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                self.skip(self.token.len)
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            if self.progress_callback:
 | 
					 | 
				
			||||||
                self.progress_callback(self)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.Library.structures[self.structure.name] = self.structure
 | 
					 | 
				
			||||||
        self.structure = None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return True
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def parse_element(self, element):
 | 
					 | 
				
			||||||
        if self.token.ident == Records.ELFLAGS:
 | 
					 | 
				
			||||||
            element.elflags = self.read_short()
 | 
					 | 
				
			||||||
            self.next_token(True)
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        if self.token.ident == Records.PLEX:
 | 
					 | 
				
			||||||
            element.plex = self.read_int()
 | 
					 | 
				
			||||||
            self.next_token(True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def parse_layer(self, element):
 | 
					 | 
				
			||||||
        if self.token.ident != Records.LAYER:
 | 
					 | 
				
			||||||
            raise ParserError(errors.EXPECTED_LAYER)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        element.layer = self.read_ushort()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def parse_boundary(self):
 | 
					 | 
				
			||||||
        element = Boundary()
 | 
					 | 
				
			||||||
        self.next_token(True)
 | 
					 | 
				
			||||||
        self.parse_element(element)
 | 
					 | 
				
			||||||
        self.parse_layer(element)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if not self.next_token() or self.token.ident != Records.DATATYPE:
 | 
					 | 
				
			||||||
            raise ParserError(errors.EXPECTED_DATATYPE)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        element.datatype = self.read_short()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if not self.next_token() or self.token.ident != Records.XY:
 | 
					 | 
				
			||||||
            raise ParserError(errors.EXPECTED_POINTS)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        element.points = self.read_coords(self.token.len)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if not self.next_token() or self.token.ident != Records.ENDEL:
 | 
					 | 
				
			||||||
            raise ParserError(errors.EXPECTED_ENDEL)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.structure.elements.append(element)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def parse_path(self):
 | 
					 | 
				
			||||||
        element = Path()
 | 
					 | 
				
			||||||
        self.next_token(True)
 | 
					 | 
				
			||||||
        self.parse_element(element)
 | 
					 | 
				
			||||||
        self.parse_layer(element)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if not self.next_token() or self.token.ident != Records.DATATYPE:
 | 
					 | 
				
			||||||
            raise ParserError(errors.EXPECTED_DATATYPE)
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        element.datatype = self.read_short()
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
        self.next_token(True)
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        if self.token.ident == Records.PATHTYPE:
 | 
					 | 
				
			||||||
            pathtype = self.read_short()
 | 
					 | 
				
			||||||
            if pathtype < 0 or pathtype > 4 or pathtype == 3:  
 | 
					 | 
				
			||||||
                raise ParserError(errors.INVALID_PATHTYPE)
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            element.pathStyle = Path.Styles(pathtype)
 | 
					 | 
				
			||||||
            self.next_token(True)
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        if self.token.ident == Records.WIDTH:
 | 
					 | 
				
			||||||
            element.width = self.read_int()
 | 
					 | 
				
			||||||
            self.next_token(True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if self.token.ident == Records.BGNEXTN:
 | 
					 | 
				
			||||||
            element.extendEnd[0] = self.read_int()
 | 
					 | 
				
			||||||
            self.next_token(True)
 | 
					 | 
				
			||||||
        elif element.pathStyle == Path.Styles.OFFSET_ENDS:
 | 
					 | 
				
			||||||
            element.extendEnd[0] = element.width/2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if self.token.ident == Records.ENDEXTN:
 | 
					 | 
				
			||||||
            element.extendEnd[1] = self.read_int()
 | 
					 | 
				
			||||||
            self.next_token(True)
 | 
					 | 
				
			||||||
        elif element.pathStyle == Path.Styles.OFFSET_ENDS:
 | 
					 | 
				
			||||||
            element.extendEnd[1] = element.width/2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if self.token.ident != Records.XY:
 | 
					 | 
				
			||||||
            raise ParserError(errors.EXPECTED_POINTS)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        element.points = self.read_coords(self.token.len)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if not self.next_token() or self.token.ident != Records.ENDEL:
 | 
					 | 
				
			||||||
            raise ParserError(errors.EXPECTED_ENDEL)
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
        self.structure.elements.append(element)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def parse_text(self):
 | 
					 | 
				
			||||||
        element = Text()
 | 
					 | 
				
			||||||
        self.next_token(True)
 | 
					 | 
				
			||||||
        self.parse_element(element)
 | 
					 | 
				
			||||||
        self.parse_layer(element)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if not self.next_token() or self.token.ident != Records.TEXTTYPE:
 | 
					 | 
				
			||||||
            raise ParserError(errors.EXPECTED_TEXTTYPE)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        element.datatype = self.read_short()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.next_token(True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if self.token.ident == Records.PRESENTATION:
 | 
					 | 
				
			||||||
            temp = self.read_short()
 | 
					 | 
				
			||||||
            element.fontnumber = (temp>>10)&0x03
 | 
					 | 
				
			||||||
            element.verticalJustification   = Text.VJust((temp>>12)&0x03)
 | 
					 | 
				
			||||||
            element.horizontalJustification = Text.HJust((temp>>14)&0X03)
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            self.next_token(True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if self.token.ident == Records.PATHTYPE:
 | 
					 | 
				
			||||||
            element.pathStype = Path.Styles(self.read_short())
 | 
					 | 
				
			||||||
            self.next_token(True)
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        if self.token.ident == Records.WIDTH:
 | 
					 | 
				
			||||||
            element.pathWidth = self.read_short()
 | 
					 | 
				
			||||||
            self.next_token(True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.parse_strans(element.transformation)
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        if self.token.ident != Records.XY:
 | 
					 | 
				
			||||||
            raise ParserError(errors.EXPECTED_POINT)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        element.point = self.read_coord()
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        # skip potential array (if given)
 | 
					 | 
				
			||||||
        self.skip(self.token.len - 8)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if not self.next_token() or self.token.ident != Records.STRING:
 | 
					 | 
				
			||||||
            raise ParserError(errors.EXPECTED_STRING)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        element.string = self.read_ascii(self.token.len)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if not self.next_token() or self.token.ident != Records.ENDEL:
 | 
					 | 
				
			||||||
            raise ParserError(errors.EXPECTED_ENDEL)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.structure.elements.append(element)
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def parse_strans(self, trans:Transformation):
 | 
					 | 
				
			||||||
        if self.token.ident != Records.STRANS:
 | 
					 | 
				
			||||||
            return
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        flags = self.read_ushort()
 | 
					 | 
				
			||||||
        if flags & 0x01:
 | 
					 | 
				
			||||||
            trans.mirror_x = True
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if flags & 0x2000:
 | 
					 | 
				
			||||||
            trans.absolute_magnification = True
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if flags & 0x4000:
 | 
					 | 
				
			||||||
            trans.absolute_rotation = True
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
        self.next_token(True) 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if self.token.ident == Records.MAG:
 | 
					 | 
				
			||||||
            trans.zoom = self.read_double()
 | 
					 | 
				
			||||||
            self.next_token(True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if self.token.ident == Records.ANGLE:
 | 
					 | 
				
			||||||
            trans.rotation = self.read_double()
 | 
					 | 
				
			||||||
            self.next_token(True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def parse_box(self):
 | 
					 | 
				
			||||||
        element = Box()
 | 
					 | 
				
			||||||
        self.next_token(True)
 | 
					 | 
				
			||||||
        self.parse_element(element)
 | 
					 | 
				
			||||||
        self.parse_layer(element)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if not self.next_token() or self.token.ident != Records.BOXTYPE:
 | 
					 | 
				
			||||||
            raise ParserError(errors.EXPECTED_BOXTYPE)
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        element.datatype = self.read_short()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if not self.next_token() or self.token.ident != Records.XY:
 | 
					 | 
				
			||||||
            raise ParserError(errors.EXPECTED_POINTS)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        element.points = self.read_coords(self.token.len)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if not self.next_token() or self.token.ident != Records.ENDEL:
 | 
					 | 
				
			||||||
            raise ParserError(errors.EXPECTED_ENDEL)
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        self.structure.elements.append(element)
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    def parse_sref(self):
 | 
					 | 
				
			||||||
        element = SRef()
 | 
					 | 
				
			||||||
        element.parent = self.structure
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if not self.next_token(): 
 | 
					 | 
				
			||||||
            raise ParserError(errors.EXPECTED_SNAME)
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        self.parse_element(element)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if self.token.ident != Records.SNAME:
 | 
					 | 
				
			||||||
            raise ParserError(errors.EXPECTED_SNAME)
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        element.structure = self.read_ascii(self.token.len)
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        self.next_token(True)
 | 
					 | 
				
			||||||
        self.parse_strans(element.transformation)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if self.token.ident != Records.XY:
 | 
					 | 
				
			||||||
            raise ParserError(errors.EXPECTED_POINT)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        element.position = self.read_coord()
 | 
					 | 
				
			||||||
        self.skip(self.token.len - 8)
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        if not self.next_token() or self.token.ident != Records.ENDEL:
 | 
					 | 
				
			||||||
            raise ParserError(errors.EXPECTED_ENDEL)
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        self.structure.references.append(element)
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    def parse_aref(self):
 | 
					 | 
				
			||||||
        element = ARef()
 | 
					 | 
				
			||||||
        element.parent = self.structure
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if not self.next_token(): 
 | 
					 | 
				
			||||||
            raise ParserError(errors.EXPECTED_SNAME)
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        self.parse_element(element)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if self.token.ident != Records.SNAME:
 | 
					 | 
				
			||||||
            raise ParserError(errors.EXPECTED_SNAME)
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        element.structure = self.read_ascii(self.token.len)
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        self.next_token(True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.parse_strans(element.transformation)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if self.token.ident != Records.COLROW:
 | 
					 | 
				
			||||||
            raise ParserError(errors.EXPECTED_COLROW)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        element.size = (self.read_short(), self.read_short())
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if not self.next_token() or self.token.ident != Records.XY:
 | 
					 | 
				
			||||||
            raise ParserError(errors.EXPECTED_POINT)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if self.token.len != 3*8:
 | 
					 | 
				
			||||||
            raise ParserError(errors.AREF_MISSING_POINTS)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        element.position = self.read_coord()
 | 
					 | 
				
			||||||
        element.bounds[0] = self.read_coord()
 | 
					 | 
				
			||||||
        element.bounds[1] = self.read_coord()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if not self.next_token() or self.token.ident != Records.ENDEL:
 | 
					 | 
				
			||||||
            raise ParserError(errors.EXPECTED_ENDEL)
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        self.structure.references.append(element)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def parse_file(file, progress_func=None):
 | 
					 | 
				
			||||||
    parser = Parser(file, progress_callback=progress_func)
 | 
					 | 
				
			||||||
    parser.parse_lib()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return parser.Library
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
							
								
								
									
										148
									
								
								gds/reader.py
									
									
									
									
									
								
							
							
						
						
									
										148
									
								
								gds/reader.py
									
									
									
									
									
								
							@ -1,148 +0,0 @@
 | 
				
			|||||||
from datetime import datetime
 | 
					 | 
				
			||||||
from .record import *
 | 
					 | 
				
			||||||
import abc
 | 
					 | 
				
			||||||
import ctypes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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):
 | 
					 | 
				
			||||||
    @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
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @property
 | 
					 | 
				
			||||||
    def total(self):
 | 
					 | 
				
			||||||
        return 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_uint(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_ushort(self):
 | 
					 | 
				
			||||||
        temp = self.stream.read(2)
 | 
					 | 
				
			||||||
        if len(temp) != 2:
 | 
					 | 
				
			||||||
            return None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return int(temp[1]) | int(temp[0]) << 8
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def read_short(self):
 | 
					 | 
				
			||||||
        temp = self.read_ushort()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if temp == None:
 | 
					 | 
				
			||||||
            return None
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        return ctypes.c_short(temp).value
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
    def read_int(self):
 | 
					 | 
				
			||||||
        temp = self.read_uint()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if temp == None:
 | 
					 | 
				
			||||||
            return None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return ctypes.c_int(temp).value
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
    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
 | 
					 | 
				
			||||||
                for j in range(1,8):
 | 
					 | 
				
			||||||
                    result += float(temp[j])/(2.0**(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):
 | 
					 | 
				
			||||||
        # removes zero terminators
 | 
					 | 
				
			||||||
        # as well as trailing and beginning whitespaces
 | 
					 | 
				
			||||||
        return self.stream.read(len).decode("ASCII").replace("\x00", "").strip()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def read_record(self):
 | 
					 | 
				
			||||||
        result = Record()
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            result.len = self.read_ushort() 
 | 
					 | 
				
			||||||
            result.ident = Records(self.read_ushort())
 | 
					 | 
				
			||||||
        except ValueError:
 | 
					 | 
				
			||||||
            return None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        result.len -= 4 # remove record header len 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return result
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def read_date(self):
 | 
					 | 
				
			||||||
        # date
 | 
					 | 
				
			||||||
        year  = self.read_ushort()
 | 
					 | 
				
			||||||
        month = self.read_ushort()
 | 
					 | 
				
			||||||
        day   = self.read_ushort()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # time
 | 
					 | 
				
			||||||
        hour   = self.read_ushort()
 | 
					 | 
				
			||||||
        minute = self.read_ushort()
 | 
					 | 
				
			||||||
        second = self.read_ushort()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        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
 | 
					 | 
				
			||||||
@ -1,52 +0,0 @@
 | 
				
			|||||||
from enum import Enum
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Records(Enum):
 | 
					 | 
				
			||||||
    UNKNOWN      = 0x0000
 | 
					 | 
				
			||||||
    HEADER       = 0x0002
 | 
					 | 
				
			||||||
    BGNLIB       = 0x0102
 | 
					 | 
				
			||||||
    LIBNAME      = 0x0206
 | 
					 | 
				
			||||||
    REFLIBS      = 0x1F06
 | 
					 | 
				
			||||||
    FONTS        = 0x2006
 | 
					 | 
				
			||||||
    ATTRTABLE    = 0x2306
 | 
					 | 
				
			||||||
    GENERATIONS  = 0x2202
 | 
					 | 
				
			||||||
    FORMAT       = 0x3602
 | 
					 | 
				
			||||||
    MASK         = 0x3706
 | 
					 | 
				
			||||||
    ENDMASKS     = 0x3800
 | 
					 | 
				
			||||||
    UNITS        = 0x0305
 | 
					 | 
				
			||||||
    ENDLIB       = 0x0400
 | 
					 | 
				
			||||||
    BGNSTR       = 0x0502
 | 
					 | 
				
			||||||
    STRNAME      = 0x0606
 | 
					 | 
				
			||||||
    ENDEL        = 0x1100
 | 
					 | 
				
			||||||
    ENDSTR       = 0x0700
 | 
					 | 
				
			||||||
    BOUNDARY     = 0x0800
 | 
					 | 
				
			||||||
    PATH         = 0x0900
 | 
					 | 
				
			||||||
    SREF         = 0x0A00
 | 
					 | 
				
			||||||
    AREF         = 0x0B00
 | 
					 | 
				
			||||||
    TEXT         = 0x0C00
 | 
					 | 
				
			||||||
    NODE         = 0x1500
 | 
					 | 
				
			||||||
    BOX          = 0x2D00
 | 
					 | 
				
			||||||
    ELFLAGS      = 0x2601
 | 
					 | 
				
			||||||
    PLEX         = 0x2F03
 | 
					 | 
				
			||||||
    LAYER        = 0x0D02
 | 
					 | 
				
			||||||
    DATATYPE     = 0x0E02
 | 
					 | 
				
			||||||
    XY	         = 0x1003
 | 
					 | 
				
			||||||
    PATHTYPE     = 0x2102
 | 
					 | 
				
			||||||
    WIDTH        = 0x0F03
 | 
					 | 
				
			||||||
    BGNEXTN      = 0x3003
 | 
					 | 
				
			||||||
    ENDEXTN      = 0x3103
 | 
					 | 
				
			||||||
    SNAME        = 0x1206
 | 
					 | 
				
			||||||
    STRANS       = 0x1A01
 | 
					 | 
				
			||||||
    MAG          = 0x1B05
 | 
					 | 
				
			||||||
    ANGLE        = 0x1C05
 | 
					 | 
				
			||||||
    COLROW       = 0x1302
 | 
					 | 
				
			||||||
    TEXTTYPE     = 0x1602
 | 
					 | 
				
			||||||
    PRESENTATION = 0x1701
 | 
					 | 
				
			||||||
    NODETYPE     = 0x2A02
 | 
					 | 
				
			||||||
    BOXTYPE      = 0x2E02
 | 
					 | 
				
			||||||
    STRING       = 0x1906
 | 
					 | 
				
			||||||
    PROPATTR     = 0x2B02
 | 
					 | 
				
			||||||
    PROPVALUE    = 0x2C06
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Record(object):
 | 
					 | 
				
			||||||
    ident = Records.UNKNOWN
 | 
					 | 
				
			||||||
    len   = 0
 | 
					 | 
				
			||||||
@ -1,14 +0,0 @@
 | 
				
			|||||||
from datetime import datetime
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Structure(object):
 | 
					 | 
				
			||||||
    def __init__(self):
 | 
					 | 
				
			||||||
        # metainfo
 | 
					 | 
				
			||||||
        self.creation_date = datetime.now()
 | 
					 | 
				
			||||||
        self.last_mod      = datetime.now()
 | 
					 | 
				
			||||||
        self.name          = "NONAME"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # contains all the low level elements
 | 
					 | 
				
			||||||
        self.elements = []
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        # contains all sref and aref elements
 | 
					 | 
				
			||||||
        self.references = []
 | 
					 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user