diff options
author | michelou <michelou@epfl.ch> | 2008-02-06 10:43:23 +0000 |
---|---|---|
committer | michelou <michelou@epfl.ch> | 2008-02-06 10:43:23 +0000 |
commit | df55a8175a90180194c61f91592a5e34b0bcf2e5 (patch) | |
tree | 39e75364a900c39b2f0d16389aea763e6ec4519f /src/dotnet-library | |
parent | 09f0838d0799149c0545970d68b3c052a7827aef (diff) | |
download | scala-df55a8175a90180194c61f91592a5e34b0bcf2e5.tar.gz scala-df55a8175a90180194c61f91592a5e34b0bcf2e5.tar.bz2 scala-df55a8175a90180194c61f91592a5e34b0bcf2e5.zip |
switched to Scala implementation of StringBuilder
Diffstat (limited to 'src/dotnet-library')
-rw-r--r-- | src/dotnet-library/scala/Predef.scala | 2 | ||||
-rw-r--r-- | src/dotnet-library/scala/StringBuilder.scala | 439 | ||||
-rw-r--r-- | src/dotnet-library/scala/compat/Math.scala | 54 | ||||
-rw-r--r-- | src/dotnet-library/scala/compat/StringBuilder.scala | 73 | ||||
-rw-r--r-- | src/dotnet-library/scala/runtime/RichInt.scala | 8 | ||||
-rw-r--r-- | src/dotnet-library/scala/runtime/RichString.scala | 4 |
6 files changed, 446 insertions, 134 deletions
diff --git a/src/dotnet-library/scala/Predef.scala b/src/dotnet-library/scala/Predef.scala index fe3e048a88..dc45fe2bec 100644 --- a/src/dotnet-library/scala/Predef.scala +++ b/src/dotnet-library/scala/Predef.scala @@ -36,7 +36,6 @@ object Predef { type unit = scala.Unit type String = System.String - type StringBuilder = compat.StringBuilder type Class[T] = System.Type type Runnable = scala.runtime.Runnable @@ -49,6 +48,7 @@ object Predef { type ClassCastException = System.InvalidCastException type IndexOutOfBoundsException = System.IndexOutOfRangeException type ArrayIndexOutOfBoundsException = System.IndexOutOfRangeException + type StringIndexOutOfBoundsException = System.IndexOutOfRangeException type UnsupportedOperationException = System.InvalidOperationException type IllegalArgumentException = System.ArgumentException type NoSuchElementException = System.InvalidOperationException diff --git a/src/dotnet-library/scala/StringBuilder.scala b/src/dotnet-library/scala/StringBuilder.scala new file mode 100644 index 0000000000..683f0afa70 --- /dev/null +++ b/src/dotnet-library/scala/StringBuilder.scala @@ -0,0 +1,439 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2006-2008, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id: $ + + +package scala + +import Predef._ + +/** <p> + * A mutable sequence of characters. This class provides an API compatible + * with <code>java.lang.StringBuilder</code>, but with no guarantee of + * synchronization. + * </p> + * + * @author Stephane Micheloud + */ +@throws(classOf[NullPointerException]) +final class StringBuilder(initCapacity: Int, private val initValue: String) extends (Int => Char) with Proxy { + if (initCapacity < 0) throw new IllegalArgumentException + if (initValue eq null) throw new NullPointerException + + /** The value is used for character storage. */ + private var value = new Array[Char](initCapacity + initValue.length) + + /** The count is the number of characters used. */ + private var count: Int = 0 + + def this() = this(16, "") + + def this(capacity: Int) = this(capacity, "") + + @throws(classOf[NullPointerException]) + def this(str: String) = this(16, str) + + append(initValue) + + def self = this + + def toArray: Array[Char] = value + + def length: Int = count + + def length_=(n: Int) { setLength(n) } + + @throws(classOf[StringIndexOutOfBoundsException]) + def setLength(n: Int) { + if (n < 0) + throw new StringIndexOutOfBoundsException//(n) + if (n > value.length) expandCapacity(n) + if (count < n) + while (count < n) { + value(count) = '\0'; count += 1 + } + else + count = n + } + + def capacity: Int = value.length + + def capacity_=(n: Int) { ensureCapacity(n) } + + def ensureCapacity(n: Int) { + if (n > value.length) expandCapacity(n) + } + + private def expandCapacity(n: Int) { + val newCapacity = (value.length + 1) * 2 + value = StringBuilder.copyOf( + value, + if (newCapacity < 0) Math.MAX_INT else if (n > newCapacity) n else newCapacity + ) + } + + @throws(classOf[StringIndexOutOfBoundsException]) + def charAt(index: Int): Char = { + if (index < 0 || index >= count) + throw new StringIndexOutOfBoundsException//(index) + value(index) + } + + @throws(classOf[StringIndexOutOfBoundsException]) + def apply(i: Int): Char = charAt(i) + + @throws(classOf[StringIndexOutOfBoundsException]) + def deleteCharAt(index: Int): StringBuilder = { + if (index < 0 || index >= count) + throw new StringIndexOutOfBoundsException//(index) + compat.Platform.arraycopy(value, index + 1, value, index, count - index - 1) + count -= 1 + this + } + + @throws(classOf[StringIndexOutOfBoundsException]) + def setCharAt(index: Int, c: Char) { + if (index < 0 || index >= count) + throw new StringIndexOutOfBoundsException//(index) + value(index) = c + } + + @throws(classOf[StringIndexOutOfBoundsException]) + def update(i: Int, c: Char) { setCharAt(i, c) } + + @throws(classOf[StringIndexOutOfBoundsException]) + def substring(start: Int): String = substring(start, count) + + @throws(classOf[StringIndexOutOfBoundsException]) + def substring(start: Int, end: Int): String = { + if (start < 0) + throw new StringIndexOutOfBoundsException//(start) + if (end > count) + throw new StringIndexOutOfBoundsException//(end) + if (start > end) + throw new StringIndexOutOfBoundsException//(end - start) + new String(value, start, end - start) + } + + def append(x: Any): StringBuilder = + append(System.Convert.ToString(x)) + + /** Appends the specified string to this character sequence. + * + * @param s + * @return + */ + def append(s: String): StringBuilder = { + val str = if (s == null) "null" else s + val len = str.length + if (len > 0) { + val newCount = count + len + if (newCount > value.length) expandCapacity(newCount) + compat.Platform.arraycopy(str.toArray: Array[Char], 0, value, count, len) + count = newCount + } + this + } + + /** Appends the specified string builder to this sequence. + * + * @param sb + * @return + */ + def append(sb: StringBuilder): StringBuilder = + if (sb == null) + append("null") + else { + val len = sb.length + val newCount = count + len + if (newCount > value.length) expandCapacity(newCount) + compat.Platform.arraycopy(sb.toArray, 0, value, count, len) + count = newCount + this + } + + def append(x: Array[Char]): StringBuilder = + append(x, 0, x.length) + + def append(x: Array[Char], offset: Int, len: Int): StringBuilder = { + val newCount = count + len + if (newCount > value.length) expandCapacity(newCount) + compat.Platform.arraycopy(x, offset, value, count, len) + count = newCount + this + } + + def append(x: Boolean): StringBuilder = { + if (x) { + val newCount = count + 4 + if (newCount > value.length) expandCapacity(newCount) + value(count) = 't'; count += 1 + value(count) = 'r'; count += 1 + value(count) = 'u'; count += 1 + value(count) = 'e'; count += 1 + } else { + val newCount = count + 5 + if (newCount > value.length) expandCapacity(newCount) + value(count) = 'f'; count += 1 + value(count) = 'a'; count += 1 + value(count) = 'l'; count += 1 + value(count) = 's'; count += 1 + value(count) = 'e'; count += 1 + } + this + } + + def append(x: Char): StringBuilder = { + val newCount = count + 1 + if (newCount > value.length) expandCapacity(newCount) + value(count) = x; count += 1 + this + } + + def append(x: Int): StringBuilder = + append(System.Convert.ToString(x)) + + def append(x: Long): StringBuilder = + append(System.Convert.ToString(x)) + + def append(x: Float): StringBuilder = + append(System.Convert.ToString(x)) + + def append(x: Double): StringBuilder = + append(System.Convert.ToString(x)) + + @throws(classOf[StringIndexOutOfBoundsException]) + def delete(start: Int, end: Int): StringBuilder = { + if (start < 0 || start > end) + throw new StringIndexOutOfBoundsException//(start) + val end0 = if (end > count) count else end + val len = end0 - start + if (len > 0) { + compat.Platform.arraycopy(value, start + len, value, start, count - end0) + count -= len + } + this + } + + @throws(classOf[StringIndexOutOfBoundsException]) + def replace(start: Int, end: Int, str: String) { + if (start < 0 || start > count || start > end) + throw new StringIndexOutOfBoundsException//(start) + + val end0 = if (end > count) count else end + val len = str.length() + val newCount = count + len - (end0 - start) + if (newCount > value.length) expandCapacity(newCount) + + compat.Platform.arraycopy(value, end, value, start + len, count - end) + compat.Platform.arraycopy(str.toArray, 0, value, start, len) + count = newCount + this + } + + @throws(classOf[StringIndexOutOfBoundsException]) + def insert(index: Int, str: Array[Char], offset: Int, len: Int): StringBuilder = { + if (index < 0 || index > count) + throw new StringIndexOutOfBoundsException//(index) + if (offset < 0 || len < 0 || offset > str.length - len) + throw new StringIndexOutOfBoundsException/*( + "offset " + offset + ", len " + len + + ", str.length " + str.length)*/ + val newCount = count + len + if (newCount > value.length) expandCapacity(newCount) + compat.Platform.arraycopy(value, index, value, index + len, count - index) + compat.Platform.arraycopy(str, offset, value, index, len) + count = newCount + this + } + + @throws(classOf[StringIndexOutOfBoundsException]) + def insert(at: Int, x: Any): StringBuilder = + insert(at, System.Convert.ToString(x)) + + @throws(classOf[StringIndexOutOfBoundsException]) + def insert(at: Int, x: String): StringBuilder = { + if (at < 0 || at > count) + throw new StringIndexOutOfBoundsException//(at) + val str = if (x == null) "null" else x + val len = str.length + val newCount = count + len + if (newCount > value.length) expandCapacity(newCount) + compat.Platform.arraycopy(value, at, value, at + len, count - at) + compat.Platform.arraycopy(str.toArray: Array[Char], 0, value, at, len) + count = newCount + this + } + + @throws(classOf[StringIndexOutOfBoundsException]) + def insert(at: Int, x: Array[Char]): StringBuilder = { + if (at < 0 || at > count) + throw new StringIndexOutOfBoundsException//(at) + val len = x.length + val newCount = count + len + if (newCount > value.length) expandCapacity(newCount) + compat.Platform.arraycopy(value, at, value, at + len, count - at) + compat.Platform.arraycopy(x, 0, value, at, len) + count = newCount + this + } + + @throws(classOf[StringIndexOutOfBoundsException]) + def insert(at: Int, x: Boolean): StringBuilder = + insert(at, System.Convert.ToString(x)) + + @throws(classOf[StringIndexOutOfBoundsException]) + def insert(at: Int, x: Char): StringBuilder = { + if (at < 0 || at > count) + throw new StringIndexOutOfBoundsException//(at) + val newCount = count + 1 + if (newCount > value.length) expandCapacity(newCount) + compat.Platform.arraycopy(value, at, value, at + 1, count - at) + value(at) = x + count = newCount + this + } + + @throws(classOf[StringIndexOutOfBoundsException]) + def insert(at: Int, x: Int): StringBuilder = + insert(at, System.Convert.ToString(x)) + + @throws(classOf[StringIndexOutOfBoundsException]) + def insert(at: Int, x: Long): StringBuilder = + insert(at, System.Convert.ToString(x)) + + @throws(classOf[StringIndexOutOfBoundsException]) + def insert(at: Int, x: Float): StringBuilder = + insert(at, System.Convert.ToString(x)) + + @throws(classOf[StringIndexOutOfBoundsException]) + def insert(at: Int, x: Double): StringBuilder = + insert(at, System.Convert.ToString(x)) + + @throws(classOf[NullPointerException]) + def indexOf(str: String): Int = indexOf(str, 0) + + @throws(classOf[NullPointerException]) + def indexOf(str: String, fromIndex: Int): Int = + StringBuilder.indexOf(value, 0, count, str.toArray, 0, str.length(), fromIndex) + + @throws(classOf[NullPointerException]) + def lastIndexOf(str: String): Int = lastIndexOf(str, count) + + @throws(classOf[NullPointerException]) + def lastIndexOf(str: String, fromIndex: Int): Int = + StringBuilder.lastIndexOf(value, 0, count, str.toArray, 0, str.length(), fromIndex) + + def reverse(): StringBuilder = { + val n = count - 1 + var j = (n-1) >> 1 + while (j >= 0) { + val temp = value(j) + val temp2 = value(n - j) + value(j) = temp2 + value(n - j) = temp + j -= 1 + } + this + } + + override def toString(): String = new String(value, 0, count) + +} + + +object StringBuilder { + + // method <code>java.util.Arrays.copyOf</code> exists since 1.6 + private def copyOf(src: Array[Char], newLength: Int): Array[Char] = { + val dest = new Array[Char](newLength) + val (start, end) = + if (src.length < newLength) (src.length, newLength) + else (newLength, src.length) + compat.Platform.arraycopy(src, 0, dest, 0, start) + // For any indices that are valid in the copy but not the original, + // the copy will contain '\\u000'. + for (i <- start until end) dest(i) = '\0' + dest + } + + private def indexOf(source: Array[Char], sourceOffset: Int, sourceCount: Int, + target: Array[Char], targetOffset: Int, targetCount: Int, + fromIndex: Int): Int = + if (fromIndex >= sourceCount) + if (targetCount == 0) sourceCount else -1 + else { + val inx = if (fromIndex < 0) 0 else fromIndex + if (targetCount == 0) + inx + else { + val first = target(targetOffset) + val max = sourceOffset + (sourceCount - targetCount) + + var i = sourceOffset + inx + while (i <= max) { + /* Look for first character. */ + if (source(i) != first) { + i += 1 + while (i <= max && source(i) != first) i += 1 + } + /* Found first character, now look at the rest of v2 */ + if (i <= max) { + var j = i + 1 + val end = j + targetCount - 1 + var k = targetOffset + 1 + while (j < end && source(j) == target(k)) { + j += 1 + k += 1 + } + if (j == end) { + /* Found whole string. */ + return i - sourceOffset + } + } // if + i += 1 + } // while + -1 + } + } + + private def lastIndexOf(source: Array[Char], sourceOffset: Int, sourceCount: Int, + target: Array[Char], targetOffset: Int, targetCount: Int, + fromIndex: Int): Int = { + val rightIndex = sourceCount - targetCount + if (fromIndex < 0) return -1 + val inx = if (fromIndex > rightIndex) rightIndex else fromIndex + // Empty string always matches + if (targetCount == 0) return inx + + val strLastIndex = targetOffset + targetCount - 1 + val strLastChar = target(strLastIndex) + val min = sourceOffset + targetCount - 1 + var i = min + fromIndex + + while (true) { + while (i >= min && source(i) != strLastChar) i -= 1 + if (i < min) return -1 + var j = i - 1 + val start = j - (targetCount - 1) + var k = strLastIndex - 1 + var outerWhile = false + while (j > start && !outerWhile) { + if (source(j) != target(k)) { + j -= 1 + k -= 1 + i -= 1 + outerWhile = true + } + } + if (!outerWhile) return start - sourceOffset + 1 + } + -1 + } +} diff --git a/src/dotnet-library/scala/compat/Math.scala b/src/dotnet-library/scala/compat/Math.scala deleted file mode 100644 index d59f3bdd15..0000000000 --- a/src/dotnet-library/scala/compat/Math.scala +++ /dev/null @@ -1,54 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2007, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -// $Id$ - - -package scala.compat - -/** - * This class will be removed soon. Use <code>scala.Math</code> instead. - */ -@deprecated -object Math { - val MIN_BYTE = System.Byte.MinValue - val MAX_BYTE = System.Byte.MaxValue - val MIN_SHORT = System.Int16.MinValue - val MAX_SHORT = System.Int16.MaxValue - val MIN_CHAR = System.Char.MinValue - val MAX_CHAR = System.Char.MaxValue - val MIN_INT = System.Int32.MinValue - val MAX_INT = System.Int32.MaxValue - val MIN_LONG = System.Int64.MinValue - val MAX_LONG = System.Int64.MaxValue - - val MIN_FLOAT = System.Single.MinValue - val EPS_FLOAT = System.Single.Epsilon - val MAX_FLOAT = System.Single.MinValue - //val NaN_FLOAT = System.Single.NaN - //val NEG_INF_FLOAT = System.Double.NegativeInfinity - //val POS_INF_FLOAT = System.Double.PositiveInfinity - - val MIN_DOUBLE = System.Double.MinValue - val EPS_DOUBLE = System.Double.Epsilon - val MAX_DOUBLE = System.Double.MaxValue - //val NaN_DOUBLE = System.Double.NaN - //val NEG_INF_DOUBLE = System.Double.NegativeInfinity - //val POS_INF_DOUBLE = System.Double.PositiveInfinity - - def E: Double = System.Math.E - def PI: Double = System.Math.PI - - def min(x: Int, y: Int): Int = System.Math.Min(x, y) - def max(x: Int, y: Int): Int = System.Math.Max(x, y) - - def ceil (x: Double): Double = System.Math.Ceiling(x) - def floor(x: Double): Double = System.Math.Floor(x) - def log (x: Double): Double = System.Math.Log(x) - def sqrt (x: Double): Double = System.Math.Sqrt(x) -} diff --git a/src/dotnet-library/scala/compat/StringBuilder.scala b/src/dotnet-library/scala/compat/StringBuilder.scala deleted file mode 100644 index 2ce9ad178f..0000000000 --- a/src/dotnet-library/scala/compat/StringBuilder.scala +++ /dev/null @@ -1,73 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2007, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -// $Id$ - - -package scala.compat - - -import System.Text.{StringBuilder => StringBuffer} - - -/** Consult the documentation of <code>java.lang.StringBuffer</code> - * for more details. - */ -final class StringBuilder(val self: StringBuffer) extends (Int => Char) with Proxy { - - def this() = this(new StringBuffer()) - def this(n: Int) = this(new StringBuffer(n)) - def this(s: String) = this(new StringBuffer(s)) - - def length: Int = self.Length - def length_=(n: Int) { self.Length = n } - def setLength(n: Int) { self.Length = n } - - def capacity: Int = self.Capacity - def capacity_=(n: Int) { self.Capacity = n } - def ensureCapacity(n: Int) { self.Capacity = n } - - def charAt(i: Int): Char = self(i) - def apply(i: Int): Char = self(i) - def deleteCharAt(index: Int) = self.Remove(index, 1) - - def setCharAt(i: Int, c: Char) { self(i) = c } - def update(i: Int, c: Char) { self(i) = c } - - def substring(i: Int): String = self.ToString(i, length) - def substring(i: Int, j: Int): String = self.ToString(i, j) - - def append(x: Any): StringBuilder = { self.Append(x); this } - def append(x: Boolean): StringBuilder = { self.Append(x); this } -// def append(x: Byte): StringBuilder = { self.Append(x); this } - def append(x: Short): StringBuilder = { self.Append(x); this } - def append(x: Char): StringBuilder = { self.Append(x); this } - def append(x: Int): StringBuilder = { self.Append(x); this } - def append(x: Long): StringBuilder = { self.Append(x); this } - def append(x: Float): StringBuilder = { self.Append(x); this } - def append(x: Double): StringBuilder = { self.Append(x); this } - def append(x: String): StringBuilder = { self.Append(x); this } - def append(x: Array[Char]): StringBuilder = { self.Append(x); this } - def append(x: Array[Char], start: Int, length: Int): StringBuilder = - { self.Append(x, start, length); this } - - def insert(at: Int, x: Any): StringBuilder = { self.Insert(at, x); this } - def insert(at: Int, x: Boolean): StringBuilder = { self.Insert(at, x); this } -// def insert(at: Int, x: Byte): StringBuilder = { self.Insert(at, x); this } - def insert(at: Int, x: Short): StringBuilder = { self.Insert(at, x); this } - def insert(at: Int, x: Char): StringBuilder = { self.Insert(at, x); this } - def insert(at: Int, x: Int): StringBuilder = { self.Insert(at, x); this } - def insert(at: Int, x: Long): StringBuilder = { self.Insert(at, x); this } - def insert(at: Int, x: Float): StringBuilder = { self.Insert(at, x); this } - def insert(at: Int, x: Double): StringBuilder = { self.Insert(at, x); this } - def insert(at: Int, x: String): StringBuilder = { self.Insert(at, x); this } - def insert(at: Int, x: Array[Char]): StringBuilder = { self.Insert(at, x); this } - def insert(at: Int, x: Array[Char], start: Int, length: Int): StringBuilder = - { self.Insert(at, x, start, length); this } - -} diff --git a/src/dotnet-library/scala/runtime/RichInt.scala b/src/dotnet-library/scala/runtime/RichInt.scala index 368a886df9..fc5080f9b3 100644 --- a/src/dotnet-library/scala/runtime/RichInt.scala +++ b/src/dotnet-library/scala/runtime/RichInt.scala @@ -1,6 +1,6 @@ /* __ *\ ** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2007, LAMP/EPFL ** +** / __/ __// _ | / / / _ | (c) 2002-2008, LAMP/EPFL ** ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** ** /____/\___/_/ |_/____/_/ | | ** ** |/ ** @@ -21,13 +21,13 @@ final class RichInt(start: Int) extends Proxy with Ordered[Int] { def compare(that: Int): Int = if (start < that) -1 else if (start > that) 1 else 0 /** See <code>Iterator.range</code>. */ - def until(end: Int): Range = Iterator.range(start, end) + def until(end: Int): Range = new Range(start, end, 1) /** See <code>Iterator.range</code>. */ - def until(end: Int, step: Int): Range = Iterator.range(start, end, step) + def until(end: Int, step: Int): Range = new Range(start, end, step) /** like <code>until</code>, but includes the last index */ - def to(end: Int) = until(end + 1) + def to(end: Int) = new Range.Inclusive(start, end, 1) def min(that: Int): Int = if (start < that) start else that def max(that: Int): Int = if (start > that) start else that diff --git a/src/dotnet-library/scala/runtime/RichString.scala b/src/dotnet-library/scala/runtime/RichString.scala index 2a71306686..150edc000e 100644 --- a/src/dotnet-library/scala/runtime/RichString.scala +++ b/src/dotnet-library/scala/runtime/RichString.scala @@ -1,6 +1,6 @@ /* __ *\ ** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2007, LAMP/EPFL ** +** / __/ __// _ | / / / _ | (c) 2002-2008, LAMP/EPFL ** ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** ** /____/\___/_/ |_/____/_/ | | ** ** |/ ** @@ -141,7 +141,7 @@ final class RichString(val self: String) extends Proxy with RandomAccessSeq[Char * </blockquote> */ def stripMargin(marginChar: Char): String = { - val buf = new scala.compat.StringBuilder() + val buf = new StringBuilder() for (line <- linesWithSeparators) { val len = line.length var index = 0 |