def parse()

in src/pycalendar/containerbase.py [0:0]


    def parse(self, ins):

        result = False

        self.setProperties({})

        LOOK_FOR_CONTAINER = 0
        GET_PROPERTY_OR_COMPONENT = 1

        state = LOOK_FOR_CONTAINER

        # Get lines looking for start of calendar
        lines = [None, None]
        comp = self
        compend = None
        componentstack = []

        while readFoldedLine(ins, lines):

            line = lines[0]

            if state == LOOK_FOR_CONTAINER:

                # Look for start
                if line == self.getBeginDelimiter():
                    # Next state
                    state = GET_PROPERTY_OR_COMPONENT

                    # Indicate success at this point
                    result = True

                # Handle blank line
                elif len(line) == 0:
                    # Raise if requested, otherwise just ignore
                    if ParserContext.BLANK_LINES_IN_DATA == ParserContext.PARSER_RAISE:
                        raise InvalidData("%s data has blank lines" % (self.sContainerDescriptor,))

                # Unrecognized data
                else:
                    raise InvalidData("%s data not recognized" % (self.sContainerDescriptor,), line)

            elif state == GET_PROPERTY_OR_COMPONENT:

                # Parse property or look for start of component
                if line.startswith("BEGIN:") and self.sComponentType is not None:

                    # Push previous details to stack
                    componentstack.append((comp, compend,))

                    # Start a new component
                    comp = self.sComponentType.makeComponent(line[6:], comp)
                    compend = comp.getEndDelimiter()

                # Look for end of object
                elif line == self.getEndDelimiter():

                    # Finalise the current calendar
                    self.finalise()

                    # Change state
                    state = LOOK_FOR_CONTAINER

                # Look for end of current component
                elif line == compend:

                    # Finalise the component (this caches data from the properties)
                    comp.finalise()

                    # Embed component in parent and reset to use parent
                    componentstack[-1][0].addComponent(comp)
                    comp, compend = componentstack.pop()

                # Blank line
                elif len(line) == 0:
                    # Raise if requested, otherwise just ignore
                    if ParserContext.BLANK_LINES_IN_DATA == ParserContext.PARSER_RAISE:
                        raise InvalidData("%s data has blank lines" % (self.sContainerDescriptor,))

                # Must be a property
                else:

                    # Parse parameter/value for top-level calendar item
                    prop = self.sPropertyType.parseText(line)

                    # Check for valid property
                    if comp is self:
                        if not comp.validProperty(prop):
                            raise InvalidData("Invalid property", str(prop))
                        else:
                            comp.addProperty(prop)
                    else:
                        comp.addProperty(prop)

        # Check for truncated data
        if state != LOOK_FOR_CONTAINER:
            raise InvalidData("%s data not complete" % (self.sContainerDescriptor,))

        # Validate some things
        if result and not self.hasProperty("VERSION"):
            raise InvalidData("%s missing VERSION" % (self.sContainerDescriptor,))

        return result