def createShallowCopy()

in http-core/src/main/scala/org/apache/pekko/http/impl/engine/parsing/HttpHeaderParser.scala [109:165]


  def createShallowCopy(): HttpHeaderParser =
    new HttpHeaderParser(settings, log, onIllegalHeader, nodes, nodeCount, branchData, branchDataCount, values,
      valueCount)

  /**
   * Parses a header line and returns the line start index of the subsequent line.
   * The parsed header instance is written to the `resultHeader` member.
   * If the trie still has space for this type of header (and as a whole) the parsed header is cached.
   * Throws a `NotEnoughDataException` if the given input doesn't contain enough data to fully parse the given header
   * line. Note that there must be at least one byte available after a CRLF sequence, in order to distinguish a true
   * line ending from a line fold.
   * If the header is invalid a respective `ParsingException` is thrown.
   */
  @tailrec
  def parseHeaderLine(input: ByteString, lineStart: Int = 0)(cursor: Int = lineStart, nodeIx: Int = 0): Int = {
    def startValueBranch(rootValueIx: Int, valueParser: HeaderValueParser) = {
      val (header, endIx) = valueParser(this, input, cursor, onIllegalHeader)
      if (valueParser.cachingEnabled)
        try {
          val valueIx = newValueIndex // compute early in order to trigger OutOfTrieSpaceExceptions before any change
          unshareIfRequired()
          val nodeIx = nodeCount
          insertRemainingCharsAsNewNodes(input, header)(cursor, endIx, valueIx)
          values(rootValueIx) = ValueBranch(rootValueIx, valueParser, branchRootNodeIx = nodeIx, valueCount = 1)
        } catch {
          case OutOfTrieSpaceException => // if we cannot insert a value then we simply don't
        }
      resultHeader = header
      endIx
    }
    val node = nodes(nodeIx)
    node & 0xFF match {
      case 0 => // leaf node (or intermediate ValueBranch pointer)
        val valueIx = (node >>> 8) - 1
        values(valueIx) match {
          case branch: ValueBranch            => parseHeaderValue(input, cursor, branch)()
          case valueParser: HeaderValueParser => startValueBranch(valueIx, valueParser) // no header yet of this type
          case EmptyHeader                    => resultHeader = EmptyHeader; cursor
        }
      case nodeChar =>
        val char = toLowerCase(byteChar(input, cursor))
        if (char == node) // fast match, advance and descend
          parseHeaderLine(input, lineStart)(cursor + 1, nodeIx + 1)
        else node >>> 8 match {
          case 0 => // header doesn't exist yet and has no model (since we have not yet seen a colon)
            parseRawHeader(input, lineStart, cursor, nodeIx)
          case msb => // branching node
            val signum = math.signum(char - nodeChar)
            branchData(rowIx(msb) + 1 + signum) match {
              case 0 => // header doesn't exist yet and has no model (otherwise we'd arrive at a value)
                parseRawHeader(input, lineStart, cursor, nodeIx)
              case subNodeIx => // descend into branch and advance on char matches (otherwise descend but don't advance)
                parseHeaderLine(input, lineStart)(cursor + 1 - math.abs(signum), subNodeIx)
            }
        }
    }
  }