def _extract_frame_info(frame_line, json_dump):
    """given a pipe dump Frame line, extract the parts and put them in their
    proper location within the json_dump"""
    if 'threads' not in json_dump:
        json_dump.threads = []
    thread_number = _get_int(frame_line, 0, None)
    if thread_number is None:
        return
    if thread_number >=len(json_dump.threads):
        # threads are supposed to arrive in order.  We've not seen this thread
        # before, fill in a new entry in the 'threads' section of the json_dump
        # making sure that intervening missing threads have empty thread data
        for i in range(thread_number - len(json_dump.threads) + 1):
            thread = DotDict()
            thread.frame_count = 0
            thread.frames = []
            json_dump.threads.append(thread)
    # collect frame info from the pipe dump line
    tmp_frame = _get_int(frame_line, 1, None)
    tmp_module = _get(frame_line, 2, None)
    tmp_function = _get(frame_line, 3, None)
    tmp_file = _get(frame_line, 4, None)
    tmp_line = _get_int(frame_line, 5, None)
    tmp_offset = _get(frame_line, 6, None)
    frame = DotDictWithPut()
    frame.put_if_not_none('frame', tmp_frame)
    frame.put_if_not_none('module', tmp_module)
    frame.put_if_not_none('function', tmp_function)
    frame.put_if_not_none('file', tmp_file)
    frame.put_if_not_none('line', tmp_line)
    if tmp_file and tmp_line is not None:
        # skip offset entirely
        pass
    elif not tmp_file and tmp_function:
        frame.function_offset = tmp_offset
    elif not tmp_function and tmp_module:
        frame.module_offset = tmp_offset
    else:
        frame.offset = tmp_offset
    # save the frame info into the json
    json_dump.threads[thread_number].frames.append(frame)
    json_dump.threads[thread_number].frame_count += 1
def _extract_frame_info(frame_line, json_dump):
    """given a pipe dump Frame line, extract the parts and put them in their
    proper location within the json_dump"""
    if 'threads' not in json_dump:
        json_dump.threads = []
    thread_number = _get_int(frame_line, 0, None)
    if thread_number is None:
        return
    if thread_number >= len(json_dump.threads):
        # threads are supposed to arrive in order.  We've not seen this thread
        # before, fill in a new entry in the 'threads' section of the json_dump
        # making sure that intervening missing threads have empty thread data
        for i in range(thread_number - len(json_dump.threads) + 1):
            thread = DotDict()
            thread.frame_count = 0
            thread.frames = []
            json_dump.threads.append(thread)
    # collect frame info from the pipe dump line
    tmp_frame = _get_int(frame_line, 1, None)
    tmp_module = _get(frame_line, 2, None)
    tmp_function = _get(frame_line, 3, None)
    tmp_file = _get(frame_line, 4, None)
    tmp_line = _get_int(frame_line, 5, None)
    tmp_offset = _get(frame_line, 6, None)
    frame = DotDictWithPut()
    frame.put_if_not_none('frame', tmp_frame)
    frame.put_if_not_none('module', tmp_module)
    frame.put_if_not_none('function', tmp_function)
    frame.put_if_not_none('file', tmp_file)
    frame.put_if_not_none('line', tmp_line)
    if tmp_file and tmp_line is not None:
        # skip offset entirely
        pass
    elif not tmp_file and tmp_function:
        frame.function_offset = tmp_offset
    elif not tmp_function and tmp_module:
        frame.module_offset = tmp_offset
    else:
        frame.offset = tmp_offset
    # save the frame info into the json
    json_dump.threads[thread_number].frames.append(frame)
    json_dump.threads[thread_number].frame_count += 1
def pipe_dump_to_json_dump(pipe_dump_iterable):
    """given a list (or any iterable) of strings representing a MDSW pipe dump,
    this function will convert it into a json format."""
    json_dump = DotDict()
    crashing_thread = None
    module_counter = 0
    thread_counter = 0
    for a_line in pipe_dump_iterable:
        parts = a_line.split('|')
        if parts[0] == 'OS':
            _extract_OS_info(parts, json_dump)
        elif parts[0] == 'CPU':
            _extract_CPU_info(parts, json_dump)
        elif parts[0] == 'Crash':
            crashing_thread = _extract_crash_info(parts, json_dump)
        elif parts[0] == 'Module':
            _extract_module_info(parts, json_dump, module_counter)
            module_counter += 1
        else:
            try:
                thread_number = int(parts[0])
            except (ValueError, IndexError):
                continue  # unknow line type, ignore it
            _extract_frame_info(parts, json_dump)
    try:
        json_dump.thread_count = len(json_dump.threads)
    except KeyError:  # no threads were over found, 'threads' key was not made
        json_dump.thread_count = 0
    if crashing_thread is not None:
        crashing_thread_frames = DotDict()
        crashing_thread_frames.threads_index = crashing_thread
        crashing_thread_frames.total_frames = \
            len(json_dump.threads[crashing_thread].frames)
        crashing_thread_frames.frames = \
            json_dump.threads[crashing_thread].frames[:10]
        json_dump.crashing_thread = crashing_thread_frames
    return json_dump
def pipe_dump_to_json_dump(pipe_dump_iterable):
    """given a list (or any iterable) of strings representing a MDSW pipe dump,
    this function will convert it into a json format."""
    json_dump = DotDict()
    crashing_thread = None
    module_counter = 0
    thread_counter = 0
    for a_line in pipe_dump_iterable:
        parts = a_line.split('|')
        if parts[0] == 'OS':
            _extract_OS_info(parts, json_dump)
        elif parts[0] == 'CPU':
            _extract_CPU_info(parts, json_dump)
        elif parts[0] == 'Crash':
            crashing_thread = _extract_crash_info(parts, json_dump)
        elif parts[0] == 'Module':
            _extract_module_info(parts, json_dump, module_counter)
            module_counter += 1
        else:
            try:
                thread_number = int(parts[0])
            except (ValueError, IndexError):
                continue  # unknow line type, ignore it
            _extract_frame_info(parts, json_dump)
    try:
        json_dump.thread_count = len(json_dump.threads)
    except KeyError:  # no threads were over found, 'threads' key was not made
        json_dump.thread_count = 0
    if crashing_thread is not None:
        crashing_thread_frames = DotDict()
        crashing_thread_frames.threads_index = crashing_thread
        crashing_thread_frames.total_frames = \
            len(json_dump.threads[crashing_thread].frames)
        crashing_thread_frames.frames = \
            json_dump.threads[crashing_thread].frames[:10]
        json_dump.crashing_thread = crashing_thread_frames
    return json_dump