summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/library/scala/collection/Iterator.scala14
-rw-r--r--src/library/scala/io/Codec.scala39
-rw-r--r--src/library/scala/io/Source.scala16
-rw-r--r--test/files/neg/t1215.check2
4 files changed, 39 insertions, 32 deletions
diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala
index dabbc86cbc..9dad248462 100644
--- a/src/library/scala/collection/Iterator.scala
+++ b/src/library/scala/collection/Iterator.scala
@@ -102,24 +102,14 @@ object Iterator {
else empty.next()
}
- /** An iterator that repeatedly applies a given function to a start value.
- *
- * @param start the start value of the iterator
- * @param len the number of elements returned by the iterator
- * @param f the function that's repeatedly applied
- * @return the iterator returning `len` values in the sequence `start, f(start), f(f(start)), ...`
- */
- @deprecated("Use `iterate(start)(f) take len' instead")
- def iterate[T](start: T, len: Int)(f: T => T): Iterator[T] = iterate(start)(f) take len
-
- /** An infinite iterator that repeatedly applies a given function to a start value.
+ /** An infinite iterator that repeatedly applies a given function to the previous result.
*
* @param start the start value of the iterator
* @param f the function that's repeatedly applied
* @return the iterator returning the infinite sequence of values `start, f(start), f(f(start)), ...`
*/
def iterate[T](start: T)(f: T => T): Iterator[T] = new Iterator[T] {
- private var acc = start
+ private[this] var acc = start
def hasNext: Boolean = true
def next(): T = { val res = acc ; acc = f(acc) ; res }
}
diff --git a/src/library/scala/io/Codec.scala b/src/library/scala/io/Codec.scala
index 9c5d79d95b..a9483077a2 100644
--- a/src/library/scala/io/Codec.scala
+++ b/src/library/scala/io/Codec.scala
@@ -29,47 +29,52 @@ import java.nio.charset.{ Charset, CharsetDecoder, CharsetEncoder, CharacterCodi
class Codec(val charSet: Charset)
{
type Configure[T] = (T => T, Boolean)
+ type Handler = CharacterCodingException => Int
- type Handler = CharacterCodingException => Int
- private[this] var _onMalformedInput: Action = null
- private[this] var _onUnmappableCharacter: Action = null
- // private[this] var _replacement: Array[Byte] = null
+ // these variables allow configuring the Codec object, and then
+ // all decoders and encoders retrieved from it will use these settings.
+ private[this] var _onMalformedInput: Action = null
+ private[this] var _onUnmappableCharacter: Action = null
+ private[this] var _encodingReplacement: Array[Byte] = null
+ private[this] var _decodingReplacement: String = null
+ private[this] var _onCodingException: Handler = e => throw e
- private[this] var _onCodingException: Handler = e => throw e
+ // these methods can be chained to configure the variables above
+ def onMalformedInput(newAction: Action): this.type = { _onMalformedInput = newAction ; this }
+ def onUnmappableCharacter(newAction: Action): this.type = { _onUnmappableCharacter = newAction ; this }
+ def decodingReplaceWith(newReplacement: String): this.type = { _decodingReplacement = newReplacement ; this }
+ def encodingReplaceWith(newReplacement: Array[Byte]): this.type = { _encodingReplacement = newReplacement ; this }
+ def onCodingException(handler: Handler): this.type = { _onCodingException = handler ; this }
def name = charSet.name
def encoder =
applyFunctions[CharsetEncoder](charSet.newEncoder(),
(_ onMalformedInput _onMalformedInput, _onMalformedInput != null),
- (_ onUnmappableCharacter _onUnmappableCharacter, _onUnmappableCharacter != null)
- // (_ replaceWith _replacement, _replacement != null)
+ (_ onUnmappableCharacter _onUnmappableCharacter, _onUnmappableCharacter != null),
+ (_ replaceWith _encodingReplacement, _encodingReplacement != null)
)
def decoder =
applyFunctions[CharsetDecoder](charSet.newDecoder(),
(_ onMalformedInput _onMalformedInput, _onMalformedInput != null),
- (_ onUnmappableCharacter _onUnmappableCharacter, _onUnmappableCharacter != null)
- // (_ replaceWith _replacement, _replacement != null)
+ (_ onUnmappableCharacter _onUnmappableCharacter, _onUnmappableCharacter != null),
+ (_ replaceWith _decodingReplacement, _decodingReplacement != null)
)
def wrap(body: => Int): Int =
try body catch { case e: CharacterCodingException => _onCodingException(e) }
- // by default we ignore bad characters.
- // this behavior can be altered by overriding these two methods
- def onMalformedInput(newAction: Action): this.type = { _onMalformedInput = newAction ; this }
- def onUnmappableCharacter(newAction: Action): this.type = { _onUnmappableCharacter = newAction ; this }
- // def replaceWith(newReplacement: String): this.type = { _replacement = newReplacement ; this }
- def onCodingException(handler: Handler): this.type = { _onCodingException = handler ; this }
-
// call a series of side effecting methods on an object, finally returning the object
- def applyFunctions[T](x: T, fs: Configure[T]*) =
+ private def applyFunctions[T](x: T, fs: Configure[T]*) =
fs.foldLeft(x)((x, pair) => pair match {
case (f, cond) => if (cond) f(x) else x
})
}
object Codec {
+ final val ISO8859 = Charset forName "ISO-8859-1"
+ final val UTF8 = Charset forName "UTF-8"
+
def default = apply(Charset.defaultCharset)
def apply(encoding: String): Codec = new Codec(Charset forName encoding)
def apply(charSet: Charset): Codec = new Codec(charSet)
diff --git a/src/library/scala/io/Source.scala b/src/library/scala/io/Source.scala
index 98c373bdeb..e7bf43d00d 100644
--- a/src/library/scala/io/Source.scala
+++ b/src/library/scala/io/Source.scala
@@ -57,8 +57,8 @@ object Source {
*/
def fromString(s: String): Source = fromIterable(s)
- /** Create a <code>Source</code> from array of bytes, with
- * empty description.
+ /** Create a <code>Source</code> from array of bytes, decoding
+ * the bytes according to codec.
*
* @param bytes ...
* @param enc ...
@@ -67,6 +67,11 @@ object Source {
def fromBytes(bytes: Array[Byte])(implicit codec: Codec = Codec.default): Source =
fromString(new String(bytes, codec.name))
+ /** Create a <code>Source</code> from array of bytes, assuming
+ * one byte per character (ISO-8859-1 encoding.)
+ */
+ def fromRawBytes(bytes: Array[Byte]): Source = fromString(new String(bytes, Codec.ISO8859.name))
+
/** creates Source from file with given name, setting
* its description to filename.
*/
@@ -120,6 +125,13 @@ object Source {
}
}
+// Coming Soon?
+//
+// abstract class Source2[T] extends Iterable[T] { }
+//
+// abstract class ByteSource() extends Source2[Byte] { }
+//
+// abstract class CharSource(implicit codec: Codec = Codec.default) extends Source2[Char] { }
/** The class <code>Source</code> implements an iterable representation
* of source data. Calling method <code>reset</code> returns an identical,
diff --git a/test/files/neg/t1215.check b/test/files/neg/t1215.check
index 1f9dd6bf38..77a9304b48 100644
--- a/test/files/neg/t1215.check
+++ b/test/files/neg/t1215.check
@@ -1,4 +1,4 @@
t1215.scala:2: error: value += is not a member of Int
val x = 1 += 1
- ^
+ ^
one error found