text: #!/usr/local/bin/python3
  
  # contributor license agreements.  See the NOTICE file distributed with
  # this work for additional information regarding copyright ownership.
  # The ASF licenses this file to You under the Apache License, Version 2.0
  # (the "License"); you may not use this file except in compliance with
  # the License.  You may obtain a copy of the License at
  #
  #      http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  import json
  import queue
  import os
  import re
  import sys
  import threading
  import traceback
  
  
  from modified_utf8 import utf8m_to_utf8s
  from numeric_conversion import to_hex_digit
  import command_line
  
  from ds_codes import ds_codes
  from connection_types import ConnectionTypes, ConnectionTypeStrings
  from read_values import (
      read_number_from_hex_string,
      read_byte_value,
      read_number_from_hex_string,
      read_short_value,
      read_number_from_hex_string,
      read_int_value,
      read_long_value,
      read_string_value,
      read_jmutf8_string_value,
      read_number_from_hex_string,
      call_reader_function,
  )
  from client_message_decoder import ClientMessageDecoder
  from server_message_decoder import ServerMessageDecoder
  from handshake_decoder import HandshakeDecoder
  
  
  def scan_opened_file(
      file,
      handshake_decoder,
      client_decoder,
      server_decoder,
      output_queue,
      dump_handshake,
      dump_messages,
      thread_id,
      start_string,
  ):
      separator = start_string
      if dump_handshake:
          handshake_decoder = HandshakeDecoder(output_queue)
          for line in file:
              handshake_decoder.process_line(line.decode("utf-8"))
              try:
                  data = output_queue.get_nowait()
                  for key, value in data.items():
                      if key == "handshake":
                          print(separator + json.dumps(value, indent=2, default=str))
                          separator = ","
              except queue.Empty:
                  continue
  
      separator = start_string
      for line in file:
          linestr = line.decode("utf-8")
          client_decoder.process_line(linestr)
          server_decoder.process_line(linestr)
          try:
              data = output_queue.get_nowait()
              for key, value in data.items():
                  if key == "message" and dump_messages:
                      if thread_id:
                          if "tid" in value.keys() and value["tid"] == thread_id:
                              print(separator + json.dumps(value, indent=2, default=str))
                              separator = ","
                      else:
                          print(separator + json.dumps(value, indent=2, default=str))
                          separator = ","
  
          except queue.Empty:
              continue
          except:
              traceback.print_exc()
              continue
  
      while True:
          try:
              data = output_queue.get_nowait()
              for key, value in data.items():
                  if key == "message" and dump_messages:
                      print(separator + json.dumps(data, indent=2, default=str))
                      separator = ","
          except queue.Empty:
              break
  
  
  def scan_file(filename, dump_handshake, dump_messages, thread_id):
      print("[")
  
      output_queue = queue.Queue()
  
      f = open(filename, "rb")
      print("Scanning " + filename, file=sys.stderr)
      scan_opened_file(
          f,
          HandshakeDecoder(output_queue),
          ClientMessageDecoder(output_queue),
          ServerMessageDecoder(output_queue),
          output_queue,
          dump_handshake,
          dump_messages,
          thread_id,
          "",
      )
      f.close()
  
      print("]")
  
  
  def scan_file_sequence(file, handshake, messages, thread_id):
      dirname = os.path.dirname(file)
      basename, ext = os.path.splitext(os.path.basename(file))
  
      base_parts = basename.split("-")
      if len(base_parts) == 2:
          print("[")
  
          root = base_parts[0]
          roll_index = int(base_parts[1])
  
          output_queue = queue.Queue()
          handshake_decoder = HandshakeDecoder(output_queue)
          client_decoder = ClientMessageDecoder(output_queue)
          server_decoder = ServerMessageDecoder(output_queue)
          start_string = ""
          last_chance = False
  
          while True:
              if last_chance:
                  filename = dirname + os.sep + root + ext
              else:
                  filename = dirname + os.sep + root + "-" + str(roll_index) + ext
  
              try:
                  f = open(filename, "rb")
                  print("Scanning " + filename, file=sys.stderr)
                  scan_opened_file(
                      f,
                      handshake_decoder,
                      client_decoder,
                      server_decoder,
                      output_queue,
                      handshake,
                      messages,
                      thread_id,
                      start_string,
                  )
                  start_string = ","
                  f.close()
                  roll_index += 1
                  if last_chance:
                      break
              except FileNotFoundError:
                  last_chance = True
                  continue
  
          print("]")
  
      else:
          raise ValueError(basename + " is not a valid rolled logfile name")
  
  
  if __name__ == "__main__":
      (file, handshake, messages, thread_id, rolled) = command_line.parse_command_line()
  
      if rolled:
          scan_file_sequence(file, handshake, messages, thread_id)
      else:
          scan_file(file, handshake, messages, thread_id)
  