summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2009-06-24 13:38:55 +0000
committerPaul Phillips <paulp@improving.org>2009-06-24 13:38:55 +0000
commit6ab1f0b7710af132401848bc25da9101a364093b (patch)
tree8b9c83f311b9ed4647f0e40448b723223a2fd7c0
parentec70057db55dd4f65a80e50fee085a5c62022a7a (diff)
downloadscala-6ab1f0b7710af132401848bc25da9101a364093b.tar.gz
scala-6ab1f0b7710af132401848bc25da9101a364093b.tar.bz2
scala-6ab1f0b7710af132401848bc25da9101a364093b.zip
Working my way toward a consistent interface fo...
Working my way toward a consistent interface for scala.io.Source. Now all the Source factory methods whose input is something Byte based rather than Char based require an implicit Codec, which will be Codec.default if no implicit is available. The idea is that if one uses the scala APIs, your desired encoding can be expressed as an implicit value and it will always be used; and that we (if so inclined) can change the default in one place.
-rw-r--r--src/library/scala/io/BufferedSource.scala2
-rw-r--r--src/library/scala/io/Codec.scala2
-rw-r--r--src/library/scala/io/Source.scala215
-rw-r--r--src/library/scala/xml/parsing/ConstructingParser.scala6
-rw-r--r--src/library/scala/xml/parsing/ExternalSources.scala2
-rw-r--r--src/library/scala/xml/persistent/CachedFileStorage.scala2
6 files changed, 55 insertions, 174 deletions
diff --git a/src/library/scala/io/BufferedSource.scala b/src/library/scala/io/BufferedSource.scala
index b6543688f8..a1dbe1306f 100644
--- a/src/library/scala/io/BufferedSource.scala
+++ b/src/library/scala/io/BufferedSource.scala
@@ -31,7 +31,7 @@ object BufferedSource
inputStream: InputStream,
bufferSize: Int = DefaultBufSize,
reset: () => Source = null
- )(implicit codec: Codec = defaultCodec) =
+ )(implicit codec: Codec = Codec.default) =
{
if (reset == null) new BufferedSource(inputStream, bufferSize, codec)
else {
diff --git a/src/library/scala/io/Codec.scala b/src/library/scala/io/Codec.scala
index 9ecf3f0b1b..a5e8deada9 100644
--- a/src/library/scala/io/Codec.scala
+++ b/src/library/scala/io/Codec.scala
@@ -16,6 +16,7 @@ import java.nio.charset.{ Charset, CharsetDecoder, CodingErrorAction }
*
*/
class Codec(charSet: Charset) {
+ def name = charSet.name
def decoder = charSet.newDecoder()
// by default we replace bad chars with the decoder's replacement value (e.g. "?")
@@ -25,6 +26,7 @@ class Codec(charSet: Charset) {
}
object Codec {
+ def default = apply(Charset.defaultCharset)
def apply(encoding: String): Codec = new Codec(Charset forName encoding)
def apply(charSet: Charset): Codec = new Codec(charSet)
def apply(decoder: CharsetDecoder): Codec = {
diff --git a/src/library/scala/io/Source.scala b/src/library/scala/io/Source.scala
index 756cb66e8b..bd0de4a584 100644
--- a/src/library/scala/io/Source.scala
+++ b/src/library/scala/io/Source.scala
@@ -12,125 +12,72 @@
package scala.io
-import java.io.{BufferedInputStream, File, FileInputStream, InputStream,
- PrintStream}
-import java.net.{URI, URL}
-import java.nio.{ByteBuffer, CharBuffer}
-import java.nio.charset.Charset
+import java.io.{ File, FileInputStream, InputStream, PrintStream }
+import java.net.{ URI, URL }
/** This object provides convenience methods to create an iterable
* representation of a source file.
*
- * @author Burak Emir
+ * @author Burak Emir, Paul Phillips
* @version 1.0, 19/08/2004
*/
-object Source
-{
+object Source {
val DefaultBufSize = 2048
val NoReset: () => Source = () => throw new UnsupportedOperationException()
- def defaultCodec = Codec(util.Properties.encodingString)
-
- /** Creates a <code>Source</code> instance from the given array of bytes,
- * with empty description.
- *
- * @param bytes ...
- * @return the created <code>Source</code> instance.
- */
- def fromBytes(bytes: Array[Byte]): Source =
- fromString(new String(bytes))
-
- /** Creates Source from array of bytes with given encoding, with
- * empty description.
- *
- * @param bytes ...
- * @param enc ...
- * @return ...
- */
- def fromBytes(bytes: Array[Byte], enc: String): Source =
- fromString(new String(bytes, enc))
+ def fromIterable(iterable: Iterable[Char]): Source = new Source {
+ def reset() = fromIterable(iterable)
+ val iter = iterable.iterator
+ }
/** Creates a <code>Source</code> instance from a single character.
*
* @param c ...
* @return the create <code>Source</code> instance.
*/
- def fromChar(c: Char): Source = {
- val it = Iterator.single(c)
- new Source {
- def reset() = fromChar(c)
- val iter = it
- }
- }
+ def fromChar(c: Char): Source = fromIterable(Array(c))
/** creates Source from array of characters, with empty description.
*
* @param chars ...
* @return ...
*/
- def fromChars(chars: Array[Char]): Source = {
- val it = chars.iterator
- new Source {
- def reset() = fromChars(chars)
- val iter = it
- }
- }
+ def fromChars(chars: Array[Char]): Source = fromIterable(chars)
/** creates Source from string, with empty description.
*
* @param s ...
* @return ...
*/
- def fromString(s: String): Source = {
- val it = s.iterator
- new Source {
- def reset() = fromString(s)
- val iter = it
- }
- }
+ def fromString(s: String): Source = fromIterable(s)
- /** creates Source from file with given name, setting its description to
- * filename.
+ /** Create a <code>Source</code> from array of bytes, with
+ * empty description.
+ *
+ * @param bytes ...
+ * @param enc ...
+ * @return the created <code>Source</code> instance.
*/
- def fromFile(name: String): Source =
- fromFile(name, util.Properties.encodingString)
+ def fromBytes(bytes: Array[Byte])(implicit codec: Codec = Codec.default): Source =
+ fromString(new String(bytes, codec.name))
- /** creates Source from file with given name, using given encoding, setting
+ /** creates Source from file with given name, setting
* its description to filename.
*/
- def fromFile(name: String, enc: String): Source =
- fromFile(new File(name), enc)
+ def fromFilename(name: String)(implicit codec: Codec = Codec.default): Source = fromFile(new File(name))
/** creates <code>Source</code> from file with given file: URI
*/
- def fromFile(uri: URI): Source =
- fromFile(uri, util.Properties.encodingString)
-
- /** creates Source from file with given file: URI
- */
- def fromFile(uri: URI, enc: String): Source =
- fromFile(new File(uri), enc)
-
- /** creates Source from file, using default character encoding, setting its
- * description to filename.
- */
- def fromFile(file: File): Source =
- fromFile(file, util.Properties.encodingString, Source.DefaultBufSize)
-
- /** same as fromFile(file, enc, Source.DefaultBufSize)
- */
- def fromFile(file: File, enc: String): Source =
- fromFile(file, enc, Source.DefaultBufSize)
+ def fromURI(uri: URI)(implicit codec: Codec = Codec.default): Source = fromFile(new File(uri))
/** Creates Source from <code>file</code>, using given character encoding,
* setting its description to filename. Input is buffered in a buffer of
* size <code>bufferSize</code>.
*/
- def fromFile(file: File, enc: String, bufferSize: Int): Source = {
- val inpStream = new FileInputStream(file)
- val size = if (bufferSize > 0) bufferSize else Source.DefaultBufSize
+ def fromFile(file: File, bufferSize: Int = DefaultBufSize)(implicit codec: Codec = Codec.default): Source = {
+ val inputStream = new FileInputStream(file)
setFileDescriptor(file,
- BufferedSource.fromInputStream(inpStream, size, () => fromFile(file, enc, size))(Codec(enc)))
+ BufferedSource.fromInputStream(inputStream, bufferSize, () => fromFile(file, bufferSize)(codec)))
}
/** This method sets the descr property of the given source to a string of the form "file:"+path
@@ -138,79 +85,20 @@ object Source
* @param s the source whose property we set
* @return s
*/
- private def setFileDescriptor(file: File, s: Source): Source = {
- s.descr = new StringBuilder("file:").append(file.getAbsolutePath()).toString();
- s
- }
-
- /**
- * @param s ...
- * @return ...
- */
- @deprecated("use fromURL(s, enc)")
- def fromURL(s: String): Source =
- fromURL(new URL(s))
-
- /** same as fromURL(new URL(s), enc)
- */
- def fromURL(s: String, enc:String): Source =
- fromURL(new URL(s), enc)
-
- /**
- * @param url the source URL
- * @return ...
- */
- @deprecated("use fromURL(url, enc)")
- def fromURL(url: URL): Source = {
- val it = new Iterator[Char] {
- var data: Int = _
- def hasNext = {data != -1}
- def next = {val x = data.asInstanceOf[Char]; data = bufIn.read(); x}
- val in = url.openStream()
- val bufIn = new BufferedInputStream(in)
- data = bufIn.read()
- }
- val s = new Source {
- def reset() = fromURL(url)
- val iter = it
- }
- s.descr = url.toString()
- s
+ private def setFileDescriptor(file: File, source: Source): Source = {
+ source.descr = "file:" + file.getAbsolutePath
+ source
}
/** same as fromInputStream(url.openStream(), enc)
*/
- def fromURL(url: URL, enc:String): Source =
- fromInputStream(url.openStream(), enc)
-
- /** reads data from <code>istream</code> into a byte array, and calls
- * <code>fromBytes</code> with given encoding <code>enc</code>.
- * If <code>maxlen</code> is given, reads not more bytes than <code>maxlen</code>;
- * if <code>maxlen</code> was not given, or <code>was &lt;= 0</code>, then
- * whole <code>istream</code> is read and closed afterwards.
- *
- * @param istream the input stream from which to read
- * @param enc the encoding to apply to the bytes
- * @param maxlen optionally, a positive int specifying maximum number of bytes to read
- */
- @deprecated
- def fromInputStream(istream: InputStream, enc: String, maxlen: Option[Int]): Source = {
- val limit = maxlen match { case Some(i) => i; case None => 0 }
- val bi = new BufferedInputStream(istream, DefaultBufSize)
- val bytes = new collection.mutable.ArrayBuffer[Byte]()
- var b = 0
- var i = 0
- while ( {b = bi.read; i += 1; b} != -1 && (limit <= 0 || i < limit)) {
- bytes += b.toByte;
- }
- if(limit <= 0) bi.close
- fromBytes(bytes.toArray, enc)
- }
+ def fromURL(url: URL)(implicit codec: Codec = Codec.default): Source =
+ fromInputStream(url.openStream())
/** same as BufferedSource.fromInputStream(is)
*/
- def fromInputStream(is: InputStream, codec: Codec = defaultCodec): Source =
- BufferedSource.fromInputStream(is, DefaultBufSize, () => fromInputStream(is, codec))(codec)
+ def fromInputStream(inputStream: InputStream)(implicit codec: Codec = Codec.default): Source =
+ BufferedSource.fromInputStream(inputStream, DefaultBufSize, () => fromInputStream(inputStream)(codec))
}
/** The class <code>Source</code> implements an iterable representation
@@ -332,22 +220,17 @@ abstract class Source extends Iterator[Char] {
ch
}
- /** Reports an error message to console.
- *
- * @param pos the source position (line/column)
- * @param msg the error message to report
- */
- def reportError(pos: Int, msg: String) {
- reportError(pos, msg, Console.out)
- }
-
/** Reports an error message to the output stream <code>out</code>.
*
* @param pos the source position (line/column)
* @param msg the error message to report
- * @param out ...
+ * @param out PrintStream to use (optional: defaults to <code>Console.err</code>)
*/
- def reportError(pos: Int, msg: String, out: PrintStream) {
+ def reportError(
+ pos: Int,
+ msg: String,
+ out: PrintStream = Console.err)
+ {
nerrors += 1
report(pos, msg, out)
}
@@ -355,7 +238,7 @@ abstract class Source extends Iterator[Char] {
/**
* @param pos the source position (line/column)
* @param msg the error message to report
- * @param out ...
+ * @param out PrintStream to use
*/
def report(pos: Int, msg: String, out: PrintStream) {
val buf = new StringBuilder
@@ -372,26 +255,20 @@ abstract class Source extends Iterator[Char] {
out.println(buf.toString)
}
- /** Reports a warning message to <code>Console.out</code>.
- *
- * @param pos the source position (line/column)
- * @param msg the warning message to report
- */
- def reportWarning(pos: Int, msg: String) {
- reportWarning(pos, msg, Console.out)
- }
-
/**
* @param pos the source position (line/column)
* @param msg the warning message to report
- * @param out ...
+ * @param out PrintStream to use (optional: defaults to <code>Console.out</code>)
*/
- def reportWarning(pos: Int, msg: String, out: PrintStream) {
+ def reportWarning(
+ pos: Int,
+ msg: String,
+ out: PrintStream = Console.out)
+ {
nwarnings += 1
report(pos, "warning! " + msg, out)
}
- /** the actual reset method */
+ /** The reset() method creates a fresh copy of this Source. */
def reset(): Source
-
}
diff --git a/src/library/scala/xml/parsing/ConstructingParser.scala b/src/library/scala/xml/parsing/ConstructingParser.scala
index a35c1c5f77..1a5119baf8 100644
--- a/src/library/scala/xml/parsing/ConstructingParser.scala
+++ b/src/library/scala/xml/parsing/ConstructingParser.scala
@@ -13,12 +13,14 @@ package scala.xml.parsing
import java.io.File
-import scala.io.Source
+import scala.io.{ Source, Codec }
object ConstructingParser {
def fromFile(inp: File, preserveWS: Boolean) = {
- val p = new ConstructingParser(Source.fromFile(inp), preserveWS)
+ // XXX why does the default implicit not work here when building locker,
+ // unless the empty parameter list is supplied?
+ val p = new ConstructingParser(Source.fromFile(inp)(), preserveWS)
p.nextch
p
}
diff --git a/src/library/scala/xml/parsing/ExternalSources.scala b/src/library/scala/xml/parsing/ExternalSources.scala
index 3289d3628d..4638f4de42 100644
--- a/src/library/scala/xml/parsing/ExternalSources.scala
+++ b/src/library/scala/xml/parsing/ExternalSources.scala
@@ -76,7 +76,7 @@ trait ExternalSources { self: ExternalSources with MarkupParser with MarkupHandl
} else
fileStr = fileStr.substring(0,
fileStr.lastIndexOf(java.io.File.separator)+1)
- Source.fromFile(fileStr + systemId)
+ Source.fromFilename(fileStr + systemId)()
}
}
diff --git a/src/library/scala/xml/persistent/CachedFileStorage.scala b/src/library/scala/xml/persistent/CachedFileStorage.scala
index 19d232deee..aa958b68ea 100644
--- a/src/library/scala/xml/persistent/CachedFileStorage.scala
+++ b/src/library/scala/xml/persistent/CachedFileStorage.scala
@@ -73,7 +73,7 @@ extends java.lang.Thread with scala.util.logging.Logged {
import scala.io.Source
import scala.xml.parsing.ConstructingParser
log("[load]\nloading "+theFile)
- val src = Source.fromFile( theFile )
+ val src = Source.fromFile(theFile)()
log("parsing "+theFile)
val res = ConstructingParser.fromSource(src,false).document.docElem(0)
switch