text: """
  Support for "biological sequence" files.
  
  :Author: Bob Harris (rsharris@bx.psu.edu)
  
  See seq.py for more information
  """
  
  import struct
  
  from . import fasta, nib, qdna
  
  # DNA reverse complement table
  
  DNA_COMP = "                                             -                  " \
             " TVGH  CD  M KN   YSA BWXR       tvgh  cd  m kn   ysa bwxr      " \
             "                                                                " \
             "                                                                "
  
  
  def reverse_complement(text):
      return text.translate(DNA_COMP)[::-1]
  
  
  def seq_file(file, format=None, revcomp=False, name="", gap=None, contig=None):
      if (format is None):
          format = infer_format(file)
      if (contig is not None) and (format not in ["fasta", None]):
          raise ValueError("Contigs are not supported for format %s" % format)
      if (format == "fasta"):
          return fasta.FastaFile(file, revcomp=revcomp, name=name, gap=gap, contig=contig)
      elif (format == "nib"):
          return nib.NibFile(file, revcomp=revcomp, name=name, gap=gap)
      elif (format == "qdna"):
          return qdna.QdnaFile(file, revcomp=revcomp, name=name, gap=gap)
      else:
          if (format is None):
              format = ""
          else:
              format = " " + format
          raise ValueError(f"Unknown sequence format{format} in {file.name}")
  
  
  def seq_reader(file, format=None, revcomp=False, name="", gap=None):
      if (format is None):
          format = infer_format(file)
      if (format == "fasta"):
          return fasta.FastaReader(file, revcomp=revcomp, name=name, gap=gap)
      elif (format == "nib"):
          return nib.NibReader(file, revcomp=revcomp, name=name, gap=gap)
      elif (format == "qdna"):
          return qdna.QdnaReader(file, revcomp=revcomp, name=name, gap=gap)
      else:
          raise ValueError("Unknown sequence format %s" % format)
  
  
  def seq_writer(outfile, format=None, name=""):
      if (format == "fasta"):
          return fasta.FastaWriter(outfile)
      elif (format == "nib"):
          return nib.NibWriter(outfile)
      elif (format == "qdna"):
          return qdna.QdnaWriter(outfile)
      else:
          raise ValueError("Unknown sequence format %s" % format)
  
  
  def infer_format(file):
      format = None
      magic = struct.unpack(">L", file.read(4))[0]
      if (magic == nib.NIB_MAGIC_NUMBER) or (magic == nib.NIB_MAGIC_NUMBER_SWAP):
          format = "nib"
      elif (magic == qdna.qdnaMagic) or (magic == qdna.qdnaMagicSwap):
          format = "qdna"
      else:
          file.seek(0)
          if (file.read(1) == b">"):
              format = "fasta"
      file.seek(0)
      return format
  