Skip to content

Commit b3f33f9

Browse files
committed
inline some functions used in parsing
scalafmt
1 parent a6b03ea commit b3f33f9

File tree

6 files changed

+146
-34
lines changed

6 files changed

+146
-34
lines changed

http-core/src/main/scala/org/apache/pekko/http/impl/engine/parsing/package.scala renamed to http-core/src/main/scala-2.13/org/apache/pekko/http/impl/engine/package.scala

Lines changed: 8 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@
1414
package org.apache.pekko.http.impl.engine
1515

1616
import java.lang.{ StringBuilder => JStringBuilder }
17+
1718
import org.apache.pekko
19+
import pekko.event.LoggingAdapter
20+
import pekko.http.scaladsl.model.ErrorInfo
1821
import pekko.http.scaladsl.settings.ParserSettings
22+
import pekko.util.ByteString
1923

2024
import scala.annotation.tailrec
21-
import pekko.event.LoggingAdapter
22-
import pekko.util.ByteString
23-
import pekko.http.scaladsl.model.{ ErrorInfo, StatusCode, StatusCodes }
24-
import pekko.http.impl.util.SingletonException
2525

2626
/**
2727
* INTERNAL API
@@ -36,17 +36,21 @@ package object parsing {
3636
case x => x.toString
3737
}
3838

39+
@inline
3940
private[http] def byteChar(input: ByteString, ix: Int): Char = (byteAt(input, ix) & 0xFF).toChar
4041

42+
@inline
4143
private[http] def byteAt(input: ByteString, ix: Int): Byte =
4244
if (ix < input.length) input(ix) else throw NotEnoughDataException
4345

46+
@inline
4447
private[http] def asciiString(input: ByteString, start: Int, end: Int): String = {
4548
@tailrec def build(ix: Int = start, sb: JStringBuilder = new JStringBuilder(end - start)): String =
4649
if (ix == end) sb.toString else build(ix + 1, sb.append(input(ix).toChar))
4750
if (start == end) "" else build()
4851
}
4952

53+
@inline
5054
private[http] def logParsingError(info: ErrorInfo, log: LoggingAdapter,
5155
settings: ParserSettings.ErrorLoggingVerbosity,
5256
ignoreHeaderNames: Set[String] = Set.empty): Unit =
@@ -60,29 +64,3 @@ package object parsing {
6064
log.warning(info.formatPretty)
6165
}
6266
}
63-
64-
package parsing {
65-
66-
import pekko.annotation.InternalApi
67-
68-
/**
69-
* INTERNAL API
70-
*/
71-
@InternalApi
72-
private[parsing] class ParsingException(
73-
val status: StatusCode,
74-
val info: ErrorInfo) extends RuntimeException(info.formatPretty) {
75-
def this(status: StatusCode, summary: String) =
76-
this(status, ErrorInfo(if (summary.isEmpty) status.defaultMessage else summary))
77-
def this(summary: String) =
78-
this(StatusCodes.BadRequest, ErrorInfo(summary))
79-
def this(summary: String, detail: String) =
80-
this(StatusCodes.BadRequest, ErrorInfo(summary, detail))
81-
}
82-
83-
/**
84-
* INTERNAL API
85-
*/
86-
@InternalApi
87-
private[parsing] object NotEnoughDataException extends SingletonException
88-
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* license agreements; and to You under the Apache License, version 2.0:
4+
*
5+
* https://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* This file is part of the Apache Pekko project, which was derived from Akka.
8+
*/
9+
10+
/*
11+
* Copyright (C) 2009-2022 Lightbend Inc. <https://www.lightbend.com>
12+
*/
13+
14+
package org.apache.pekko.http.impl.util
15+
16+
import org.apache.pekko
17+
import pekko.annotation.InternalApi
18+
19+
@InternalApi
20+
private[http] object CharUtils {
21+
22+
/**
23+
* Internal Pekko HTTP Use only.
24+
*
25+
* Efficiently lower-cases the given character.
26+
* Note: only works for 7-bit ASCII letters (which is enough for header names)
27+
*/
28+
@inline def toLowerCase(c: Char): Char =
29+
if (c >= 'A' && c <= 'Z') (c + 0x20 /* - 'A' + 'a' */ ).toChar else c
30+
31+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* license agreements; and to You under the Apache License, version 2.0:
4+
*
5+
* https://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* This file is part of the Apache Pekko project, which was derived from Akka.
8+
*/
9+
10+
/*
11+
* Copyright (C) 2009-2022 Lightbend Inc. <https://www.lightbend.com>
12+
*/
13+
14+
package org.apache.pekko.http.impl.engine
15+
16+
import java.lang.{ StringBuilder => JStringBuilder }
17+
18+
import org.apache.pekko
19+
import pekko.event.LoggingAdapter
20+
import pekko.http.scaladsl.model.ErrorInfo
21+
import pekko.http.scaladsl.settings.ParserSettings
22+
import pekko.util.ByteString
23+
24+
import scala.annotation.tailrec
25+
26+
/**
27+
* INTERNAL API
28+
*/
29+
package object parsing {
30+
31+
private[http] inline def escape(c: Char): String = c match {
32+
case '\t' => "\\t"
33+
case '\r' => "\\r"
34+
case '\n' => "\\n"
35+
case x if Character.isISOControl(x) => "\\u%04x".format(c.toInt)
36+
case x => x.toString
37+
}
38+
39+
private[http] inline def byteChar(input: ByteString, ix: Int): Char = (byteAt(input, ix) & 0xFF).toChar
40+
41+
private[http] inline def byteAt(input: ByteString, ix: Int): Byte =
42+
if (ix < input.length) input(ix) else throw NotEnoughDataException
43+
44+
private[http] inline def asciiString(input: ByteString, start: Int, end: Int): String = {
45+
@tailrec def build(ix: Int = start, sb: JStringBuilder = new JStringBuilder(end - start)): String =
46+
if (ix == end) sb.toString else build(ix + 1, sb.append(input(ix).toChar))
47+
if (start == end) "" else build()
48+
}
49+
50+
private[http] inline def logParsingError(info: ErrorInfo, log: LoggingAdapter,
51+
settings: ParserSettings.ErrorLoggingVerbosity,
52+
ignoreHeaderNames: Set[String] = Set.empty): Unit =
53+
settings match {
54+
case ParserSettings.ErrorLoggingVerbosity.Off => // nothing to do
55+
case ParserSettings.ErrorLoggingVerbosity.Simple =>
56+
if (!ignoreHeaderNames.contains(info.errorHeaderName))
57+
log.warning(info.summary)
58+
case ParserSettings.ErrorLoggingVerbosity.Full =>
59+
if (!ignoreHeaderNames.contains(info.errorHeaderName))
60+
log.warning(info.formatPretty)
61+
}
62+
}

http-core/src/main/scala/org/apache/pekko/http/impl/util/CharUtils.scala renamed to http-core/src/main/scala-3/org/apache/pekko/http/impl/util/CharUtils.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ private[http] object CharUtils {
2525
* Efficiently lower-cases the given character.
2626
* Note: only works for 7-bit ASCII letters (which is enough for header names)
2727
*/
28-
final def toLowerCase(c: Char): Char =
28+
inline def toLowerCase(c: Char): Char =
2929
if (c >= 'A' && c <= 'Z') (c + 0x20 /* - 'A' + 'a' */ ).toChar else c
3030

3131
}

http-core/src/main/scala/org/apache/pekko/http/impl/engine/parsing/HttpHeaderParser.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -242,8 +242,8 @@ private[engine] final class HttpHeaderParser private (
242242
private def insert(input: ByteString, value: AnyRef)(cursor: Int = 0, endIx: Int = input.length, nodeIx: Int = 0,
243243
colonIx: Int = 0): Unit = {
244244
val char =
245-
if (cursor < colonIx) toLowerCase((input(cursor) & 0xFF).toChar)
246-
else if (cursor < endIx) (input(cursor) & 0xFF).toChar
245+
if (cursor < colonIx) toLowerCase(byteChar(input, cursor))
246+
else if (cursor < endIx) byteChar(input, cursor)
247247
else '\u0000'
248248
val node = nodes(nodeIx)
249249
if (char == node) insert(input, value)(cursor + 1, endIx, nodeIx + 1, colonIx) // fast match, descend into only subnode
@@ -290,7 +290,7 @@ private[engine] final class HttpHeaderParser private (
290290
endIx: Int = input.length, valueIx: Int = newValueIndex, colonIx: Int = 0): Unit = {
291291
val newNodeIx = newNodeIndex
292292
if (cursor < endIx) {
293-
val c = (input(cursor) & 0xFF).toChar
293+
val c = byteChar(input, cursor)
294294
val char = if (cursor < colonIx) toLowerCase(c) else c
295295
nodes(newNodeIx) = char
296296
insertRemainingCharsAsNewNodes(input, value)(cursor + 1, endIx, valueIx, colonIx)
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* license agreements; and to You under the Apache License, version 2.0:
4+
*
5+
* https://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* This file is part of the Apache Pekko project, which was derived from Akka.
8+
*/
9+
10+
/*
11+
* Copyright (C) 2009-2022 Lightbend Inc. <https://www.lightbend.com>
12+
*/
13+
14+
package org.apache.pekko.http.impl.engine
15+
package parsing
16+
17+
import org.apache.pekko
18+
import pekko.annotation.InternalApi
19+
import pekko.http.impl.util.SingletonException
20+
import pekko.http.scaladsl.model.{ ErrorInfo, StatusCode, StatusCodes }
21+
22+
/**
23+
* INTERNAL API
24+
*/
25+
@InternalApi
26+
private[parsing] class ParsingException(
27+
val status: StatusCode,
28+
val info: ErrorInfo) extends RuntimeException(info.formatPretty) {
29+
def this(status: StatusCode, summary: String) =
30+
this(status, ErrorInfo(if (summary.isEmpty) status.defaultMessage else summary))
31+
def this(summary: String) =
32+
this(StatusCodes.BadRequest, ErrorInfo(summary))
33+
def this(summary: String, detail: String) =
34+
this(StatusCodes.BadRequest, ErrorInfo(summary, detail))
35+
}
36+
37+
/**
38+
* INTERNAL API
39+
*/
40+
@InternalApi
41+
private[parsing] object NotEnoughDataException extends SingletonException

0 commit comments

Comments
 (0)