# Path: core/ezdxf/lldxf/types.py
# NONE_TAG = DXFTag(None, None)
# TAG_STRING_FORMAT = '%3d\n%s\n'
# TYPE_TABLE = _build_type_table([
#     (internal_type, (-10, )),  # spacial tags for internal use
#     (ustr, range(0, 10)),
#     (point_tuple, range(10, 20)),  # 2d or 3d points
#     (float, range(20, 60)),  # code 20-39 belongs to 2d/3d points and should not appear alone
#     (int, range(60, 100)),
#     (ustr, range(100, 106)),
#     (point_tuple, range(110, 113)),  # 110, 111, 112 - UCS definition
#     (float, range(113, 150)),  # 113-139 belongs to UCS definition and should not appear alone
#     (int, range(160, 170)),
#     (int, range(170, 180)),
#     (point_tuple, [210]),  # extrusion direction
#     (float, range(211, 240)),  # code 220, 230 belongs to extrusion direction and should not appear alone
#     (int, range(270, 290)),
#     (int, range(290, 300)),  # bool 1=True 0=False
#     (ustr, range(300, 370)),
#     (int, range(370, 390)),
#     (ustr, range(390, 400)),
#     (int, range(400, 410)),
#     (ustr, range(410, 420)),
#     (int, range(420, 430)),
#     (ustr, range(430, 440)),
#     (int, range(440, 460)),
#     (float, range(460, 470)),
#     (ustr, range(470, 480)),
#     (ustr, range(480, 482)),
#     (ustr, range(999, 1010)),
#     (point_tuple, range(1010, 1020)),
#     (float, range(1020, 1060)),  # code 1020-1039 belongs to 2d/3d points and should not appear alone
#     (int, range(1060, 1072)),
# ])
# def point_tuple(value):
# def _build_type_table(types):
# def internal_type(value):
# def is_point_code(code):
# def is_point_tag(tag):
# def cast_tag(tag, types=TYPE_TABLE):
# def cast_tag_value(code, value, types=TYPE_TABLE):
# def tag_type(code):
# def strtag(tag):
# def strtag2(tag):
# def convert_tags_to_text_lines(line_tags):
# def convert_text_lines_to_tags(text_lines):
# 
# Path: core/ezdxf/lldxf/const.py
# class DXFStructureError(DXFError):
#     pass


from .types import DXFTag, is_point_code, cast_tag
from .const import DXFStructureError
def stream_tagger(stream):
    """ Generates DXFTag() from a stream (untrusted external source). Does not skip comment tags 999.
    """
    class Counter:
        def __init__(self):
            self.counter = 0

    undo_tag = None
    line = Counter()  # writeable line counter for next_tag(), Python 2.7 does not support the nonlocal statement

    def next_tag():
        code = stream.readline()
        value = stream.readline()
        line.counter += 2
        if code and value:  # StringIO(): empty strings indicates EOF
            return DXFTag(int(code[:-1]), value[:-1])  # without '\n'
        else:  # StringIO(): missing '\n' indicates EOF
            raise EOFError()

    while True:
        try:
            if undo_tag is not None:
                x = undo_tag
                undo_tag = None
            else:
                x = next_tag()
            code = x.code
            if is_point_code(code):
                y = next_tag()  # y coordinate is mandatory
                if y.code != code + 10:

# Path: core/ezdxf/lldxf/types.py
# NONE_TAG = DXFTag(None, None)
# TAG_STRING_FORMAT = '%3d\n%s\n'
# TYPE_TABLE = _build_type_table([
#     (internal_type, (-10, )),  # spacial tags for internal use
#     (ustr, range(0, 10)),
#     (point_tuple, range(10, 20)),  # 2d or 3d points
#     (float, range(20, 60)),  # code 20-39 belongs to 2d/3d points and should not appear alone
#     (int, range(60, 100)),
#     (ustr, range(100, 106)),
#     (point_tuple, range(110, 113)),  # 110, 111, 112 - UCS definition
#     (float, range(113, 150)),  # 113-139 belongs to UCS definition and should not appear alone
#     (int, range(160, 170)),
#     (int, range(170, 180)),
#     (point_tuple, [210]),  # extrusion direction
#     (float, range(211, 240)),  # code 220, 230 belongs to extrusion direction and should not appear alone
#     (int, range(270, 290)),
#     (int, range(290, 300)),  # bool 1=True 0=False
#     (ustr, range(300, 370)),
#     (int, range(370, 390)),
#     (ustr, range(390, 400)),
#     (int, range(400, 410)),
#     (ustr, range(410, 420)),
#     (int, range(420, 430)),
#     (ustr, range(430, 440)),
#     (int, range(440, 460)),
#     (float, range(460, 470)),
#     (ustr, range(470, 480)),
#     (ustr, range(480, 482)),
#     (ustr, range(999, 1010)),
#     (point_tuple, range(1010, 1020)),
#     (float, range(1020, 1060)),  # code 1020-1039 belongs to 2d/3d points and should not appear alone
#     (int, range(1060, 1072)),
# ])
# def point_tuple(value):
# def _build_type_table(types):
# def internal_type(value):
# def is_point_code(code):
# def is_point_tag(tag):
# def cast_tag(tag, types=TYPE_TABLE):
# def cast_tag_value(code, value, types=TYPE_TABLE):
# def tag_type(code):
# def strtag(tag):
# def strtag2(tag):
# def convert_tags_to_text_lines(line_tags):
# def convert_text_lines_to_tags(text_lines):
# 
# Path: core/ezdxf/lldxf/const.py
# class DXFStructureError(DXFError):
#     pass


# Path: core/ezdxf/lldxf/tagger.py
from .types import DXFTag, is_point_code, cast_tag
from .const import DXFStructureError

def stream_tagger(stream):
    """ Generates DXFTag() from a stream (untrusted external source). Does not skip comment tags 999.
    """
    class Counter:
        def __init__(self):
            self.counter = 0

    undo_tag = None
    line = Counter()  # writeable line counter for next_tag(), Python 2.7 does not support the nonlocal statement

    def next_tag():
        code = stream.readline()
        value = stream.readline()
        line.counter += 2
        if code and value:  # StringIO(): empty strings indicates EOF
            return DXFTag(int(code[:-1]), value[:-1])  # without '\n'
        else:  # StringIO(): missing '\n' indicates EOF
            raise EOFError()

    while True:
        try:
            if undo_tag is not None:
                x = undo_tag
                undo_tag = None
            else:
                x = next_tag()
            code = x.code
            if is_point_code(code):
                y = next_tag()  # y coordinate is mandatory
                if y.code != code + 10:

                    raise DXFStructureError("Missing required y coordinate near line: {}.".format(line.counter))