def read_header_value(event_name): """ Read and emit characters of a (possibly multi-line) header value. Note that the header is not "demangled" in any way, only the newlines are removed. """ auto = Automaton() start = auto.start() start.set_name(event_name) start.mark_enter() line, end = newline() auto.join(start, line) start.loop_fallback() continuation = auto.add_state() continuation.loop("HorizWhitespace", LabelType.Special) continuation.add_fallback(start) end.add_transition("HorizWhitespace", LabelType.Special, continuation) return auto, end, False
def read_boundary(): """ Read a boundary=value from a header. This is meant for content type header (we ignore the actual content type) """ # States: # * We linger in read_until_colon first, then transition to waiting_word. # * The waiting_word is responsible to find the 'boundary=' word # * Then in_boundary accumulates the actual boundary # If we leave it, it means it is somehow unknown and we loop back to # waiting for another colon. # # And then to complicate things, there might be a newline that either means # end of the header or it may be a header continuation. In the latter case, # we need to distinguish the state of somewhere before or after colon. auto = Automaton() line, end = newline() read_until_colon = auto.start() waiting_word = auto.add_state() # Target od waiting_word's path equals = auto.add_state() in_boundary = auto.add_state("Boundary") equals.add_fallback(in_boundary) in_boundary.mark_enter() # Including newlines, yes - they'll be handled later. in_boundary.add_transition("Whitespace", LabelType.Special, read_until_colon, fallthrough=True) in_boundary.add_transition(';', LabelType.Char, read_until_colon, fallthrough=True) in_boundary.loop_fallback() waiting_word.set_path("boundary=", True) waiting_word.loop("HorizWhitespace", LabelType.Special) waiting_line, waiting_end = newline() auto.join(waiting_word, waiting_line) waiting_continuation = auto.add_state() waiting_continuation.loop("HorizWhitespace", LabelType.Special) waiting_continuation.add_fallback(waiting_word, fallthrough=True) waiting_word.add_fallback(read_until_colon, fallthrough=True) waiting_end.add_transition("HorizWhitespace", LabelType.Special, waiting_continuation) waiting_end.add_fallback(end, fallthrough=True) read_until_colon.add_transition(';', LabelType.Char, waiting_word) auto.join(read_until_colon, line) continuation = auto.add_state() continuation.loop("HorizWhitespace", LabelType.Special) continuation.add_fallback(read_until_colon, fallthrough=True) end.add_transition("HorizWhitespace", LabelType.Special, continuation) read_until_colon.loop_fallback() return auto, end, False