equal
deleted
inserted
replaced
6 |
6 |
7 package isabelle |
7 package isabelle |
8 |
8 |
9 |
9 |
10 import java.io.{ByteArrayInputStream, ByteArrayOutputStream, FileInputStream, FileOutputStream, |
10 import java.io.{ByteArrayInputStream, ByteArrayOutputStream, FileInputStream, FileOutputStream, |
11 InputStream, OutputStream, File => JFile} |
11 InputStreamReader, InputStream, OutputStream, File => JFile} |
12 import java.nio.ByteBuffer |
12 import java.nio.ByteBuffer |
13 import java.nio.charset.StandardCharsets.ISO_8859_1 |
13 import java.nio.charset.StandardCharsets.ISO_8859_1 |
14 import java.nio.channels.FileChannel |
14 import java.nio.channels.FileChannel |
15 import java.nio.file.StandardOpenOption |
15 import java.nio.file.StandardOpenOption |
16 import java.util.Arrays |
16 import java.util.Arrays |
23 |
23 |
24 object Bytes { |
24 object Bytes { |
25 /* internal sizes */ |
25 /* internal sizes */ |
26 |
26 |
27 private val array_size: Long = Int.MaxValue - 8 // see java.io.InputStream.MAX_BUFFER_SIZE |
27 private val array_size: Long = Int.MaxValue - 8 // see java.io.InputStream.MAX_BUFFER_SIZE |
|
28 private val string_size: Long = Int.MaxValue / 2 |
28 private val block_size: Int = 16384 // see java.io.InputStream.DEFAULT_BUFFER_SIZE |
29 private val block_size: Int = 16384 // see java.io.InputStream.DEFAULT_BUFFER_SIZE |
29 private val chunk_size: Long = Space.MiB(100).bytes |
30 private val chunk_size: Long = Space.MiB(100).bytes |
30 |
31 |
31 private def make_size(chunks: Array[Array[Byte]], buffer: Array[Byte]): Long = |
32 private def make_size(chunks: Array[Array[Byte]], buffer: Array[Byte]): Long = |
32 chunks.foldLeft(buffer.length.toLong)((n, chunk) => n + chunk.length) |
33 chunks.foldLeft(buffer.length.toLong)((n, chunk) => n + chunk.length) |
481 val buf = new ByteArrayOutputStream(small_size) |
482 val buf = new ByteArrayOutputStream(small_size) |
482 for (a <- subarray_iterator) { buf.write(a.array, a.offset, a.length) } |
483 for (a <- subarray_iterator) { buf.write(a.array, a.offset, a.length) } |
483 buf.toByteArray |
484 buf.toByteArray |
484 } |
485 } |
485 |
486 |
486 override def text: String = |
487 def text: String = |
487 if (is_empty) "" |
488 if (is_empty) "" |
488 else { |
489 else { |
489 var i = 0L |
490 val reader = new InputStreamReader(stream(), UTF8.charset) |
490 var utf8 = false |
491 val buf = new Array[Char]((size min Bytes.string_size).toInt + 1) |
491 while (i < size && !utf8) { |
492 var m = 0 |
492 if (byte_unchecked(i) < 0) { utf8 = true } |
493 var n = 0 |
493 i += 1 |
494 while (m >= 0 && n < buf.length) { |
494 } |
495 m = reader.read(buf, n, (buf.length - n) min Bytes.block_size) |
495 utf8 |
496 if (m > 0) { n += m } |
496 |
497 } |
497 if (utf8) UTF8.decode_permissive(bytes) |
498 require(m == -1, "Malformed UTF-8 string: overlong result") |
498 else new String(make_array, UTF8.charset) |
499 new String(buf, 0, n) |
499 } |
500 } |
500 |
501 |
501 def wellformed_text: Option[String] = |
502 def wellformed_text: Option[String] = |
502 try { |
503 try { |
503 val s = text |
504 val s = text |