@@ -2,34 +2,34 @@ package dotty.tools.dotc.core.tasty
2
2
3
3
import scala .runtime .quoted .Unpickler .Pickled
4
4
5
+ import java .io ._
6
+ import java .util .Base64
7
+ import java .nio .charset .StandardCharsets .UTF_8
8
+
5
9
/** Utils for String representation of TASTY */
6
10
object TastyString {
7
11
8
- // Conservative encoding, each byte is encoded in a char
9
- // TODO improve encoding compression
10
- private final val maxStringSize = 65535 / 2
12
+ // Max size of a string literal in the bytecode
13
+ private final val maxStringSize = 65535
11
14
12
15
/** Encode TASTY bytes into an Seq of String */
13
- def pickle (bytes : Array [Byte ]): Pickled =
14
- bytes.sliding(maxStringSize, maxStringSize).map(bytesToString).toList
15
-
16
- /** Decode the TASTY String into TASTY bytes */
17
- def unpickle (strings : Pickled ): Array [Byte ] = {
18
- val bytes = new Array [Byte ](strings.map(_.length).sum)
19
- var i = 0
20
- for (str <- strings; j <- str.indices) {
21
- bytes(i) = str.charAt(j).toByte
22
- i += 1
16
+ def pickle (bytes : Array [Byte ]): Pickled = {
17
+ val str = new String (Base64 .getEncoder().encode(bytes), UTF_8 )
18
+ def split (sliceEnd : Int , acc : List [String ]): List [String ] = {
19
+ if (sliceEnd == 0 ) acc
20
+ else {
21
+ val sliceStart = (sliceEnd - maxStringSize) max 0
22
+ split(sliceStart, str.substring(sliceStart, sliceEnd) :: acc)
23
+ }
23
24
}
24
- bytes
25
+ split(str.length, Nil )
25
26
}
26
27
27
- /** Encode bytes into a String */
28
- private def bytesToString (bytes : Array [Byte ]): String = {
29
- assert(bytes.length <= maxStringSize)
30
- val chars = new Array [Char ](bytes.length)
31
- for (i <- bytes.indices) chars(i) = (bytes(i) & 0xff ).toChar
32
- new String (chars)
28
+ /** Decode the TASTY String into TASTY bytes */
29
+ def unpickle (strings : Pickled ): Array [Byte ] = {
30
+ val string = new StringBuilder
31
+ strings.foreach(string.append)
32
+ Base64 .getDecoder().decode(string.result().getBytes(UTF_8 ))
33
33
}
34
34
35
35
}
0 commit comments