diff options
-rw-r--r-- | src/library/scala/collection/Iterator.scala | 14 | ||||
-rw-r--r-- | src/library/scala/io/Codec.scala | 39 | ||||
-rw-r--r-- | src/library/scala/io/Source.scala | 16 | ||||
-rw-r--r-- | test/files/neg/t1215.check | 2 |
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 |