From c05a0b7a4953f5b835441bf3fca1806f842a3935 Mon Sep 17 00:00:00 2001
From: Geoffrey Washburn
- * A wrapper around a Java sorted set.
- *
- * The comparator of the sorted set matches the comparator of this set.
- *
- * A map that is backed by a Java weak hash map, whose keys are maintained
- * as weak references.
- *
- * Because keys are weak references, the garbage collector can collect
- * them if they are not referred to elsewhere.
- *
- * Useful for implementing caches.
- *
- * This attribute indicates that a JavaBean-compliant BeanInfo
- * class should be generated for this attributed Scala class.
- * A val becomes a read-only property. A var becomes a read-write
- * property. A def becomes a method.
- *
- * This attribute adds a setter and a getter method, following the
- * Java Bean convention (first letter of the property is capitalized)
- * used by popular Java web frameworks. For example:
- *
- * adds the following methods to the generated code
- *
- * However, you cannot call
- * For example, in the following code
- *
- * the implicit conversions are performed using the predefined view
- *
- * Strip trailing line end character from this string if it has one.
- * A line end character is one of
- *
- * If a line feed character LF is preceded by a carriage return CR
- * (0x0D hex), the CR character is also stripped (Windows convention).
- *
- * Return all lines in this string in an iterator, including trailing
- * line end characters.
- *
- * The number of strings returned is one greater than the number of line
- * end characters in this string. For an empty string, a single empty
- * line is returned. A line end character is one of
- *
- * For every line in this string:
- *
- * For every line in this string:
- *
- * DynamicVariables provide a binding mechanism where the current
- * value is found through dynamic scope, but where
- * access to the variable itself is resolved through static
- * scope.
- *
- * The current value can be retrieved with the
- *
- * Usage of
- * Each thread gets its own stack of bindings. When a
- * new thread is created, the fluid gets a copy of
- * the stack of bindings from the parent thread, and
- * from then on the bindings for the new thread
- * are independent of those for the original thread.
- *
- *
- * Constructs an
- * Mutable storage of immutable xml trees. Everything is kept in memory,
- * with a thread periodically checking for changes and writing to file.
- * To ensure atomicity, two files are used, filename1 and '$'+filename1.
- * The implementation switches between the two, deleting the older one
- * after a complete dump of the database has been written.
- *
- * A pull parser that offers to view an XML document as a series of events.
- * Please note that this API might change. Here's how to use this class
- *
- *
- * Translated from Elliotte Rusty Harold's Java source
- *
- * This utility method ????.
- *
- * This is a SAX filter which resolves all XInclude include elements
- * before passing them on to the client application. Currently this
- * class has the following known deviation from the XInclude specification:
- *
- * Furthermore, I would definitely use a new instance of this class
- * for each document you want to process. I doubt it can be used
- * successfully on multiple documents. Furthermore, I can virtually
- * guarantee that this class is not thread safe. You have been
- * warned.
- *
- * Since this class is not designed to be subclassed, and since
- * I have not yet considered how that might affect the methods
- * herein or what other protected methods might be needed to support
- * subclasses, I have declared this class final. I may remove this
- * restriction later, though the use-case for subclassing is weak.
- * This class is designed to have its functionality extended via a
- * a horizontal chain of filters, not a
- * vertical hierarchy of sub and superclasses.
- *
- * To use this class:
- * e.g.idx
*/
- def remove(idx : Int) = {
- val i = elements;
- val ret = i.seek(idx); i.remove; ret;
- }
- /** Removes N elements from index idx
*/
- def remove(idx : Int, length : Int) = {
- val i = elements
- i.seek(idx)
- for (j <- 0.until(length)) i.remove
- }
- /** replaces */
- def replace(from : Int, length : Int, added : Seq[A]) = {
- val min = if (length < added.length) length else added.length
- val i = added.elements
- var j = 0
- while (j < length && i.hasNext) {
- set(from + j, i.next); j = j + 1
- }
- assert(j == min)
- if (i.hasNext) {
- val slice = added.drop(length)
- assert(!slice.isEmpty)
- addAll(from + min, slice)
- } else if (j < length) {
- assert(length > min)
- remove(from + min, length - min)
- }
- }
-
- /** Replaces the element at index "idx" with "a."
- * @returns the element replaced.
- */
- def set(idx : Int, a : A) : A = {
- val i = elements;
- val ret = i.seek(idx); i.set(a); ret;
- }
-
- /** Equivalent to set except the replaced element is not returned. */
- def update(idx : Int, a : A) : Unit = set(idx, a);
-
- /** @returns always true. */
- def add(a : A) : Boolean = {
- val i = elements;
- while (i.hasNext) i.next;
- i.add(a);
- true;
- }
-
- /** Inserts "a" into this buffer just before the element at index "idx." */
- def add(idx: Int, a: A): Unit = {
- val i = elements; i.seek(idx);
- i.add(a);
- }
-
- /** Inserts all elements of that
into this buffer just before
- * the element at index idx
.
- *
- * @param idx ..
- * @param that ..
- */
- def addAll(idx: Int, that: Iterable[A]): Unit = {
- val i = elements; i.seek(idx);
- for (that <- that) {
- i.add(that); i.next;
- }
- }
-
- override def transform(f: A => A): Boolean = {
- var changed = false;
- val i = elements;
- while (i.hasNext) {
- val a0 = i.next;
- val a1 = f(a0);
- if (a0 != a1) {
- i.set(a1); changed = true;
- }
- }
- changed;
- }
- override def +(a : A) : this.type = super[Collection].+(a);
- override def -=(a : A) = super[Collection].-=(a);
- override def isEmpty = super[MutableSeq].isEmpty;
- override def rangeImpl(from : Option[Int], until : Option[Int]) : Buffer[A] = new Range(from, until);
-
-
- protected class Range(var from : Option[Int], var until : Option[Int]) extends Buffer[A] {
- if (from == None && until == None) throw new IllegalArgumentException;
- if (from != None && until != None && !(from.get < until.get)) throw new IllegalArgumentException;
- override def add(a : A) =
- if (until == None) Buffer.this.add(a);
- else {
- Buffer.this.add(until.get, a);
- true;
- }
- private def translate(idx : Int) = {
- if (until != None && idx > until.get) throw new IllegalArgumentException;
- else if (from != None) from.get + idx;
- else idx;
- }
- override def apply(idx : Int) : A = Buffer.this.apply(translate(idx));
- override def set(idx : Int, a : A) = Buffer.this.set(translate(idx), a);
- override def add(idx : Int, a : A) = Buffer.this.add(translate(idx), a);
- override def remove(idx : Int) = Buffer.this.remove(translate(idx));
- override def length = {
- if (until != None) {
- if (from != None) until.get - from.get;
- else until.get;
- } else super.length;
- }
- override def elements : BufferIterator[Int,A] = new RangeIterator;
- class RangeIterator extends BufferIterator[Int,A] {
- val underlying = Buffer.this.elements;
- if (from != None) underlying.seek(from.get);
- def hasNext = underlying.hasNext &&
- (until == None || underlying.nextIndex < until.get);
- def hasPrevious = underlying.hasPrevious &&
- (from == None || underlying.previousIndex >= from.get);
- def next = {
- if (until != None && underlying.nextIndex >= until.get) throw new NoSuchElementException;
- underlying.next;
- }
- def previous = {
- if (from != None && underlying.previousIndex < from.get) throw new NoSuchElementException;
- underlying.previous;
- }
- def add(a : A) = {
- if (until != None && underlying.nextIndex > until.get) throw new NoSuchElementException;
- if (from != None && underlying.previousIndex < from.get) throw new NoSuchElementException;
- underlying.add(a);
- if (until != None) until = Some(until.get + 1);
- }
- def set(a : A) = {
- if (until != None && underlying.nextIndex > until.get) throw new NoSuchElementException;
- if (from != None && underlying.previousIndex < from.get) throw new NoSuchElementException;
- underlying.set(a);
- }
- def remove = {
- if (until != None && underlying.nextIndex > until.get) throw new NoSuchElementException;
- if (from != None && underlying.previousIndex < from.get) throw new NoSuchElementException;
- underlying.remove;
- }
- def nextIndex = {
- val ret = underlying.nextIndex;
- if (until != None && ret >= until.get) throw new NoSuchElementException;
- if (from != None) ret - from.get;
- else ret;
- }
- def previousIndex = {
- val ret = underlying.previousIndex;
- if (from != None && ret < from.get) throw new NoSuchElementException;
- if (from != None) ret - from.get;
- else ret;
- }
- }
- }
- /*
- protected class Map[B](f : A => B) extends super.Map[B](f) with Buffer.Projection[B] {
- override def elements = Buffer.this.elements.map[B](f);
- //override def apply(idx : Int) = f(MutableSeq.this.apply(idx));
- //override def size = length;
- }
- */
-}
-object Buffer {
- def apply[T](list : java.util.List[T]) = new BufferWrapper[T] {
- val underlying = list
- }
-
- trait Projection0[A] extends MutableSeq.Projection[A] with RandomAccessSeq.Projection[A] {
- override def projection : Projection0[A] = this
- override def elements : SeqIterator[Int,A] = new DefaultSeqIterator
-
- protected class MapProjection[B](f : A => B) extends super.MapProjection[B](f) with Projection0[B] {
- override def projection = this
- }
- override def map[B](f: A => B) : Projection0[B] = new MapProjection[B](f)
- }
- class Projection[A] extends Collection.Projection[A] with RandomAccessSeq.MutableProjection[A] with Projection0[A] with Buffer[A] {
- override def elements : BufferIterator[Int,A] = new DefaultBufferIterator
- override def projection : Buffer.Projection[A] = this
- }
-}
diff --git a/src/library/jvm/scala/collection/jcl/BufferIterator.scala b/src/library/jvm/scala/collection/jcl/BufferIterator.scala
deleted file mode 100644
index bb7b79d099..0000000000
--- a/src/library/jvm/scala/collection/jcl/BufferIterator.scala
+++ /dev/null
@@ -1,31 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.collection.jcl;
-
-/** An iterator for a buffer that supports element update and insertion.
- *
- * @author Sean McDirmid
- */
-trait BufferIterator[K,A] extends SeqIterator[K,A] {
-
- /** Sets the element before this iterator's cursor to "a."
- * Replaces either the last element returned by "next" or,
- * if previous was called,
- * the next element that would be return by "previous."
- */
- def set(a: A): Unit;
-
- /** Inserts "a" after the iterator's cursor.
- * If next was last called, "a" is inserted after the element returned.
- * If previous was last called, "a" is inserted before the element returned.
- */
- def add(a: A): Unit;
-}
diff --git a/src/library/jvm/scala/collection/jcl/BufferWrapper.scala b/src/library/jvm/scala/collection/jcl/BufferWrapper.scala
deleted file mode 100644
index 0472c15dea..0000000000
--- a/src/library/jvm/scala/collection/jcl/BufferWrapper.scala
+++ /dev/null
@@ -1,52 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.collection.jcl;
-
-/** Wraps Java lists.
- *
- * @author Sean McDirmid
- */
-trait BufferWrapper[A] extends Buffer[A] with CollectionWrapper[A] {
- def underlying : java.util.List[A];
- override def elements : BufferIterator[Int,A] = new IteratorWrapper(underlying.listIterator);
- override def remove(idx : Int) = underlying.remove(idx).asInstanceOf[A];
- override def add(a : A) = underlying.add(a);
- override def add(idx : Int, a : A) = underlying.add(idx,a);
- override def addAll(idx : Int, that : Iterable[A]) = that match {
- case that : CollectionWrapper[_] => underlying.addAll(idx, that.underlying); {}
- case _ => super.addAll(idx, that);
- }
- override def indexOf(a : A) = {
- val result = underlying.indexOf(a);
- if (result == -1) None;
- else Some(result);
- }
- override def apply(idx : Int) = underlying.get(idx).asInstanceOf[A];
- override def set(idx : Int, a : A) = underlying.set(idx, a).asInstanceOf[A];
- override def rangeImpl(from : Option[Int], until : Option[Int]) : Buffer[A] = new Range(from, until);
- protected class Range(from : Option[Int], until : Option[Int]) extends super.Range(from,until) with BufferWrapper[A] {
- val underlying = {
- val fromi = if (from == None) 0 else from.get;
- val toi = if (until == None) BufferWrapper.this.size else until.get;
- BufferWrapper.this.underlying.subList(fromi, toi);
- }
- override def elements = super[BufferWrapper].elements;
- }
- class IteratorWrapper(underlying : java.util.ListIterator[A]) extends MutableIterator.Wrapper[A](underlying) with BufferIterator[Int,A] {
- def add(a : A) = underlying.add(a);
- def set(a : A) = underlying.set(a);
- def hasPrevious = underlying.hasPrevious;
- def previous = underlying.previous.asInstanceOf[A];
- def previousIndex = underlying.previousIndex;
- def nextIndex = underlying.nextIndex;
- }
- override def length = underlying.size;
-}
diff --git a/src/library/jvm/scala/collection/jcl/Collection.scala b/src/library/jvm/scala/collection/jcl/Collection.scala
deleted file mode 100644
index 0df2f74f4b..0000000000
--- a/src/library/jvm/scala/collection/jcl/Collection.scala
+++ /dev/null
@@ -1,67 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.collection.jcl;
-
-object Collection {
- val DEFAULT_FILTER : Any => Boolean = x => true;
- trait Projection[A] extends Collection[A] with MutableIterable.Projection[A] {
- override def projection = this
- }
-}
-
-/** Analogous to a Java collection.
- *
- * @author Sean McDirmid
- */
-trait Collection[A] extends MutableIterable[A] {
- /** Type-safe version of containsAll.
- **
- ** @author Sean McDirmid
- **/
- def hasAll(i: Iterable[A]): Boolean = i.forall(elements.has);
-
- /** Adds "a" to the collection, return true if "a" is actually added. */
- def add(a: A): Boolean;
-
- /** Adds all elements in "i" to the collection, return true if any elements are added. */
- def addAll(i: Iterable[A]): Boolean = {
- var changed = false;
- i.foreach(t => changed = add(t) || changed);
- changed;
- }
- /** Operator shortcut for addAll. */
- def ++(that: Iterable[A]): this.type = {
- addAll(that); this;
- }
-
- /** removes "a" from the collection. */
- def -=(a : A) : Unit = remove(a);
-
- /** adds "a" from the collection. */
- def +=(t : A) : Unit = add(t);
-
- /** adds "a" from the collection. Useful for chaining. */
- def +(t : A) : this.type = { add(t); this; }
-
- /** Transforms each element of the collection in-place according to
- * f
.
- *
- * @param f
- * @return true
if the collection is actually updated.
- */
- def transform(f: A => A): Boolean
- override def projection : Collection.Projection[A] = new Collection.Projection[A] {
- override def elements = Collection.this.elements
- override def size = Collection.this.size
- override def add(a: A): Boolean = Collection.this.add(a)
- override def transform(f : A => A) = Collection.this.transform(f);
- }
-}
diff --git a/src/library/jvm/scala/collection/jcl/CollectionWrapper.scala b/src/library/jvm/scala/collection/jcl/CollectionWrapper.scala
deleted file mode 100644
index ec6a22f325..0000000000
--- a/src/library/jvm/scala/collection/jcl/CollectionWrapper.scala
+++ /dev/null
@@ -1,43 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.collection.jcl;
-
-/** Used to wrap Java collections in Scala.
- *
- * @author Sean McDirmid
- */
-trait CollectionWrapper[A] extends Collection[A] with IterableWrapper[A] {
- /** Override to specify the collection being accessed through this wrapper.
- ** Collection operations are then routed through the wrapped Java collection.
- **/
- def underlying : java.util.Collection[A];
- override def has(a : A) = underlying.contains(a);
- override def elements : MutableIterator[A] = super.elements;
- override def size = underlying.size;
-
- override def hasAll(that : Iterable[A]) = that match {
- case that : CollectionWrapper[_] =>
- val u = underlying;
- u.containsAll(that.underlying);
- case _ => super.hasAll(that);
- }
- override def add(a : A) = underlying.add(a);
- override def addAll(that : Iterable[A]) = that match {
- case that : CollectionWrapper[_] => underlying.addAll(that.underlying);
- case _ => super.addAll(that);
- }
- override def toString = underlying.toString;
- override def hashCode = underlying.hashCode;
- override def equals(that : Any) = that match {
- case that: CollectionWrapper[_] => underlying == that.underlying;
- case _ => super.equals(that);
- }
-}
diff --git a/src/library/jvm/scala/collection/jcl/Conversions.scala b/src/library/jvm/scala/collection/jcl/Conversions.scala
deleted file mode 100644
index edb96322b6..0000000000
--- a/src/library/jvm/scala/collection/jcl/Conversions.scala
+++ /dev/null
@@ -1,17 +0,0 @@
-package scala.collection.jcl
-
-object Conversions {
- implicit def convertSet[T](set : java.util.Set[T]) = Set(set)
- implicit def convertList[T](set : java.util.List[T]) = Buffer(set)
- implicit def convertSortedSet[T](set : java.util.SortedSet[T]) = SortedSet(set)
- implicit def convertMap[T,E](set : java.util.Map[T,E]) = Map(set)
- implicit def convertSortedMap[T,E](set : java.util.SortedMap[T,E]) = SortedMap(set)
-
- implicit def unconvertSet[T](set : SetWrapper[T]) = set.underlying
- implicit def unconvertCollection[T](set : CollectionWrapper[T]) = set.underlying
- implicit def unconvertList[T](set : BufferWrapper[T]) = set.underlying
- implicit def unconvertSortedSet[T](set : SortedSetWrapper[T]) = set.underlying
- implicit def unconvertMap[T,E](set : MapWrapper[T,E]) = set.underlying
- implicit def unconvertSortedMap[T,E](set : SortedMapWrapper[T,E]) = set.underlying
-
-}
\ No newline at end of file
diff --git a/src/library/jvm/scala/collection/jcl/HashMap.scala b/src/library/jvm/scala/collection/jcl/HashMap.scala
deleted file mode 100644
index e9c156f655..0000000000
--- a/src/library/jvm/scala/collection/jcl/HashMap.scala
+++ /dev/null
@@ -1,21 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2008, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.collection.jcl
-
-/** A map that is backed by a Java hash map.
- *
- * @author Sean McDirmid
- */
-class HashMap[K, E](override val underlying: java.util.HashMap[K, E]) extends MapWrapper[K, E] {
- def this() = this(new java.util.HashMap[K, E])
- override def clone: HashMap[K, E] =
- new HashMap[K, E](underlying.clone().asInstanceOf[java.util.HashMap[K, E]])
-}
diff --git a/src/library/jvm/scala/collection/jcl/HashSet.scala b/src/library/jvm/scala/collection/jcl/HashSet.scala
deleted file mode 100644
index 7d57278273..0000000000
--- a/src/library/jvm/scala/collection/jcl/HashSet.scala
+++ /dev/null
@@ -1,21 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2008, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.collection.jcl
-
-/** A hash set that is backed by a Java hash set.
- *
- * @author Sean McDirmid
- */
-class HashSet[A](override val underlying: java.util.HashSet[A]) extends SetWrapper[A] {
- def this() = this(new java.util.HashSet[A])
- override def clone: HashSet[A] =
- new HashSet[A](underlying.clone().asInstanceOf[java.util.HashSet[A]])
-}
diff --git a/src/library/jvm/scala/collection/jcl/Hashtable.scala b/src/library/jvm/scala/collection/jcl/Hashtable.scala
deleted file mode 100644
index c46c762163..0000000000
--- a/src/library/jvm/scala/collection/jcl/Hashtable.scala
+++ /dev/null
@@ -1,22 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2008, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.collection.jcl
-
-/** A hash set that is backed by a Java hash table.
- *
- * @author Sean McDirmid
- */
-class Hashtable[K,E](override val underlying: java.util.Hashtable[K,E]) extends MapWrapper[K,E] {
- def this() = this(new java.util.Hashtable[K,E])
-
- override def clone() : Hashtable[K,E] =
- new Hashtable[K,E](underlying.clone().asInstanceOf[java.util.Hashtable[K,E]])
-}
diff --git a/src/library/jvm/scala/collection/jcl/IdentityHashMap.scala b/src/library/jvm/scala/collection/jcl/IdentityHashMap.scala
deleted file mode 100644
index c3113388e9..0000000000
--- a/src/library/jvm/scala/collection/jcl/IdentityHashMap.scala
+++ /dev/null
@@ -1,24 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2008, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.collection.jcl
-
-/** A map that is backed by a Java identity hash map, which compares keys
- * by their reference-based identity as opposed to using equals and hashCode.
- * An identity hash map will often perform better than traditional hash map
- * because it can utilize linear probing.
- *
- * @author Sean McDirmid
- */
-class IdentityHashMap[K, E](override val underlying : java.util.IdentityHashMap[K, E]) extends MapWrapper[K, E] {
- def this() = this(new java.util.IdentityHashMap[K, E])
- override def clone: IdentityHashMap[K, E] =
- new IdentityHashMap[K, E](underlying.clone().asInstanceOf[java.util.IdentityHashMap[K, E]])
-}
diff --git a/src/library/jvm/scala/collection/jcl/IterableWrapper.scala b/src/library/jvm/scala/collection/jcl/IterableWrapper.scala
deleted file mode 100644
index caa31d10cf..0000000000
--- a/src/library/jvm/scala/collection/jcl/IterableWrapper.scala
+++ /dev/null
@@ -1,32 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.collection.jcl;
-
-/** A wrapper around a Java collection that only supports remove mutations.
- *
- * @author Sean McDirmid
- */
-trait IterableWrapper[A] extends MutableIterable[A] {
- def underlying: java.util.Collection[A];
- override def remove(a: A) = underlying.remove(a);
- override def removeAll(that: Iterable[A]) = that match {
- case that: IterableWrapper[_] => underlying.removeAll(that.underlying);
- case _ => super.removeAll(that);
- }
- override def retainAll(that : Iterable[A]) = that match {
- case that : IterableWrapper[_] => underlying.retainAll(that.underlying);
- case _ => super.retainAll(that);
- }
- override def size = underlying.size;
- override def isEmpty = underlying.isEmpty;
- override def clear = underlying.clear;
- override def elements : MutableIterator[A] = new MutableIterator.Wrapper[A](underlying.iterator);
-}
diff --git a/src/library/jvm/scala/collection/jcl/LinkedHashMap.scala b/src/library/jvm/scala/collection/jcl/LinkedHashMap.scala
deleted file mode 100644
index 424043ba9a..0000000000
--- a/src/library/jvm/scala/collection/jcl/LinkedHashMap.scala
+++ /dev/null
@@ -1,22 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2008, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.collection.jcl
-
-/** A map that is backed by a Java linked hash map, which fixes iteration
- * order in terms of insertion order.
- *
- * @author Sean McDirmid
- */
-class LinkedHashMap[K, E](override val underlying: java.util.LinkedHashMap[K, E]) extends MapWrapper[K, E] {
- def this() = this(new java.util.LinkedHashMap[K, E])
- override def clone: LinkedHashMap[K, E] =
- new LinkedHashMap[K, E](underlying.clone().asInstanceOf[java.util.LinkedHashMap[K, E]])
-}
diff --git a/src/library/jvm/scala/collection/jcl/LinkedHashSet.scala b/src/library/jvm/scala/collection/jcl/LinkedHashSet.scala
deleted file mode 100644
index 2d0d1dddff..0000000000
--- a/src/library/jvm/scala/collection/jcl/LinkedHashSet.scala
+++ /dev/null
@@ -1,22 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2008, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.collection.jcl
-
-/** A set that is backed by a Java linked hash set, which fixes iteration
- * order in terms of insertion order.
- *
- * @author Sean McDirmid
- */
-class LinkedHashSet[A](override val underlying: java.util.LinkedHashSet[A]) extends SetWrapper[A] {
- def this() = this(new java.util.LinkedHashSet[A])
- override def clone: LinkedHashSet[A] =
- new LinkedHashSet[A](underlying.clone().asInstanceOf[java.util.LinkedHashSet[A]])
-}
diff --git a/src/library/jvm/scala/collection/jcl/LinkedList.scala b/src/library/jvm/scala/collection/jcl/LinkedList.scala
deleted file mode 100644
index a7fc726af6..0000000000
--- a/src/library/jvm/scala/collection/jcl/LinkedList.scala
+++ /dev/null
@@ -1,32 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.collection.jcl;
-
-/** Creates a buffer backed by a Java linked list. Includes additional
- * peek/poll/removeFirst/removeLast APIs that are useful in implementing
- * queues and stacks.
- *
- * @author Sean McDirmid
- */
-class LinkedList[A](override val underlying : java.util.LinkedList[A]) extends BufferWrapper[A] {
- def this() = this(new java.util.LinkedList[A]);
- override def elements = super[BufferWrapper].elements;
- override def add(idx : Int, a : A) =
- if (idx == 0) underlying.addFirst(a);
- else super.add(idx, a);
- //def peek = underlying.peek.asInstanceOf[A];
- //def poll = underlying.poll.asInstanceOf[A];
- //def removeFirst = underlying.removeFirst.asInstanceOf[A];
- //def removeLast = underlying.removeLast.asInstanceOf[A];
-
- override def clone: LinkedList[A] =
- new LinkedList[A](underlying.clone().asInstanceOf[java.util.LinkedList[A]])
-}
diff --git a/src/library/jvm/scala/collection/jcl/Map.scala b/src/library/jvm/scala/collection/jcl/Map.scala
deleted file mode 100644
index 4dc0625b71..0000000000
--- a/src/library/jvm/scala/collection/jcl/Map.scala
+++ /dev/null
@@ -1,129 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.collection.jcl;
-
-/** A mutable map that is compatible with Java maps.
- *
- * @author Sean McDirmid
- */
-trait Map[K,E] extends MutableIterable[Tuple2[K,E]] with scala.collection.mutable.Map[K,E] {
- override def clear() = super[MutableIterable].clear;
- override def isEmpty = super[MutableIterable].isEmpty;
- override def keySet : Set[K] = new KeySet;
- override final def keys = keySet.elements;
- /** The values of this map as a projection, which means
- removals from the returned collection will remove the element from this map.
- @returns a projection of this map's elements. */
- def valueSet : MutableIterable.Projection[E] = projection.map(_._2);
-
- override def put(key : K, elem : E) : Option[E] = throw new java.lang.AbstractMethodError
-
- override def ++=(that : Iterable[(K,E)]) : Unit =
- that.foreach(p => put(p._1, p._2));
-
- override def removeKey(key : K) : Option[E] = {
- val i = elements;
- while (!i.hasNext) {
- val result = i.next;
- if (result._1 == key) {
- i.remove;
- return Some(result._2);
- }
- }
- return None;
- }
- override def has(pair : Tuple2[K,E]) = get(pair._1) match {
- case Some(e) if e == pair._2 => true;
- case _ => false;
- }
- override def get(key : K) = elements.find(p => p._1 == key).map(_._2);
- override def update(key : K, e : E) : Unit = put(key,e);
- override def +(pair : Tuple2[K,E]) : this.type = {
- put(pair._1,pair._2); this;
- }
- override def +=(pair : Tuple2[K,E]) : Unit = put(pair._1, pair._2);
- override def -(key : K) : this.type = {
- removeKey(key); this;
- }
- override def remove(p : (K,E)) = get(p._1) match {
- case Some(p._2) => this -= p._1; true
- case _ => false;
- }
-
- override def -=(key : K) : Unit = removeKey(key);
- override def elements : MutableIterator[Tuple2[K,E]];
-
- override def projection : Map.Projection[K,E] = new Map.Projection[K,E] {
- override def elements = Map.this.elements
- override def size = Map.this.size
- override def get(k : K) = Map.this.get(k)
- override def put(k : K, e : E) = Map.this.put(k, e)
- }
- /**
- */
- def lense[F](f : E => F, g : F => E) : jcl.Map.Projection[K,F] = new Lense[F](f,g);
-
- protected class Lense[F](f : E => F, g : F => E) extends jcl.Map.Projection[K,F] {
- override def elements = Map.this.elements.map(k => Tuple2(k._1, f(k._2)));
- override def removeKey(key : K) = Map.this.removeKey(key).map(f);
- override def put(key : K, elem : F) = Map.this.put(key, g(elem)).map(f);
- override def get(key : K) = Map.this.get(key).map(f);
- override def lense[G](f0 : F => G, g0 : G => F) : jcl.Map.Projection[K,G] =
- Map.this.lense[G](x => f0(f(x)), y => g(g0(y)));
- override def size = size0;
- }
- protected class KeySet extends Set[K] {
- override def size = Map.this.size;
- override def add(k : K) = Map.this.put(k, default(k)) == None;
- override def elements = Map.this.elements.map(_._1);
- override def has(k : K) = Map.this.contains(k);
- }
- override def filterKeys(p : K => Boolean) : Map.Projection[K,E] = new Filter(p);
-
- protected class Filter(p : K => Boolean) extends Map.Projection[K,E] {
- override def elements = {
- val i = Map.this.elements.filter(e => p(e._1));
- new MutableIterator[(K,E)] {
- def next = i.next
- def hasNext = i.hasNext
- def remove : Unit = throw new NoSuchMethodException
- }
- }
- override def removeKey(key : K) = {
- if (!p(key)) throw new IllegalArgumentException;
- Map.this.removeKey(key);
- }
- override def contains(key : K) = p(key) && Map.this.contains(key);
- override def put(key : K, elem : E) = {
- if (!p(key)) throw new IllegalArgumentException;
- Map.this.put(key, elem);
- }
- override def get(key : K) = {
- if (!p(key)) None;
- else Map.this.get(key);
- }
- override def filterKeys(p0 : K => Boolean) : Map.Projection[K,E] =
- Map.this.filterKeys(e => p(e) && p0(e));
-
- override def size = size0;
- }
-}
-
-object Map {
- trait MutableIterableProjection[A] extends MutableIterable.Projection[A];
- trait Projection[K,E] extends MutableIterableProjection[(K,E)] with scala.collection.Map.Projection[K,E] with Map[K,E] {
- override def projection = this
- override def map[B](f : ((K,E)) => B) : MutableIterable.Projection[B] = super[MutableIterableProjection].map(f);
- }
- def apply[T,E](map0 : java.util.Map[T,E]) = new MapWrapper[T,E] {
- val underlying = map0
- }
-}
diff --git a/src/library/jvm/scala/collection/jcl/MapWrapper.scala b/src/library/jvm/scala/collection/jcl/MapWrapper.scala
deleted file mode 100644
index 7fed4d2e8f..0000000000
--- a/src/library/jvm/scala/collection/jcl/MapWrapper.scala
+++ /dev/null
@@ -1,76 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2008, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.collection.jcl
-
-/** A wrapper around a Java map.
- *
- * @author Sean McDirmid
- */
-trait MapWrapper[K, E] extends jcl.Map[K, E] {
- def underlying: java.util.Map[K, E]
- override def size = underlying.size
- override def isEmpty = underlying.isEmpty
- override def clear() = underlying.clear
-
- override def put(key: K, elem: E) = {
- //if (elem == null) throw new IllegalArgumentException;
- val ret = underlying.put(key, elem)
- if (ret == null) None else Some(ret.asInstanceOf[E])
- }
-
- override def get(key : K) : Option[E] = {
- val ret = underlying.get(key);
- if (ret == null) None else Some(ret.asInstanceOf[E]);
- }
-
- override def ++=(that : Iterable[Tuple2[K,E]]) : Unit = that match {
- case that : MapWrapper[_,_] => underlying.putAll(that.underlying);
- case _ => super.++=(that)
- }
-
- override def removeKey(key: K) = {
- val ret = underlying.remove(key)
- if (ret == null) None else Some(ret.asInstanceOf[E])
- }
-
- override def contains(key: K) = underlying.containsKey(key)
- override def keySet: Set.Projection[K] = new KeySet
- override def valueSet: MutableIterable.Projection[E] = new ValueSet
- override def elements: MutableIterator[Tuple2[K,E]] = new IteratorWrapper
-
- class IteratorWrapper extends MutableIterator[Tuple2[K,E]] {
- val underlying = MapWrapper.this.underlying.entrySet.iterator
- def hasNext = underlying.hasNext
- def remove = underlying.remove
- def next = {
- val next = underlying.next.asInstanceOf[java.util.Map.Entry[K,E]]
- Tuple2(next.getKey.asInstanceOf[K],next.getValue.asInstanceOf[E])
- }
- }
-
- class KeySet extends super.KeySet with SetWrapper[K] with Set.Projection[K] {
- val underlying = MapWrapper.this.underlying.keySet
- }
-
- class ValueSet extends IterableWrapper[E] with MutableIterable.Projection[E] {
- override def size = MapWrapper.this.size
- val underlying = MapWrapper.this.underlying.values
- override def has(e : E) = MapWrapper.this.underlying.containsValue(e)
- }
-
- override def toString = underlying.toString
- override def hashCode = underlying.hashCode
-
- override def equals(that : Any) = that match {
- case that: MapWrapper[_,_] => underlying == that.underlying
- case _ => super.equals(that)
- }
-}
diff --git a/src/library/jvm/scala/collection/jcl/MutableIterable.scala b/src/library/jvm/scala/collection/jcl/MutableIterable.scala
deleted file mode 100644
index 3988ed8d93..0000000000
--- a/src/library/jvm/scala/collection/jcl/MutableIterable.scala
+++ /dev/null
@@ -1,110 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.collection.jcl;
-
-/**
- * An iterable collection that supports remove operations.
- * Useful for representing projections of mutable collections that where only
- * the remove operation makes sense.
- *
- * @author Sean McDirmid
- */
-trait MutableIterable[A] extends scala.Collection[A] {
- /** @return true if t is in the collection.
- **/
- def has(t : A ) : Boolean = elements.contains(t);
-
- /** @return true if t was removed from this collection.
- **/
- def remove(t : A ) : Boolean = elements.remove(t);
- /** @return true if any element in that was removed from this collection.
- **/
- def removeAll(that : Iterable[A]) : Boolean = {
- var changed = false;
- that.foreach(t => changed = elements.remove(t) || changed);
- changed;
- }
- /** Operator shortcut for removeAll. */
- def --(that : Iterable[A]) : this.type = {
- removeAll(that); this;
- }
-
- /** @return the collection that t was removed from.
- */
- def -(t : A) : this.type = { remove(t); this; }
- /** retain only elements in the collection that predicate p is true for.
- */
- def retainOnly(p : A => Boolean) : Unit = elements.retain(p);
- /** retain only elements that are also in that.
- */
- def retainAll(that : Iterable[A]) : Boolean = elements.retain(s => that.exists(t => t == s));
-
- /** @return the current number of elements in the collection.
- */
- protected def size0 : Int = {
- var count = 0;
- val i = elements;
- while (i.hasNext) { count = count + 1; i.next; }
- count;
- }
-
- /** clear all elements from the collection.
- */
- def clear(): Unit = {
- val i = elements;
- while (i.hasNext) {
- i.next; i.remove;
- }
- }
- override def projection : MutableIterable.Projection[A] = new MutableIterable.Projection[A] {
- override def elements = MutableIterable.this.elements
- override def size = MutableIterable.this.size
- override def remove(t : A ) : Boolean = MutableIterable.this.remove(t)
- override def filter(p : A => Boolean) : MutableIterable.Projection[A] = super.filter(p)
- }
- /** The default implementation of a map over mutable iterable collections.
- **/
- override def elements : MutableIterator[A];
- protected class Map[B](f : A => B) extends MutableIterable.Projection[B] {
- override def elements = MutableIterable.this.elements.map(f)
- override def size = MutableIterable.this.size
- }
- trait Filter extends MutableIterable.Projection[A] {
- protected def p(a : A) : Boolean
- override def has(a : A) = if (!p(a)) false else MutableIterable.this.has(a);
- override def remove(a : A) = {
- if (!p(a)) throw new IllegalArgumentException;
- MutableIterable.this.remove(a);
- }
- override def filter(p0 : A => Boolean) : MutableIterable.Projection[A] =
- MutableIterable.this.projection.filter(a => p(a) && p0(a));
- def elements = {
- val i = MutableIterable.this.elements.filter(p);
- new MutableIterator[A] {
- def next = i.next
- def hasNext = i.hasNext
- def remove : Unit = throw new NoSuchMethodException
- }
- }
- def size = size0;
- }
-}
-
-object MutableIterable {
- trait Projection[A] extends MutableIterable[A] with Iterable.Projection[A] {
- override def projection = this
- override def map[B](f : A => B) : Projection[B] = new Map[B](f);
- override def filter(pp : A => Boolean) : Projection[A] = new Filter {
- def p(a : A) = pp(a)
- }
- }
-}
-
diff --git a/src/library/jvm/scala/collection/jcl/MutableIterator.scala b/src/library/jvm/scala/collection/jcl/MutableIterator.scala
deleted file mode 100644
index 5f92746358..0000000000
--- a/src/library/jvm/scala/collection/jcl/MutableIterator.scala
+++ /dev/null
@@ -1,70 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.collection.jcl;
-
-object MutableIterator {
- class Wrapper[A](val underlying : java.util.Iterator[A]) extends MutableIterator[A] {
- def hasNext = underlying.hasNext;
- def next = underlying.next.asInstanceOf[A];
- def remove = underlying.remove;
- }
-}
-
-/** An iterator that supports the remove operation.
- * These iterators wrap Java iterators, and so have the same fail fast
- * behavior when dealing with concurrent modifications.
- *
- * @author Sean McDirmid
- */
-trait MutableIterator[A] extends Iterator[A] {
- def remove : Unit;
-
- /* filter doesnt' support remove yet.
- override def filter(f : A => Boolean) : MutableIterator[A] = {
- val buffered = this.buffered0;
- new buffered.Filter(f);
- }
- */
-
- override def map[B](f: A => B) : MutableIterator[B] = new Map(f);
- /** A type-safe version of contains.
- **/
- def has(a: A) = exists(b => a == a);
-
- /** Finds and removes the first instance of "a" through the iterator.
- * After execution, the iterator's cursor is located where the removed
- * element existed.
- *
- * @param a ..
- * @return false
if "a" is not encountered in the iterator
- * and the iterator's cursor is located at the end of its elements.
- */
- def remove(a: A): Boolean = {
- while (hasNext)
- if (next == a) { remove; return true; }
- return false;
- }
- /** Removes all elements in the iterator that predicate "p" returns false on.
- **/
- def retain(p : A => Boolean) : Boolean = {
- var changed = false;
- while (hasNext)
- if (!p(next)) { remove; changed = true; }
- changed;
- }
-
- /** Standard implementation of a mapped iterator. **/
- class Map[B](f : A => B) extends MutableIterator[B] {
- def hasNext = MutableIterator.this.hasNext
- def next = f(MutableIterator.this.next)
- def remove = MutableIterator.this.remove
- }
-}
diff --git a/src/library/jvm/scala/collection/jcl/MutableSeq.scala b/src/library/jvm/scala/collection/jcl/MutableSeq.scala
deleted file mode 100644
index 559965c9ea..0000000000
--- a/src/library/jvm/scala/collection/jcl/MutableSeq.scala
+++ /dev/null
@@ -1,123 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.collection.jcl;
-
-/** A mutable sequence that supports the remove operation and is ordered.
- *
- * @author Sean McDirmid
- */
-trait MutableSeq[A] extends Seq[A] with MutableIterable[A] {
- protected class DefaultSeqIterator extends SeqIterator[Int,A] {
- protected var index = 0
- override def hasNext = index < length
- override def next = {
- if (!hasNext) throw new NoSuchElementException("no lookahead")
- index = index + 1
- MutableSeq.this.apply(index - 1)
- }
- override def hasPrevious = index > 0
- override def previous = {
- if (!hasPrevious) throw new NoSuchElementException
- index = index - 1
- MutableSeq.this.apply(index)
- }
-
- override def nextIndex = index
- override def previousIndex = {
- if (index == 0) throw new NoSuchElementException
- else index - 1
- }
- def remove = throw new UnsupportedOperationException
- }
- override def elements : SeqIterator[Int,A] = new DefaultSeqIterator
-
- override def isEmpty = super[MutableIterable].isEmpty;
-
- override def apply(idx : Int) = elements.seek(idx);
- override def projection : MutableSeq.Projection[A] = new MutableSeq.Projection[A] {
- override def length = MutableSeq.this.length
- override def elements = MutableSeq.this.elements
- override def apply(idx : Int) = MutableSeq.this.apply(idx)
- }
-
- /** Find the index of "a" in this sequence.
- * @returns None if the "a" is not in this sequence.
- */
- def indexOf(a : A) = elements.indexOf(a);
-
- override def length = {
- var i = elements;
- var sz = 0;
- while (i.hasNext) {
- sz = sz + 1;
- i.next;
- }
- sz;
- }
- protected trait Filter extends MutableSeq.Projection[A] {
- protected def p(a : A) : Boolean
- override def elements : SeqIterator[Int,A] = new FilterIterator(MutableSeq.this.elements);
- class FilterIterator(underlying : SeqIterator[Int,A]) extends SeqIterator[Int,A] {
- private var index = 0;
- protected def seekNext : Option[A] = {
- while (underlying.hasNext) {
- val next = underlying.next;
- if (p(next)) return Some(next);
- }
- return None;
- }
- protected def seekPrevious : Option[A] = {
- while (underlying.hasPrevious) {
- val previous = underlying.previous;
- if (p(previous)) return Some(previous);
- }
- return None;
- }
- def hasNext : Boolean = seekNext match {
- case None => false;
- case Some(_) => underlying.previous; true;
- }
- def nextIndex = index;
- def next = seekNext match {
- case None => throw new NoSuchElementException;
- case Some(result) => index = index + 1; result;
- }
- def hasPrevious : Boolean = seekPrevious match {
- case None => false;
- case Some(_) => underlying.previous; true;
- }
- def previousIndex = {
- if (index == 0) throw new NoSuchElementException;
- index - 1;
- }
- def previous = seekPrevious match {
- case None => throw new NoSuchElementException;
- case Some(result) => index = index - 1; result;
- }
- def remove = underlying.remove;
- }
- }
- protected class Map[B](f : A => B) extends super.Map[B](f) with MutableSeq.Projection[B] {
- override def elements = MutableSeq.this.elements.map(f);
- override def apply(idx : Int) = f(MutableSeq.this.apply(idx));
- override def size = length;
- }
-}
-object MutableSeq {
- trait Projection[A] extends MutableSeq[A] with MutableIterable.Projection[A] with Seq.Projection[A] {
- override def projection = this
- override def filter(pp : A => Boolean) : Projection[A] = new Filter {
- override def p(a : A) = pp(a)
- }
- override def map[B](f : A => B) : Projection[B] = new Map[B](f);
- }
-}
-
diff --git a/src/library/jvm/scala/collection/jcl/Ranged.scala b/src/library/jvm/scala/collection/jcl/Ranged.scala
deleted file mode 100644
index 054d9c381d..0000000000
--- a/src/library/jvm/scala/collection/jcl/Ranged.scala
+++ /dev/null
@@ -1,54 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.collection.jcl;
-
-/** Any collection (including maps) whose keys (or elements) are ordered.
- *
- * @author Sean McDirmid
- */
-trait Ranged[K,A] extends scala.collection.Ranged[K,A] with MutableIterable[A] {
- protected type SortedSelf <: Ranged[K,A];
-
- /** Comparison function that orders keys. */
- def compare(k0: K, k1: K): Int;
-
- /** Creates a ranged projection of this collection. Any mutations in the
- * ranged projection will update this collection and vice versa. Note: keys
- * are not garuanteed to be consistent between this collection and the projection.
- * This is the case for buffers where indexing is relative to the projection.
- *
- * @param from The lower-bound (inclusive) of the ranged projection.
- * None
if there is no lower bound.
- * @param until The upper-bound (exclusive) of the ranged projection.
- * None
if there is no upper bound.
- */
- def rangeImpl(from: Option[K], until: Option[K]) : SortedSelf;
- /** Creates a ranged projection of this collection with no upper-bound.
- ** @param from The lower-bound (inclusive) of the ranged projection.
- **/
- override final def from(from: K): SortedSelf = rangeImpl(Some(from), None);
- /** Creates a ranged projection of this collection with no lower-bound.
- ** @param until The upper-bound (exclusive) of the ranged projection.
- **/
- override final def until(until: K): SortedSelf = rangeImpl(None, Some(until));
-
- /** Creates a ranged projection of this collection with both a lower-bound and an upper-bound.
- ** @param from The upper-bound (exclusive) of the ranged projection.
- **/
- override final def range(from: K, until: K) : SortedSelf = rangeImpl(Some(from),Some(until));
-
- /** A wrapper around Java comparators. */
- protected class Comparator[K <% Ordered[K]] extends java.util.Comparator[Any] {
- def compare(x0 : Any, x1 : Any) = {
- x0.asInstanceOf[K].compare(x1.asInstanceOf[K]); //!!!
- }
- }
-}
diff --git a/src/library/jvm/scala/collection/jcl/SeqIterator.scala b/src/library/jvm/scala/collection/jcl/SeqIterator.scala
deleted file mode 100644
index 5461928735..0000000000
--- a/src/library/jvm/scala/collection/jcl/SeqIterator.scala
+++ /dev/null
@@ -1,58 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.collection.jcl;
-
-/** An iterator for a sequence that can move both forwards and backwards.
- * over a set of ordered keys.
- *
- * @author Sean McDirmid
- */
-trait SeqIterator[K,A] extends MutableIterator[A] {
- /** @returns The index at the iterator's cursor. */
- def nextIndex: K;
-
- /** @returns The index of the element before the iterator's cursor. */
- def previousIndex: K;
-
- /** @return The previous element, will move the iterator's cursor backwards. */
- def previous: A;
-
- /** @return True if and only if the iterator's cursor is not at the beging of the iteration. */
- def hasPrevious : Boolean;
-
- /** Winds the iteration forward until index "idx" is found */
- def seek(idx: K) = {
- while (nextIndex != idx) next;
- next;
- }
- /** finds the index of the next "a" in this iteration.
- *
- * @param a ..
- * @return None
if "a" is not found in the iteration.
- */
- def indexOf(a: A): Option[K] = {
- while (hasNext) {
- val ret = next;
- if (ret == a) return Some(previousIndex);
- }
- return None;
- }
-
- override def map[B](f: A => B) : SeqIterator[K,B] = new Map[B](f);
- class Map[B](f: A => B) extends super.Map[B](f) with SeqIterator[K,B] {
- override def hasPrevious = SeqIterator.this.hasPrevious;
- override def previous = f(SeqIterator.this.previous);
- override def previousIndex = SeqIterator.this.previousIndex;
- override def nextIndex = SeqIterator.this.nextIndex;
- override def map[C](g : B => C) : SeqIterator[K,C] =
- SeqIterator.this.map(a => g(f(a)));
- }
-}
diff --git a/src/library/jvm/scala/collection/jcl/Set.scala b/src/library/jvm/scala/collection/jcl/Set.scala
deleted file mode 100644
index 7ef9360c2a..0000000000
--- a/src/library/jvm/scala/collection/jcl/Set.scala
+++ /dev/null
@@ -1,72 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.collection.jcl
-
-/** Analogous to a Java set.
- *
- * @author Sean McDirmid
- */
-trait Set[A] extends scala.collection.mutable.Set[A] with Collection[A] {
- final def contains(a : A) = has(a)
-
- /** Add will return false if "a" already exists in the set. **/
- override def add(a: A): Boolean
-
- override def ++(i: Iterable[A]) : this.type = super[Collection].++(i)
- override def --(i: Iterable[A]) : this.type = super[Collection].--(i)
- override def +(t: A) : this.type = super[Collection].+(t)
- override def -(t: A) : this.type = super[Collection].-(t)
- override final def retain(f: A => Boolean) = retainOnly(f)
- override def isEmpty = super[Collection].isEmpty
- override def clear() = super.clear()
- override def subsetOf(set : scala.collection.Set[A]) = set match {
- case set : Set[_] => set.hasAll(this)
- case set => super.subsetOf(set)
- }
-
- override def transform(f: A => A) = {
- var toAdd : List[A] = Nil
- val i = elements
- while (i.hasNext) {
- val i0 = i.next
- val i1 = f(i0)
- if (i0 != i1) {
- i.remove; toAdd = i1 :: toAdd
- }
- }
- addAll(toAdd)
- }
- class Filter(pp : A => Boolean) extends super.Filter with Set.Projection[A] {
- override def p(a : A) = pp(a)
- override def retainOnly(p0 : A => Boolean): Unit =
- Set.this.retainOnly(e => !p(e) || p0(e))
- override def add(a : A) = {
- if (!p(a)) throw new IllegalArgumentException
- else Set.this.add(a)
- }
- }
- override def projection : Set.Projection[A] = new Set.Projection[A] {
- override def add(a: A): Boolean = Set.this.add(a)
- override def elements = Set.this.elements
- override def size = Set.this.size
- override def has(a : A) : Boolean = Set.this.has(a)
- }
-}
-
-object Set {
- trait Projection[A] extends Collection.Projection[A] with Set[A] {
- override def filter(p : A => Boolean) : Projection[A] = new Filter(p);
- override def projection = this
- }
- def apply[T](set : java.util.Set[T]) = new SetWrapper[T] {
- val underlying = set
- }
-}
diff --git a/src/library/jvm/scala/collection/jcl/SetWrapper.scala b/src/library/jvm/scala/collection/jcl/SetWrapper.scala
deleted file mode 100644
index 5aeaf57a1b..0000000000
--- a/src/library/jvm/scala/collection/jcl/SetWrapper.scala
+++ /dev/null
@@ -1,22 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.collection.jcl;
-
-/** Used to wrap Java sets.
- *
- * @author Sean McDirmid
- */
-trait SetWrapper[A] extends Set[A] with CollectionWrapper[A] {
- def underlying: java.util.Set[A];
- override def isEmpty = super[CollectionWrapper].isEmpty;
- override def clear() = super[CollectionWrapper].clear;
- override def size = underlying.size;
-}
diff --git a/src/library/jvm/scala/collection/jcl/Sorted.scala b/src/library/jvm/scala/collection/jcl/Sorted.scala
deleted file mode 100644
index 7bbe49da75..0000000000
--- a/src/library/jvm/scala/collection/jcl/Sorted.scala
+++ /dev/null
@@ -1,46 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.collection.jcl;
-
-/** Any collection (including maps) whose keys (or elements) are ordered.
- *
- * @author Sean McDirmid
- */
-trait Sorted[K,A] extends scala.collection.Sorted[K,A] with Ranged[K,A] {
- override protected type SortedSelf <: Sorted[K,A];
- /** return as a projection the set of keys in this collection */
- override def keySet : SortedSet[K];
-
- /** Creates a ranged projection of this collection. Any mutations in the
- * ranged projection will update this collection and vice versa. Keys
- * are garuanteed to be consistent between the collection and its projection.
- *
- * @param from The lower-bound (inclusive) of the ranged projection.
- * None
if there is no lower bound.
- * @param until The upper-bound (exclusive) of the ranged projection.
- * None
if there is no upper bound.
- */
- override def rangeImpl(from: Option[K], until: Option[K]) : SortedSelf;
-
- /** Create a range projection of this collection with no lower-bound.
- ** @param to The upper-bound (inclusive) of the ranged projection.
- **/
- final override def to(to : K): SortedSelf = {
- // tough!
- val i = keySet.from(to).elements;
- if (!i.hasNext) return this.asInstanceOf[SortedSelf];
- val next = i.next;
- if (next == to) {
- if (!i.hasNext) return this.asInstanceOf[SortedSelf];
- else return until(i.next);
- } else return until(next);
- }
-}
diff --git a/src/library/jvm/scala/collection/jcl/SortedMap.scala b/src/library/jvm/scala/collection/jcl/SortedMap.scala
deleted file mode 100644
index be5591e7b8..0000000000
--- a/src/library/jvm/scala/collection/jcl/SortedMap.scala
+++ /dev/null
@@ -1,103 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.collection.jcl;
-
-object SortedMap {
- trait Projection[K,E] extends Map.Projection[K,E] with SortedMap[K,E] {
- override def projection = this
- }
- def apply[T,E](map0 : java.util.SortedMap[T,E]) = new SortedMapWrapper[T,E] {
- val underlying = map0
- }
-}
-/** A map whose keys are sorted.
- *
- * @author Sean McDirmid
- */
-trait SortedMap[K,E] extends scala.collection.SortedMap[K,E] with Map[K,E] with Sorted[K,Tuple2[K,E]] {
- final protected type SortedSelf = SortedMap[K,E];
- override def compare(k0 : K, k1 : K) : Int;
- override def firstKey : K = elements.next._1;
- override def lastKey : K = {
- val i = elements;
- var last : K = i.next._1;
- while (i.hasNext) last = i.next._1;
- last;
- }
- override def rangeImpl(from : Option[K], until : Option[K]) : SortedMap[K,E] = Range(from, until);
- override def keySet : SortedSet.Projection[K] = new KeySet;
-
- override def projection : SortedMap.Projection[K,E] = new SortedMap.Projection[K,E] {
- override def elements = SortedMap.this.elements
- override def size = SortedMap.this.size
- override def get(k : K) = SortedMap.this.get(k)
- override def put(k : K, e : E) = SortedMap.this.put(k, e)
- override def compare(k0 : K, k1 : K) = SortedMap.this.compare(k0, k1)
- }
-
- override def lense[F](f : E => F, g : F => E) : jcl.SortedMap.Projection[K,F] = new Lense[F](f,g);
-
- protected class Lense[F](f : E => F, g : F => E) extends super.Lense[F](f,g) with SortedMap.Projection[K,F] {
- def compare(k0 : K, k1 : K) = SortedMap.this.compare(k0, k1);
- override def filterKeys(p : K => Boolean) : SortedMap.Projection[K,F] =
- SortedMap.this.projection.filterKeys(p).lense(f,g);
- override def lense[G](f0 : F => G, g0 : G => F) : jcl.SortedMap.Projection[K,G] =
- SortedMap.this.lense[G]({x:E => f0(f(x))}, {y:G => g(g0(y))});
- override def rangeImpl(from : Option[K], until : Option[K]) =
- SortedMap.this.rangeImpl(from,until).lense(f,g);
- }
- protected class KeySet extends super.KeySet with SortedSet.Projection[K] {
- def compare(k0 : K, k1 : K) = SortedMap.this.compare(k0,k1);
- override def firstKey = SortedMap.this.firstKey;
- override def lastKey = SortedMap.this.lastKey;
- override def rangeImpl(from : Option[K], until : Option[K]) =
- SortedMap.this.rangeImpl(from,until).keySet;
- }
- override def filterKeys(p : K => Boolean) : SortedMap.Projection[K,E] = new Filter(p);
- protected class Filter(p : K => Boolean) extends super.Filter(p) with SortedMap.Projection[K,E] {
- def compare(k0 : K, k1 : K) = SortedMap.this.compare(k0,k1);
- override def filterKeys(p0 : K => Boolean) : SortedMap.Projection[K,E] =
- SortedMap.this.filterKeys(k => p(k) && p0(k));
- override def rangeImpl(from : Option[K], until : Option[K]) : SortedMap.Projection[K,E] =
- SortedMap.this.Range(from, until).projection.filterKeys(p);
- }
- protected def Range(from : Option[K], until : Option[K]) : SortedMap.Projection[K,E] = new Range(from,until);
- protected class Range(from : Option[K], until : Option[K]) extends super.Filter(key => {
- ((from == None || (compare(from.get,key) <= 0)) &&
- (until == None || (compare(key,until.get) < 0)));
- }) with SortedMap.Projection[K,E] {
- def compare(k0 : K, k1 : K) = SortedMap.this.compare(k0,k1);
- private def contains0(key : K) =
- (from == None || (compare(from.get,key) <= 0)) &&
- (until == None || (compare(key,until.get) < 0));
-
- override def contains(key : K) = SortedMap.this.contains(key) && contains0(key);
- override def get(key : K) = if (!contains0(key)) None else SortedMap.this.get(key);
- override def put(key : K, elem : E) = {
- if (!contains0(key)) throw new IllegalArgumentException;
- SortedMap.this.put(key, elem);
- }
- override def rangeImpl(from : Option[K], until : Option[K]) : SortedMap[K,E] = {
- if (this.from != None && from == None) return rangeImpl(this.from, until);
- if (this.until != None && until == None) return rangeImpl(from, this.until);
- if (from != None && compare(this.from.get, from.get) > 0) return rangeImpl(this.from, until);
- if (until != None && compare(this.until.get, until.get) < 0) return rangeImpl(from, this.until);
- SortedMap.this.Range(from, until);
- }
- override def filterKeys(p : K => Boolean) : SortedMap.Projection[K,E] = new Filter(p);
- protected class Filter(p : K => Boolean) extends super.Filter(p) with SortedMap.Projection[K,E] {
- //def compare(k0 : K, k1 : K) = Range.this.compare(k0, k1);
- override def filterKeys(p0 : K => Boolean) = Range.this.projection.filterKeys(k => p(k) && p0(k));
- override def rangeImpl(from : Option[K], until : Option[K]) : SortedMap.Projection[K,E] =
- Range.this.rangeImpl(from,until).projection.filterKeys(p);
- }
- }
-}
diff --git a/src/library/jvm/scala/collection/jcl/SortedMapWrapper.scala b/src/library/jvm/scala/collection/jcl/SortedMapWrapper.scala
deleted file mode 100644
index c706a4fec9..0000000000
--- a/src/library/jvm/scala/collection/jcl/SortedMapWrapper.scala
+++ /dev/null
@@ -1,39 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.collection.jcl;
-
-/** A sorted map that wraps an underlying Java sorted map.
- *
- * @author Sean McDirmid
- */
-trait SortedMapWrapper[K,E] extends SortedMap[K,E] with MapWrapper[K,E] {
- override def underlying : java.util.SortedMap[K,E];
- /** the comparator function of this sorted map is defined in terms
- * of the underlying sorted map's comparator.
- */
- def compare(k0 : K, k1 : K) = underlying.comparator.compare(k0,k1);
- override def firstKey = underlying.firstKey.asInstanceOf[K];
- override def lastKey = underlying.lastKey.asInstanceOf[K];
- override def keySet : SortedSet.Projection[K] = new KeySet;
- override protected def Range(from : Option[K], until : Option[K]) = new Range(from,until);
- protected class Range(from : Option[K], until : Option[K]) extends super.Range(from,until) with SortedMapWrapper[K,E] {
- val underlying = Tuple2(from,until) match {
- case Tuple2(None,None) => throw new IllegalArgumentException;
- case Tuple2(Some(from),None) => SortedMapWrapper.this.underlying.tailMap(from);
- case Tuple2(None,Some(until)) => SortedMapWrapper.this.underlying.headMap(until);
- case Tuple2(Some(from),Some(until)) => SortedMapWrapper.this.underlying.subMap(from,until);
- }
- override def compare(k0 : K, k1 : K) = super[SortedMapWrapper].compare(k0, k1);
- }
- protected class KeySet extends super[SortedMap].KeySet with SetWrapper[K] with SortedSet.Projection[K] {
- val underlying = SortedMapWrapper.this.underlying.keySet;
- }
-}
diff --git a/src/library/jvm/scala/collection/jcl/SortedSet.scala b/src/library/jvm/scala/collection/jcl/SortedSet.scala
deleted file mode 100644
index 5050a1c36a..0000000000
--- a/src/library/jvm/scala/collection/jcl/SortedSet.scala
+++ /dev/null
@@ -1,99 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.collection.jcl;
-import Predef._
-
-object SortedSet {
- trait Projection[A] extends Set.Projection[A] with SortedSet[A] {
- override def projection = this
- override def filter(p : A => Boolean) : Projection[A] = new Filter(p);
- }
- def apply[T](set : java.util.SortedSet[T]) = new SortedSetWrapper[T] {
- val underlying = set
- }
-
-}
-
-/** Analogous to a Java sorted set.
- *
- * @author Sean McDirmid
- */
-trait SortedSet[A] extends scala.collection.SortedSet[A] with jcl.Set[A] with Sorted[A,A] {
- final protected type SortedSelf = SortedSet[A];
- override def keySet = this;
- def compare(a0 : A, a1 : A) : Int;
- override def firstKey : A = {
- val i = elements;
- if (i.hasNext) i.next;
- else throw new NoSuchElementException;
- }
- override def subsetOf(that : scala.collection.Set[A]) = super[SortedSet].subsetOf(that);
- override def hasAll(that : Iterable[A]) = super[Sorted].hasAll(that.elements);
-
- override def lastKey : A = {
- var last : A = null.asInstanceOf[A];
- val i = elements;
- while (i.hasNext) last = i.next;
- if (last == null) throw new NoSuchElementException;
- else last;
- }
- override def rangeImpl(from : Option[A], until : Option[A]) : SortedSet[A] = new Range(from, until);
- override def projection : SortedSet.Projection[A] = new SortedSet.Projection[A] {
- override def compare(a0 : A, a1 : A) = SortedSet.this.compare(a0, a1)
- override def add(a: A): Boolean = SortedSet.this.add(a)
- override def elements = SortedSet.this.elements
- override def size = SortedSet.this.size
- override def has(a : A) : Boolean = SortedSet.this.has(a)
- }
-
- protected class Filter(pp : A => Boolean) extends super.Filter(pp) with SortedSet.Projection[A] {
- override def p(a : A) = pp(a)
- def compare(a0 : A, a1 : A) : Int = SortedSet.this.compare(a0, a1);
- override def filter(p0 : A => Boolean) = SortedSet.this.projection.filter(k => p(k) && p0(k));
- }
- protected class Range(from : Option[A], until : Option[A]) extends Filter(key => {
- (from == None || (compare(from.get,key) <= 0)) &&
- (until == None || (compare(key,until.get) < 0));
- }) with SortedSet.Projection[A] {
- if (from == None && until == None) throw new IllegalArgumentException;
- if (from != None && until != None && !(SortedSet.this.compare(from.get, until.get) < 0))
- throw new IllegalArgumentException;
- //override def elements : MutableIterator[A] =
- // new RangeIterator(SortedSet.this.elements.buffered0);
- private def contains1(key : A) =
- (from == None || (compare(from.get,key) <= 0)) &&
- (until == None || (compare(key,until.get) < 0));
- override def has(elem : A) = contains1(elem) && SortedSet.this.has(elem);
- override def rangeImpl(from : Option[A], until : Option[A]) : SortedSet[A] = {
- if (this.from != None && from == None) return rangeImpl(this.from, until);
- if (this.until != None && until == None) return rangeImpl(from, this.until);
- if (from != None && compare(this.from.get, from.get) > 0) return rangeImpl(this.from, until);
- if (until != None && compare(this.until.get, until.get) < 0) return rangeImpl(from, this.until);
- SortedSet.this.rangeImpl(from, until);
- }
- /*
- class RangeIterator(underlying : MutableIterator[A]#Buffered) extends MutableIterator[A] {
- if (from != None)
- underlying.seekNext(a => compare(from.get, a) <= 0);
-
- private def okNext(a : A) =
- if (until == None) true;
- else compare(a, until.get) < 0;
-
- def hasNext = underlying.hasNext && okNext(underlying.peekNext);
- def next = underlying.seekNext(okNext) match {
- case Some(result) => underlying.next; result;
- case None => throw new NoSuchElementException;
- }
- def remove = underlying.remove;
- }*/
- }
-}
diff --git a/src/library/jvm/scala/collection/jcl/SortedSetWrapper.scala b/src/library/jvm/scala/collection/jcl/SortedSetWrapper.scala
deleted file mode 100644
index 39b066bfd7..0000000000
--- a/src/library/jvm/scala/collection/jcl/SortedSetWrapper.scala
+++ /dev/null
@@ -1,39 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.collection.jcl;
-
-/** A
.
- *
- * @author Sean McDirmid
- */
-class TreeSet[A <% Ordered[A]] extends SortedSetWrapper[A] { ts =>
- val underlying = new java.util.TreeSet[A](new Comparator[A])
- override def clone: TreeSet[A] =
- new TreeSet[A] {
- override val underlying =
- ts.underlying.clone().asInstanceOf[java.util.TreeSet[A]]
- }
-}
diff --git a/src/library/jvm/scala/collection/jcl/WeakHashMap.scala b/src/library/jvm/scala/collection/jcl/WeakHashMap.scala
deleted file mode 100644
index 1d8ff4207e..0000000000
--- a/src/library/jvm/scala/collection/jcl/WeakHashMap.scala
+++ /dev/null
@@ -1,31 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2008, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.collection.jcl
-
-/** java.util.Map
interface.
- *
- * @author Matthias Zenger
- * @version 1.0, 21/07/2003
- * @deprecated Use scala.collection.jcl.Map(jmap)
instead
- */
-@deprecated class JavaMapAdaptor[A, B](jmap: java.util.Map[A, B]) extends Map[A, B] {
-
- def size: Int = jmap.size()
-
- def get(key: A): Option[B] =
- if (jmap.containsKey(key)) Some(jmap.get(key).asInstanceOf[B]) else None
-
- override def isEmpty: Boolean = jmap.isEmpty()
-
- override def apply(key: A): B = jmap.get(key).asInstanceOf[B]
-
- override def contains(key: A): Boolean = jmap.containsKey(key)
-
- override def isDefinedAt(key: A) = jmap.containsKey(key)
-
- override def keys: Iterator[A] = new Iterator[A] {
- val iter = jmap.keySet().iterator()
- def hasNext = iter.hasNext()
- def next = iter.next().asInstanceOf[A]
- }
-
- override def values: Iterator[B] = new Iterator[B] {
- val iter = jmap.values().iterator()
- def hasNext = iter.hasNext()
- def next = iter.next().asInstanceOf[B]
- }
-
- def elements: Iterator[(A, B)] = new Iterator[(A, B)] {
- val iter = jmap.keySet().iterator()
- def hasNext = iter.hasNext()
- def next = {
- val key = iter.next().asInstanceOf[A]
- (key, apply(key))
- }
- }
-
- def update(key: A, value: B): Unit = { val x = jmap.put(key, value); }
-
- def -= (key: A): Unit = { val x = jmap.remove(key); }
-
- override def clear(): Unit = jmap.clear()
-
- override def clone(): Map[A, B] = {
- val res = new HashMap[A, B]
- res ++= this
- res
- }
-}
diff --git a/src/library/jvm/scala/collection/mutable/JavaSetAdaptor.scala b/src/library/jvm/scala/collection/mutable/JavaSetAdaptor.scala
deleted file mode 100644
index f3a6f3386d..0000000000
--- a/src/library/jvm/scala/collection/mutable/JavaSetAdaptor.scala
+++ /dev/null
@@ -1,47 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2006, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.collection.mutable
-
-
-/** This class can be used as an adaptor to create mutable sets from
- * Java classes that implement interface java.util.Set
.
- *
- * @author Matthias Zenger
- * @version 1.0, 19/09/2003
- * @deprecated Use scala.collection.jcl.Set(jmap)
instead
- */
-@deprecated class JavaSetAdaptor[A](jset: java.util.Set[A]) extends Set[A] {
-
- def size: Int = jset.size()
-
- override def isEmpty: Boolean = jset.isEmpty()
-
- def contains(elem: A): Boolean = jset.contains(elem)
-
- def elements: Iterator[A] = new Iterator[A] {
- val iter = jset.iterator()
- def hasNext = iter.hasNext()
- def next = iter.next().asInstanceOf[A]
- }
-
- def +=(elem: A): Unit = { val x = jset.add(elem); }
-
- def -=(elem: A): Unit = { val x = jset.remove(elem); }
-
- override def clear(): Unit = jset.clear()
-
- override def clone(): Set[A] = {
- val res = new HashSet[A]
- res ++= this
- res
- }
-}
diff --git a/src/library/jvm/scala/concurrent/ops.scala b/src/library/jvm/scala/concurrent/ops.scala
deleted file mode 100644
index 0d3c485300..0000000000
--- a/src/library/jvm/scala/concurrent/ops.scala
+++ /dev/null
@@ -1,78 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.concurrent
-
-
-import java.lang.Thread
-
-/** The object ops
...
- *
- * @author Martin Odersky, Stepan Koltsov
- * @version 1.0, 12/03/2003
- */
-object ops {
-
- /**
- * @param p ...
- */
- def spawn(p: => Unit) = {
- val t = new Thread() { override def run() = p }
- t.start()
- }
-
- /**
- * @param p ...
- * @return ...
- */
- def future[A](p: => A): () => A = {
- val result = new SyncVar[A]
- spawn { result setWithCatch p }
- () => result.get
- }
-
- /**
- * @param xp ...
- * @param yp ...
- * @return ...
- */
- def par[A, B](xp: => A, yp: => B): (A, B) = {
- val y = new SyncVar[B]
- spawn { y setWithCatch yp }
- (xp, y.get)
- }
-
- /**
- * @param start ...
- * @param end ...
- * @param p ...
- */
- def replicate(start: Int, end: Int)(p: Int => Unit) {
- if (start == end)
- ()
- else if (start + 1 == end)
- p(start)
- else {
- val mid = (start + end) / 2
- spawn { replicate(start, mid)(p) }
- replicate(mid, end)(p)
- }
- }
-
-/*
- def parMap[a,b](f: a => b, xs: Array[a]): Array[b] = {
- val results = new Array[b](xs.length);
- replicate(0, xs.length) { i => results(i) = f(xs(i)) }
- results
- }
-*/
-
-}
diff --git a/src/library/jvm/scala/io/BufferedSource.scala b/src/library/jvm/scala/io/BufferedSource.scala
deleted file mode 100644
index 99d8d036ae..0000000000
--- a/src/library/jvm/scala/io/BufferedSource.scala
+++ /dev/null
@@ -1,98 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2008, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.io
-
-import java.io.InputStream
-import java.nio.{ByteBuffer, CharBuffer}
-import java.nio.channels.{ByteChannel, Channels, ReadableByteChannel}
-import java.nio.charset.{Charset, CharsetDecoder}
-
-object BufferedSource {
-
- /** same as fromInputStream(inpStream, Charset.forName(enc), buffer_size, do_reset) */
- def fromInputStream(inpStream: InputStream, enc: String, buffer_size: Int, do_reset: () => Source): BufferedSource =
- fromInputStream(inpStream, Charset.forName(enc), buffer_size, do_reset)
-
- /** same as fromInputStream(inpStream, charSet.newDecoder(), buffer_size, do_reset) */
- def fromInputStream(inpStream: InputStream, charSet: Charset, buffer_size: Int, do_reset: () => Source): BufferedSource =
- fromInputStream(inpStream, charSet.newDecoder(), buffer_size, do_reset)
-
- /** constructs a BufferedSource instance from an input stream, using given decoder */
- def fromInputStream(inpStream: InputStream, decoder: CharsetDecoder, buffer_size: Int, do_reset: () => Source): BufferedSource = {
- val byteChannel = Channels.newChannel(inpStream)
- return new BufferedSource(byteChannel, decoder) {
- val buf_size = buffer_size
- override def reset = do_reset()
- def close { inpStream.close }
- }
- }
-}
-
-/** This object provides convenience methods to create an iterable
- * representation of a source file.
- *
- * @author Burak Emir
- * @version 1.0, 19/08/2004
- */
-abstract class BufferedSource(byteChannel: ReadableByteChannel, decoder: CharsetDecoder) extends Source {
-
- val buf_size: Int
-
- def close: Unit
-
- val byteBuffer = ByteBuffer.allocate(buf_size)
- var charBuffer = CharBuffer.allocate(buf_size)
- byteBuffer.position(byteBuffer.limit())
- charBuffer.position(charBuffer.limit())
- decoder.reset()
- var endOfInput = false
-
- def fillBuffer() = {
- byteBuffer.compact()
- charBuffer.position(0)
- var num_bytes = byteChannel.read(byteBuffer)
- while (0 == num_bytes) {
- Thread.sleep(1); // wait 1 ms for new data
- num_bytes = byteChannel.read(byteBuffer)
- }
- num_bytes match {
- case -1 =>
- endOfInput = true;
- byteBuffer.position(0)
- decoder.decode(byteBuffer, charBuffer, true)
- decoder.flush(charBuffer)
- case num_bytes =>
- endOfInput = false
- byteBuffer.flip()
- decoder.decode(byteBuffer, charBuffer, false)
- charBuffer.flip()
- }
- }
- override val iter = new Iterator[Char] {
- var buf_char = {
- fillBuffer()
- if (endOfInput) ' ' else charBuffer.get()
- }
- def hasNext = { charBuffer.remaining() > 0 || !endOfInput}
- def next = {
- val c = buf_char
- if (charBuffer.remaining() == 0) {
- fillBuffer()
- }
- if (!endOfInput) {
- buf_char = charBuffer.get()
- }
- c
- }
- }
-}
-
diff --git a/src/library/jvm/scala/io/Source.scala b/src/library/jvm/scala/io/Source.scala
deleted file mode 100644
index 90bff94028..0000000000
--- a/src/library/jvm/scala/io/Source.scala
+++ /dev/null
@@ -1,400 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2008, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.io
-
-
-import java.io.{BufferedInputStream, File, FileInputStream, InputStream,
- PrintStream}
-import java.nio.{ByteBuffer, CharBuffer}
-import java.nio.charset.Charset
-import java.net.{URI, URL}
-
-/** This object provides convenience methods to create an iterable
- * representation of a source file.
- *
- * @author Burak Emir
- * @version 1.0, 19/08/2004
- */
-object Source {
-
- val DefaultBufSize = 2048
-
- val NoReset: () => Source = () => throw new UnsupportedOperationException()
-
- /** Creates a Source
instance from the given array of bytes,
- * with empty description.
- *
- * @param bytes ...
- * @return the created Source
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))
-
- /** Creates a Source
instance from a single character.
- *
- * @param c ...
- * @return the create Source
instance.
- */
- def fromChar(c: Char): Source = {
- val it = Iterator.single(c)
- new Source {
- def reset() = fromChar(c)
- val iter = it
- }
- }
-
- /** creates Source from array of characters, with empty description.
- *
- * @param chars ...
- * @return ...
- */
- def fromChars(chars: Array[Char]): Source = {
- val it = chars.elements
- new Source {
- def reset() = fromChars(chars)
- val iter = it
- }
- }
-
- /** creates Source from string, with empty description.
- *
- * @param s ...
- * @return ...
- */
- def fromString(s: String): Source = {
- val it = s.elements
- new Source {
- def reset() = fromString(s)
- val iter = it
- }
- }
-
- /** creates Source from file with given name, setting its description to
- * filename.
- */
- def fromFile(name: String): Source =
- fromFile(name, util.Properties.encodingString)
-
- /** creates Source from file with given name, using given encoding, setting
- * its description to filename.
- */
- def fromFile(name: String, enc: String): Source =
- fromFile(new File(name), enc)
-
- /** creates Source
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)
-
- /** Creates Source from file
, using given character encoding,
- * setting its description to filename. Input is buffered in a buffer of
- * size bufferSize
.
- */
- def fromFile(file: File, enc: String, bufferSize: Int): Source = {
- val inpStream = new FileInputStream(file)
- val size = if (bufferSize > 0) bufferSize else Source.DefaultBufSize
- setFileDescriptor(file,
- BufferedSource.fromInputStream(inpStream, enc, size, { () => fromFile(file, enc, size)}))
- }
-
- /** This method sets the descr property of the given source to a string of the form "file:"+path
- * @param file the file whose path we want to describe
- * @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 ...
- * @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
- }
-
- /** same as fromInputStream(url.openStream(), enc)
- */
- def fromURL(url: URL, enc:String): Source =
- fromInputStream(url.openStream(), enc)
-
- /** reads data from istream
into a byte array, and calls
- * fromBytes
with given encoding enc
.
- * If maxlen
is given, reads not more bytes than maxlen
;
- * if maxlen
was not given, or was <= 0
, then
- * whole istream
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, Source.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)
- }
-
- /** same as BufferedSource.fromInputStream(is, enc, Source.DefaultBufSize)
- */
- def fromInputStream(is: InputStream, enc: String): Source =
- BufferedSource.fromInputStream(is, enc, Source.DefaultBufSize, { () => fromInputStream(is, enc) })
-
- /** same as BufferedSource.fromInputStream(is, "utf-8", Source.DefaultBufSize) */
- def fromInputStream(is: InputStream): Source =
- BufferedSource.fromInputStream(is, "utf-8", Source.DefaultBufSize, { () => fromInputStream(is) })
-
-}
-
-/** The class Source
implements an iterable representation
- * of source files. Calling method reset
returns an identical,
- * resetted source.
- *
- * @author Burak Emir
- * @version 1.0
- */
-abstract class Source extends Iterator[Char] {
-
- // ------ protected values
-
- /** the actual iterator */
- protected val iter: Iterator[Char]
-
- protected var cline = 1
- protected var ccol = 1
-
- // ------ public values
-
- /** position of last character returned by next*/
- var pos = 0
-
- /** the last character returned by next.
- * the value before the first call to next is undefined.
- */
- var ch: Char = _
-
- /** description of this source, default empty */
- var descr: String = ""
-
- var nerrors = 0
- var nwarnings = 0
-
- /** default col increment for tabs '\t', set to 4 initially
- */
- var tabinc = 4
-
- //
- // -- methods
- //
-
- /** convenience method, returns given line (not including newline)
- * from Source.
- *
- * @param line the line index, first line is 1
- * @return the character string of the specified line.
- * @throws scala.compat.Platform.IllegalArgumentException
- *
- */
- def getLine(line: Int): String = { // faster than getLines.drop(line).next
- // todo: should @throws scala.compat.Platform.IndexOutOfBoundsException
- if (line < 1) throw new IllegalArgumentException(line.toString);
- val buf = new StringBuilder()
- val it = reset
- var i = 0
-
- while (it.hasNext && i < (line-1))
- if ('\n' == it.next)
- i += 1;
-
- if (!it.hasNext) // this should not happen
- throw new IllegalArgumentException(
- "line " + line + " does not exist"
- );
-
- var ch = it.next
- while (it.hasNext && '\n' != ch) {
- buf append ch
- ch = it.next
- }
-
- if ('\n' != ch)
- buf append ch
-
- val res = buf.toString()
- buf setLength 0 // hopefully help collector to deallocate StringBuilder
- res
- }
-
- /** returns an iterator who returns lines (including newline character).
- * a line ends in \n.
- */
- def getLines: Iterator[String] = new Iterator[String] {
- val buf = new StringBuilder
- def next = {
- var ch = iter.next
- while(ch != '\n' && iter.hasNext) {
- buf append ch
- ch = iter.next
- }
- buf.append(ch)
- val res = buf.toString()
- buf setLength 0 // clean things up for next call of "next"
- res
- }
- def hasNext = iter.hasNext
- }
- /** Returns true
if this source has more characters.
- */
- def hasNext = iter.hasNext
-
- /** returns next character and has the following side-effects: updates
- * position (ccol and cline) and assigns the character to ch
- */
- def next = {
- ch = iter.next
- pos = Position.encode(cline,ccol)
- ch match {
- case '\n' =>
- ccol = 1
- cline += 1
- case '\t' =>
- ccol += tabinc
- case _ =>
- ccol += 1
- }
- ch
- }
-
- /** Reports an error message to console.
- *
- * @param pos ...
- * @param msg the error message to report
- */
- def reportError(pos: Int, msg: String) {
- reportError(pos, msg, java.lang.System.out)
- }
-
- /** Reports an error message to the output stream out
.
- *
- * @param pos ...
- * @param msg the error message to report
- * @param out ...
- */
- def reportError(pos: Int, msg: String, out: PrintStream) {
- nerrors = nerrors + 1
- report(pos, msg, out)
- }
-
- /**
- * @param pos ...
- * @param msg the error message to report
- * @param out ...
- */
- def report(pos: Int, msg: String, out: PrintStream) {
- val buf = new StringBuilder
- val line = Position.line(pos)
- val col = Position.column(pos)
- buf.append(descr + ":" + line + ":" + col + ": " + msg)
- buf.append(getLine(line))
- var i = 1
- while (i < col) {
- buf.append(' ')
- i += 1
- }
- buf.append('^')
- out.println(buf.toString)
- }
-
- /** Reports a warning message to java.lang.System.out
.
- *
- * @param pos ...
- * @param msg the warning message to report
- */
- def reportWarning(pos: Int, msg: String) {
- reportWarning(pos, msg, java.lang.System.out)
- }
-
- /**
- * @param pos ...
- * @param msg the warning message to report
- * @param out ...
- */
- def reportWarning(pos: Int, msg: String, out: PrintStream) {
- nwarnings = nwarnings + 1
- report(pos, "warning! " + msg, out)
- }
-
- /** the actual reset method */
- def reset(): Source
-
-}
diff --git a/src/library/jvm/scala/reflect/BeanInfo.scala b/src/library/jvm/scala/reflect/BeanInfo.scala
deleted file mode 100644
index a5ea0fb975..0000000000
--- a/src/library/jvm/scala/reflect/BeanInfo.scala
+++ /dev/null
@@ -1,22 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2008, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.reflect
-
-/**
- * @BeanProperty
- * var status = ""
- *
- * def setStatus(s: String) { this.status = s }
- * def getStatus: String = this.status
- *
- * setStatus
from
- * Scala,
- * you should use the normal Scala access and assignment.
- * equals
method that overrides the
- * default equals because Java's boxed primitives are utterly broken. This equals
- * is inserted instead of a normal equals by the Scala compiler (in the
- * ICode phase, method genEqEqPrimitive
) only when either
- * side of the comparison is a subclass of AnyVal
, of
- * java.lang.Number
, of java.lang.Character
or
- * is exactly Any
or AnyRef
. */
- public static boolean equals(Object a, Object b) {
- if (a == null || b == null)
- return a == b;
- if (a.equals(b))
- return true;
- if (a instanceof Number || a instanceof Character || b instanceof Number || b instanceof Character) {
- int acode = typeCode(a);
- int bcode = typeCode(b);
- int maxcode = (acode < bcode) ? bcode : acode;
- if (maxcode <= INT) {
- int aa = (acode == CHAR) ? ((Character) a).charValue() : ((Number) a).intValue();
- int bb = (bcode == CHAR) ? ((Character) b).charValue() : ((Number) b).intValue();
- return aa == bb;
- }
- if (maxcode <= LONG) {
- long aa = (acode == CHAR) ? ((Character) a).charValue() : ((Number) a).longValue();
- long bb = (bcode == CHAR) ? ((Character) b).charValue() : ((Number) b).longValue();
- return aa == bb;
- }
- if (maxcode <= FLOAT) {
- float aa = (acode == CHAR) ? ((Character) a).charValue() : ((Number) a).floatValue();
- float bb = (bcode == CHAR) ? ((Character) b).charValue() : ((Number) b).floatValue();
- return aa == bb;
- }
- if (maxcode <= DOUBLE) {
- double aa = (acode == CHAR) ? ((Character) a).charValue() : ((Number) a).doubleValue();
- double bb = (bcode == CHAR) ? ((Character) b).charValue() : ((Number) b).doubleValue();
- return aa == bb;
- }
- return b.equals(a);
- }
- return false;
- }
-
-/* OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS */
-
- /** arg1 + arg2 */
- public static Object add(Object arg1, Object arg2) throws NoSuchMethodException {
- int code1 = typeCode(arg1);
- int code2 = typeCode(arg2);
- int maxcode = (code1 < code2) ? code2 : code1;
- if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
- return boxToInteger(val1 + val2);
- }
- if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
- return boxToLong(val1 + val2);
- }
- if (maxcode <= FLOAT) {
- float val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).floatValue();
- float val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).floatValue();
- return boxToFloat(val1 + val2);
- }
- if (maxcode <= DOUBLE) {
- double val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).doubleValue();
- double val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).doubleValue();
- return boxToDouble(val1 + val2);
- }
- throw new NoSuchMethodException();
- }
-
- /** arg1 - arg2 */
- public static Object subtract(Object arg1, Object arg2) throws NoSuchMethodException {
- int code1 = typeCode(arg1);
- int code2 = typeCode(arg2);
- int maxcode = (code1 < code2) ? code2 : code1;
- if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
- return boxToInteger(val1 - val2);
- }
- if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
- return boxToLong(val1 - val2);
- }
- if (maxcode <= FLOAT) {
- float val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).floatValue();
- float val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).floatValue();
- return boxToFloat(val1 - val2);
- }
- if (maxcode <= DOUBLE) {
- double val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).doubleValue();
- double val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).doubleValue();
- return boxToDouble(val1 - val2);
- }
- throw new NoSuchMethodException();
- }
-
- /** arg1 * arg2 */
- public static Object multiply(Object arg1, Object arg2) throws NoSuchMethodException {
- int code1 = typeCode(arg1);
- int code2 = typeCode(arg2);
- int maxcode = (code1 < code2) ? code2 : code1;
- if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
- return boxToInteger(val1 * val2);
- }
- if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
- return boxToLong(val1 * val2);
- }
- if (maxcode <= FLOAT) {
- float val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).floatValue();
- float val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).floatValue();
- return boxToFloat(val1 * val2);
- }
- if (maxcode <= DOUBLE) {
- double val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).doubleValue();
- double val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).doubleValue();
- return boxToDouble(val1 * val2);
- }
- throw new NoSuchMethodException();
- }
-
- /** arg1 / arg2 */
- public static Object divide(Object arg1, Object arg2) throws NoSuchMethodException {
- int code1 = typeCode(arg1);
- int code2 = typeCode(arg2);
- int maxcode = (code1 < code2) ? code2 : code1;
- if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
- return boxToInteger(val1 / val2);
- }
- if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
- return boxToLong(val1 / val2);
- }
- if (maxcode <= FLOAT) {
- float val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).floatValue();
- float val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).floatValue();
- return boxToFloat(val1 / val2);
- }
- if (maxcode <= DOUBLE) {
- double val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).doubleValue();
- double val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).doubleValue();
- return boxToDouble(val1 / val2);
- }
- throw new NoSuchMethodException();
- }
-
- /** arg1 % arg2 */
- public static Object takeModulo(Object arg1, Object arg2) throws NoSuchMethodException {
- int code1 = typeCode(arg1);
- int code2 = typeCode(arg2);
- int maxcode = (code1 < code2) ? code2 : code1;
- if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
- return boxToInteger(val1 % val2);
- }
- if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
- return boxToLong(val1 % val2);
- }
- if (maxcode <= FLOAT) {
- float val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).floatValue();
- float val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).floatValue();
- return boxToFloat(val1 % val2);
- }
- if (maxcode <= DOUBLE) {
- double val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).doubleValue();
- double val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).doubleValue();
- return boxToDouble(val1 % val2);
- }
- throw new NoSuchMethodException();
- }
-
- /** arg1 >> arg2 */
- public static Object shiftSignedRight(Object arg1, Object arg2) throws NoSuchMethodException {
- int code1 = typeCode(arg1);
- int code2 = typeCode(arg2);
- if (code1 <= INT) {
- int val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).intValue();
- if (code2 <= INT) {
- int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
- return boxToInteger(val1 >> val2);
- }
- if (code2 <= LONG) {
- long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
- return boxToInteger(val1 >> val2);
- }
- }
- if (code1 <= LONG) {
- long val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).longValue();
- if (code2 <= INT) {
- int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
- return boxToLong(val1 >> val2);
- }
- if (code2 <= LONG) {
- long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
- return boxToLong(val1 >> val2);
- }
- }
- throw new NoSuchMethodException();
- }
-
- /** arg1 << arg2 */
- public static Object shiftSignedLeft(Object arg1, Object arg2) throws NoSuchMethodException {
- int code1 = typeCode(arg1);
- int code2 = typeCode(arg2);
- if (code1 <= INT) {
- int val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).intValue();
- if (code2 <= INT) {
- int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
- return boxToInteger(val1 << val2);
- }
- if (code2 <= LONG) {
- long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
- return boxToInteger(val1 << val2);
- }
- }
- if (code1 <= LONG) {
- long val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).longValue();
- if (code2 <= INT) {
- int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
- return boxToLong(val1 << val2);
- }
- if (code2 <= LONG) {
- long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
- return boxToLong(val1 << val2);
- }
- }
- throw new NoSuchMethodException();
- }
-
- /** arg1 >>> arg2 */
- public static Object shiftLogicalRight(Object arg1, Object arg2) throws NoSuchMethodException {
- int code1 = typeCode(arg1);
- int code2 = typeCode(arg2);
- if (code1 <= INT) {
- int val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).intValue();
- if (code2 <= INT) {
- int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
- return boxToInteger(val1 >>> val2);
- }
- if (code2 <= LONG) {
- long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
- return boxToInteger(val1 >>> val2);
- }
- }
- if (code1 <= LONG) {
- long val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).longValue();
- if (code2 <= INT) {
- int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
- return boxToLong(val1 >>> val2);
- }
- if (code2 <= LONG) {
- long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
- return boxToLong(val1 >>> val2);
- }
- }
- throw new NoSuchMethodException();
- }
-
- /** -arg */
- public static Object negate(Object arg) throws NoSuchMethodException {
- int code = typeCode(arg);
- if (code <= INT) {
- int val = (code == CHAR) ? ((Character) arg).charValue() : ((Number) arg).intValue();
- return boxToInteger(-val);
- }
- if (code <= LONG) {
- long val = (code == CHAR) ? ((Character) arg).charValue() : ((Number) arg).longValue();
- return boxToLong(-val);
- }
- if (code <= FLOAT) {
- float val = (code == CHAR) ? ((Character) arg).charValue() : ((Number) arg).floatValue();
- return boxToFloat(-val);
- }
- if (code <= DOUBLE) {
- double val = (code == CHAR) ? ((Character) arg).charValue() : ((Number) arg).doubleValue();
- return boxToDouble(-val);
- }
- throw new NoSuchMethodException();
- }
-
- /** +arg */
- public static Object positive(Object arg) throws NoSuchMethodException {
- int code = typeCode(arg);
- if (code <= INT) {
- int val = (code == CHAR) ? ((Character) arg).charValue() : ((Number) arg).intValue();
- return boxToInteger(+val);
- }
- if (code <= LONG) {
- long val = (code == CHAR) ? ((Character) arg).charValue() : ((Number) arg).longValue();
- return boxToLong(+val);
- }
- if (code <= FLOAT) {
- float val = (code == CHAR) ? ((Character) arg).charValue() : ((Number) arg).floatValue();
- return boxToFloat(+val);
- }
- if (code <= DOUBLE) {
- double val = (code == CHAR) ? ((Character) arg).charValue() : ((Number) arg).doubleValue();
- return boxToDouble(+val);
- }
- throw new NoSuchMethodException();
- }
-
- /** arg1 & arg2 */
- public static Object takeAnd(Object arg1, Object arg2) throws NoSuchMethodException {
- if ((arg1 instanceof Boolean) || (arg2 instanceof Boolean)) {
- if (!((arg1 instanceof Boolean) && (arg2 instanceof Boolean))) {
- throw new NoSuchMethodException();
- }
- return boxToBoolean(((Boolean) arg1).booleanValue() & ((Boolean) arg2).booleanValue());
- }
- int code1 = typeCode(arg1);
- int code2 = typeCode(arg2);
- int maxcode = (code1 < code2) ? code2 : code1;
- if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
- return boxToInteger(val1 & val2);
- }
- if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
- return boxToLong(val1 & val2);
- }
- throw new NoSuchMethodException();
- }
-
- /** arg1 | arg2 */
- public static Object takeOr(Object arg1, Object arg2) throws NoSuchMethodException {
- if ((arg1 instanceof Boolean) || (arg2 instanceof Boolean)) {
- if (!((arg1 instanceof Boolean) && (arg2 instanceof Boolean))) {
- throw new NoSuchMethodException();
- }
- return boxToBoolean(((Boolean) arg1).booleanValue() | ((Boolean) arg2).booleanValue());
- }
- int code1 = typeCode(arg1);
- int code2 = typeCode(arg2);
- int maxcode = (code1 < code2) ? code2 : code1;
- if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
- return boxToInteger(val1 | val2);
- }
- if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
- return boxToLong(val1 | val2);
- }
- throw new NoSuchMethodException();
- }
-
- /** arg1 ^ arg2 */
- public static Object takeXor(Object arg1, Object arg2) throws NoSuchMethodException {
- if ((arg1 instanceof Boolean) || (arg2 instanceof Boolean)) {
- if (!((arg1 instanceof Boolean) && (arg2 instanceof Boolean))) {
- throw new NoSuchMethodException();
- }
- return boxToBoolean(((Boolean) arg1).booleanValue() ^ ((Boolean) arg2).booleanValue());
- }
- int code1 = typeCode(arg1);
- int code2 = typeCode(arg2);
- int maxcode = (code1 < code2) ? code2 : code1;
- if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
- return boxToInteger(val1 ^ val2);
- }
- if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
- return boxToLong(val1 ^ val2);
- }
- throw new NoSuchMethodException();
- }
-
- /** arg1 && arg2 */
- public static Object takeConditionalAnd(Object arg1, Object arg2) throws NoSuchMethodException {
- if ((arg1 instanceof Boolean) && (arg2 instanceof Boolean)) {
- return boxToBoolean(((Boolean) arg1).booleanValue() && ((Boolean) arg2).booleanValue());
- }
- throw new NoSuchMethodException();
- }
-
- /** arg1 || arg2 */
- public static Object takeConditionalOr(Object arg1, Object arg2) throws NoSuchMethodException {
- if ((arg1 instanceof Boolean) && (arg2 instanceof Boolean)) {
- return boxToBoolean(((Boolean) arg1).booleanValue() || ((Boolean) arg2).booleanValue());
- }
- throw new NoSuchMethodException();
- }
-
- /** ~arg */
- public static Object complement(Object arg) throws NoSuchMethodException {
- int code = typeCode(arg);
- if (code <= INT) {
- int val = (code == CHAR) ? ((Character) arg).charValue() : ((Number) arg).intValue();
- return boxToInteger(~val);
- }
- if (code <= LONG) {
- long val = (code == CHAR) ? ((Character) arg).charValue() : ((Number) arg).longValue();
- return boxToLong(~val);
- }
- throw new NoSuchMethodException();
- }
-
- /** !arg */
- public static Object takeNot(Object arg) throws NoSuchMethodException {
- if (arg instanceof Boolean) {
- return boxToBoolean(!((Boolean) arg).booleanValue());
- }
- throw new NoSuchMethodException();
- }
-
- public static Object testEqual(Object arg1, Object arg2) throws NoSuchMethodException {
- return boxToBoolean(arg1 == arg2);
- }
-
- public static Object testNotEqual(Object arg1, Object arg2) throws NoSuchMethodException {
- return boxToBoolean(arg1 != arg2);
- }
-
- public static Object testLessThan(Object arg1, Object arg2) throws NoSuchMethodException {
- int code1 = typeCode(arg1);
- int code2 = typeCode(arg2);
- int maxcode = (code1 < code2) ? code2 : code1;
- if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
- return boxToBoolean(val1 < val2);
- }
- if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
- return boxToBoolean(val1 < val2);
- }
- if (maxcode <= FLOAT) {
- float val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).floatValue();
- float val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).floatValue();
- return boxToBoolean(val1 < val2);
- }
- if (maxcode <= DOUBLE) {
- double val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).doubleValue();
- double val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).doubleValue();
- return boxToBoolean(val1 < val2);
- }
- throw new NoSuchMethodException();
- }
-
- public static Object testLessOrEqualThan(Object arg1, Object arg2) throws NoSuchMethodException {
- int code1 = typeCode(arg1);
- int code2 = typeCode(arg2);
- int maxcode = (code1 < code2) ? code2 : code1;
- if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
- return boxToBoolean(val1 <= val2);
- }
- if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
- return boxToBoolean(val1 <= val2);
- }
- if (maxcode <= FLOAT) {
- float val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).floatValue();
- float val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).floatValue();
- return boxToBoolean(val1 <= val2);
- }
- if (maxcode <= DOUBLE) {
- double val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).doubleValue();
- double val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).doubleValue();
- return boxToBoolean(val1 <= val2);
- }
- throw new NoSuchMethodException();
- }
-
- public static Object testGreaterOrEqualThan(Object arg1, Object arg2) throws NoSuchMethodException {
- int code1 = typeCode(arg1);
- int code2 = typeCode(arg2);
- int maxcode = (code1 < code2) ? code2 : code1;
- if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
- return boxToBoolean(val1 >= val2);
- }
- if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
- return boxToBoolean(val1 >= val2);
- }
- if (maxcode <= FLOAT) {
- float val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).floatValue();
- float val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).floatValue();
- return boxToBoolean(val1 >= val2);
- }
- if (maxcode <= DOUBLE) {
- double val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).doubleValue();
- double val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).doubleValue();
- return boxToBoolean(val1 >= val2);
- }
- throw new NoSuchMethodException();
- }
-
- public static Object testGreaterThan(Object arg1, Object arg2) throws NoSuchMethodException {
- int code1 = typeCode(arg1);
- int code2 = typeCode(arg2);
- int maxcode = (code1 < code2) ? code2 : code1;
- if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
- return boxToBoolean(val1 > val2);
- }
- if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
- return boxToBoolean(val1 > val2);
- }
- if (maxcode <= FLOAT) {
- float val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).floatValue();
- float val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).floatValue();
- return boxToBoolean(val1 > val2);
- }
- if (maxcode <= DOUBLE) {
- double val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).doubleValue();
- double val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).doubleValue();
- return boxToBoolean(val1 > val2);
- }
- throw new NoSuchMethodException();
- }
-
- /** arg.toChar */
- public static Character toCharacter(Object arg) throws NoSuchMethodException {
- if (arg instanceof Character) return (Character)arg;
- if (arg instanceof Byte) return boxToCharacter((char)unboxToByte(arg));
- if (arg instanceof Short) return boxToCharacter((char)unboxToShort(arg));
- if (arg instanceof Integer) return boxToCharacter((char)unboxToInt(arg));
- if (arg instanceof Long) return boxToCharacter((char)unboxToLong(arg));
- if (arg instanceof Float) return boxToCharacter((char)unboxToFloat(arg));
- if (arg instanceof Double) return boxToCharacter((char)unboxToDouble(arg));
- throw new NoSuchMethodException();
- }
-
- /** arg.toByte */
- public static Byte toByte(Object arg) throws NoSuchMethodException {
- if (arg instanceof Character) return boxToByte((byte)unboxToChar(arg));
- if (arg instanceof Byte) return (Byte)arg;
- if (arg instanceof Short) return boxToByte((byte)unboxToShort(arg));
- if (arg instanceof Integer) return boxToByte((byte)unboxToInt(arg));
- if (arg instanceof Long) return boxToByte((byte)unboxToLong(arg));
- if (arg instanceof Float) return boxToByte((byte)unboxToFloat(arg));
- if (arg instanceof Double) return boxToByte((byte)unboxToDouble(arg));
- throw new NoSuchMethodException();
- }
-
- /** arg.toShort */
- public static Short toShort(Object arg) throws NoSuchMethodException {
- if (arg instanceof Character) return boxToShort((short)unboxToChar(arg));
- if (arg instanceof Byte) return boxToShort((short)unboxToByte(arg));
- if (arg instanceof Short) return (Short)arg;
- if (arg instanceof Integer) return boxToShort((short)unboxToInt(arg));
- if (arg instanceof Long) return boxToShort((short)unboxToLong(arg));
- if (arg instanceof Float) return boxToShort((short)unboxToFloat(arg));
- if (arg instanceof Double) return boxToShort((short)unboxToDouble(arg));
- throw new NoSuchMethodException();
- }
-
- /** arg.toInt */
- public static Integer toInteger(Object arg) throws NoSuchMethodException {
- if (arg instanceof Character) return boxToInteger((int)unboxToChar(arg));
- if (arg instanceof Byte) return boxToInteger((int)unboxToByte(arg));
- if (arg instanceof Short) return boxToInteger((int)unboxToShort(arg));
- if (arg instanceof Integer) return (Integer)arg;
- if (arg instanceof Long) return boxToInteger((int)unboxToLong(arg));
- if (arg instanceof Float) return boxToInteger((int)unboxToFloat(arg));
- if (arg instanceof Double) return boxToInteger((int)unboxToDouble(arg));
- throw new NoSuchMethodException();
- }
-
- /** arg.toLong */
- public static Long toLong(Object arg) throws NoSuchMethodException {
- if (arg instanceof Character) return boxToLong((long)unboxToChar(arg));
- if (arg instanceof Byte) return boxToLong((long)unboxToByte(arg));
- if (arg instanceof Short) return boxToLong((long)unboxToShort(arg));
- if (arg instanceof Integer) return boxToLong((long)unboxToInt(arg));
- if (arg instanceof Long) return (Long)arg;
- if (arg instanceof Float) return boxToLong((long)unboxToFloat(arg));
- if (arg instanceof Double) return boxToLong((long)unboxToDouble(arg));
- throw new NoSuchMethodException();
- }
-
- /** arg.toFloat */
- public static Float toFloat(Object arg) throws NoSuchMethodException {
- if (arg instanceof Character) return boxToFloat((float)unboxToChar(arg));
- if (arg instanceof Byte) return boxToFloat((float)unboxToByte(arg));
- if (arg instanceof Short) return boxToFloat((float)unboxToShort(arg));
- if (arg instanceof Integer) return boxToFloat((float)unboxToInt(arg));
- if (arg instanceof Long) return boxToFloat((float)unboxToLong(arg));
- if (arg instanceof Float) return (Float)arg;
- if (arg instanceof Double) return boxToFloat((float)unboxToDouble(arg));
- throw new NoSuchMethodException();
- }
-
- /** arg.toDouble */
- public static Double toDouble(Object arg) throws NoSuchMethodException {
- if (arg instanceof Character) return boxToDouble((double)unboxToChar(arg));
- if (arg instanceof Byte) return boxToDouble((double)unboxToByte(arg));
- if (arg instanceof Short) return boxToDouble((double)unboxToShort(arg));
- if (arg instanceof Integer) return boxToDouble((double)unboxToInt(arg));
- if (arg instanceof Long) return boxToDouble((double)unboxToLong(arg));
- if (arg instanceof Float) return boxToDouble((double)unboxToFloat(arg));
- if (arg instanceof Double) return (Double)arg;
- throw new NoSuchMethodException();
- }
-
-}
diff --git a/src/library/jvm/scala/runtime/ByteRef.java b/src/library/jvm/scala/runtime/ByteRef.java
deleted file mode 100644
index 1e67f18a1f..0000000000
--- a/src/library/jvm/scala/runtime/ByteRef.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2008, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.runtime;
-
-
-public class ByteRef implements java.io.Serializable {
- private static final long serialVersionUID = -100666928446877072L;
-
- public byte elem;
- public ByteRef(byte elem) { this.elem = elem; }
- public String toString() { return Byte.toString(elem); }
-}
diff --git a/src/library/jvm/scala/runtime/CharRef.java b/src/library/jvm/scala/runtime/CharRef.java
deleted file mode 100644
index a64b59dfd7..0000000000
--- a/src/library/jvm/scala/runtime/CharRef.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2008, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.runtime;
-
-
-public class CharRef implements java.io.Serializable {
- private static final long serialVersionUID = 6537214938268005702L;
-
- public char elem;
- public CharRef(char elem) { this.elem = elem; }
- public String toString() { return Character.toString(elem); }
-}
diff --git a/src/library/jvm/scala/runtime/DoubleRef.java b/src/library/jvm/scala/runtime/DoubleRef.java
deleted file mode 100644
index 086429e03e..0000000000
--- a/src/library/jvm/scala/runtime/DoubleRef.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2008, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.runtime;
-
-
-public class DoubleRef implements java.io.Serializable {
- private static final long serialVersionUID = 8304402127373655534L;
-
- public double elem;
- public DoubleRef(double elem) { this.elem = elem; }
- public String toString() { return Double.toString(elem); }
-}
diff --git a/src/library/jvm/scala/runtime/ExceptionHandling.java b/src/library/jvm/scala/runtime/ExceptionHandling.java
deleted file mode 100644
index 0fcc1e2b1c..0000000000
--- a/src/library/jvm/scala/runtime/ExceptionHandling.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.runtime;
-
-
-public abstract class ExceptionHandling {
-
- public static Throwable tryCatch(Runnable runnable) {
- try {
- runnable.run();
- return null;
- } catch (Throwable exception) {
- return exception;
- }
- }
-
-}
diff --git a/src/library/jvm/scala/runtime/FloatRef.java b/src/library/jvm/scala/runtime/FloatRef.java
deleted file mode 100644
index 2160f54977..0000000000
--- a/src/library/jvm/scala/runtime/FloatRef.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2008, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.runtime;
-
-
-public class FloatRef implements java.io.Serializable {
- private static final long serialVersionUID = -5793980990371366933L;
-
- public float elem;
- public FloatRef(float elem) { this.elem = elem; }
- public String toString() { return Float.toString(elem); }
-}
diff --git a/src/library/jvm/scala/runtime/IntRef.java b/src/library/jvm/scala/runtime/IntRef.java
deleted file mode 100644
index 3ad9ad69e5..0000000000
--- a/src/library/jvm/scala/runtime/IntRef.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2008, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.runtime;
-
-
-public class IntRef implements java.io.Serializable {
- private static final long serialVersionUID = 1488197132022872888L;
-
- public int elem;
- public IntRef(int elem) { this.elem = elem; }
- public String toString() { return Integer.toString(elem); }
-}
diff --git a/src/library/jvm/scala/runtime/LongRef.java b/src/library/jvm/scala/runtime/LongRef.java
deleted file mode 100644
index 31b9cd3b55..0000000000
--- a/src/library/jvm/scala/runtime/LongRef.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2008, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.runtime;
-
-
-public class LongRef implements java.io.Serializable {
- private static final long serialVersionUID = -3567869820105829499L;
-
- public long elem;
- public LongRef(long elem) { this.elem = elem; }
- public String toString() { return Long.toString(elem); }
-}
diff --git a/src/library/jvm/scala/runtime/ObjectRef.java b/src/library/jvm/scala/runtime/ObjectRef.java
deleted file mode 100644
index 1154c1dd26..0000000000
--- a/src/library/jvm/scala/runtime/ObjectRef.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2008, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.runtime;
-
-
-public class ObjectRef implements java.io.Serializable {
- private static final long serialVersionUID = -9055728157600312291L;
-
- public Object elem;
- public ObjectRef(Object elem) { this.elem = elem; }
- public String toString() { return "" + elem; }
-}
diff --git a/src/library/jvm/scala/runtime/RichChar.scala b/src/library/jvm/scala/runtime/RichChar.scala
deleted file mode 100644
index d06aa62a57..0000000000
--- a/src/library/jvm/scala/runtime/RichChar.scala
+++ /dev/null
@@ -1,71 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.runtime
-
-
-import java.lang.Character
-import Predef.NoSuchElementException
-
-/**
- * object test extends Application {
- * Console.println(
- * Predef.charWrapper
.
- * x
in radians.
- */
- def toRadians: Double = Math.toRadians(x)
-
- /** Converts an angle measured in radians to an approximately equivalent
- * angle measured in degrees.
- *
- * @param x angle, in radians
- * @return the measurement of the angle x
in degrees.
- */
- def toDegrees: Double = Math.toDegrees(x)
-
- // isNaN is provided by the implicit conversion to java.lang.Double
- // def isNaN: Boolean = java.lang.Double.isNaN(x)
- def isInfinity: Boolean = java.lang.Double.isInfinite(x)
- def isPosInfinity: Boolean = isInfinity && x > 0.0
- def isNegInfinity: Boolean = isInfinity && x < 0.0
-
-}
diff --git a/src/library/jvm/scala/runtime/RichFloat.scala b/src/library/jvm/scala/runtime/RichFloat.scala
deleted file mode 100644
index 482ec3fbc0..0000000000
--- a/src/library/jvm/scala/runtime/RichFloat.scala
+++ /dev/null
@@ -1,56 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.runtime
-
-
-import Predef._
-
-final class RichFloat(x: Float) extends Proxy with Ordered[Float] {
-
- // Proxy.self
- def self: Any = x
-
- // Ordered[Float].compare
- //def compare(y: Float): Int = if (x < y) -1 else if (x > y) 1 else 0
- def compare(y: Float): Int = java.lang.Float.compare(x, y)
-
- def min(y: Float) = Math.min(x, y)
- def max(y: Float) = Math.max(x, y)
- def abs: Float = Math.abs(x)
-
- def round: Int = Math.round(x)
- def ceil: Float = Math.ceil(x).toFloat
- def floor: Float = Math.floor(x).toFloat
-
- /** Converts an angle measured in degrees to an approximately equivalent
- * angle measured in radians.
- *
- * @param x an angle, in degrees
- * @return the measurement of the angle x
in radians.
- */
- def toRadians: Float = Math.toRadians(x).toFloat
-
- /** Converts an angle measured in radians to an approximately equivalent
- * angle measured in degrees.
- *
- * @param x angle, in radians
- * @return the measurement of the angle x
in degrees.
- */
- def toDegrees: Float = Math.toDegrees(x).toFloat
-
- // isNaN is provided by the implicit conversion to java.lang.Float
- // def isNaN: Boolean = java.lang.Float.isNaN(x)
- def isInfinity: Boolean = java.lang.Float.isInfinite(x)
- def isPosInfinity: Boolean = isInfinity && x > 0.0f
- def isNegInfinity: Boolean = isInfinity && x < 0.0f
-
-}
diff --git a/src/library/jvm/scala/runtime/RichInt.scala b/src/library/jvm/scala/runtime/RichInt.scala
deleted file mode 100644
index 73b13afa28..0000000000
--- a/src/library/jvm/scala/runtime/RichInt.scala
+++ /dev/null
@@ -1,39 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2008, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.runtime
-
-
-final class RichInt(start: Int) extends Proxy with Ordered[Int] {
-
- // Proxy
- def self: Any = start
-
- // Ordered[Int]
- def compare(that: Int): Int = if (start < that) -1 else if (start > that) 1 else 0
-
- /** See Iterator.range
. */
- def until(end: Int): Range = new Range(start, end, 1)
-
- /** See Iterator.range
. */
- def until(end: Int, step: Int): Range = new Range(start, end, step)
-
- /** like until
, but includes the last index */
- 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
- def abs: Int = if (start < 0) -start else start
-
- def toBinaryString: String = java.lang.Integer.toBinaryString(start)
- def toHexString: String = java.lang.Integer.toHexString(start)
- def toOctalString: String = java.lang.Integer.toOctalString(start)
-}
diff --git a/src/library/jvm/scala/runtime/RichLong.scala b/src/library/jvm/scala/runtime/RichLong.scala
deleted file mode 100644
index 7e835f10c3..0000000000
--- a/src/library/jvm/scala/runtime/RichLong.scala
+++ /dev/null
@@ -1,30 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2008, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.runtime
-
-
-final class RichLong(x: Long) extends Proxy with Ordered[Long] {
-
- // Proxy.self
- def self: Any = x
-
- // Ordered[Long].compare
- def compare(y: Long): Int = if (x < y) -1 else if (x > y) 1 else 0
-
- def min(y: Long): Long = if (x < y) x else y
- def max(y: Long): Long = if (x > y) x else y
- def abs: Long = if (x < 0) -x else x
-
- def toBinaryString: String = java.lang.Long.toBinaryString(x)
- def toHexString: String = java.lang.Long.toHexString(x)
- def toOctalString: String = java.lang.Long.toOctalString(x)
-}
diff --git a/src/library/jvm/scala/runtime/RichString.scala b/src/library/jvm/scala/runtime/RichString.scala
deleted file mode 100644
index 192cf62ebb..0000000000
--- a/src/library/jvm/scala/runtime/RichString.scala
+++ /dev/null
@@ -1,245 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2008, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.runtime
-
-import Predef._
-import scala.util.matching.Regex
-
-final class RichString(val self: String) extends Proxy with CharSequence with RandomAccessSeq[Char] with Ordered[String] {
- import RichString._
- override def apply(n: Int) = self charAt n
- override def length = self.length
- override def toString = self
- override def mkString = self
-
- override def slice(from: Int, until: Int): RichString = {
- val len = self.length
- new RichString(
- if (from >= until || from >= len)
- ""
- else {
- val from0 = if (from < 0) 0 else from
- val until0 = if (until > len) len else until
- self.substring(from0, until0)
- }
- )
- }
-
- //override def ++ [B >: A](that: Iterable[B]): Seq[B] = {
- override def ++[B >: Char](that: Iterable[B]): RandomAccessSeq[B] = that match {
- case that: RichString => new RichString(self + that.self)
- case that => super.++(that)
- }
-
- override def take(until: Int): RichString = slice(0, until)
-
- override def drop(from: Int): RichString = slice(from, self.length)
-
- override def startsWith[B](that: Seq[B]) = that match {
- case that: RichString => self startsWith that.self
- case that => super.startsWith(that)
- }
-
- override def endsWith[B](that: Seq[B]) = that match {
- case that: RichString => self endsWith that.self
- case that => super.endsWith(that)
- }
-
- override def indexOf[B](that: Seq[B]) = that match {
- case that: RichString => self indexOf that.self
- case that => super.indexOf(that)
- }
-
- override def containsSlice[B](that: Seq[B]) = that match {
- case that: RichString => self contains that.self
- case that => super.containsSlice(that)
- }
-
- override def reverse: RichString = {
- val buf = new StringBuilder
- var i = self.length - 1
- while (i >= 0) {
- buf append (self charAt i)
- i -= 1
- }
- new RichString(buf.toString)
- }
-
- def charAt(index: Int) = self.charAt(index)
-
- def subSequence(start: Int, end: Int): CharSequence =
- new RichString(self.substring(start, end))
-
- /** return n times the current string
- */
- def * (n: Int): String = {
- val buf = new StringBuilder
- for (i <- 0 until n) buf append self
- buf.toString
- }
-
- override def compare(other: String) = self compareTo other
-
- private def isLineBreak(c: Char) = c == LF || c == FF
-
- /**
- *
- *
- *
- */
- def linesWithSeparators = new Iterator[String] {
- val len = self.length
- var index = 0
- def hasNext: Boolean = index < len
- def next(): String = {
- if (index >= len) throw new NoSuchElementException("next on empty iterator")
- val start = index
- while (index < len && !isLineBreak(apply(index))) index += 1
- index += 1
- self.substring(start, index min len)
- }
- }
-
- /** Return all lines in this string in an iterator, excluding trailing line
- * end characters, i.e. apply .stripLineEnd
to all lines
- * returned by linesWithSeparators
.
- */
- def lines: Iterator[String] =
- linesWithSeparators map (line => new RichString(line).stripLineEnd)
-
- /** Returns this string with first character converted to upper case */
- def capitalize: String =
- if (self == null) null
- else if (self.length == 0) ""
- else {
- val chars = self.toCharArray
- chars(0) = chars(0).toUpperCase
- new String(chars)
- }
-
- /**
- * Strip a leading prefix consisting of blanks or control characters
- * followed by
- */
- def stripMargin(marginChar: Char): String = {
- val buf = new StringBuilder
- for (line <- linesWithSeparators) {
- val len = line.length
- var index = 0
- while (index < len && line.charAt(index) <= ' ') index += 1
- buf append
- (if (index < len && line.charAt(index) == marginChar) line.substring(index + 1) else line)
- }
- buf.toString
- }
-
- /** marginChar
from the line.
- *
- * Strip a leading prefix consisting of blanks or control characters
- * followed by
- */
- def stripMargin: String = stripMargin('|')
-
- // NB. "\\Q" + '\\' + "\\E" works on Java 1.5 and newer, but not on Java 1.4
- private def escape(ch: Char): String = ch match {
- case '\\' => "\\\\"
- case _ => "\\Q"+ch+"\\E"
- }
-
- @throws(classOf[java.util.regex.PatternSyntaxException])
- def split(separator: Char): Array[String] = self.split(escape(separator))
-
- @throws(classOf[java.util.regex.PatternSyntaxException])
- def split(separators: Array[Char]): Array[String] = {
- val re = separators.foldLeft("[")(_+escape(_)) + "]"
- self.split(re)
- }
-
- /** You can follow a string with `.r', turning
- * it into a Regex. E.g.
- *
- * """A\w*""".r is the regular expression for identifiers starting with `A'.
- */
- def r: Regex = new Regex(self)
-
- def toBoolean: Boolean = parseBoolean(self)
- def toByte: Byte = java.lang.Byte.parseByte(self)
- def toShort: Short = java.lang.Short.parseShort(self)
- def toInt: Int = java.lang.Integer.parseInt(self)
- def toLong: Long = java.lang.Long.parseLong(self)
- def toFloat: Float = java.lang.Float.parseFloat(self)
- def toDouble: Double = java.lang.Double.parseDouble(self)
-
- override def toArray: Array[Char] = {
- val result = new Array[Char](length)
- self.getChars(0, length, result, 0)
- result
- }
-}
-
-object RichString {
- // just statics for rich string.
- private final val LF: Char = 0x0A
- private final val FF: Char = 0x0C
- private final val CR: Char = 0x0D
- private final val SU: Char = 0x1A
-
- private def parseBoolean(s: String): Boolean =
- if (s != null) s.toLowerCase match {
- case "true" => true
- case "false" => false
- case _ => throw new NumberFormatException("For input string: \""+s+"\"")
- }
- else
- throw new NumberFormatException("For input string: \"null\"")
-}
diff --git a/src/library/jvm/scala/runtime/ShortRef.java b/src/library/jvm/scala/runtime/ShortRef.java
deleted file mode 100644
index b471056260..0000000000
--- a/src/library/jvm/scala/runtime/ShortRef.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2008, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.runtime;
-
-
-public class ShortRef implements java.io.Serializable {
- private static final long serialVersionUID = 4218441291229072313L;
-
- public short elem;
- public ShortRef(short elem) { this.elem = elem; }
-}
diff --git a/src/library/jvm/scala/runtime/StringAdd.scala b/src/library/jvm/scala/runtime/StringAdd.scala
deleted file mode 100644
index 272e2cbb08..0000000000
--- a/src/library/jvm/scala/runtime/StringAdd.scala
+++ /dev/null
@@ -1,41 +0,0 @@
-/* *\
-** ________ ___ __ ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ |_| **
-** **
-\* */
-
-// $Id$
-
-
-package scala.runtime
-
-
-import Predef._
-
-object StringAdd {
- // Needed for the format hack. Can be removed once we drop 1.4
- lazy val formatMethod: java.lang.reflect.Method = {
- val paramTypes = Array[Class[T] forSome { type T }](classOf[String], classOf[Array[Object]])
- classOf[String].getDeclaredMethod("format", paramTypes)
- }
-}
-final class StringAdd(self: Any) {
-
- def +(other: String) = self.toString + other
-
- /** Returns string formatted according to given |
from the line.
- * format
string.
- * Format strings are as for String.format
- * (@see java.lang.String.format).
- * Only works on Java 1.5 or higher!
- */
- def formatted(format: String): String = {
- // This should be:
- // String.format(format, Array(self.asInstanceOf[Object]))
- // However, the line above does not compile on Java 1.4 because String.format exists only in 1.5
- // Therefore, we do the following hack:
- val args = Array(self.asInstanceOf[Object])
- StringAdd.formatMethod.invoke(null, Array[Object](format, args)).asInstanceOf[String]
- }
-}
diff --git a/src/library/jvm/scala/util/DynamicVariable.scala b/src/library/jvm/scala/util/DynamicVariable.scala
deleted file mode 100644
index 552e946250..0000000000
--- a/src/library/jvm/scala/util/DynamicVariable.scala
+++ /dev/null
@@ -1,84 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2008, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.util
-
-
-import Predef._
-import java.lang.InheritableThreadLocal
-
-/** value
method. New values should be
- * pushed using the withValue
method.
- * Values pushed via withValue
only
- * stay valid while the withValue
's
- * second argument, a parameterless closure,
- * executes. When the second argument finishes,
- * the variable reverts to the previous value.
- * withValue
looks like this:
- *
- *
- * someDynamicVariable.withValue(newValue) {
- * // ... code called in here that calls value ...
- * // ... will be given back the newValue ...
- * }
- *
withValue()
gives better semantics.
- */
- def value_=(newval: T) = { tl.set(newval) }
-
- override def toString: String = "DynamicVariable(" + value +")"
-}
diff --git a/src/library/jvm/scala/util/Properties.scala b/src/library/jvm/scala/util/Properties.scala
deleted file mode 100644
index 2fa885dc3a..0000000000
--- a/src/library/jvm/scala/util/Properties.scala
+++ /dev/null
@@ -1,57 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2008, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.util
-
-/** A utility to load the library properties from a Java properties file
- * included in the jar.
- *
- * @author Stephane Micheloud
- */
-object Properties {
-
- /** The name of the properties file */
- private val propFilename = "/library.properties"
-
- /** The loaded properties */
- private val props = {
- val props = new java.util.Properties
- val stream = classOf[Application].getResourceAsStream(propFilename)
- if (stream != null)
- props.load(stream)
- props
- }
-
- /** The version number of the jar this was loaded from, or
- * "(unknown)" if it cannot be determined.
- */
- val versionString: String = {
- val defaultString = "(unknown)"
- "version " + props.getProperty("version.number")
- }
-
- val copyrightString: String = {
- val defaultString = "(c) 2002-2008 LAMP/EPFL"
- props.getProperty("copyright.string", defaultString)
- }
-
- val encodingString: String = {
- val defaultString = "UTF8" //"ISO-8859-1"
- props.getProperty("file.encoding", defaultString)
- }
-
- private val writer = new java.io.PrintWriter(Console.err, true)
-
- val versionMsg = "Scala library " + versionString + " -- " + copyrightString
-
- def main(args: Array[String]) {
- writer.println(versionMsg)
- }
-}
diff --git a/src/library/jvm/scala/util/matching/Regex.scala b/src/library/jvm/scala/util/matching/Regex.scala
deleted file mode 100644
index 32fc300bf1..0000000000
--- a/src/library/jvm/scala/util/matching/Regex.scala
+++ /dev/null
@@ -1,274 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2007-2008, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.util.matching
-
-import java.util.regex.{Pattern, Matcher}
-
-/** This class provides methods for creating and using regular expressions.
- * It is based on the regular expressions of the JDK since 1.4.
- *
- * @author Thibaud Hottelier
- * @author Philipp Haller
- * @author Martin Odersky
- * @version 1.1, 29/01/2008
- *
- * @param regex A string representing a regular expression
- * @param groupNames A mapping from names to indices in capture groups
- */
-class Regex(regex: String, groupNames: String*) {
-
- import Regex._
-
- /** The compiled pattern */
- val pattern = Pattern.compile(regex)
-
- /** Tries to match target (whole match) and returns
- * the matches.
- *
- * @param target The string to match
- * @return The matches
- */
- def unapplySeq(target: Any): Option[List[String]] = target match {
- case s: java.lang.CharSequence =>
- val m = pattern.matcher(s)
- if (m.matches) Some((1 to m.groupCount).toList map m.group)
- else None
- case Match(s) =>
- unapplySeq(s)
- case _ =>
- None
- }
-
- /** Return all matches of this regexp in given character sequence as an iterator
- */
- def findAllIn(source: CharSequence) = new Regex.MatchIterator(source, this, groupNames)
-
- /** Return optionally first matching string of this regexp in given character sequence,
- * None if it does not exist.
- */
- def findFirstIn(source: CharSequence): Option[String] = {
- val m = pattern.matcher(source)
- if (m.find) Some(m.group) else None
- }
-
- /** Return optionally first match of this regexp in given character sequence,
- * None if it does not exist.
- */
- def findFirstMatchIn(source: CharSequence): Option[Match] = {
- val m = pattern.matcher(source)
- if (m.find) Some(new Match(source, m, groupNames)) else None
- }
-
- /** Return optionally match of this regexp at the beginning of the
- * given character sequence, or None if regexp matches no prefix
- * of the character sequence.
- */
- def findPrefixOf(source: CharSequence): Option[String] = {
- val m = pattern.matcher(source)
- if (m.lookingAt) Some(m.group) else None
- }
-
- /** Return optionally match of this regexp at the beginning of the
- * given character sequence, or None if regexp matches no prefix
- * of the character sequence.
- */
- def findPrefixMatchOf(source: CharSequence): Option[Match] = {
- val m = pattern.matcher(source)
- if (m.lookingAt) Some(new Match(source, m, groupNames)) else None
- }
-
- /** Replaces all matches by a string.
- *
- * @param target The string to match
- * @param replacement The string that will replace each match
- * @return The resulting string
- */
- def replaceAllIn(target: CharSequence, replacement: String): String = {
- val m = pattern.matcher(target)
- m.replaceAll(replacement)
- }
-
- /** Replaces the first match by a string.
- *
- * @param target The string to match
- * @param replacement The string that will replace the match
- * @return The resulting string
- */
- def replaceFirstIn(target: CharSequence, replacement: String): String = {
- val m = pattern.matcher(target)
- m.replaceFirst(replacement)
- }
-
- /** The string defining the regular expression */
- override def toString = regex
-}
-
-/** This object defines inner classes that describe
- * regex matches. The class hirrachy is as follows.
- *
- * MatchData
- * | \
- * MatchIterator Match
- */
-object Regex {
-
- /** This class provides methods to access
- * the details of a match.
- */
- trait MatchData {
-
- /** The source from where the match originated */
- val source: CharSequence
-
- /** The names of the groups, or some empty sequence if one defined */
- val groupNames: Seq[String]
-
- /** The index of the first matched character */
- def start: Int
-
- /** The index of the first matched character in group i
*/
- def start(i: Int): Int
-
- /** The index of the last matched character */
- def end: Int
-
- /** The number of subgroups */
- def groupCount: Int
-
- /** The index following the last matched character in group i
*/
- def end(i: Int): Int
-
- /** The matched string */
- def matched: String = source.subSequence(start, end).toString
-
- /** The matched string in group i
*/
- def group(i: Int): String = source.subSequence(start(i), end(i)).toString
-
- /** All matched subgroups, i.e. not including group(0) */
- def subgroups: List[String] = (1 to groupCount).toList map group
-
- /** The char sequence before first character of match */
- def before: CharSequence = source.subSequence(0, start)
-
- /** The char sequence before first character of match in group i
*/
- def before(i: Int): CharSequence = source.subSequence(0, start(i))
-
- /** Returns char sequence after last character of match */
- def after: CharSequence = source.subSequence(end)
-
- /** The char sequence after last character of match in group i
*/
- def after(i: Int): CharSequence = source.subSequence(end(i))
-
- private lazy val nameToIndex: Map[String, Int] = Map() ++ ("" :: groupNames.toList).zipWithIndex
-
- /** Returns the group with given name
- *
- * @param id The group name
- * @return The requested group
- * @throws NoSuchElementException
if the requested
- * group name is not defined
- */
- def group(id: String): String = nameToIndex.get(id) match {
- case None => throw new NoSuchElementException("group name "+id+" not defined")
- case Some(index) => group(index)
- }
-
- /** The matched string; equivalent to matched.toString
*/
- override def toString = matched
-
- }
-
- /** A case class for a succesful match.
- */
- class Match(val source: CharSequence,
- matcher: Matcher,
- val groupNames: Seq[String]) extends MatchData {
-
- /** The index of the first matched character */
- val start = matcher.start
-
- /** The index following the last matched character */
- val end = matcher.end
-
- /** The number of subgroups */
- def groupCount = matcher.groupCount
-
- private lazy val starts: Array[Int] =
- ((1 to groupCount) map matcher.start).toArray
- private lazy val ends: Array[Int] =
- ((1 to groupCount) map matcher.end).toArray
-
- /** The index of the first matched character in group i
*/
- def start(i: Int) = starts(i)
-
- /** The index following the last matched character in group i
*/
- def end(i: Int) = ends(i)
-
- /** The match itself with matcher-dependent lazy vals forced,
- * so that match is valid even once matcher is advanced
- */
- def force: this.type = { starts; ends; this }
- }
-
- /** An extractor object for Matches, yielding the matched string */
- object Match {
- def unapply(m: Match): Some[String] = Some(m.matched)
- }
-
- /** A class to step through a sequence of regex matches
- */
- class MatchIterator(val source: CharSequence, val regex: Regex, val groupNames: Seq[String])
- extends Iterator[String] with MatchData { self =>
-
- private val matcher = regex.pattern.matcher(source)
- private var nextSeen = false
-
- /** Is there another match? */
- def hasNext: Boolean = {
- if (!nextSeen) nextSeen = matcher.find()
- nextSeen
- }
-
- /** The next matched substring of `source' */
- def next: String = {
- if (!hasNext) throw new NoSuchElementException
- nextSeen = false
- matcher.group
- }
-
- override def toString = super[Iterator].toString
-
- /** The index of the first matched character */
- def start: Int = matcher.start
-
- /** The index of the first matched character in group i
*/
- def start(i: Int): Int = matcher.start(i)
-
- /** The index of the last matched character */
- def end: Int = matcher.end
-
- /** The index following the last matched character in group i
*/
- def end(i: Int): Int = matcher.end(i)
-
- /** The number of subgroups */
- def groupCount = matcher.groupCount
-
- /** Convert to an iterator that yields MatchData elements instead of Strings */
- def matchData = new Iterator[Match] {
- def hasNext = self.hasNext
- def next = { self.next; new Match(source, matcher, groupNames).force }
- }
- }
-}
-
-
-
diff --git a/src/library/jvm/scala/util/parsing/CharInputStreamIterator.scala b/src/library/jvm/scala/util/parsing/CharInputStreamIterator.scala
deleted file mode 100644
index b58650e025..0000000000
--- a/src/library/jvm/scala/util/parsing/CharInputStreamIterator.scala
+++ /dev/null
@@ -1,52 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.util.parsing
-
-
-import java.io.InputStream
-import java.io.{IOException, EOFException}
-
-/** This class ...
- *
- * @author Burak Emir
- * @version 1.0
- *
- * @deprecated use classes from
- * scala.util.parsing.input
instead.
- */
-@deprecated
-class CharInputStreamIterator(in: InputStream) extends Iterator[Char] {
-
- private var ch: Int = _
- private var chSet = false
- private var error: IOException = null
-
- private def lookahead() {
- try {
- ch = in.read(); chSet = ch >= 0
- } catch {
- case ex: EOFException => ch = -1
- case ex: IOException => ch = 1; error = ex
- }
- }
-
- def hasNext: Boolean = {
- if (!chSet) lookahead()
- chSet
- }
-
- def next(): Char = {
- if (!chSet) lookahead()
- chSet = false
- ch.asInstanceOf[Char]
- }
-}
diff --git a/src/library/jvm/scala/util/parsing/combinator/RegexParsers.scala b/src/library/jvm/scala/util/parsing/combinator/RegexParsers.scala
deleted file mode 100644
index 37b5f1d10c..0000000000
--- a/src/library/jvm/scala/util/parsing/combinator/RegexParsers.scala
+++ /dev/null
@@ -1,84 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.util.parsing.combinator
-
-import java.util.regex.Pattern
-import scala.util.matching.Regex
-import scala.util.parsing.input._
-
-trait RegexParsers extends Parsers {
-
- type Elem = Char
-
- protected val whiteSpace = """\s+""".r
-
- def skipWhitespace = whiteSpace.toString.length > 0
-
- protected def handleWhiteSpace(source: CharSequence, offset: Int): Int =
- if (skipWhitespace)
- (whiteSpace findPrefixMatchOf (source subSequence offset)) match {
- case Some(matched) => offset + matched.end
- case None => offset
- }
- else
- offset
-
- /** A parser that matches a literal string */
- implicit def literal(s: String): Parser[String] = new Parser[String] {
- def apply(in: Input) = {
- val source = in.source
- val offset = in.offset
- val start = handleWhiteSpace(source, offset)
- var i = 0
- var j = start
- while (i < s.length && source.isDefinedAt(j) && s.charAt(i) == source.charAt(j)) {
- i += 1
- j += 1
- }
- if (i == s.length)
- Success(source.subSequence(start, j).toString, in.drop(j - offset))
- else
- Failure("`"+s+"' expected but `"+in.first+"' found", in.drop(start - offset))
- }
- }
-
- /** A parser that matches a regex string */
- implicit def regex(r: Regex): Parser[String] = new Parser[String] {
- def apply(in: Input) = {
- val source = in.source
- val offset = in.offset
- val start = handleWhiteSpace(source, offset)
- (r findPrefixMatchOf (source subSequence start)) match {
- case Some(matched) =>
- Success(source.subSequence(start, start + matched.end).toString,
- in.drop(start + matched.end - offset))
- case None =>
- Failure("string matching regex `+r+' expected but `"+in.first+"' found", in.drop(start - offset))
- }
- }
- }
-
- /** Parse some prefix of character sequence `in' with parser `p' */
- def parse[T](p: Parser[T], in: CharSequence): ParseResult[T] =
- p(new CharSequenceReader(in))
-
- /** Parse some prefix of reader `in' with parser `p' */
- def parse[T](p: Parser[T], in: Reader[Char]): ParseResult[T] =
- p(in)
-
- /** Parse all of character sequence `in' with parser `p' */
- def parseAll[T](p: Parser[T], in: CharSequence): ParseResult[T] =
- parse(phrase(p), in)
-
- /** Parse all of reader `in' with parser `p' */
- def parseAll[T](p: Parser[T], in: Reader[Char]): ParseResult[T] =
- parse(phrase(p), in)
-}
diff --git a/src/library/jvm/scala/util/parsing/input/StreamReader.scala b/src/library/jvm/scala/util/parsing/input/StreamReader.scala
deleted file mode 100644
index f997590f18..0000000000
--- a/src/library/jvm/scala/util/parsing/input/StreamReader.scala
+++ /dev/null
@@ -1,74 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.util.parsing.input
-
-import java.io.BufferedReader
-
-/** An object to create a StreamReader from a java.io.Reader
.
- *
- * @param in the java.io.Reader
that provides the underlying
- * stream of characters for this Reader.
- *
- * @author Miles Sabin
- */
-object StreamReader {
- final val EofCh = '\032'
-
- def apply(in: java.io.Reader): StreamReader = {
- new StreamReader(new LazyCharSequence(in), 0, 1)
- }
-}
-
-/** A character array reader reads a stream of characters (keeping track of
- * their positions) from an array.
- *
- * NOTE:
- * StreamReaders do not really fulfill the new contract for readers, which
- * requires a `source' CharSequence representing the full input.
- * Instead source is treated line by line.
- * As a consequence, regex matching cannot extend beyond a single lines
- * when a StreamReader are used for input.
- *
- * @param bin the underlying java.io.BufferedReader
- * @param sourceLine the line at column `col' in the stream
- * @param line the 1-based line number of the character returned by `first'
- * @param column the 1-based column number of the character returned by `first'
- *
- * @author Miles Sabin
- */
-sealed class StreamReader(source: CharSequence, offset: Int, lnum: Int) extends CharSequenceReader(source, offset) {
- import StreamReader._
-
- override def rest: CharSequenceReader =
- if (offset == source.length) this
- else if (source(offset) == '\n') new StreamReader(source.subSequence(offset + 1), 0, lnum + 1)
- else new StreamReader(source, offset + 1, lnum)
-
- private def nextEol = {
- var i = offset
- while (i < source.length && source(i) != '\n' && source(i) != EofCh) i += 1
- i
- }
-
- override def drop(n: Int): StreamReader = {
- val eolPos = nextEol
- if (eolPos < offset + n && eolPos < source.length)
- new StreamReader(source.subSequence(eolPos + 1), 0, lnum + 1).drop(offset + n - (eolPos + 1))
- else
- new StreamReader(source, offset + n, lnum)
- }
-
- override def pos: Position = new Position {
- def line = lnum
- def column = offset + 1
- def lineContents = source.subSequence(0, nextEol).toString
- }
-}
diff --git a/src/library/jvm/scala/xml/Parsing.scala b/src/library/jvm/scala/xml/Parsing.scala
deleted file mode 100644
index 9f2934a7b5..0000000000
--- a/src/library/jvm/scala/xml/Parsing.scala
+++ /dev/null
@@ -1,105 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.xml
-
-
-/** The object Parsing
...
- *
- * @author Burak Emir
- * @version 1.0
- *
- * @deprecated use either parsing.TokenTests
or
- * Utilty
(helper functions for parsing XML fragments).
- */
-object Parsing {
-
- /** (#x20 | #x9 | #xD | #xA)
*/
- final def isSpace(ch: Char): Boolean = ch match {
- case '\u0009' | '\u000A' | '\u000D' | '\u0020' => true
- case _ => false
- }
-
- /** (#x20 | #x9 | #xD | #xA)+
*/
- final def isSpace(cs: Seq[Char]): Boolean = {
- val it = cs.elements
- it.hasNext && it.forall { isSpace }
- }
-
- /** NameChar ::= Letter | Digit | '.' | '-' | '_' | ':'
- * | CombiningChar | Extender
- *
- * see [4] and Appendix B of XML 1.0 specification
- */
- def isNameChar(ch: Char) = isNameStart(ch) || (ch match {
- case '.' | '-' | ':' => true
- case _ => java.lang.Character.getType(ch).asInstanceOf[Byte] match {
- case java.lang.Character.COMBINING_SPACING_MARK => true // Mc
- case java.lang.Character.ENCLOSING_MARK => true // Me
- case java.lang.Character.NON_SPACING_MARK => true // Mn
- case java.lang.Character.MODIFIER_LETTER => true // Lm
- case java.lang.Character.DECIMAL_DIGIT_NUMBER => true // Nd
- case _ => false
- }
- });
-
- /** NameStart ::= ( Letter | '_' )
- * where Letter means in one of the Unicode general
- * categories { Ll, Lu, Lo, Lt, Nl }
- *
- * We do not allow a name to start with ':'.
- * see [3] and Appendix B of XML 1.0 specification
- */
- def isNameStart(ch: Char) =
- java.lang.Character.getType(ch).asInstanceOf[Byte] match {
- case java.lang.Character.LOWERCASE_LETTER => true
- case java.lang.Character.UPPERCASE_LETTER => true
- case java.lang.Character.OTHER_LETTER => true
- case java.lang.Character.TITLECASE_LETTER => true
- case java.lang.Character.LETTER_NUMBER => true
- case _ => ch == '_'
- }
-
- /** Name ::= ( Letter | '_' ) (NameChar)*
- *
- * see [5] of XML 1.0 specification
- */
- def isName(s: String): Boolean =
- if (s.length() > 0) {
- val z: Seq[Char] = s
- val y = z.elements
- if (isNameStart(y.next)) {
- while (y.hasNext && isNameChar(y.next)) {}
- !y.hasNext
- } else false
- } else false
-
- def isPubIDChar(c: Char) = c match {
- case '\u0020' | '\u000D' | '\u000A' => true
- case _ if
- ('0' < c && c < '9')||('a' < c && c < 'z')||('A' < c && c < 'Z') => true
- case '-' | '\''| '(' | ')' | '+' | ',' | '.' | '/' | ':' | '=' |
- '?' | ';' | '!' | '*' | '#' | '@' | '$' | '_' | '%' => true
- case _ => false
- }
-
- def checkSysID(s: String): Boolean =
- s.indexOf('"') == -1 || s.indexOf('\'') == -1
-
- def checkPubID(s: String): Boolean =
- if (s.length() > 0) {
- val z:Seq[Char] = s
- val y = z.elements
- while (y.hasNext && isPubIDChar(y.next)) {}
- !y.hasNext
- } else true
-
-}
diff --git a/src/library/jvm/scala/xml/PrettyPrinter.scala b/src/library/jvm/scala/xml/PrettyPrinter.scala
deleted file mode 100644
index 05c612ce81..0000000000
--- a/src/library/jvm/scala/xml/PrettyPrinter.scala
+++ /dev/null
@@ -1,308 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.xml
-
-import scala.collection.Map
-
-/** Class for pretty printing. After instantiating, you can use the
- * toPrettyXML methods to convert XML to a formatted string. The class
- * can be reused to pretty print any number of XML nodes.
- *
- * @author Burak Emir
- * @version 1.0
- *
- * @param width the width to fit the output into
- * @step indentation
- */
-class PrettyPrinter( width:Int, step:Int ) {
-
- class BrokenException() extends java.lang.Exception
-
- class Item
- case object Break extends Item {
- override def toString() = "\\"
- }
- case class Box(col: Int, s: String) extends Item
- case class Para(s: String) extends Item
-
- protected var items: List[Item] = Nil
-
- protected var cur = 0
- //protected var pmap:Map[String,String] = _
-
- protected def reset() = {
- cur = 0
- items = Nil
- }
-
- /** Try to cut at whitespace.
- *
- * @param s ...
- * @param ind ...
- * @return ...
- */
- protected def cut(s: String, ind: Int): List[Item] = {
- val tmp = width - cur
- if (s.length < tmp)
- return List(Box(ind, s))
- val sb = new StringBuilder()
- var i = s.indexOf(' ')
- if (i > tmp || i == -1) throw new BrokenException() // cannot break
-
- var last: List[Int] = Nil
- while (i != -1 && i < tmp) {
- last = i::last
- i = s.indexOf(' ', i+1)
- }
- var res: List[Item] = Nil
- while (Nil != last) try {
- val b = Box(ind, s.substring(0, last.head))
- cur = ind
- res = b :: Break :: cut(s.substring(last.head, s.length), ind)
- // backtrack
- last = last.tail
- } catch {
- case _:BrokenException => last = last.tail
- }
- throw new BrokenException()
- }
-
- /** Try to make indented box, if possible, else para.
- *
- * @param ind ...
- * @param s ...
- * @return ...
- */
- protected def makeBox(ind: Int, s: String) = {
- if (cur < ind)
- cur == ind
- if (cur + s.length > width) { // fits in this line
- items = Box(ind, s) :: items
- cur += s.length
- } else try {
- for (b <- cut(s, ind).elements) // break it up
- items = b :: items
- } catch {
- case _:BrokenException => makePara(ind, s) // give up, para
- }
- }
-
- // dont respect indent in para, but afterwards
- protected def makePara(ind: Int, s: String) = {
- items = Break::Para(s)::Break::items
- cur = ind
- }
-
- // respect indent
- protected def makeBreak() = { // using wrapping here...
- items = Break :: items
- cur = 0
- }
-
- /**
- * @param n ...
- * @return ...
- */
- protected def leafTag(n: Node) = {
- val sb = new StringBuilder("<")
- n.nameToString(sb)
- //Utility.appendPrefixedName( n.prefix, n.label, pmap, sb );
- n.attributes.toString(sb)
- //Utility.attr2xml( n.scope, n.attributes, pmap, sb );
- sb.append("/>")
- sb.toString()
- }
-
- protected def startTag(n: Node, pscope: NamespaceBinding): (String, Int) = {
- val sb = new StringBuilder("<")
- n.nameToString(sb) //Utility.appendPrefixedName( n.prefix, n.label, pmap, sb );
- val i = sb.length + 1
- n.attributes.toString(sb)
- n.scope.toString(sb, pscope)
- sb.append('>')
- (sb.toString(), i)
- }
-
- protected def endTag(n: Node) = {
- val sb = new StringBuilder("")
- n.nameToString(sb) //Utility.appendPrefixedName( n.prefix, n.label, pmap, sb );
- sb.append('>')
- sb.toString()
- }
-
- protected def childrenAreLeaves(n: Node): Boolean = {
- val it = n.child.elements
- while (it.hasNext)
- it.next match {
- case _:Atom[_] | _:Comment | _:EntityRef | _:ProcInstr =>
- case _:Node =>
- return false
- }
- true
- }
-
- protected def fits(test: String) =
- test.length < width - cur
-
- /** @param tail: what we'd like to sqeeze in */
- protected def traverse(node: Node, pscope: NamespaceBinding, ind: Int): Unit = node match {
-
- case Text(s) if s.trim() == "" =>
- ;
- case _:Atom[_] | _:Comment | _:EntityRef | _:ProcInstr =>
- makeBox( ind, node.toString().trim() )
- case g @ Group(xs) =>
- traverse(xs.elements, pscope, ind)
- case _ =>
- val test = {
- val sb = new StringBuilder()
- Utility.toXML(node, pscope, sb, false)
- if (node.attribute("http://www.w3.org/XML/1998/namespace", "space") == "preserve")
- sb.toString()
- else
- TextBuffer.fromString(sb.toString()).toText(0)._data
- }
- if (childrenAreLeaves(node) && fits(test)) {
- makeBox(ind, test)
- } else {
- val (stg, len2) = startTag(node, pscope)
- val etg = endTag(node)
- if (stg.length < width - cur) { // start tag fits
- makeBox(ind, stg)
- makeBreak()
- traverse(node.child.elements, node.scope, ind + step)
- makeBox(ind, etg)
- } else if (len2 < width - cur) {
- // Text
implements an XML node for text (PCDATA).
- * It is used in both non-bound and bound XML representations.
- *
- * @author Burak Emir
- *
- * @param text the text contained in this node, may not be null.
- */
-case class Text(_data: String) extends Atom[String](_data) {
-
- if (null == data)
- throw new java.lang.NullPointerException("tried to construct Text with null")
-
- final override def equals(x: Any) = x match {
- case s:String => s.equals(data)
- case s:Text => data == s.data
- case _ => false
- }
-
- /** Returns text, with some characters escaped according to the XML
- * specification.
- *
- * @param sb ...
- * @return ...
- */
- override def toString(sb: StringBuilder) =
- Utility.escape(data, sb)
-
-}
diff --git a/src/library/jvm/scala/xml/Unparsed.scala b/src/library/jvm/scala/xml/Unparsed.scala
deleted file mode 100644
index 6bda932b89..0000000000
--- a/src/library/jvm/scala/xml/Unparsed.scala
+++ /dev/null
@@ -1,35 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.xml
-
-/** An XML node for unparsed content. It will be output verbatim, all bets
- * are off regarding wellformedness etc.
- *
- * @author Burak Emir
- * @param _data content in this node, may not be null.
- */
-case class Unparsed(_data: String) extends Atom[String](_data) {
-
- if (null == data)
- throw new java.lang.NullPointerException("tried to construct Unparsed with null")
-
- final override def equals(x: Any) = x match {
- case s:String => s.equals(data)
- case s:Text => data == s.data
- case s:Unparsed => data == s.data
- case _ => false
- }
-
- /** returns text, with some characters escaped according to XML spec */
- override def toString(sb: StringBuilder) = sb append data
-
-}
diff --git a/src/library/jvm/scala/xml/XML.scala b/src/library/jvm/scala/xml/XML.scala
deleted file mode 100644
index 675d4dcbb7..0000000000
--- a/src/library/jvm/scala/xml/XML.scala
+++ /dev/null
@@ -1,158 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.xml
-
-
-import Predef._
-import scala.xml.parsing.NoBindingFactoryAdapter
-import org.xml.sax.InputSource
-import java.io.{File, FileDescriptor, FileInputStream, FileOutputStream}
-import java.io.{InputStream, Reader, StringReader, Writer}
-
-/** The object XML
provides constants, and functions to load
- * and save XML elements. Use this when data binding is not desired, i.e.
- * when XML is handled using Symbol
nodes.
- *
- * @author Burak Emir
- * @version 1.0, 25/04/2005
- */
-object XML {
-
- val xml = "xml"
- val xmlns = "xmlns"
- val namespace = "http://www.w3.org/XML/1998/namespace"
- val preserve = "preserve"
- val space = "space"
- val lang = "lang"
- val encoding = "ISO-8859-1"
-
- // functions for generic xml loading, saving
-
- /** loads XML from given file, using XML parser in JDK. */
- final def loadFile(file: File): Elem =
- new NoBindingFactoryAdapter().loadXML(new InputSource(
- new FileInputStream(file)
- ))
-
- /** loads XML from given file descriptor, using XML parser in JDK.
- *
- * @param fileDesc ...
- * @return ...
- */
- final def loadFile(fileDesc: FileDescriptor): Elem =
- new NoBindingFactoryAdapter().loadXML(new InputSource(
- new FileInputStream(fileDesc)
- ))
-
- /** loads XML from given file, using XML parser in JDK. */
- final def loadFile(fileName: String): Elem =
- new NoBindingFactoryAdapter().loadXML(new InputSource(
- new FileInputStream(fileName)
- ));
-
- /** loads XML from given InputStream, using XML parser in JDK. */
- final def load( is:InputStream ): Elem =
- new NoBindingFactoryAdapter().loadXML(new InputSource(is))
-
- /** loads XML from given Reader, using XML parser in JDK. */
- final def load(reader: Reader): Elem =
- new NoBindingFactoryAdapter().loadXML(new InputSource(reader))
-
- /** loads XML from given sysID, using XML parser in JDK. */
- final def load(sysID: String): Elem =
- new NoBindingFactoryAdapter().loadXML(new InputSource(sysID))
-
- /** loads XML from a given input source, using XML parser in JDK.
- *
- * @param source ...
- * @return ...
- */
- final def load(source: InputSource): Elem =
- new NoBindingFactoryAdapter().loadXML(source)
-
- /** loads XML from a string, using XML parser in JDK. */
- final def loadString(string: String): Elem =
- load(new StringReader(string))
-
- /** Saves XML to filename with encoding ISO-8859-1 without xml-decl without
- * doctype
.
- *
- * @param filename ...
- * @param node ...
- */
- final def save(filename: String, node: Node): Unit =
- save(filename, node, encoding)
-
- /** saves XML to filename with given encoding, without xml-decl without
- * doctype
.
- *
- * @param filename ...
- * @param node ...
- * @param enc ...
- */
- final def save(filename: String, node: Node, enc: String): Unit =
- saveFull(filename, node, enc, false, null);
-
- /** saves a node to a file with given filename using encoding iso-8859-1
- * optionally with xmldecl and doctype declaration.
- *
- * @param filename the filename
- * @param node the xml node we want to write
- * @param xmlDecl if true, write xml declaration
- * @param doctype if not null, write doctype declaration
- */
- final def saveFull(filename: String, node: Node, xmlDecl: Boolean, doctype: dtd.DocType): Unit =
- saveFull(filename, node, encoding, xmlDecl, doctype)
-
- /** Saves a node to a file with given filename using given encoding
- * optionally with xmldecl and doctype declaration.
- *
- * @param filename the filename
- * @param node the xml node we want to write
- * @param enc encoding to use
- * @param xmlDecl if true, write xml declaration
- * @param doctype if not null, write doctype declaration
- */
-
- final def saveFull(filename: String, node: Node, enc: String, xmlDecl: Boolean, doctype: dtd.DocType) {
- var fos: FileOutputStream = null
- var w: Writer = null
- try {
- // using NIO classes of JDK 1.4
- import java.io.{FileOutputStream, Writer}
- import java.nio.channels.{Channels, FileChannel}
-
- fos = new FileOutputStream(filename)
- w = Channels.newWriter(fos.getChannel(), enc)
- write(w, node, enc, xmlDecl, doctype)
- } finally {
- w.close()
- fos.close()
- }
- }
-
- /** Writes the given node using writer, optionally with xml decl and doctype.
- * It's the caller's responsibility to close the writer.
- *
- * @param w the writer
- * @param node the xml node we want to write
- * @param enc the string to be used in xmlDecl
- * @param xmlDecl if true, write xml declaration
- * @param doctype if not null, write doctype declaration
- */
- final def write(w: java.io.Writer, node: Node, enc: String, xmlDecl: Boolean, doctype: dtd.DocType) {
- /* TODO: optimize by giving writer parameter to toXML*/
- if (xmlDecl) w.write("\n")
- if (doctype ne null) w.write( doctype.toString() + "\n")
- w.write(Utility.toXML(node))
- }
-}
diff --git a/src/library/jvm/scala/xml/include/XIncludeException.scala b/src/library/jvm/scala/xml/include/XIncludeException.scala
deleted file mode 100644
index 5563d68c38..0000000000
--- a/src/library/jvm/scala/xml/include/XIncludeException.scala
+++ /dev/null
@@ -1,64 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.xml.include
-
-/**
- * XIncludeException
is the generic superclass
- * for all checked exceptions that may be thrown as a result
- * of a violation of XInclude's rules.
- * XIncludeException
with the specified detail
- * message. The error message string message
can later be
- * retrieved by the {@link java.lang.Throwable#getMessage}
- * method of class java.lang.Throwable
.
- * null
as its error detail message.
- */
- def this() = this(null)
-
- private var rootCause: Throwable = null
-
- /**
- * When an IOException
, MalformedURLException
- * or other generic exception is thrown while processing an XML document
- * for XIncludes, it is customarily replaced
- * by some form of XIncludeException
.
- * This method allows you to store the original exception.
- *
- * @param nestedException the underlying exception which
- caused the XIncludeException to be thrown
- */
- def setRootCause(nestedException: Throwable ) {
- this.rootCause = nestedException
- }
-
- /**
- * When an IOException
, MalformedURLException
- * or other generic exception is thrown while processing an XML document
- * for XIncludes, it is customarily replaced
- * by some form of XIncludeException
.
- * This method allows you to retrieve the original exception.
- * It returns null if no such exception caused this XIncludeException
.
- *
- * @return Throwable the underlying exception which caused the
- * XIncludeException
to be thrown
- */
- def getRootCause(): Throwable = this.rootCause
-
-}
diff --git a/src/library/jvm/scala/xml/include/parsing/ConstructingParser.scala b/src/library/jvm/scala/xml/include/parsing/ConstructingParser.scala
deleted file mode 100644
index b7c88c79ec..0000000000
--- a/src/library/jvm/scala/xml/include/parsing/ConstructingParser.scala
+++ /dev/null
@@ -1,67 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2006, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.xml.parsing
-
-import java.io.File
-
-import scala.io.Source
-
-object ConstructingParser {
-
- def fromFile(inp: File, preserveWS: Boolean) = {
- val p = new ConstructingParser(Source.fromFile(inp), preserveWS)
- p.nextch
- p
- }
-
- def fromSource(inp: Source, preserveWS: Boolean) = {
- val p = new ConstructingParser(inp, preserveWS)
- p.nextch
- p
- }
-}
-
-/** An xml parser. parses XML and invokes callback methods of a MarkupHandler.
- * Don't forget to call next.ch on a freshly instantiated parser in order to
- * initialize it. If you get the parser from the object method, initialization
- * is already done for you.
- *
- *
-object parseFromURL {
- def main(args:Array[String]): Unit = {
- val url = args(0);
- val src = scala.io.Source.fromURL(url);
- val cpa = scala.xml.parsing.ConstructingParser.fromSource(src, false); // fromSource initializes automatically
- val doc = cpa.document();
-
- // let's see what it is
- val ppr = new scala.xml.PrettyPrinter(80,5);
- val ele = doc.docElem;
- Console.println("finished parsing");
- val out = ppr.format(ele);
- Console.println(out);
- }
-}
-
- */
-class ConstructingParser(inp: Source, presWS:Boolean)
-extends ConstructingHandler
-with ExternalSources
-with MarkupParser {
-
- // default impl. of Logged
- override def log(msg: String): Unit = {}
-
- val preserveWS = presWS
- val input = inp
-}
-
diff --git a/src/library/jvm/scala/xml/include/parsing/ExternalSources.scala b/src/library/jvm/scala/xml/include/parsing/ExternalSources.scala
deleted file mode 100644
index cbfee413e6..0000000000
--- a/src/library/jvm/scala/xml/include/parsing/ExternalSources.scala
+++ /dev/null
@@ -1,82 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.xml.parsing
-
-import java.net.URL
-
-import scala.io.Source
-
-/**
- * @author Burak Emir
- * @version 1.0
- */
-trait ExternalSources { self: ExternalSources with MarkupParser with MarkupHandler =>
-
- private def externalSourceFromURL(url: URL): Source = {
- import java.io.{BufferedReader, InputStreamReader}
- val in =
- new BufferedReader(
- new InputStreamReader(
- url.openStream()))
-
- //@todo: replace this hack with proper Source implementation
-
- val str = new StringBuilder()
- var inputLine: String = null
-
- //while (inputLine = in.readLine()) != null) {
- while ({inputLine = in.readLine(); inputLine} ne null) {
- // Console.println(inputLine) // DEBUG
- str.append(inputLine)
- str.append('\n') // readable output
- }
- in.close()
-
- class MyClass extends Source {
-
- def newIter = new Iterator[Char] {
- var i = -1
- private val len = str.length-1
- def hasNext = i < len
- def next = { i += 1; str.charAt(i) }
- }
-
- val iter = newIter
-
- def reset: Source = new MyClass
-
- /*override var*/ descr = url.toExternalForm()
- }
-
- new MyClass
- }
-
- /** ...
- *
- * @param systemId ...
- * @return ...
- */
- def externalSource(systemId: String): Source = {
- if (systemId startsWith "http:")
- return externalSourceFromURL(new URL(systemId))
-
- var fileStr = input.descr
-
- if (input.descr startsWith "file:") {
- fileStr = input.descr.substring(5, input.descr.length)
- } else
- fileStr = fileStr.substring(0,
- fileStr.lastIndexOf(java.io.File.separator)+1)
- Source.fromFile(fileStr + systemId)
- }
-
-}
diff --git a/src/library/jvm/scala/xml/include/parsing/FactoryAdapter.scala b/src/library/jvm/scala/xml/include/parsing/FactoryAdapter.scala
deleted file mode 100644
index 32c58c3ff6..0000000000
--- a/src/library/jvm/scala/xml/include/parsing/FactoryAdapter.scala
+++ /dev/null
@@ -1,321 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.xml.parsing
-
-import java.io.{InputStream, Reader, File, FileDescriptor, FileInputStream}
-import scala.collection.mutable.{HashMap,Stack}
-
-import org.xml.sax.{Attributes, InputSource}
-
-import org.xml.sax.SAXException
-import org.xml.sax.SAXNotRecognizedException
-import org.xml.sax.SAXNotSupportedException
-import org.xml.sax.SAXParseException
-import org.xml.sax.helpers.DefaultHandler
-
-import javax.xml.parsers.SAXParserFactory
-import javax.xml.parsers.ParserConfigurationException
-import javax.xml.parsers.SAXParser
-
-
-/** SAX adapter class, for use with Java SAX parser. Keeps track of
- * namespace bindings, without relying on namespace handling of the
- * underlying SAX parser.
- */
-abstract class FactoryAdapter extends DefaultHandler() {
-
- val buffer = new StringBuilder()
- val attribStack = new Stack[MetaData]
- val hStack = new Stack[Node] // [ element ] contains siblings
- val tagStack = new Stack[String]
- var scopeStack = new Stack[NamespaceBinding]
-
- var curTag : String = null
- var capture: Boolean = false
-
- // abstract methods
-
- /** Tests if an XML element contains text.
- * @return true if element named localName
contains text.
- */
- def nodeContainsText(localName: String): Boolean // abstract
-
- /** creates an new non-text(tree) node.
- * @param elemName
- * @param attribs
- * @param chIter
- * @return a new XML element.
- */
- def createNode(pre: String, elemName: String, attribs: MetaData,
- scope: NamespaceBinding, chIter: List[Node]): Node //abstract
-
- /** creates a Text node.
- * @param text
- * @return a new Text node.
- */
- def createText(text: String): Text // abstract
-
- /** creates a new processing instruction node.
- */
- def createProcInstr(target: String, data: String): Seq[ProcInstr]
-
- //
- // ContentHandler methods
- //
-
- val normalizeWhitespace = false
-
- /** Characters.
- * @param ch
- * @param offset
- * @param length
- */
- override def characters(ch: Array[Char], offset: Int, length: Int): Unit = {
- if (capture) {
- if (normalizeWhitespace) {
- // normalizing whitespace is not compliant, but useful */
- var i: Int = offset
- var ws = false
- while (i < offset + length) {
- if (ch(i).isWhitespace) {
- if (!ws) {
- buffer.append(' ')
- ws = true
- }
- } else {
- buffer.append(ch(i))
- ws = false
- }
- i += 1
- }
- } else { // compliant:report every character
- buffer.append(ch, offset, length)
- }
- }
- }
-
- //var elemCount = 0; //STATISTICS
-
- /* ContentHandler methods */
-
- /* Start prefix mapping - use default impl.
- def startPrefixMapping( prefix:String , uri:String ):Unit = {}
- */
-
- /* Start element. */
- override def startElement(uri: String, _localName: String,
- qname: String, attributes: Attributes): Unit = {
- /*elemCount = elemCount + 1; STATISTICS */
- captureText()
- //Console.println("FactoryAdapter::startElement("+uri+","+_localName+","+qname+","+attributes+")");
- tagStack.push(curTag)
- curTag = qname; //localName ;
-
- val colon = qname.indexOf(':'.asInstanceOf[Int])
- val localName = if(-1 == colon) qname else qname.substring(colon+1,qname.length())
-
- //Console.println("FactoryAdapter::startElement - localName ="+localName);
-
- capture = nodeContainsText(localName)
-
- hStack.push(null)
- var m: MetaData = Null
-
- var scpe = scopeStack.top
- for (i <- List.range(0, attributes.getLength())) {
- //val attrType = attributes.getType(i); // unused for now
- val qname = attributes.getQName(i)
- val value = attributes.getValue(i)
- val colon = qname.indexOf(':'.asInstanceOf[Int])
- if (-1 != colon) { // prefixed attribute
- val pre = qname.substring(0, colon)
- val key = qname.substring(colon+1, qname.length())
- if ("xmlns" /*XML.xmlns*/ == pre)
- scpe = value.length() match {
- case 0 => new NamespaceBinding(key, null, scpe)
- case _ => new NamespaceBinding(key, value, scpe)
- }
- else
- m = new PrefixedAttribute(pre, key, Text(value), m)
- } else if ("xmlns" /*XML.xmlns*/ == qname)
- scpe = value.length() match {
- case 0 => new NamespaceBinding(null, null, scpe)
- case _ => new NamespaceBinding(null, value, scpe)
- }
- else
- m = new UnprefixedAttribute(qname, Text(value), m)
- }
- scopeStack.push(scpe)
- attribStack.push(m)
- ()
- } // startElement(String,String,String,Attributes)
-
-
- /** captures text, possibly normalizing whitespace
- */
- def captureText(): Unit = {
- if (capture) {
- val text = buffer.toString()
- if (text.length() > 0 && !text.equals(" ")) {
- hStack.push(createText(text))
- }
- }
- buffer.setLength(0)
- }
-
- /** End element.
- * @param uri
- * @param localName
- * @param qname
- * @throws org.xml.sax.SAXException if ..
- */
- override def endElement(uri: String , _localName: String , qname: String): Unit = {
- captureText()
-
- val metaData = attribStack.pop
-
- // reverse order to get it right
- var v: List[Node] = Nil
- var child: Node = hStack.pop
- while (child ne null) {
- v = child::v
- child = hStack.pop
- }
-
- val colon = qname.indexOf(':'.asInstanceOf[Int])
- val localName =
- if (-1 == colon) qname
- else qname.substring(colon+1, qname.length())
-
- val scp = scopeStack.pop
- // create element
- val pre = if (-1 == colon) null else qname.substring(0, colon)
- rootElem = createNode(pre, localName, metaData, scp, v)
-
- hStack.push(rootElem)
-
- // set
- curTag = tagStack.pop
-
- capture =
- if (curTag ne null) nodeContainsText(curTag) // root level
- else false
- } // endElement(String,String,String)
-
- /** Processing instruction.
- */
- override def processingInstruction(target: String, data: String) {
- for (pi <- createProcInstr(target, data))
- hStack.push(pi)
- }
-
- //
- // ErrorHandler methods
- //
-
- /** Warning.*/
- override def warning(ex: SAXParseException): Unit = {
- // ignore warning, crimson warns even for entity resolution!
- //printError("Warning", ex);
- }
-
- /** Error. */
- override def error(ex: SAXParseException): Unit =
- printError("Error", ex)
-
- /** Fatal error.*/
- override def fatalError(ex: SAXParseException): Unit =
- printError("Fatal Error", ex)
-
- //
- // Protected methods
- //
-
- /** Prints the error message */
- protected def printError(errtype: String, ex: SAXParseException): Unit =
- Console.withOut(Console.err) {
- Console.print("[")
- Console.print(errtype)
- Console.print("] ")
-
- var systemId = ex.getSystemId()
- if (systemId ne null) {
- val index = systemId.lastIndexOf('/'.asInstanceOf[Int])
- if (index != -1)
- systemId = systemId.substring(index + 1)
- //Console.print(systemId)
- }
-
- Console.print(':')
- Console.print(ex.getLineNumber())
- Console.print(':')
- Console.print(ex.getColumnNumber())
- Console.print(": ")
- Console.print(ex.getMessage())
- Console.println
- Console.flush
- }
-
- var rootElem: Node = null:Node
-
- //FactoryAdapter
- // MAIN
- //
-
- /** load XML document
- * @param source
- * @return a new XML document object
- */
- def loadXML(source: InputSource): Node = {
- // create parser
- val parser: SAXParser = try {
- val f = SAXParserFactory.newInstance()
- f.setNamespaceAware(false)
- f.newSAXParser()
- } catch {
- case e: Exception =>
- Console.err.println("error: Unable to instantiate parser")
- throw e
- }
-
- // parse file
- scopeStack.push(TopScope)
- parser.parse(source, this)
- scopeStack.pop
- return rootElem
- } // loadXML
-
- /** loads XML from given file */
- def loadFile(file: File): Node =
- loadXML(new InputSource(new FileInputStream(file)))
-
- /** loads XML from given file descriptor */
- def loadFile(fileDesc: FileDescriptor): Node =
- loadXML(new InputSource(new FileInputStream(fileDesc)))
-
- /** loads XML from given file */
- def loadFile(fileName: String): Node =
- loadXML(new InputSource(new FileInputStream(fileName)))
-
- /** loads XML from given InputStream */
- def load(is: InputStream): Node =
- loadXML(new InputSource(is))
-
- /** loads XML from given Reader */
- def load(reader: Reader): Node =
- loadXML(new InputSource(reader))
-
- /** loads XML from given sysID */
- def load(sysID: String): Node =
- loadXML(new InputSource(sysID))
-
-}
diff --git a/src/library/jvm/scala/xml/include/parsing/FatalError.scala b/src/library/jvm/scala/xml/include/parsing/FatalError.scala
deleted file mode 100644
index 2768becb8b..0000000000
--- a/src/library/jvm/scala/xml/include/parsing/FatalError.scala
+++ /dev/null
@@ -1,15 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2006, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.xml.parsing;
-
-
-case class FatalError(msg:String) extends java.lang.RuntimeException(msg);
diff --git a/src/library/jvm/scala/xml/include/parsing/MarkupParser.scala b/src/library/jvm/scala/xml/include/parsing/MarkupParser.scala
deleted file mode 100644
index 541cc65ac2..0000000000
--- a/src/library/jvm/scala/xml/include/parsing/MarkupParser.scala
+++ /dev/null
@@ -1,1215 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.xml.parsing
-
-import scala.io.Source
-import scala.xml.dtd._
-
-/**
- * An XML parser.
- *
- * Parses XML 1.0, invokes callback methods of a MarkupHandler
- * and returns whatever the markup handler returns. Use
- * ConstructingParser
if you just want to parse XML to
- * construct instances of scala.xml.Node
.
- *
- * While XML elements are returned, DTD declarations - if handled - are
- * collected using side-effects.
- *
- * @author Burak Emir
- * @version 1.0
- */
-trait MarkupParser extends AnyRef with TokenTests { self: MarkupParser with MarkupHandler =>
-
- val input: Source
-
- /** if true, does not remove surplus whitespace */
- val preserveWS: Boolean
-
- def externalSource(systemLiteral: String): Source
-
- //
- // variables, values
- //
-
- var curInput: Source = input
-
- /** the handler of the markup, returns this */
- private val handle: MarkupHandler = this
-
- /** stack of inputs */
- var inpStack: List[Source] = Nil
-
- /** holds the position in the source file */
- var pos: Int = _
-
-
- /* used when reading external subset */
- var extIndex = -1
-
- /** holds temporary values of pos */
- var tmppos: Int = _
-
- /** holds the next character */
- var ch: Char = _
-
- /** character buffer, for names */
- protected val cbuf = new StringBuilder()
-
- var dtd: DTD = null
-
- protected var doc: Document = null
-
- var eof: Boolean = false
-
- //
- // methods
- //
-
- /** <? prolog ::= xml S ... ?>
- */
- def xmlProcInstr(): MetaData = {
- xToken("xml")
- xSpace
- val (md,scp) = xAttributes(TopScope)
- if (scp != TopScope)
- reportSyntaxError("no xmlns definitions here, please.");
- xToken('?')
- xToken('>')
- md
- }
-
- /** <? prolog ::= xml S?
- * // this is a bit more lenient than necessary...
- */
- def prolog(): Tuple3[Option[String], Option[String], Option[Boolean]] = {
-
- //Console.println("(DEBUG) prolog")
- var n = 0
- var info_ver: Option[String] = None
- var info_enc: Option[String] = None
- var info_stdl: Option[Boolean] = None
-
- var m = xmlProcInstr()
-
- xSpaceOpt
-
- m("version") match {
- case null => ;
- case Text("1.0") => info_ver = Some("1.0"); n += 1
- case _ => reportSyntaxError("cannot deal with versions != 1.0")
- }
-
- m("encoding") match {
- case null => ;
- case Text(enc) =>
- if (!isValidIANAEncoding(enc))
- reportSyntaxError("\"" + enc + "\" is not a valid encoding")
- else {
- info_enc = Some(enc)
- n += 1
- }
- }
- m("standalone") match {
- case null => ;
- case Text("yes") => info_stdl = Some(true); n += 1
- case Text("no") => info_stdl = Some(false); n += 1
- case _ => reportSyntaxError("either 'yes' or 'no' expected")
- }
-
- if (m.length - n != 0) {
- reportSyntaxError("VersionInfo EncodingDecl? SDDecl? or '?>' expected!");
- }
- //Console.println("[MarkupParser::prolog] finished parsing prolog!");
- Tuple3(info_ver,info_enc,info_stdl)
- }
-
- /** prolog, but without standalone */
- def textDecl(): Tuple2[Option[String],Option[String]] = {
-
- var info_ver: Option[String] = None
- var info_enc: Option[String] = None
-
- var m = xmlProcInstr()
- var n = 0
-
- m("version") match {
- case null => ;
- case Text("1.0") => info_ver = Some("1.0"); n += 1
- case _ => reportSyntaxError("cannot deal with versions != 1.0")
- }
-
- m("encoding") match {
- case null => ;
- case Text(enc) =>
- if (!isValidIANAEncoding(enc))
- reportSyntaxError("\"" + enc + "\" is not a valid encoding")
- else {
- info_enc = Some(enc)
- n += 1
- }
- }
-
- if (m.length - n != 0) {
- reportSyntaxError("VersionInfo EncodingDecl? or '?>' expected!");
- }
- //Console.println("[MarkupParser::textDecl] finished parsing textdecl");
- Tuple2(info_ver, info_enc);
- }
-
- /**
- *[22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?
- *[23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
- *[24] VersionInfo ::= S 'version' Eq ("'" VersionNum "'" | '"' VersionNum '"')
- *[25] Eq ::= S? '=' S?
- *[26] VersionNum ::= '1.0'
- *[27] Misc ::= Comment | PI | S
- */
-
- def document(): Document = {
-
- //Console.println("(DEBUG) document")
- doc = new Document()
-
- this.dtd = null
- var info_prolog: Tuple3[Option[String], Option[String], Option[Boolean]] = Tuple3(None, None, None);
- if ('<' != ch) {
- reportSyntaxError("< expected")
- return null
- }
-
- nextch // is prolog ?
- var children: NodeSeq = null
- if ('?' == ch) {
- //Console.println("[MarkupParser::document] starts with xml declaration");
- nextch;
- info_prolog = prolog()
- doc.version = info_prolog._1
- doc.encoding = info_prolog._2
- doc.standAlone = info_prolog._3
-
- children = content(TopScope) // DTD handled as side effect
- } else {
- //Console.println("[MarkupParser::document] does not start with xml declaration");
- //
-
- val ts = new NodeBuffer();
- content1(TopScope, ts); // DTD handled as side effect
- ts &+ content(TopScope);
- children = NodeSeq.fromSeq(ts);
- }
- //Console.println("[MarkupParser::document] children now: "+children.toList);
- var elemCount = 0;
- var theNode: Node = null;
- for (c <- children) c match {
- case _:ProcInstr => ;
- case _:Comment => ;
- case _:EntityRef => // todo: fix entities, shouldn't be "special"
- reportSyntaxError("no entity references alllowed here");
- case s:SpecialNode =>
- if (s.toString().trim().length > 0) //non-empty text nodes not allowed
- elemCount = elemCount + 2;
- case m:Node =>
- elemCount = elemCount + 1;
- theNode = m;
- }
- if (1 != elemCount) {
- reportSyntaxError("document must contain exactly one element")
- Console.println(children.toList)
- }
-
- doc.children = children
- doc.docElem = theNode
- doc
- }
-
- /** append Unicode character to name buffer*/
- protected def putChar(c: Char) = cbuf.append(c)
-
- //var xEmbeddedBlock = false;
-
- /** this method assign the next character to ch and advances in input */
- def nextch {
- if (curInput.hasNext) {
- ch = curInput.next
- pos = curInput.pos
- } else {
- val ilen = inpStack.length;
- //Console.println(" ilen = "+ilen+ " extIndex = "+extIndex);
- if ((ilen != extIndex) && (ilen > 0)) {
- /** for external source, inpStack == Nil ! need notify of eof! */
- pop()
- } else {
- eof = true
- ch = 0.asInstanceOf[Char]
- }
- }
- }
-
- //final val enableEmbeddedExpressions: Boolean = false;
-
- /** munch expected XML token, report syntax error for unexpected
- */
- def xToken(that: Char) {
- if (ch == that)
- nextch
- else {
- reportSyntaxError("'" + that + "' expected instead of '" + ch + "'")
- error("FATAL")
- }
- }
-
- def xToken(that: Seq[Char]): Unit = {
- val it = that.elements;
- while (it.hasNext)
- xToken(it.next);
- }
-
- /** parse attribute and create namespace scope, metadata
- * [41] Attributes ::= { S Name Eq AttValue }
- */
- def xAttributes(pscope:NamespaceBinding): (MetaData,NamespaceBinding) = {
- var scope: NamespaceBinding = pscope
- var aMap: MetaData = Null
- while (isNameStart(ch)) {
- val pos = this.pos
-
- val qname = xName
- val _ = xEQ
- val value = xAttributeValue()
-
- Utility.prefix(qname) match {
- case Some("xmlns") =>
- val prefix = qname.substring(6 /*xmlns:*/ , qname.length);
- scope = new NamespaceBinding(prefix, value, scope);
-
- case Some(prefix) =>
- val key = qname.substring(prefix.length+1, qname.length);
- aMap = new PrefixedAttribute(prefix, key, Text(value), aMap);
-
- case _ =>
- if( qname == "xmlns" )
- scope = new NamespaceBinding(null, value, scope);
- else
- aMap = new UnprefixedAttribute(qname, Text(value), aMap);
- }
-
- if ((ch != '/') && (ch != '>') && ('?' != ch))
- xSpace;
- }
-
- if(!aMap.wellformed(scope))
- reportSyntaxError( "double attribute");
-
- (aMap,scope)
- }
-
- /** attribute value, terminated by either ' or ". value may not contain <.
- * AttValue ::= `'` { _ } `'`
- * | `"` { _ } `"`
- */
- def xAttributeValue(): String = {
- val endch = ch
- nextch
- while (ch != endch) {
- if ('<' == ch)
- reportSyntaxError( "'<' not allowed in attrib value" );
- putChar(ch)
- nextch
- }
- nextch
- val str = cbuf.toString()
- cbuf.length = 0
-
- // well-formedness constraint
- normalizeAttributeValue(str)
- }
-
- /** entity value, terminated by either ' or ". value may not contain <.
- * AttValue ::= `'` { _ } `'`
- * | `"` { _ } `"`
- */
- def xEntityValue(): String = {
- val endch = ch
- nextch
- while (ch != endch) {
- putChar(ch)
- nextch
- }
- nextch
- val str = cbuf.toString()
- cbuf.length = 0
- str
- }
-
-
- /** parse a start or empty tag.
- * [40] STag ::= '<' Name { S Attribute } [S]
- * [44] EmptyElemTag ::= '<' Name { S Attribute } [S]
- */
- protected def xTag(pscope:NamespaceBinding): Tuple3[String, MetaData, NamespaceBinding] = {
- val qname = xName
-
- xSpaceOpt
- val (aMap: MetaData, scope: NamespaceBinding) = {
- if (isNameStart(ch))
- xAttributes(pscope)
- else
- (Null, pscope)
- }
- (qname, aMap, scope)
- }
-
- /** [42] '<' xmlEndTag ::= '<' '/' Name S? '>'
- */
- def xEndTag(n: String) = {
- xToken('/')
- val m = xName
- if (n != m)
- reportSyntaxError("expected closing tag of " + n/* +", not "+m*/);
- xSpaceOpt
- xToken('>')
- }
-
- /** '<! CharData ::= [CDATA[ ( {char} - {char}"]]>"{char} ) ']]>'
- *
- * see [15]
- */
- def xCharData: NodeSeq = {
- xToken("[CDATA[")
- val pos1 = pos
- val sb: StringBuilder = new StringBuilder()
- while (true) {
- if (ch==']' &&
- { sb.append(ch); nextch; ch == ']' } &&
- { sb.append(ch); nextch; ch == '>' } ) {
- sb.length = sb.length - 2
- nextch;
- return handle.text( pos1, sb.toString() );
- } else sb.append( ch );
- nextch;
- }
- throw FatalError("this cannot happen");
- };
-
- /** CharRef ::= "&#" '0'..'9' {'0'..'9'} ";"
- * | "&#x" '0'..'9'|'A'..'F'|'a'..'f' { hexdigit } ";"
- *
- * see [66]
- */
- def xCharRef(ch: () => Char, nextch: () => Unit): String = {
- Utility.parseCharRef(ch, nextch, reportSyntaxError _)
- /*
- val hex = (ch() == 'x') && { nextch(); true };
- val base = if (hex) 16 else 10;
- var i = 0;
- while (ch() != ';') {
- ch() match {
- case '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' =>
- i = i * base + Character.digit( ch(), base );
- case 'a' | 'b' | 'c' | 'd' | 'e' | 'f'
- | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' =>
- if (! hex)
- reportSyntaxError("hex char not allowed in decimal char ref\n"
- +"Did you mean to write ?");
- else
- i = i * base + Character.digit(ch(), base);
- case _ =>
- reportSyntaxError("character '" + ch() + " not allowed in char ref\n");
- }
- nextch();
- }
- new String(Array(i.asInstanceOf[char]))
- */
- }
-
-
- /** Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
- *
- * see [15]
- */
- def xComment: NodeSeq = {
- val sb: StringBuilder = new StringBuilder()
- xToken('-')
- xToken('-')
- while (true) {
- if (ch == '-' && { sb.append(ch); nextch; ch == '-' }) {
- sb.length = sb.length - 1
- nextch
- xToken('>')
- return handle.comment(pos, sb.toString())
- } else sb.append(ch)
- nextch
- }
- throw FatalError("this cannot happen")
- }
-
- /* todo: move this into the NodeBuilder class */
- def appendText(pos: Int, ts: NodeBuffer, txt: String): Unit = {
- if (preserveWS)
- ts &+ handle.text(pos, txt);
- else
- for (t <- TextBuffer.fromString(txt).toText) {
- ts &+ handle.text(pos, t.text);
- }
- }
-
- /** '<' content1 ::= ... */
- def content1(pscope: NamespaceBinding, ts: NodeBuffer): Unit =
- ch match {
- case '!' =>
- nextch
- if ('[' == ch) // CDATA
- ts &+ xCharData
- else if ('D' == ch) // doctypedecl, parse DTD // @todo REMOVE HACK
- parseDTD()
- else // comment
- ts &+ xComment
- case '?' => // PI
- nextch
- ts &+ xProcInstr
- case _ =>
- ts &+ element1(pscope) // child
- }
-
- /** content1 ::= '<' content1 | '&' charref ... */
- def content(pscope: NamespaceBinding): NodeSeq = {
- var ts = new NodeBuffer
- var exit = eof
- while (! exit) {
- //Console.println("in content, ch = '"+ch+"' line="+scala.io.Position.line(pos));
- /* if( xEmbeddedBlock ) {
- ts.append( xEmbeddedExpr );
- } else {*/
- tmppos = pos;
- exit = eof;
- if(!eof)
- ch match {
- case '<' => // another tag
- //Console.println("before ch = '"+ch+"' line="+scala.io.Position.line(pos)+" pos="+pos);
- nextch;
- //Console.println("after ch = '"+ch+"' line="+scala.io.Position.line(pos)+" pos="+pos);
-
- if('/' ==ch)
- exit = true; // end tag
- else
- content1(pscope, ts)
- //case '{' =>
-/* if( xCheckEmbeddedBlock ) {
- ts.appendAll(xEmbeddedExpr);
- } else {*/
- // val str = new StringBuilder("{");
- // str.append(xText);
- // appendText(tmppos, ts, str.toString());
- /*}*/
- // postcond: xEmbeddedBlock == false!
- case '&' => // EntityRef or CharRef
- nextch;
- ch match {
- case '#' => // CharacterRef
- nextch;
- val theChar = handle.text( tmppos,
- xCharRef ({ ()=> ch },{ () => nextch }) );
- xToken(';');
- ts &+ theChar ;
- case _ => // EntityRef
- val n = xName
- xToken(';')
- n match {
- case "lt" => ts &+ '<'
- case "gt" => ts &+ '>'
- case "amp" => ts &+ '&'
- case "quot" => ts &+ '"'
- case _ =>
- /*
- ts + handle.entityRef( tmppos, n ) ;
- */
- push(n)
- }
- }
- case _ => // text content
- //Console.println("text content?? pos = "+pos);
- appendText(tmppos, ts, xText);
- // here xEmbeddedBlock might be true
- }
- /*}*/
- }
- val list = ts.toList
- // 2do: optimize seq repr.
- new NodeSeq {
- val theSeq = list
- }
- } // content(NamespaceBinding)
-
- /** externalID ::= SYSTEM S syslit
- * PUBLIC S pubid S syslit
- */
-
- def externalID(): ExternalID = ch match {
- case 'S' =>
- nextch
- xToken("YSTEM")
- xSpace
- val sysID = systemLiteral()
- new SystemID(sysID)
- case 'P' =>
- nextch; xToken("UBLIC")
- xSpace
- val pubID = pubidLiteral()
- xSpace
- val sysID = systemLiteral()
- new PublicID(pubID, sysID)
- }
-
-
- /** parses document type declaration and assigns it to instance variable
- * dtd.
- *
- * <! parseDTD ::= DOCTYPE name ... >
- */
- def parseDTD(): Unit = { // dirty but fast
- //Console.println("(DEBUG) parseDTD");
- var extID: ExternalID = null
- if (this.dtd ne null)
- reportSyntaxError("unexpected character (DOCTYPE already defined");
- xToken("DOCTYPE")
- xSpace
- val n = xName
- xSpace
- //external ID
- if ('S' == ch || 'P' == ch) {
- extID = externalID()
- xSpaceOpt
- }
-
- /* parse external subset of DTD
- */
-
- if ((null != extID) && isValidating) {
-
- pushExternal(extID.systemId)
- //val extSubsetSrc = externalSource( extID.systemId );
-
- extIndex = inpStack.length
- /*
- .indexOf(':') != -1) { // assume URI
- Source.fromFile(new java.net.URI(extID.systemLiteral));
- } else {
- Source.fromFile(extID.systemLiteral);
- }
- */
- //Console.println("I'll print it now");
- //val old = curInput;
- //tmppos = curInput.pos;
- //val oldch = ch;
- //curInput = extSubsetSrc;
- //pos = 0;
- //nextch;
-
- extSubset()
-
- pop()
-
- extIndex = -1
-
- //curInput = old;
- //pos = curInput.pos;
- //ch = curInput.ch;
- //eof = false;
- //while(extSubsetSrc.hasNext)
- //Console.print(extSubsetSrc.next);
-
- //Console.println("returned from external, current ch = "+ch )
- }
-
- if ('[' == ch) { // internal subset
- nextch
- /* TODO */
- //Console.println("hello");
- intSubset()
- //while(']' != ch)
- // nextch;
- // TODO: do the DTD parsing?? ?!?!?!?!!
- xToken(']')
- xSpaceOpt
- }
- xToken('>')
- this.dtd = new DTD {
- /*override var*/ externalID = extID
- /*override val */decls = handle.decls.reverse
- }
- //this.dtd.initializeEntities();
- if (doc ne null)
- doc.dtd = this.dtd
-
- handle.endDTD(n)
- }
-
- def element(pscope: NamespaceBinding): NodeSeq = {
- xToken('<')
- element1(pscope)
- }
-
- /** '<' element ::= xmlTag1 '>' { xmlExpr | '{' simpleExpr '}' } ETag
- * | xmlTag1 '/' '>'
- */
- def element1(pscope: NamespaceBinding): NodeSeq = {
- val pos = this.pos
- val Tuple3(qname, aMap, scope) = xTag(pscope)
- val Tuple2(pre, local) = Utility.prefix(qname) match {
- case Some(p) => (p,qname.substring(p.length+1, qname.length))
- case _ => (null,qname)
- }
- val ts = {
- if (ch == '/') { // empty element
- xToken('/')
- xToken('>')
- handle.elemStart(pos, pre, local, aMap, scope)
- NodeSeq.Empty
- }
- else { // element with content
- xToken('>')
- handle.elemStart(pos, pre, local, aMap, scope)
- val tmp = content(scope)
- xEndTag(qname)
- tmp
- }
- }
- val res = handle.elem(pos, pre, local, aMap, scope, ts)
- handle.elemEnd(pos, pre, local)
- res
- }
-
- //def xEmbeddedExpr: MarkupType;
-
- /** Name ::= (Letter | '_' | ':') (NameChar)*
- *
- * see [5] of XML 1.0 specification
- */
- def xName: String = {
- if (isNameStart(ch)) {
- while (isNameChar(ch)) {
- putChar(ch)
- nextch
- }
- val n = cbuf.toString().intern()
- cbuf.length = 0
- n
- } else {
- reportSyntaxError("name expected")
- ""
- }
- }
-
- /** scan [S] '=' [S]*/
- def xEQ = { xSpaceOpt; xToken('='); xSpaceOpt }
-
- /** skip optional space S? */
- def xSpaceOpt = while (isSpace(ch) && !eof) { nextch; }
-
- /** scan [3] S ::= (#x20 | #x9 | #xD | #xA)+ */
- def xSpace =
- if (isSpace(ch)) { nextch; xSpaceOpt }
- else reportSyntaxError("whitespace expected")
-
- /** '<?' ProcInstr ::= Name [S ({Char} - ({Char}'>?' {Char})]'?>'
- *
- * see [15]
- */
- def xProcInstr: NodeSeq = {
- val sb:StringBuilder = new StringBuilder()
- val n = xName
- if (isSpace(ch)) {
- xSpace
- while (true) {
- if (ch == '?' && { sb.append( ch ); nextch; ch == '>' }) {
- sb.length = sb.length - 1;
- nextch;
- return handle.procInstr(tmppos, n, sb.toString);
- } else
- sb.append(ch);
- nextch
- }
- };
- xToken('?')
- xToken('>')
- handle.procInstr(tmppos, n, sb.toString)
- }
-
- /** parse character data.
- * precondition: xEmbeddedBlock == false (we are not in a scala block)
- */
- def xText: String = {
- //if( xEmbeddedBlock ) throw FatalError("internal error: encountered embedded block"); // assert
-
- /*if( xCheckEmbeddedBlock )
- return ""
- else {*/
- //Console.println("in xText! ch = '"+ch+"'");
- var exit = false;
- while (! exit) {
- //Console.println("LOOP in xText! ch = '"+ch+"' + pos="+pos);
- putChar(ch);
- val opos = pos;
- nextch;
-
- //Console.println("STILL LOOP in xText! ch = '"+ch+"' + pos="+pos+" opos="+opos);
-
-
- exit = eof || /*{ nextch; xCheckEmbeddedBlock }||*/( ch == '<' ) || ( ch == '&' );
- }
- val str = cbuf.toString();
- cbuf.length = 0;
- str
- /*}*/
- }
-
- /** attribute value, terminated by either ' or ". value may not contain <.
- * AttValue ::= `'` { _ } `'`
- * | `"` { _ } `"`
- */
- def systemLiteral(): String = {
- val endch = ch
- if (ch != '\'' && ch != '"')
- reportSyntaxError("quote ' or \" expected");
- nextch
- while (ch != endch) {
- putChar(ch)
- nextch
- }
- nextch
- val str = cbuf.toString()
- cbuf.length = 0
- str
- }
-
-
- /* [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'" */
- def pubidLiteral(): String = {
- val endch = ch
- if (ch!='\'' && ch != '"')
- reportSyntaxError("quote ' or \" expected");
- nextch
- while (ch != endch) {
- putChar(ch)
- //Console.println("hello '"+ch+"'"+isPubIDChar(ch));
- if (!isPubIDChar(ch))
- reportSyntaxError("char '"+ch+"' is not allowed in public id");
- nextch
- }
- nextch
- val str = cbuf.toString()
- cbuf.length = 0
- str
- }
-
- //
- // dtd parsing
- //
-
- def extSubset(): Unit = {
- var textdecl:Tuple2[Option[String],Option[String]] = null;
- if (ch=='<') {
- nextch
- if (ch=='?') {
- nextch
- textdecl = textDecl()
- } else
- markupDecl1()
- }
- while (!eof)
- markupDecl()
- }
-
- def markupDecl1() = {
- def doInclude() = {
- xToken('['); while(']' != ch) markupDecl(); nextch // ']'
- }
- def doIgnore() = {
- xToken('['); while(']' != ch) nextch; nextch; // ']'
- }
- if ('?' == ch) {
- nextch
- xProcInstr // simply ignore processing instructions!
- } else {
- xToken('!')
- ch match {
- case '-' =>
- xComment // ignore comments
-
- case 'E' =>
- nextch
- if ('L' == ch) {
- nextch
- elementDecl()
- } else
- entityDecl()
-
- case 'A' =>
- nextch
- attrDecl()
-
- case 'N' =>
- nextch
- notationDecl()
-
- case '[' if inpStack.length >= extIndex =>
- nextch
- xSpaceOpt
- ch match {
- case '%' =>
- nextch
- val ent = xName
- xToken(';')
- xSpaceOpt
- /*
- Console.println("hello, pushing!");
- {
- val test = replacementText(ent);
- while(test.hasNext)
- Console.print(test.next);
- } */
- push(ent)
- xSpaceOpt
- //Console.println("hello, getting name");
- val stmt = xName
- //Console.println("hello, got name");
- xSpaceOpt
- //Console.println("how can we be eof = "+eof);
-
- // eof = true because not external?!
- //if(!eof)
- // error("expected only INCLUDE or IGNORE");
-
- //pop();
-
- //Console.println("hello, popped");
- stmt match {
- // parameter entity
- case "INCLUDE" =>
- doInclude()
- case "IGNORE" =>
- doIgnore()
- }
- case 'I' =>
- nextch
- ch match {
- case 'G' =>
- nextch
- xToken("NORE")
- xSpaceOpt
- doIgnore()
- case 'N' =>
- nextch
- xToken("NCLUDE")
- doInclude()
- }
- }
- xToken(']')
- xToken('>')
-
- case _ =>
- curInput.reportError(pos, "unexpected character '"+ch+"', expected some markupdecl")
- while (ch!='>')
- nextch
- }
- }
- }
-
- def markupDecl(): Unit = ch match {
- case '%' => // parameter entity reference
- nextch
- val ent = xName
- xToken(';')
- if (!isValidating)
- handle.peReference(ent) // n-v: just create PE-reference
- else
- push(ent) // v: parse replacementText
-
- //peReference
- case '<' =>
- nextch
- markupDecl1()
- case _ if isSpace(ch) =>
- xSpace
- case _ =>
- reportSyntaxError("markupdecl: unexpected character '"+ch+"' #" + ch.asInstanceOf[Int])
- nextch
- }
-
- /** "rec-xml/#ExtSubset" pe references may not occur within markup
- declarations
- */
- def intSubset() {
- //Console.println("(DEBUG) intSubset()")
- xSpace
- while (']' != ch)
- markupDecl()
- }
-
- /** <! element := ELEMENT
- */
- def elementDecl() {
- xToken("EMENT")
- xSpace
- val n = xName
- xSpace
- while ('>' != ch) {
- //Console.println("["+ch+"]")
- putChar(ch)
- nextch
- }
- //Console.println("END["+ch+"]")
- nextch
- val cmstr = cbuf.toString()
- cbuf.length = 0
- handle.elemDecl(n, cmstr)
- }
-
- /** <! attlist := ATTLIST
- */
- def attrDecl() = {
- xToken("TTLIST")
- xSpace
- val n = xName
- xSpace
- var attList: List[AttrDecl] = Nil
- // later: find the elemDecl for n
- while ('>' != ch) {
- val aname = xName
- //Console.println("attribute name: "+aname);
- var defdecl: DefaultDecl = null
- xSpace
- // could be enumeration (foo,bar) parse this later :-/
- while ('"' != ch && '\'' != ch && '#' != ch && '<' != ch) {
- if (!isSpace(ch))
- cbuf.append(ch);
- nextch;
- }
- val atpe = cbuf.toString()
- cbuf.length = 0
- //Console.println("attr type: "+atpe);
- ch match {
- case '\'' | '"' =>
- val defValue = xAttributeValue() // default value
- defdecl = DEFAULT(false, defValue)
-
- case '#' =>
- nextch
- xName match {
- case "FIXED" =>
- xSpace
- val defValue = xAttributeValue() // default value
- defdecl = DEFAULT(true, defValue)
- case "IMPLIED" =>
- defdecl = IMPLIED
- case "REQUIRED" =>
- defdecl = REQUIRED
- }
- case _ =>
- }
- xSpaceOpt
-
- attList = AttrDecl(aname, atpe, defdecl) :: attList
- cbuf.length = 0
- }
- nextch
- handle.attListDecl(n, attList.reverse)
- }
-
- /** <! element := ELEMENT
- */
- def entityDecl() = {
- //Console.println("entityDecl()")
- var isParameterEntity = false
- var entdef: EntityDef = null
- xToken("NTITY")
- xSpace
- if ('%' == ch) {
- nextch
- isParameterEntity = true
- xSpace
- }
- val n = xName
- xSpace
- ch match {
- case 'S' | 'P' => //sy
- val extID = externalID()
- if (isParameterEntity) {
- xSpaceOpt
- xToken('>')
- handle.parameterEntityDecl(n, ExtDef(extID))
- } else { // notation?
- xSpace
- if ('>' != ch) {
- xToken("NDATA")
- xSpace
- val notat = xName
- xSpaceOpt
- xToken('>')
- handle.unparsedEntityDecl(n, extID, notat)
- } else {
- nextch
- handle.parsedEntityDecl(n, ExtDef(extID))
- }
- }
-
- case '"' | '\'' =>
- val av = xEntityValue()
- xSpaceOpt
- xToken('>')
- if (isParameterEntity)
- handle.parameterEntityDecl(n, IntDef(av))
- else
- handle.parsedEntityDecl(n, IntDef(av))
- }
- {}
- } // entityDecl
-
- /** 'N' notationDecl ::= "OTATION"
- */
- def notationDecl() {
- xToken("OTATION")
- xSpace
- val notat = xName
- xSpace
- val extID = if (ch == 'S') {
- externalID();
- }
- else if (ch == 'P') {
- /** PublicID (without system, only used in NOTATION) */
- nextch
- xToken("UBLIC")
- xSpace
- val pubID = pubidLiteral()
- xSpaceOpt
- val sysID = if (ch != '>')
- systemLiteral()
- else
- null;
- new PublicID(pubID, sysID);
- } else {
- reportSyntaxError("PUBLIC or SYSTEM expected");
- error("died parsing notationdecl")
- }
- xSpaceOpt
- xToken('>')
- handle.notationDecl(notat, extID)
- }
-
- /**
- * report a syntax error
- */
- def reportSyntaxError(pos: Int, str: String) {
- curInput.reportError(pos, str)
- //error("MarkupParser::synerr") // DEBUG
- }
-
- def reportSyntaxError(str: String): Unit = reportSyntaxError(pos, str)
-
- /**
- * report a syntax error
- */
- def reportValidationError(pos: Int, str: String) {
- curInput.reportError(pos, str)
- }
-
- def push(entityName: String) {
- //Console.println("BEFORE PUSHING "+ch)
- //Console.println("BEFORE PUSHING "+pos)
- //Console.print("[PUSHING "+entityName+"]")
- if (!eof)
- inpStack = curInput :: inpStack
-
- curInput = replacementText(entityName)
- nextch
- }
-
- /*
- def push(src:Source) = {
- curInput = src
- nextch
- }
- */
-
- def pushExternal(systemId: String) {
- //Console.print("BEFORE PUSH, curInput = $"+curInput.descr)
- //Console.println(" stack = "+inpStack.map { x => "$"+x.descr })
-
- //Console.print("[PUSHING EXTERNAL "+systemId+"]")
- if (!eof)
- inpStack = curInput :: inpStack
-
- curInput = externalSource(systemId)
-
- //Console.print("AFTER PUSH, curInput = $"+curInput.descr)
- //Console.println(" stack = "+inpStack.map { x => "$"+x.descr })
-
- nextch
- }
-
- def pop() {
- curInput = inpStack.head
- inpStack = inpStack.tail
- ch = curInput.ch
- pos = curInput.pos
- eof = false // must be false, because of places where entity refs occur
- //Console.println("\n AFTER POP, curInput = $"+curInput.descr);
- //Console.println(inpStack.map { x => x.descr });
- }
-
- /** for the moment, replace only character references
- * see spec 3.3.3
- * precond: cbuf empty
- */
- def normalizeAttributeValue(attval: String): String = {
- val s: Seq[Char] = attval
- val it = s.elements
- while (it.hasNext) {
- it.next match {
- case ' '|'\t'|'\n'|'\r' =>
- cbuf.append(' ');
- case '&' => it.next match {
- case '#' =>
- var c = it.next
- val s = xCharRef ({ () => c }, { () => c = it.next })
- cbuf.append(s)
- case nchar =>
- val nbuf = new StringBuilder()
- var d = nchar
- do {
- nbuf.append(d)
- d = it.next
- } while(d != ';');
- nbuf.toString() match {
- case "lt" => cbuf.append('<')
- case "gt" => cbuf.append('>')
- case "amp" => cbuf.append('&')
- case "apos" => cbuf.append('\'')
- case "quot" => cbuf.append('"')
- case "quote" => cbuf.append('"')
- case name =>
- cbuf.append('&')
- cbuf.append(name)
- cbuf.append(';')
- }
- }
- case c =>
- cbuf.append(c)
- }
- }
- val name = cbuf.toString()
- cbuf.length = 0
- name
- }
-
-}
diff --git a/src/library/jvm/scala/xml/include/parsing/NoBindingFactoryAdapter.scala b/src/library/jvm/scala/xml/include/parsing/NoBindingFactoryAdapter.scala
deleted file mode 100644
index be71e55fef..0000000000
--- a/src/library/jvm/scala/xml/include/parsing/NoBindingFactoryAdapter.scala
+++ /dev/null
@@ -1,62 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2006, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.xml.parsing;
-
-
-import scala.xml.factory.NodeFactory;
-import org.xml.sax.InputSource;
-
-/** nobinding adaptor providing callbacks to parser to create elements.
-* implements hash-consing
-*/
-class NoBindingFactoryAdapter extends FactoryAdapter with NodeFactory[Elem] {
-
- // -- FactoryAdapter methods
-
- /** returns true. Every XML node may contain text that the application needs
- **/
- def nodeContainsText( label:java.lang.String ): Boolean = true;
-
-
- // methods for NodeFactory[Elem]
-
- /** constructs an instance of scala.xml.Elem */
- protected def create(pre: String, label: String, attrs: MetaData, scpe: NamespaceBinding, children:Seq[Node]): Elem = {
- Elem( pre, label, attrs, scpe, children:_* );
- }
-
- // -- methods for FactoryAdapter
-
- /** creates a node. never creates the same node twice, using hash-consing
- */
- def createNode(pre:String, label: String, attrs: MetaData, scpe: NamespaceBinding, children: List[Node] ): Elem = {
- //Console.println("NoBindingFactoryAdapter::createNode("+pre+","+label+","+attrs+","+scpe+","+children+")");
- Elem( pre, label, attrs, scpe, children:_* );
- //makeNode(pre, label, attrs, scpe, children);
- }
-
- /** creates a text node
- */
- def createText( text:String ) =
- Text( text );
-
- /** create a processing instruction
- */
- def createProcInstr(target: String, data: String) =
- makeProcInstr(target, data)
-
- /** loads an XML document, returning a Symbol node.
- */
- override def loadXML( source:InputSource ):Elem =
- super.loadXML( source ).asInstanceOf[ Elem ];
-
-}
diff --git a/src/library/jvm/scala/xml/include/parsing/TokenTests.scala b/src/library/jvm/scala/xml/include/parsing/TokenTests.scala
deleted file mode 100644
index d56b9bb7d7..0000000000
--- a/src/library/jvm/scala/xml/include/parsing/TokenTests.scala
+++ /dev/null
@@ -1,146 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2006, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.xml.parsing;
-
-
-/**
- * Helper functions for parsing XML fragments
- */
-trait TokenTests {
-
- /** (#x20 | #x9 | #xD | #xA) */
- final def isSpace( ch:Char ): Boolean = ch match {
- case '\u0009' | '\u000A' | '\u000D' | '\u0020' => true
- case _ => false;
- }
-
- /** (#x20 | #x9 | #xD | #xA)+ */
- final def isSpace(cs: Seq[Char]): Boolean = {
- val it = cs.elements;
- it.hasNext && it.forall { isSpace };
- }
-
- /** NameChar ::= Letter | Digit | '.' | '-' | '_' | ':'
- * | CombiningChar | Extender
- *
- * see [4] and Appendix B of XML 1.0 specification
- */
- def isNameChar(ch: Char) = isNameStart(ch) || (ch match {
- case '.' | '-' | ':' => true;
- case _ => java.lang.Character.getType( ch ).asInstanceOf[Byte] match {
- case java.lang.Character.COMBINING_SPACING_MARK => true; // Mc
- case java.lang.Character.ENCLOSING_MARK => true; // Me
- case java.lang.Character.NON_SPACING_MARK => true; // Mn
- case java.lang.Character.MODIFIER_LETTER => true; // Lm
- case java.lang.Character.DECIMAL_DIGIT_NUMBER => true; // Nd
- case _ => false;
- }
- });
-
- /** NameStart ::= ( Letter | '_' )
- * where Letter means in one of the Unicode general
- * categories { Ll, Lu, Lo, Lt, Nl }
- *
- * We do not allow a name to start with ':'.
- * see [3] and Appendix B of XML 1.0 specification
- */
- def isNameStart(ch: Char) =
- java.lang.Character.getType(ch).asInstanceOf[Byte] match {
- case java.lang.Character.LOWERCASE_LETTER => true;
- case java.lang.Character.UPPERCASE_LETTER => true;
- case java.lang.Character.OTHER_LETTER => true;
- case java.lang.Character.TITLECASE_LETTER => true;
- case java.lang.Character.LETTER_NUMBER => true;
- case _ => ch match {
- case '_' => true
- case _ => false;
- }
- }
-
- /** Name ::= ( Letter | '_' ) (NameChar)*
- *
- * see [5] of XML 1.0 specification
- */
- def isName(s: String): Boolean = {
- if( s.length() > 0 ) {
- val y = s.elements;
- if (isNameStart(y.next)) {
- while (y.hasNext && isNameChar(y.next)) {};
- !y.hasNext
- } else false;
- } else false;
- }
-
- def isPubIDChar(ch: Char): Boolean = {
- //Console.println("char: '" + ch + "'");
- ch match {
- case '\u0020' | '\u000D' | '\u000A' => true;
- case _ if
- (('0' <= ch && ch <= '9') || ('a' <= ch && ch <= 'z') ||
- ('A' <= ch && ch <= 'Z')) => true;
- case '-' | '\''| '(' | ')' | '+' | ',' | '.' |
- '/' | ':' | '=' | '?' | ';' | '!' | '*' |
- '#' | '@' | '$' | '_' | '%' => true
- case _ =>
- //Console.println("false: '" + ch + "'");
- false;
- }
- }
-
- /**
- * Returns true if the encoding name is a valid IANA encoding.
- * This method does not verify that there is a decoder available
- * for this encoding, only that the characters are valid for an
- * IANA encoding name.
- *
- * @param ianaEncoding The IANA encoding name.
- */
- def isValidIANAEncoding(ianaEncoding: Seq[Char]): Boolean = {
- val it = ianaEncoding.elements;
- if (!it.hasNext)
- return false;
-
- var c = it.next;
- if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
- while (it.hasNext) {
- c = it.next;
- if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z') &&
- (c < '0' || c > '9') && c != '.' && c != '_' &&
- c != '-') {
- return false;
- }
- }
- return true;
- } else
- return false;
- } // isValidIANAEncoding(String): Boolean
-
- def checkSysID( s:String ): Boolean = {
- s.indexOf('"'.asInstanceOf[Int]) == -1 || s.indexOf('\''.asInstanceOf[Int]) == -1
- }
-
- def checkPubID(s: String): Boolean = {
- //Console.println("checkPubID of \""+s+"\"");
- if (s.length() > 0) {
- val y = s.elements;
- var c = ' ';
- while (y.hasNext && isPubIDChar(c)) {
- //Console.println(c);
- c = y.next
- };
- !y.hasNext
- }
- else
- true
- }
-
-}
diff --git a/src/library/jvm/scala/xml/include/persistent/CachedFileStorage.scala b/src/library/jvm/scala/xml/include/persistent/CachedFileStorage.scala
deleted file mode 100644
index 137286492a..0000000000
--- a/src/library/jvm/scala/xml/include/persistent/CachedFileStorage.scala
+++ /dev/null
@@ -1,123 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.xml.persistent
-
-import java.io.{File, FileOutputStream}
-import java.nio.ByteBuffer
-import java.nio.channels.Channels
-
-/**
- * import scala.xml._
- * import scala.xml.pull._
- * import scala.io.Source
- *
- * object reader {
- * val src = Source.fromString("
- *
- * @author Burak Emir
- */
-class XMLEventReader extends Iterator[XMLEvent] {
-
- var src:Source = null
- def getSource = this.src
- def initialize(src: Source): this.type = {
- this.src = src
- this.parserThread = new Thread(new Parser())
- this.parserThread.start()
- this
- }
-
- // -- this part of the class is for communication with the thread
- var xmlEvent: XMLEvent = null
- var continue: Boolean = true
-
- def myresume = synchronized {
- while (continue) {
- wait()
- }
- continue = true
- notifyAll
- }
- def getAndClearEvent: XMLEvent = synchronized {
- while (xmlEvent eq null) {
- wait()
- }
- val r = xmlEvent
- xmlEvent = null
- r
- }
- def setEvent(e: XMLEvent) {
- xmlEvent = e
- }
-
- def doNotify() = synchronized {
- XMLEventReader.this.continue = false
- notifyAll()
- while (!XMLEventReader.this.continue) wait();
- NodeSeq.Empty
- }
-
- // iterator methods
-
- def next: XMLEvent = {
- myresume
- val r = getAndClearEvent
- r
- }
-
- def hasNext = true
-
- var parserThread: Thread = null
-
- class Parser extends MarkupHandler with MarkupParser with ExternalSources with Runnable {
-
- val preserveWS = true
- val input = XMLEventReader.this.getSource
-
- override def elemStart(pos: Int, pre: String, label: String, attrs: MetaData, scope: NamespaceBinding) {
- setEvent(ElemStart(pre, label, attrs, scope)); doNotify
- }
-
- override def elemEnd(pos: Int, pre: String, label: String) {
- setEvent(ElemEnd(pre, label)); doNotify
- }
-
- final def elem(pos: Int, pre: String, label: String, attrs: MetaData, pscope: NamespaceBinding, nodes: NodeSeq): NodeSeq =
- NodeSeq.Empty
-
- def procInstr(pos: Int, target: String, txt: String): NodeSeq = {
- setEvent(ElemStart(null, "comm", null, null)); doNotify
- }
-
- def comment(pos: Int, txt: String): NodeSeq = {
- setEvent(ElemStart(null, "comm", null, null)); doNotify
- }
-
- def entityRef(pos: Int, n: String): NodeSeq = {
- setEvent(ElemStart(null, "eref", null, null)); doNotify
- }
-
- def text(pos: Int, txt:String): NodeSeq = {
- setEvent(ElemStart(null, "tex", null, null)); doNotify
- }
-
- override def run() {
- curInput = input
- this.nextch
- doNotify()
- this.document()
- }
- }
-}
diff --git a/src/library/jvm/scala/xml/include/sax/EncodingHeuristics.scala b/src/library/jvm/scala/xml/include/sax/EncodingHeuristics.scala
deleted file mode 100644
index adab470106..0000000000
--- a/src/library/jvm/scala/xml/include/sax/EncodingHeuristics.scala
+++ /dev/null
@@ -1,177 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.xml.include.sax
-
-import java.io.{IOException, InputStreamReader, InputStream}
-
-/**
- * EncodingHeuristics
reads from a stream
- * (which should be buffered) and attempts to guess
- * what the encoding of the text in the stream is.
- * Byte order marks are stripped from the stream.
- * If it fails to determine the type of the encoding,
- * it returns the default UTF-8.
- * InputStream
to read from.
- * @return String The name of the encoding.
- * @throws IOException if the stream cannot be reset back to where it was when
- * the method was invoked.
- */
- def readEncodingFromStream(in: InputStream): String = {
- //System.err.println("EncodingHeuristics::readEncodingFromStream");
- // This may fail if there are a lot of space characters before the end
- // of the encoding declaration
- in.mark(1024)
- var ret: String = null
- try {
- // lots of things can go wrong here. If any do, I just return null
- // so that we'll fall back on the encoding declaration or the
- // UTF-8 default
- val byte1 = in.read()
- val byte2 = in.read()
- if (byte1 == 0xFE && byte2 == 0xFF) {
- // don't reset because the byte order mark should not be included????
- ret = "UnicodeBig"; // name for big-endian????
- }
- else if (byte1 == 0xFF && byte2 == 0xFE) {
- // don't reset because the byte order mark should not be included????
- // will the reader throw away the byte order mark or will it return it????
- ret = "UnicodeLittle"
- }
-
- /* In accordance with the Character Model [Character Model],
- when the text format is a Unicode encoding, the XInclude
- processor must fail the inclusion when the text in the
- selected range is non-normalized. When transcoding characters
- to a Unicode encoding from a legacy encoding, a normalizing transcoder must be used. */
-
- val byte3 = in.read()
- // check for UTF-8 byte order mark
- if (byte1 == 0xEF && byte2 == 0xBB && byte3 == 0xBF) {
- // don't reset because the byte order mark should not be included????
- // in general what happens if text document includes non-XML legal chars????
- ret = "UTF-8";
- }
-
- val byte4 = in.read();
- if (byte1 == 0x00 && byte2 == 0x00 && byte3 == 0xFE && byte4 == 0xFF) {
- // don't reset because the byte order mark should not be included????
- ret = "UCS-4"; // right name for big-endian UCS-4 in Java 1.4????
- }
- else if (byte1 == 0x00 && byte2 == 0x00 && byte3 == 0xFF && byte4 == 0xFE) {
- // don't reset because the byte order mark should not be included????
- ret = "UCS-4"; // right name for little-endian UCS-4 in Java 1.4????
- }
-
- // no byte order mark present; first character must be
- // less than sign or white space
- // Let's look for less-than signs first
- if (byte1 == 0x00 && byte2 == 0x00 && byte3 == 0x00 && byte4 == '<') {
- in.reset()
- ret = "UCS-4" // right name for big-endian UCS-4 in Java 1.4????
- }
- else if (byte1 == '<' && byte2 == 0x00 && byte3 == 0x00 && byte4 == 0x00) {
- in.reset()
- ret = "UCS-4" // right name for little-endian UCS-4 in Java 1.4????
- }
- else if (byte1 == 0x00 && byte2 == '<' && byte3 == 0x00 && byte4 == '?') {
- in.reset()
- ret = "UnicodeBigUnmarked"
- }
- else if (byte1 == '<' && byte2 == 0x00 && byte3 == '?' && byte4 == 0x00) {
- in.reset()
- ret = "UnicodeLittleUnmarked"
- }
- else if (byte1 == '<' && byte2 == '?' && byte3 == 'x' && byte4 == 'm') {
- // ASCII compatible, must read encoding declaration
- // 1024 bytes will be far enough to read most XML declarations
- val data = new Array[Byte](1024)
- data(0) = byte1.asInstanceOf[Byte]
- data(1) = byte2.asInstanceOf[Byte]
- data(2) = byte3.asInstanceOf[Byte]
- data(3) = byte4.asInstanceOf[Byte]
- val length = in.read(data, 4, 1020) + 4;
- // Use Latin-1 (ISO-8859-1) because it's ASCII compatible and
- // all byte sequences are legal Latin-1 sequences so I don't have
- // to worry about encoding errors if I slip past the
- // end of the XML/text declaration
- val declaration = new String(data, 0, length, "8859_1");
- // if any of these throw a StringIndexOutOfBoundsException
- // we just fall into the catch bloclk and return null
- // since this can't be well-formed XML
- var position = declaration.indexOf("encoding") + 8;
- var c: Char = '\0' // bogus init value
- // get rid of white space before equals sign
- do {
- c = declaration.charAt(position)
- position += 1
- } while (c == ' ' || c == '\t' || c == '\r' || c == '\n') ;
- if (c != '=') { // malformed
- in.reset()
- ret = "UTF-8"
- }
- // get rid of white space after equals sign
- do {
- c = declaration.charAt(position)
- position += 1
- } while (c == ' ' || c == '\t' || c == '\r' || c == '\n') ;
- var delimiter: Char = c
- if (delimiter != '\'' && delimiter != '"') { // malformed
- in.reset()
- ret = "UTF-8"
- }
- // now positioned to read encoding name
- val encodingName = new StringBuffer()
- do {
- c = declaration.charAt(position)
- position += 1
- encodingName.append(c)
- } while(c != delimiter)
- encodingName.setLength(encodingName.length() - 1) // rm delim
- in.reset()
- ret = encodingName.toString()
- }
- else if (byte1 == 0x4C && byte2 == 0x6F && byte3 == 0xA7 && byte4 == 0x94) {
- // EBCDIC compatible, must read encoding declaration
- // ????
- }
-
- } catch {
- case e: Exception =>
- in.reset()
- ret = "UTF-8"
- }
-
- // no XML or text declaration present
- //System.err.println("exit EncodingHeuristics::readEncodingFromStream");
-
- if (ret != null)
- ret
- else {
- in.reset()
- "UTF-8"
- }
- }
-}
diff --git a/src/library/jvm/scala/xml/include/sax/XIncludeFilter.scala b/src/library/jvm/scala/xml/include/sax/XIncludeFilter.scala
deleted file mode 100644
index 19dc5ecead..0000000000
--- a/src/library/jvm/scala/xml/include/sax/XIncludeFilter.scala
+++ /dev/null
@@ -1,422 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-package scala.xml.include.sax
-
-import org.xml.sax.Attributes
-import org.xml.sax.SAXException
-import org.xml.sax.XMLReader
-import org.xml.sax.EntityResolver
-import org.xml.sax.Locator
-import org.xml.sax.helpers.XMLReaderFactory
-import org.xml.sax.helpers.XMLFilterImpl
-import org.xml.sax.helpers.NamespaceSupport
-import org.xml.sax.helpers.AttributesImpl
-
-import java.net.URL
-import java.net.URLConnection
-import java.net.MalformedURLException
-import java.io.UnsupportedEncodingException
-import java.io.IOException
-import java.io.InputStream
-import java.io.BufferedInputStream
-import java.io.InputStreamReader
-import java.util.Stack
-
-/**
- *
- *
- *
- *
- *
- *
- * XIncludeFilter
object with a known base URLXMLReader
object from which the raw document will
- * be read to the setParent()
method of this object. ContentHandler
object to the
- * setContentHandler()
method of this object. This is the
- * object which will receive events from the parsed and included
- * document.
- * LexicalHandler
object as the value of this object's
- * http://xml.org/sax/properties/lexical-handler property.
- * Also make sure your LexicalHandler
asks this object
- * for the status of each comment using insideIncludeElement
- * before doing anything with the comment.
- * parse()
method
- * XIncludeFilter includer = new XIncludeFilter(base);
- * includer.setParent(parser);
- * includer.setContentHandler(new SAXXIncluder(System.out));
- * includer.parse(args[i]);
- *
- * This utility method returns true if and only if this reader is - * currently inside a non-empty include element. (This is - * not the same as being inside the node set which replaces - * the include element.) This is primarily needed for comments - * inside include elements. It must be checked by the actual - * LexicalHandler to see whether a comment is passed or not. - *
- * - * @return boolean - */ - def insideIncludeElement(): Boolean = level != 0 - - override def startElement(uri: String, localName: String, qName: String, atts1: Attributes) { - var atts = atts1 - if (level == 0) { // We're not inside an xi:include element - - // Adjust bases stack by pushing either the new - // value of xml:base or the base of the parent - val base = atts.getValue(NamespaceSupport.XMLNS, "base") - val parentBase = bases.peek().asInstanceOf[URL] - var currentBase = parentBase - if (base != null) { - try { - currentBase = new URL(parentBase, base) - } - catch { - case e: MalformedURLException => - throw new SAXException("Malformed base URL: " - + currentBase, e) - } - } - bases.push(currentBase); - - if (uri.equals(XINCLUDE_NAMESPACE) && localName.equals("include")) { - // include external document - val href = atts.getValue("href") - // Verify that there is an href attribute - if (href==null) { - throw new SAXException("Missing href attribute") - } - - var parse = atts.getValue("parse") - if (parse == null) parse = "xml" - - if (parse.equals("text")) { - val encoding = atts.getValue("encoding"); - includeTextDocument(href, encoding); - } - else if (parse.equals("xml")) { - includeXMLDocument(href); - } - // Need to check this also in DOM and JDOM???? - else { - throw new SAXException( - "Illegal value for parse attribute: " + parse); - } - level += 1 - } - else { - if (atRoot) { - // add xml:base attribute if necessary - val attsImpl = new AttributesImpl(atts) - attsImpl.addAttribute(NamespaceSupport.XMLNS, "base", - "xml:base", "CDATA", currentBase.toExternalForm()) - atts = attsImpl - atRoot = false - } - super.startElement(uri, localName, qName, atts) - } - } - } - - override def endElement(uri: String, localName: String, qName: String) { - if (uri.equals(XINCLUDE_NAMESPACE) - && localName.equals("include")) { - level -= 1; - } - else if (level == 0) { - bases.pop() - super.endElement(uri, localName, qName) - } - } - - private var depth = 0; - - override def startDocument() { - level = 0 - if (depth == 0) super.startDocument() - depth += 1 - } - - override def endDocument() { - locators.pop() - bases.pop(); // pop the URL for the document itself - depth -= 1 - if (depth == 0) super.endDocument() - } - - // how do prefix mappings move across documents???? - override def startPrefixMapping(prefix: String , uri: String) { - if (level == 0) super.startPrefixMapping(prefix, uri) - } - - override def endPrefixMapping(prefix: String) { - if (level == 0) super.endPrefixMapping(prefix) - } - - override def characters(ch: Array[Char], start: Int, length: Int) { - if (level == 0) super.characters(ch, start, length) - } - - override def ignorableWhitespace(ch: Array[Char], start: Int, length: Int) { - if (level == 0) super.ignorableWhitespace(ch, start, length) - } - - override def processingInstruction(target: String, data: String) { - if (level == 0) super.processingInstruction(target, data) - } - - override def skippedEntity(name: String) { - if (level == 0) super.skippedEntity(name) - } - - // convenience method for error messages - private def getLocation(): String = { - var locationString = "" - val locator = locators.peek().asInstanceOf[Locator] - var publicID = "" - var systemID = "" - var column = -1 - var line = -1 - if (locator != null) { - publicID = locator.getPublicId() - systemID = locator.getSystemId() - line = locator.getLineNumber() - column = locator.getColumnNumber() - } - locationString = (" in document included from " + publicID - + " at " + systemID - + " at line " + line + ", column " + column); - - locationString - } - - /** - *
- * This utility method reads a document at a specified URL
- * and fires off calls to characters()
.
- * It's used to include files with parse="text"
- *
- * This utility method reads a document at a specified URL
- * and fires off calls to various ContentHandler
methods.
- * It's used to include files with parse="xml"
- *
ContentHandler
- * that writes its XML document onto an output stream after resolving
- * all xinclude:include
elements.
- *
- * - * based on Eliotte Rusty Harold's SAXXIncluder - *
- */ -class XIncluder(outs:OutputStream, encoding:String) extends Object -with ContentHandler with LexicalHandler { - - var out = new OutputStreamWriter(outs, encoding) - - def setDocumentLocator(locator: Locator) {} - - def startDocument() { - try { - out.write("\r\n"); - } - catch { - case e:IOException => - throw new SAXException("Write failed", e) - } - } - - def endDocument() { - try { - out.flush() - } - catch { - case e:IOException => - throw new SAXException("Flush failed", e) - } - } - - def startPrefixMapping(prefix: String , uri: String) {} - - def endPrefixMapping(prefix: String) {} - - def startElement(namespaceURI: String, localName: String, qualifiedName: String, atts: Attributes) = { - try { - out.write("<" + qualifiedName); - var i = 0; while (i < atts.getLength()) { - out.write(" "); - out.write(atts.getQName(i)); - out.write("='"); - val value = atts.getValue(i); - // @todo Need to use character references if the encoding - // can't support the character - out.write(xml.Utility.escape(value)) - out.write("'"); - i += 1 - } - out.write(">") - } - catch { - case e:IOException => - throw new SAXException("Write failed", e) - } - } - - def endElement(namespaceURI: String, localName:String, qualifiedName: String) { - try { - out.write("" + qualifiedName + ">") - } - catch { - case e: IOException => - throw new SAXException("Write failed", e) - } - } - - // need to escape characters that are not in the given - // encoding using character references???? - def characters(ch: Array[Char], start: Int, length: Int) { - try { - var i = 0; while (i < length) { - val c = ch(start+i); - if (c == '&') out.write("&"); - else if (c == '<') out.write("<"); - // This next fix is normally not necessary. - // However, it is required if text contains ]]> - // (The end CDATA section delimiter) - else if (c == '>') out.write(">"); - else out.write(c); - i = i+1; - } - } - catch { - case e: IOException => - throw new SAXException("Write failed", e); - } - } - - def ignorableWhitespace(ch: Array[Char], start: Int , length: Int) { - this.characters(ch, start, length) - } - - // do I need to escape text in PI???? - def processingInstruction(target: String, data: String) { - try { - out.write("" + target + " " + data + "?>") - } - catch { - case e:IOException => - throw new SAXException("Write failed", e) - } - } - - def skippedEntity(name: String) { - try { - out.write("&" + name + ";") - } - catch { - case e:IOException => - throw new SAXException("Write failed", e) - } - } - - // LexicalHandler methods - private var inDTD: Boolean = false - private val entities = new Stack[String]() - - def startDTD(name: String, publicID: String, systemID: String) { - inDTD = true - // if this is the source document, output a DOCTYPE declaration - if (entities.size() == 0) { - var id = "" - if (publicID != null) id = " PUBLIC \"" + publicID + "\" \"" + systemID + '"'; - else if (systemID != null) id = " SYSTEM \"" + systemID + '"'; - try { - out.write("\r\n") - } - catch { - case e:IOException => - throw new SAXException("Error while writing DOCTYPE", e) - } - } - } - def endDTD() {} - - def startEntity(name: String) { - entities.push(name) - } - - def endEntity(name: String) { - entities.pop() - } - - def startCDATA() {} - def endCDATA() {} - - // Just need this reference so we can ask if a comment is - // inside an include element or not - private var filter: XIncludeFilter = null - - def setFilter(filter: XIncludeFilter) { - this.filter = filter - } - - def comment(ch: Array[Char], start: Int, length: Int) { - if (!inDTD && !filter.insideIncludeElement()) { - try { - out.write("") - } - catch { - case e: IOException => - throw new SAXException("Write failed", e) - } - } - } -} diff --git a/src/library/scala/collection/jcl/ArrayList.scala b/src/library/scala/collection/jcl/ArrayList.scala new file mode 100644 index 0000000000..bd54d46a69 --- /dev/null +++ b/src/library/scala/collection/jcl/ArrayList.scala @@ -0,0 +1,21 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id$ + +package scala.collection.jcl; + +/** Creates a buffer backed by a Java array list. + * + * @author Sean McDirmid + */ +class ArrayList[A](override val underlying : java.util.ArrayList[A]) extends BufferWrapper[A] { + def this() = this(new java.util.ArrayList[A]); + override def clone: ArrayList[A] = + new ArrayList[A](underlying.clone().asInstanceOf[java.util.ArrayList[A]]) +} diff --git a/src/library/scala/collection/jcl/Buffer.scala b/src/library/scala/collection/jcl/Buffer.scala new file mode 100644 index 0000000000..dfc36765d3 --- /dev/null +++ b/src/library/scala/collection/jcl/Buffer.scala @@ -0,0 +1,229 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id$ + +package scala.collection.jcl; + +/** A mutable sequence that supports element insertion and update. + * + * @author Sean McDirmid + */ +trait Buffer[A] extends RandomAccessSeq.Mutable[A] with Ranged[Int,A] with MutableSeq[A] with Collection[A] { + final protected type SortedSelf = Buffer[A]; + + override def projection : Buffer.Projection[A] = new Buffer.Projection[A] { + override def elements = Buffer.this.elements + override def length = Buffer.this.length + override def apply(idx : Int) = Buffer.this.apply(idx) + override def transform(f : A => A) = Buffer.this.transform(f) + } + + protected class DefaultBufferIterator extends DefaultSeqIterator with BufferIterator[Int,A] { + override def set(a : A) = { + if (index == 0) throw new NoSuchElementException + Buffer.this.set(index - 1, a) + } + override def add(a : A) = { + Buffer.this.add(index, a) + } + } + override def elements : BufferIterator[Int,A] = new DefaultBufferIterator + + /** The first index of a buffer is 0. */ + override def firstKey = 0; + + /** The last index of a buffer is its size - 1. */ + override def lastKey = size - 1; + + /** Indices are compared through subtraction. */ + final def compare(k0 : Int, k1 : Int) = k0 - k1; + + /** Removes the element at indexidx
*/
+ def remove(idx : Int) = {
+ val i = elements;
+ val ret = i.seek(idx); i.remove; ret;
+ }
+ /** Removes N elements from index idx
*/
+ def remove(idx : Int, length : Int) = {
+ val i = elements
+ i.seek(idx)
+ for (j <- 0.until(length)) i.remove
+ }
+ /** replaces */
+ def replace(from : Int, length : Int, added : Seq[A]) = {
+ val min = if (length < added.length) length else added.length
+ val i = added.elements
+ var j = 0
+ while (j < length && i.hasNext) {
+ set(from + j, i.next); j = j + 1
+ }
+ assert(j == min)
+ if (i.hasNext) {
+ val slice = added.drop(length)
+ assert(!slice.isEmpty)
+ addAll(from + min, slice)
+ } else if (j < length) {
+ assert(length > min)
+ remove(from + min, length - min)
+ }
+ }
+
+ /** Replaces the element at index "idx" with "a."
+ * @returns the element replaced.
+ */
+ def set(idx : Int, a : A) : A = {
+ val i = elements;
+ val ret = i.seek(idx); i.set(a); ret;
+ }
+
+ /** Equivalent to set except the replaced element is not returned. */
+ def update(idx : Int, a : A) : Unit = set(idx, a);
+
+ /** @returns always true. */
+ def add(a : A) : Boolean = {
+ val i = elements;
+ while (i.hasNext) i.next;
+ i.add(a);
+ true;
+ }
+
+ /** Inserts "a" into this buffer just before the element at index "idx." */
+ def add(idx: Int, a: A): Unit = {
+ val i = elements; i.seek(idx);
+ i.add(a);
+ }
+
+ /** Inserts all elements of that
into this buffer just before
+ * the element at index idx
.
+ *
+ * @param idx ..
+ * @param that ..
+ */
+ def addAll(idx: Int, that: Iterable[A]): Unit = {
+ val i = elements; i.seek(idx);
+ for (that <- that) {
+ i.add(that); i.next;
+ }
+ }
+
+ override def transform(f: A => A): Boolean = {
+ var changed = false;
+ val i = elements;
+ while (i.hasNext) {
+ val a0 = i.next;
+ val a1 = f(a0);
+ if (a0 != a1) {
+ i.set(a1); changed = true;
+ }
+ }
+ changed;
+ }
+ override def +(a : A) : this.type = super[Collection].+(a);
+ override def -=(a : A) = super[Collection].-=(a);
+ override def isEmpty = super[MutableSeq].isEmpty;
+ override def rangeImpl(from : Option[Int], until : Option[Int]) : Buffer[A] = new Range(from, until);
+
+
+ protected class Range(var from : Option[Int], var until : Option[Int]) extends Buffer[A] {
+ if (from == None && until == None) throw new IllegalArgumentException;
+ if (from != None && until != None && !(from.get < until.get)) throw new IllegalArgumentException;
+ override def add(a : A) =
+ if (until == None) Buffer.this.add(a);
+ else {
+ Buffer.this.add(until.get, a);
+ true;
+ }
+ private def translate(idx : Int) = {
+ if (until != None && idx > until.get) throw new IllegalArgumentException;
+ else if (from != None) from.get + idx;
+ else idx;
+ }
+ override def apply(idx : Int) : A = Buffer.this.apply(translate(idx));
+ override def set(idx : Int, a : A) = Buffer.this.set(translate(idx), a);
+ override def add(idx : Int, a : A) = Buffer.this.add(translate(idx), a);
+ override def remove(idx : Int) = Buffer.this.remove(translate(idx));
+ override def length = {
+ if (until != None) {
+ if (from != None) until.get - from.get;
+ else until.get;
+ } else super.length;
+ }
+ override def elements : BufferIterator[Int,A] = new RangeIterator;
+ class RangeIterator extends BufferIterator[Int,A] {
+ val underlying = Buffer.this.elements;
+ if (from != None) underlying.seek(from.get);
+ def hasNext = underlying.hasNext &&
+ (until == None || underlying.nextIndex < until.get);
+ def hasPrevious = underlying.hasPrevious &&
+ (from == None || underlying.previousIndex >= from.get);
+ def next = {
+ if (until != None && underlying.nextIndex >= until.get) throw new NoSuchElementException;
+ underlying.next;
+ }
+ def previous = {
+ if (from != None && underlying.previousIndex < from.get) throw new NoSuchElementException;
+ underlying.previous;
+ }
+ def add(a : A) = {
+ if (until != None && underlying.nextIndex > until.get) throw new NoSuchElementException;
+ if (from != None && underlying.previousIndex < from.get) throw new NoSuchElementException;
+ underlying.add(a);
+ if (until != None) until = Some(until.get + 1);
+ }
+ def set(a : A) = {
+ if (until != None && underlying.nextIndex > until.get) throw new NoSuchElementException;
+ if (from != None && underlying.previousIndex < from.get) throw new NoSuchElementException;
+ underlying.set(a);
+ }
+ def remove = {
+ if (until != None && underlying.nextIndex > until.get) throw new NoSuchElementException;
+ if (from != None && underlying.previousIndex < from.get) throw new NoSuchElementException;
+ underlying.remove;
+ }
+ def nextIndex = {
+ val ret = underlying.nextIndex;
+ if (until != None && ret >= until.get) throw new NoSuchElementException;
+ if (from != None) ret - from.get;
+ else ret;
+ }
+ def previousIndex = {
+ val ret = underlying.previousIndex;
+ if (from != None && ret < from.get) throw new NoSuchElementException;
+ if (from != None) ret - from.get;
+ else ret;
+ }
+ }
+ }
+ /*
+ protected class Map[B](f : A => B) extends super.Map[B](f) with Buffer.Projection[B] {
+ override def elements = Buffer.this.elements.map[B](f);
+ //override def apply(idx : Int) = f(MutableSeq.this.apply(idx));
+ //override def size = length;
+ }
+ */
+}
+object Buffer {
+ def apply[T](list : java.util.List[T]) = new BufferWrapper[T] {
+ val underlying = list
+ }
+
+ trait Projection0[A] extends MutableSeq.Projection[A] with RandomAccessSeq.Projection[A] {
+ override def projection : Projection0[A] = this
+ override def elements : SeqIterator[Int,A] = new DefaultSeqIterator
+
+ protected class MapProjection[B](f : A => B) extends super.MapProjection[B](f) with Projection0[B] {
+ override def projection = this
+ }
+ override def map[B](f: A => B) : Projection0[B] = new MapProjection[B](f)
+ }
+ class Projection[A] extends Collection.Projection[A] with RandomAccessSeq.MutableProjection[A] with Projection0[A] with Buffer[A] {
+ override def elements : BufferIterator[Int,A] = new DefaultBufferIterator
+ override def projection : Buffer.Projection[A] = this
+ }
+}
diff --git a/src/library/scala/collection/jcl/BufferIterator.scala b/src/library/scala/collection/jcl/BufferIterator.scala
new file mode 100644
index 0000000000..bb7b79d099
--- /dev/null
+++ b/src/library/scala/collection/jcl/BufferIterator.scala
@@ -0,0 +1,31 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.collection.jcl;
+
+/** An iterator for a buffer that supports element update and insertion.
+ *
+ * @author Sean McDirmid
+ */
+trait BufferIterator[K,A] extends SeqIterator[K,A] {
+
+ /** Sets the element before this iterator's cursor to "a."
+ * Replaces either the last element returned by "next" or,
+ * if previous was called,
+ * the next element that would be return by "previous."
+ */
+ def set(a: A): Unit;
+
+ /** Inserts "a" after the iterator's cursor.
+ * If next was last called, "a" is inserted after the element returned.
+ * If previous was last called, "a" is inserted before the element returned.
+ */
+ def add(a: A): Unit;
+}
diff --git a/src/library/scala/collection/jcl/BufferWrapper.scala b/src/library/scala/collection/jcl/BufferWrapper.scala
new file mode 100644
index 0000000000..0472c15dea
--- /dev/null
+++ b/src/library/scala/collection/jcl/BufferWrapper.scala
@@ -0,0 +1,52 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.collection.jcl;
+
+/** Wraps Java lists.
+ *
+ * @author Sean McDirmid
+ */
+trait BufferWrapper[A] extends Buffer[A] with CollectionWrapper[A] {
+ def underlying : java.util.List[A];
+ override def elements : BufferIterator[Int,A] = new IteratorWrapper(underlying.listIterator);
+ override def remove(idx : Int) = underlying.remove(idx).asInstanceOf[A];
+ override def add(a : A) = underlying.add(a);
+ override def add(idx : Int, a : A) = underlying.add(idx,a);
+ override def addAll(idx : Int, that : Iterable[A]) = that match {
+ case that : CollectionWrapper[_] => underlying.addAll(idx, that.underlying); {}
+ case _ => super.addAll(idx, that);
+ }
+ override def indexOf(a : A) = {
+ val result = underlying.indexOf(a);
+ if (result == -1) None;
+ else Some(result);
+ }
+ override def apply(idx : Int) = underlying.get(idx).asInstanceOf[A];
+ override def set(idx : Int, a : A) = underlying.set(idx, a).asInstanceOf[A];
+ override def rangeImpl(from : Option[Int], until : Option[Int]) : Buffer[A] = new Range(from, until);
+ protected class Range(from : Option[Int], until : Option[Int]) extends super.Range(from,until) with BufferWrapper[A] {
+ val underlying = {
+ val fromi = if (from == None) 0 else from.get;
+ val toi = if (until == None) BufferWrapper.this.size else until.get;
+ BufferWrapper.this.underlying.subList(fromi, toi);
+ }
+ override def elements = super[BufferWrapper].elements;
+ }
+ class IteratorWrapper(underlying : java.util.ListIterator[A]) extends MutableIterator.Wrapper[A](underlying) with BufferIterator[Int,A] {
+ def add(a : A) = underlying.add(a);
+ def set(a : A) = underlying.set(a);
+ def hasPrevious = underlying.hasPrevious;
+ def previous = underlying.previous.asInstanceOf[A];
+ def previousIndex = underlying.previousIndex;
+ def nextIndex = underlying.nextIndex;
+ }
+ override def length = underlying.size;
+}
diff --git a/src/library/scala/collection/jcl/Collection.scala b/src/library/scala/collection/jcl/Collection.scala
new file mode 100644
index 0000000000..0df2f74f4b
--- /dev/null
+++ b/src/library/scala/collection/jcl/Collection.scala
@@ -0,0 +1,67 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.collection.jcl;
+
+object Collection {
+ val DEFAULT_FILTER : Any => Boolean = x => true;
+ trait Projection[A] extends Collection[A] with MutableIterable.Projection[A] {
+ override def projection = this
+ }
+}
+
+/** Analogous to a Java collection.
+ *
+ * @author Sean McDirmid
+ */
+trait Collection[A] extends MutableIterable[A] {
+ /** Type-safe version of containsAll.
+ **
+ ** @author Sean McDirmid
+ **/
+ def hasAll(i: Iterable[A]): Boolean = i.forall(elements.has);
+
+ /** Adds "a" to the collection, return true if "a" is actually added. */
+ def add(a: A): Boolean;
+
+ /** Adds all elements in "i" to the collection, return true if any elements are added. */
+ def addAll(i: Iterable[A]): Boolean = {
+ var changed = false;
+ i.foreach(t => changed = add(t) || changed);
+ changed;
+ }
+ /** Operator shortcut for addAll. */
+ def ++(that: Iterable[A]): this.type = {
+ addAll(that); this;
+ }
+
+ /** removes "a" from the collection. */
+ def -=(a : A) : Unit = remove(a);
+
+ /** adds "a" from the collection. */
+ def +=(t : A) : Unit = add(t);
+
+ /** adds "a" from the collection. Useful for chaining. */
+ def +(t : A) : this.type = { add(t); this; }
+
+ /** Transforms each element of the collection in-place according to
+ * f
.
+ *
+ * @param f
+ * @return true
if the collection is actually updated.
+ */
+ def transform(f: A => A): Boolean
+ override def projection : Collection.Projection[A] = new Collection.Projection[A] {
+ override def elements = Collection.this.elements
+ override def size = Collection.this.size
+ override def add(a: A): Boolean = Collection.this.add(a)
+ override def transform(f : A => A) = Collection.this.transform(f);
+ }
+}
diff --git a/src/library/scala/collection/jcl/CollectionWrapper.scala b/src/library/scala/collection/jcl/CollectionWrapper.scala
new file mode 100644
index 0000000000..ec6a22f325
--- /dev/null
+++ b/src/library/scala/collection/jcl/CollectionWrapper.scala
@@ -0,0 +1,43 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.collection.jcl;
+
+/** Used to wrap Java collections in Scala.
+ *
+ * @author Sean McDirmid
+ */
+trait CollectionWrapper[A] extends Collection[A] with IterableWrapper[A] {
+ /** Override to specify the collection being accessed through this wrapper.
+ ** Collection operations are then routed through the wrapped Java collection.
+ **/
+ def underlying : java.util.Collection[A];
+ override def has(a : A) = underlying.contains(a);
+ override def elements : MutableIterator[A] = super.elements;
+ override def size = underlying.size;
+
+ override def hasAll(that : Iterable[A]) = that match {
+ case that : CollectionWrapper[_] =>
+ val u = underlying;
+ u.containsAll(that.underlying);
+ case _ => super.hasAll(that);
+ }
+ override def add(a : A) = underlying.add(a);
+ override def addAll(that : Iterable[A]) = that match {
+ case that : CollectionWrapper[_] => underlying.addAll(that.underlying);
+ case _ => super.addAll(that);
+ }
+ override def toString = underlying.toString;
+ override def hashCode = underlying.hashCode;
+ override def equals(that : Any) = that match {
+ case that: CollectionWrapper[_] => underlying == that.underlying;
+ case _ => super.equals(that);
+ }
+}
diff --git a/src/library/scala/collection/jcl/Conversions.scala b/src/library/scala/collection/jcl/Conversions.scala
new file mode 100644
index 0000000000..edb96322b6
--- /dev/null
+++ b/src/library/scala/collection/jcl/Conversions.scala
@@ -0,0 +1,17 @@
+package scala.collection.jcl
+
+object Conversions {
+ implicit def convertSet[T](set : java.util.Set[T]) = Set(set)
+ implicit def convertList[T](set : java.util.List[T]) = Buffer(set)
+ implicit def convertSortedSet[T](set : java.util.SortedSet[T]) = SortedSet(set)
+ implicit def convertMap[T,E](set : java.util.Map[T,E]) = Map(set)
+ implicit def convertSortedMap[T,E](set : java.util.SortedMap[T,E]) = SortedMap(set)
+
+ implicit def unconvertSet[T](set : SetWrapper[T]) = set.underlying
+ implicit def unconvertCollection[T](set : CollectionWrapper[T]) = set.underlying
+ implicit def unconvertList[T](set : BufferWrapper[T]) = set.underlying
+ implicit def unconvertSortedSet[T](set : SortedSetWrapper[T]) = set.underlying
+ implicit def unconvertMap[T,E](set : MapWrapper[T,E]) = set.underlying
+ implicit def unconvertSortedMap[T,E](set : SortedMapWrapper[T,E]) = set.underlying
+
+}
\ No newline at end of file
diff --git a/src/library/scala/collection/jcl/HashMap.scala b/src/library/scala/collection/jcl/HashMap.scala
new file mode 100644
index 0000000000..e9c156f655
--- /dev/null
+++ b/src/library/scala/collection/jcl/HashMap.scala
@@ -0,0 +1,21 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2008, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.collection.jcl
+
+/** A map that is backed by a Java hash map.
+ *
+ * @author Sean McDirmid
+ */
+class HashMap[K, E](override val underlying: java.util.HashMap[K, E]) extends MapWrapper[K, E] {
+ def this() = this(new java.util.HashMap[K, E])
+ override def clone: HashMap[K, E] =
+ new HashMap[K, E](underlying.clone().asInstanceOf[java.util.HashMap[K, E]])
+}
diff --git a/src/library/scala/collection/jcl/HashSet.scala b/src/library/scala/collection/jcl/HashSet.scala
new file mode 100644
index 0000000000..7d57278273
--- /dev/null
+++ b/src/library/scala/collection/jcl/HashSet.scala
@@ -0,0 +1,21 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2008, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.collection.jcl
+
+/** A hash set that is backed by a Java hash set.
+ *
+ * @author Sean McDirmid
+ */
+class HashSet[A](override val underlying: java.util.HashSet[A]) extends SetWrapper[A] {
+ def this() = this(new java.util.HashSet[A])
+ override def clone: HashSet[A] =
+ new HashSet[A](underlying.clone().asInstanceOf[java.util.HashSet[A]])
+}
diff --git a/src/library/scala/collection/jcl/Hashtable.scala b/src/library/scala/collection/jcl/Hashtable.scala
new file mode 100644
index 0000000000..c46c762163
--- /dev/null
+++ b/src/library/scala/collection/jcl/Hashtable.scala
@@ -0,0 +1,22 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2008, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.collection.jcl
+
+/** A hash set that is backed by a Java hash table.
+ *
+ * @author Sean McDirmid
+ */
+class Hashtable[K,E](override val underlying: java.util.Hashtable[K,E]) extends MapWrapper[K,E] {
+ def this() = this(new java.util.Hashtable[K,E])
+
+ override def clone() : Hashtable[K,E] =
+ new Hashtable[K,E](underlying.clone().asInstanceOf[java.util.Hashtable[K,E]])
+}
diff --git a/src/library/scala/collection/jcl/IdentityHashMap.scala b/src/library/scala/collection/jcl/IdentityHashMap.scala
new file mode 100644
index 0000000000..c3113388e9
--- /dev/null
+++ b/src/library/scala/collection/jcl/IdentityHashMap.scala
@@ -0,0 +1,24 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2008, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.collection.jcl
+
+/** A map that is backed by a Java identity hash map, which compares keys
+ * by their reference-based identity as opposed to using equals and hashCode.
+ * An identity hash map will often perform better than traditional hash map
+ * because it can utilize linear probing.
+ *
+ * @author Sean McDirmid
+ */
+class IdentityHashMap[K, E](override val underlying : java.util.IdentityHashMap[K, E]) extends MapWrapper[K, E] {
+ def this() = this(new java.util.IdentityHashMap[K, E])
+ override def clone: IdentityHashMap[K, E] =
+ new IdentityHashMap[K, E](underlying.clone().asInstanceOf[java.util.IdentityHashMap[K, E]])
+}
diff --git a/src/library/scala/collection/jcl/IterableWrapper.scala b/src/library/scala/collection/jcl/IterableWrapper.scala
new file mode 100644
index 0000000000..caa31d10cf
--- /dev/null
+++ b/src/library/scala/collection/jcl/IterableWrapper.scala
@@ -0,0 +1,32 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.collection.jcl;
+
+/** A wrapper around a Java collection that only supports remove mutations.
+ *
+ * @author Sean McDirmid
+ */
+trait IterableWrapper[A] extends MutableIterable[A] {
+ def underlying: java.util.Collection[A];
+ override def remove(a: A) = underlying.remove(a);
+ override def removeAll(that: Iterable[A]) = that match {
+ case that: IterableWrapper[_] => underlying.removeAll(that.underlying);
+ case _ => super.removeAll(that);
+ }
+ override def retainAll(that : Iterable[A]) = that match {
+ case that : IterableWrapper[_] => underlying.retainAll(that.underlying);
+ case _ => super.retainAll(that);
+ }
+ override def size = underlying.size;
+ override def isEmpty = underlying.isEmpty;
+ override def clear = underlying.clear;
+ override def elements : MutableIterator[A] = new MutableIterator.Wrapper[A](underlying.iterator);
+}
diff --git a/src/library/scala/collection/jcl/LinkedHashMap.scala b/src/library/scala/collection/jcl/LinkedHashMap.scala
new file mode 100644
index 0000000000..424043ba9a
--- /dev/null
+++ b/src/library/scala/collection/jcl/LinkedHashMap.scala
@@ -0,0 +1,22 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2008, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.collection.jcl
+
+/** A map that is backed by a Java linked hash map, which fixes iteration
+ * order in terms of insertion order.
+ *
+ * @author Sean McDirmid
+ */
+class LinkedHashMap[K, E](override val underlying: java.util.LinkedHashMap[K, E]) extends MapWrapper[K, E] {
+ def this() = this(new java.util.LinkedHashMap[K, E])
+ override def clone: LinkedHashMap[K, E] =
+ new LinkedHashMap[K, E](underlying.clone().asInstanceOf[java.util.LinkedHashMap[K, E]])
+}
diff --git a/src/library/scala/collection/jcl/LinkedHashSet.scala b/src/library/scala/collection/jcl/LinkedHashSet.scala
new file mode 100644
index 0000000000..2d0d1dddff
--- /dev/null
+++ b/src/library/scala/collection/jcl/LinkedHashSet.scala
@@ -0,0 +1,22 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2008, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.collection.jcl
+
+/** A set that is backed by a Java linked hash set, which fixes iteration
+ * order in terms of insertion order.
+ *
+ * @author Sean McDirmid
+ */
+class LinkedHashSet[A](override val underlying: java.util.LinkedHashSet[A]) extends SetWrapper[A] {
+ def this() = this(new java.util.LinkedHashSet[A])
+ override def clone: LinkedHashSet[A] =
+ new LinkedHashSet[A](underlying.clone().asInstanceOf[java.util.LinkedHashSet[A]])
+}
diff --git a/src/library/scala/collection/jcl/LinkedList.scala b/src/library/scala/collection/jcl/LinkedList.scala
new file mode 100644
index 0000000000..a7fc726af6
--- /dev/null
+++ b/src/library/scala/collection/jcl/LinkedList.scala
@@ -0,0 +1,32 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.collection.jcl;
+
+/** Creates a buffer backed by a Java linked list. Includes additional
+ * peek/poll/removeFirst/removeLast APIs that are useful in implementing
+ * queues and stacks.
+ *
+ * @author Sean McDirmid
+ */
+class LinkedList[A](override val underlying : java.util.LinkedList[A]) extends BufferWrapper[A] {
+ def this() = this(new java.util.LinkedList[A]);
+ override def elements = super[BufferWrapper].elements;
+ override def add(idx : Int, a : A) =
+ if (idx == 0) underlying.addFirst(a);
+ else super.add(idx, a);
+ //def peek = underlying.peek.asInstanceOf[A];
+ //def poll = underlying.poll.asInstanceOf[A];
+ //def removeFirst = underlying.removeFirst.asInstanceOf[A];
+ //def removeLast = underlying.removeLast.asInstanceOf[A];
+
+ override def clone: LinkedList[A] =
+ new LinkedList[A](underlying.clone().asInstanceOf[java.util.LinkedList[A]])
+}
diff --git a/src/library/scala/collection/jcl/Map.scala b/src/library/scala/collection/jcl/Map.scala
new file mode 100644
index 0000000000..4dc0625b71
--- /dev/null
+++ b/src/library/scala/collection/jcl/Map.scala
@@ -0,0 +1,129 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.collection.jcl;
+
+/** A mutable map that is compatible with Java maps.
+ *
+ * @author Sean McDirmid
+ */
+trait Map[K,E] extends MutableIterable[Tuple2[K,E]] with scala.collection.mutable.Map[K,E] {
+ override def clear() = super[MutableIterable].clear;
+ override def isEmpty = super[MutableIterable].isEmpty;
+ override def keySet : Set[K] = new KeySet;
+ override final def keys = keySet.elements;
+ /** The values of this map as a projection, which means
+ removals from the returned collection will remove the element from this map.
+ @returns a projection of this map's elements. */
+ def valueSet : MutableIterable.Projection[E] = projection.map(_._2);
+
+ override def put(key : K, elem : E) : Option[E] = throw new java.lang.AbstractMethodError
+
+ override def ++=(that : Iterable[(K,E)]) : Unit =
+ that.foreach(p => put(p._1, p._2));
+
+ override def removeKey(key : K) : Option[E] = {
+ val i = elements;
+ while (!i.hasNext) {
+ val result = i.next;
+ if (result._1 == key) {
+ i.remove;
+ return Some(result._2);
+ }
+ }
+ return None;
+ }
+ override def has(pair : Tuple2[K,E]) = get(pair._1) match {
+ case Some(e) if e == pair._2 => true;
+ case _ => false;
+ }
+ override def get(key : K) = elements.find(p => p._1 == key).map(_._2);
+ override def update(key : K, e : E) : Unit = put(key,e);
+ override def +(pair : Tuple2[K,E]) : this.type = {
+ put(pair._1,pair._2); this;
+ }
+ override def +=(pair : Tuple2[K,E]) : Unit = put(pair._1, pair._2);
+ override def -(key : K) : this.type = {
+ removeKey(key); this;
+ }
+ override def remove(p : (K,E)) = get(p._1) match {
+ case Some(p._2) => this -= p._1; true
+ case _ => false;
+ }
+
+ override def -=(key : K) : Unit = removeKey(key);
+ override def elements : MutableIterator[Tuple2[K,E]];
+
+ override def projection : Map.Projection[K,E] = new Map.Projection[K,E] {
+ override def elements = Map.this.elements
+ override def size = Map.this.size
+ override def get(k : K) = Map.this.get(k)
+ override def put(k : K, e : E) = Map.this.put(k, e)
+ }
+ /**
+ */
+ def lense[F](f : E => F, g : F => E) : jcl.Map.Projection[K,F] = new Lense[F](f,g);
+
+ protected class Lense[F](f : E => F, g : F => E) extends jcl.Map.Projection[K,F] {
+ override def elements = Map.this.elements.map(k => Tuple2(k._1, f(k._2)));
+ override def removeKey(key : K) = Map.this.removeKey(key).map(f);
+ override def put(key : K, elem : F) = Map.this.put(key, g(elem)).map(f);
+ override def get(key : K) = Map.this.get(key).map(f);
+ override def lense[G](f0 : F => G, g0 : G => F) : jcl.Map.Projection[K,G] =
+ Map.this.lense[G](x => f0(f(x)), y => g(g0(y)));
+ override def size = size0;
+ }
+ protected class KeySet extends Set[K] {
+ override def size = Map.this.size;
+ override def add(k : K) = Map.this.put(k, default(k)) == None;
+ override def elements = Map.this.elements.map(_._1);
+ override def has(k : K) = Map.this.contains(k);
+ }
+ override def filterKeys(p : K => Boolean) : Map.Projection[K,E] = new Filter(p);
+
+ protected class Filter(p : K => Boolean) extends Map.Projection[K,E] {
+ override def elements = {
+ val i = Map.this.elements.filter(e => p(e._1));
+ new MutableIterator[(K,E)] {
+ def next = i.next
+ def hasNext = i.hasNext
+ def remove : Unit = throw new NoSuchMethodException
+ }
+ }
+ override def removeKey(key : K) = {
+ if (!p(key)) throw new IllegalArgumentException;
+ Map.this.removeKey(key);
+ }
+ override def contains(key : K) = p(key) && Map.this.contains(key);
+ override def put(key : K, elem : E) = {
+ if (!p(key)) throw new IllegalArgumentException;
+ Map.this.put(key, elem);
+ }
+ override def get(key : K) = {
+ if (!p(key)) None;
+ else Map.this.get(key);
+ }
+ override def filterKeys(p0 : K => Boolean) : Map.Projection[K,E] =
+ Map.this.filterKeys(e => p(e) && p0(e));
+
+ override def size = size0;
+ }
+}
+
+object Map {
+ trait MutableIterableProjection[A] extends MutableIterable.Projection[A];
+ trait Projection[K,E] extends MutableIterableProjection[(K,E)] with scala.collection.Map.Projection[K,E] with Map[K,E] {
+ override def projection = this
+ override def map[B](f : ((K,E)) => B) : MutableIterable.Projection[B] = super[MutableIterableProjection].map(f);
+ }
+ def apply[T,E](map0 : java.util.Map[T,E]) = new MapWrapper[T,E] {
+ val underlying = map0
+ }
+}
diff --git a/src/library/scala/collection/jcl/MapWrapper.scala b/src/library/scala/collection/jcl/MapWrapper.scala
new file mode 100644
index 0000000000..7fed4d2e8f
--- /dev/null
+++ b/src/library/scala/collection/jcl/MapWrapper.scala
@@ -0,0 +1,76 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2008, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.collection.jcl
+
+/** A wrapper around a Java map.
+ *
+ * @author Sean McDirmid
+ */
+trait MapWrapper[K, E] extends jcl.Map[K, E] {
+ def underlying: java.util.Map[K, E]
+ override def size = underlying.size
+ override def isEmpty = underlying.isEmpty
+ override def clear() = underlying.clear
+
+ override def put(key: K, elem: E) = {
+ //if (elem == null) throw new IllegalArgumentException;
+ val ret = underlying.put(key, elem)
+ if (ret == null) None else Some(ret.asInstanceOf[E])
+ }
+
+ override def get(key : K) : Option[E] = {
+ val ret = underlying.get(key);
+ if (ret == null) None else Some(ret.asInstanceOf[E]);
+ }
+
+ override def ++=(that : Iterable[Tuple2[K,E]]) : Unit = that match {
+ case that : MapWrapper[_,_] => underlying.putAll(that.underlying);
+ case _ => super.++=(that)
+ }
+
+ override def removeKey(key: K) = {
+ val ret = underlying.remove(key)
+ if (ret == null) None else Some(ret.asInstanceOf[E])
+ }
+
+ override def contains(key: K) = underlying.containsKey(key)
+ override def keySet: Set.Projection[K] = new KeySet
+ override def valueSet: MutableIterable.Projection[E] = new ValueSet
+ override def elements: MutableIterator[Tuple2[K,E]] = new IteratorWrapper
+
+ class IteratorWrapper extends MutableIterator[Tuple2[K,E]] {
+ val underlying = MapWrapper.this.underlying.entrySet.iterator
+ def hasNext = underlying.hasNext
+ def remove = underlying.remove
+ def next = {
+ val next = underlying.next.asInstanceOf[java.util.Map.Entry[K,E]]
+ Tuple2(next.getKey.asInstanceOf[K],next.getValue.asInstanceOf[E])
+ }
+ }
+
+ class KeySet extends super.KeySet with SetWrapper[K] with Set.Projection[K] {
+ val underlying = MapWrapper.this.underlying.keySet
+ }
+
+ class ValueSet extends IterableWrapper[E] with MutableIterable.Projection[E] {
+ override def size = MapWrapper.this.size
+ val underlying = MapWrapper.this.underlying.values
+ override def has(e : E) = MapWrapper.this.underlying.containsValue(e)
+ }
+
+ override def toString = underlying.toString
+ override def hashCode = underlying.hashCode
+
+ override def equals(that : Any) = that match {
+ case that: MapWrapper[_,_] => underlying == that.underlying
+ case _ => super.equals(that)
+ }
+}
diff --git a/src/library/scala/collection/jcl/MutableIterable.scala b/src/library/scala/collection/jcl/MutableIterable.scala
new file mode 100644
index 0000000000..3988ed8d93
--- /dev/null
+++ b/src/library/scala/collection/jcl/MutableIterable.scala
@@ -0,0 +1,110 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.collection.jcl;
+
+/**
+ * An iterable collection that supports remove operations.
+ * Useful for representing projections of mutable collections that where only
+ * the remove operation makes sense.
+ *
+ * @author Sean McDirmid
+ */
+trait MutableIterable[A] extends scala.Collection[A] {
+ /** @return true if t is in the collection.
+ **/
+ def has(t : A ) : Boolean = elements.contains(t);
+
+ /** @return true if t was removed from this collection.
+ **/
+ def remove(t : A ) : Boolean = elements.remove(t);
+ /** @return true if any element in that was removed from this collection.
+ **/
+ def removeAll(that : Iterable[A]) : Boolean = {
+ var changed = false;
+ that.foreach(t => changed = elements.remove(t) || changed);
+ changed;
+ }
+ /** Operator shortcut for removeAll. */
+ def --(that : Iterable[A]) : this.type = {
+ removeAll(that); this;
+ }
+
+ /** @return the collection that t was removed from.
+ */
+ def -(t : A) : this.type = { remove(t); this; }
+ /** retain only elements in the collection that predicate p is true for.
+ */
+ def retainOnly(p : A => Boolean) : Unit = elements.retain(p);
+ /** retain only elements that are also in that.
+ */
+ def retainAll(that : Iterable[A]) : Boolean = elements.retain(s => that.exists(t => t == s));
+
+ /** @return the current number of elements in the collection.
+ */
+ protected def size0 : Int = {
+ var count = 0;
+ val i = elements;
+ while (i.hasNext) { count = count + 1; i.next; }
+ count;
+ }
+
+ /** clear all elements from the collection.
+ */
+ def clear(): Unit = {
+ val i = elements;
+ while (i.hasNext) {
+ i.next; i.remove;
+ }
+ }
+ override def projection : MutableIterable.Projection[A] = new MutableIterable.Projection[A] {
+ override def elements = MutableIterable.this.elements
+ override def size = MutableIterable.this.size
+ override def remove(t : A ) : Boolean = MutableIterable.this.remove(t)
+ override def filter(p : A => Boolean) : MutableIterable.Projection[A] = super.filter(p)
+ }
+ /** The default implementation of a map over mutable iterable collections.
+ **/
+ override def elements : MutableIterator[A];
+ protected class Map[B](f : A => B) extends MutableIterable.Projection[B] {
+ override def elements = MutableIterable.this.elements.map(f)
+ override def size = MutableIterable.this.size
+ }
+ trait Filter extends MutableIterable.Projection[A] {
+ protected def p(a : A) : Boolean
+ override def has(a : A) = if (!p(a)) false else MutableIterable.this.has(a);
+ override def remove(a : A) = {
+ if (!p(a)) throw new IllegalArgumentException;
+ MutableIterable.this.remove(a);
+ }
+ override def filter(p0 : A => Boolean) : MutableIterable.Projection[A] =
+ MutableIterable.this.projection.filter(a => p(a) && p0(a));
+ def elements = {
+ val i = MutableIterable.this.elements.filter(p);
+ new MutableIterator[A] {
+ def next = i.next
+ def hasNext = i.hasNext
+ def remove : Unit = throw new NoSuchMethodException
+ }
+ }
+ def size = size0;
+ }
+}
+
+object MutableIterable {
+ trait Projection[A] extends MutableIterable[A] with Iterable.Projection[A] {
+ override def projection = this
+ override def map[B](f : A => B) : Projection[B] = new Map[B](f);
+ override def filter(pp : A => Boolean) : Projection[A] = new Filter {
+ def p(a : A) = pp(a)
+ }
+ }
+}
+
diff --git a/src/library/scala/collection/jcl/MutableIterator.scala b/src/library/scala/collection/jcl/MutableIterator.scala
new file mode 100644
index 0000000000..5f92746358
--- /dev/null
+++ b/src/library/scala/collection/jcl/MutableIterator.scala
@@ -0,0 +1,70 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.collection.jcl;
+
+object MutableIterator {
+ class Wrapper[A](val underlying : java.util.Iterator[A]) extends MutableIterator[A] {
+ def hasNext = underlying.hasNext;
+ def next = underlying.next.asInstanceOf[A];
+ def remove = underlying.remove;
+ }
+}
+
+/** An iterator that supports the remove operation.
+ * These iterators wrap Java iterators, and so have the same fail fast
+ * behavior when dealing with concurrent modifications.
+ *
+ * @author Sean McDirmid
+ */
+trait MutableIterator[A] extends Iterator[A] {
+ def remove : Unit;
+
+ /* filter doesnt' support remove yet.
+ override def filter(f : A => Boolean) : MutableIterator[A] = {
+ val buffered = this.buffered0;
+ new buffered.Filter(f);
+ }
+ */
+
+ override def map[B](f: A => B) : MutableIterator[B] = new Map(f);
+ /** A type-safe version of contains.
+ **/
+ def has(a: A) = exists(b => a == a);
+
+ /** Finds and removes the first instance of "a" through the iterator.
+ * After execution, the iterator's cursor is located where the removed
+ * element existed.
+ *
+ * @param a ..
+ * @return false
if "a" is not encountered in the iterator
+ * and the iterator's cursor is located at the end of its elements.
+ */
+ def remove(a: A): Boolean = {
+ while (hasNext)
+ if (next == a) { remove; return true; }
+ return false;
+ }
+ /** Removes all elements in the iterator that predicate "p" returns false on.
+ **/
+ def retain(p : A => Boolean) : Boolean = {
+ var changed = false;
+ while (hasNext)
+ if (!p(next)) { remove; changed = true; }
+ changed;
+ }
+
+ /** Standard implementation of a mapped iterator. **/
+ class Map[B](f : A => B) extends MutableIterator[B] {
+ def hasNext = MutableIterator.this.hasNext
+ def next = f(MutableIterator.this.next)
+ def remove = MutableIterator.this.remove
+ }
+}
diff --git a/src/library/scala/collection/jcl/MutableSeq.scala b/src/library/scala/collection/jcl/MutableSeq.scala
new file mode 100644
index 0000000000..559965c9ea
--- /dev/null
+++ b/src/library/scala/collection/jcl/MutableSeq.scala
@@ -0,0 +1,123 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.collection.jcl;
+
+/** A mutable sequence that supports the remove operation and is ordered.
+ *
+ * @author Sean McDirmid
+ */
+trait MutableSeq[A] extends Seq[A] with MutableIterable[A] {
+ protected class DefaultSeqIterator extends SeqIterator[Int,A] {
+ protected var index = 0
+ override def hasNext = index < length
+ override def next = {
+ if (!hasNext) throw new NoSuchElementException("no lookahead")
+ index = index + 1
+ MutableSeq.this.apply(index - 1)
+ }
+ override def hasPrevious = index > 0
+ override def previous = {
+ if (!hasPrevious) throw new NoSuchElementException
+ index = index - 1
+ MutableSeq.this.apply(index)
+ }
+
+ override def nextIndex = index
+ override def previousIndex = {
+ if (index == 0) throw new NoSuchElementException
+ else index - 1
+ }
+ def remove = throw new UnsupportedOperationException
+ }
+ override def elements : SeqIterator[Int,A] = new DefaultSeqIterator
+
+ override def isEmpty = super[MutableIterable].isEmpty;
+
+ override def apply(idx : Int) = elements.seek(idx);
+ override def projection : MutableSeq.Projection[A] = new MutableSeq.Projection[A] {
+ override def length = MutableSeq.this.length
+ override def elements = MutableSeq.this.elements
+ override def apply(idx : Int) = MutableSeq.this.apply(idx)
+ }
+
+ /** Find the index of "a" in this sequence.
+ * @returns None if the "a" is not in this sequence.
+ */
+ def indexOf(a : A) = elements.indexOf(a);
+
+ override def length = {
+ var i = elements;
+ var sz = 0;
+ while (i.hasNext) {
+ sz = sz + 1;
+ i.next;
+ }
+ sz;
+ }
+ protected trait Filter extends MutableSeq.Projection[A] {
+ protected def p(a : A) : Boolean
+ override def elements : SeqIterator[Int,A] = new FilterIterator(MutableSeq.this.elements);
+ class FilterIterator(underlying : SeqIterator[Int,A]) extends SeqIterator[Int,A] {
+ private var index = 0;
+ protected def seekNext : Option[A] = {
+ while (underlying.hasNext) {
+ val next = underlying.next;
+ if (p(next)) return Some(next);
+ }
+ return None;
+ }
+ protected def seekPrevious : Option[A] = {
+ while (underlying.hasPrevious) {
+ val previous = underlying.previous;
+ if (p(previous)) return Some(previous);
+ }
+ return None;
+ }
+ def hasNext : Boolean = seekNext match {
+ case None => false;
+ case Some(_) => underlying.previous; true;
+ }
+ def nextIndex = index;
+ def next = seekNext match {
+ case None => throw new NoSuchElementException;
+ case Some(result) => index = index + 1; result;
+ }
+ def hasPrevious : Boolean = seekPrevious match {
+ case None => false;
+ case Some(_) => underlying.previous; true;
+ }
+ def previousIndex = {
+ if (index == 0) throw new NoSuchElementException;
+ index - 1;
+ }
+ def previous = seekPrevious match {
+ case None => throw new NoSuchElementException;
+ case Some(result) => index = index - 1; result;
+ }
+ def remove = underlying.remove;
+ }
+ }
+ protected class Map[B](f : A => B) extends super.Map[B](f) with MutableSeq.Projection[B] {
+ override def elements = MutableSeq.this.elements.map(f);
+ override def apply(idx : Int) = f(MutableSeq.this.apply(idx));
+ override def size = length;
+ }
+}
+object MutableSeq {
+ trait Projection[A] extends MutableSeq[A] with MutableIterable.Projection[A] with Seq.Projection[A] {
+ override def projection = this
+ override def filter(pp : A => Boolean) : Projection[A] = new Filter {
+ override def p(a : A) = pp(a)
+ }
+ override def map[B](f : A => B) : Projection[B] = new Map[B](f);
+ }
+}
+
diff --git a/src/library/scala/collection/jcl/Ranged.scala b/src/library/scala/collection/jcl/Ranged.scala
new file mode 100644
index 0000000000..054d9c381d
--- /dev/null
+++ b/src/library/scala/collection/jcl/Ranged.scala
@@ -0,0 +1,54 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.collection.jcl;
+
+/** Any collection (including maps) whose keys (or elements) are ordered.
+ *
+ * @author Sean McDirmid
+ */
+trait Ranged[K,A] extends scala.collection.Ranged[K,A] with MutableIterable[A] {
+ protected type SortedSelf <: Ranged[K,A];
+
+ /** Comparison function that orders keys. */
+ def compare(k0: K, k1: K): Int;
+
+ /** Creates a ranged projection of this collection. Any mutations in the
+ * ranged projection will update this collection and vice versa. Note: keys
+ * are not garuanteed to be consistent between this collection and the projection.
+ * This is the case for buffers where indexing is relative to the projection.
+ *
+ * @param from The lower-bound (inclusive) of the ranged projection.
+ * None
if there is no lower bound.
+ * @param until The upper-bound (exclusive) of the ranged projection.
+ * None
if there is no upper bound.
+ */
+ def rangeImpl(from: Option[K], until: Option[K]) : SortedSelf;
+ /** Creates a ranged projection of this collection with no upper-bound.
+ ** @param from The lower-bound (inclusive) of the ranged projection.
+ **/
+ override final def from(from: K): SortedSelf = rangeImpl(Some(from), None);
+ /** Creates a ranged projection of this collection with no lower-bound.
+ ** @param until The upper-bound (exclusive) of the ranged projection.
+ **/
+ override final def until(until: K): SortedSelf = rangeImpl(None, Some(until));
+
+ /** Creates a ranged projection of this collection with both a lower-bound and an upper-bound.
+ ** @param from The upper-bound (exclusive) of the ranged projection.
+ **/
+ override final def range(from: K, until: K) : SortedSelf = rangeImpl(Some(from),Some(until));
+
+ /** A wrapper around Java comparators. */
+ protected class Comparator[K <% Ordered[K]] extends java.util.Comparator[Any] {
+ def compare(x0 : Any, x1 : Any) = {
+ x0.asInstanceOf[K].compare(x1.asInstanceOf[K]); //!!!
+ }
+ }
+}
diff --git a/src/library/scala/collection/jcl/SeqIterator.scala b/src/library/scala/collection/jcl/SeqIterator.scala
new file mode 100644
index 0000000000..5461928735
--- /dev/null
+++ b/src/library/scala/collection/jcl/SeqIterator.scala
@@ -0,0 +1,58 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.collection.jcl;
+
+/** An iterator for a sequence that can move both forwards and backwards.
+ * over a set of ordered keys.
+ *
+ * @author Sean McDirmid
+ */
+trait SeqIterator[K,A] extends MutableIterator[A] {
+ /** @returns The index at the iterator's cursor. */
+ def nextIndex: K;
+
+ /** @returns The index of the element before the iterator's cursor. */
+ def previousIndex: K;
+
+ /** @return The previous element, will move the iterator's cursor backwards. */
+ def previous: A;
+
+ /** @return True if and only if the iterator's cursor is not at the beging of the iteration. */
+ def hasPrevious : Boolean;
+
+ /** Winds the iteration forward until index "idx" is found */
+ def seek(idx: K) = {
+ while (nextIndex != idx) next;
+ next;
+ }
+ /** finds the index of the next "a" in this iteration.
+ *
+ * @param a ..
+ * @return None
if "a" is not found in the iteration.
+ */
+ def indexOf(a: A): Option[K] = {
+ while (hasNext) {
+ val ret = next;
+ if (ret == a) return Some(previousIndex);
+ }
+ return None;
+ }
+
+ override def map[B](f: A => B) : SeqIterator[K,B] = new Map[B](f);
+ class Map[B](f: A => B) extends super.Map[B](f) with SeqIterator[K,B] {
+ override def hasPrevious = SeqIterator.this.hasPrevious;
+ override def previous = f(SeqIterator.this.previous);
+ override def previousIndex = SeqIterator.this.previousIndex;
+ override def nextIndex = SeqIterator.this.nextIndex;
+ override def map[C](g : B => C) : SeqIterator[K,C] =
+ SeqIterator.this.map(a => g(f(a)));
+ }
+}
diff --git a/src/library/scala/collection/jcl/Set.scala b/src/library/scala/collection/jcl/Set.scala
new file mode 100644
index 0000000000..7ef9360c2a
--- /dev/null
+++ b/src/library/scala/collection/jcl/Set.scala
@@ -0,0 +1,72 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.collection.jcl
+
+/** Analogous to a Java set.
+ *
+ * @author Sean McDirmid
+ */
+trait Set[A] extends scala.collection.mutable.Set[A] with Collection[A] {
+ final def contains(a : A) = has(a)
+
+ /** Add will return false if "a" already exists in the set. **/
+ override def add(a: A): Boolean
+
+ override def ++(i: Iterable[A]) : this.type = super[Collection].++(i)
+ override def --(i: Iterable[A]) : this.type = super[Collection].--(i)
+ override def +(t: A) : this.type = super[Collection].+(t)
+ override def -(t: A) : this.type = super[Collection].-(t)
+ override final def retain(f: A => Boolean) = retainOnly(f)
+ override def isEmpty = super[Collection].isEmpty
+ override def clear() = super.clear()
+ override def subsetOf(set : scala.collection.Set[A]) = set match {
+ case set : Set[_] => set.hasAll(this)
+ case set => super.subsetOf(set)
+ }
+
+ override def transform(f: A => A) = {
+ var toAdd : List[A] = Nil
+ val i = elements
+ while (i.hasNext) {
+ val i0 = i.next
+ val i1 = f(i0)
+ if (i0 != i1) {
+ i.remove; toAdd = i1 :: toAdd
+ }
+ }
+ addAll(toAdd)
+ }
+ class Filter(pp : A => Boolean) extends super.Filter with Set.Projection[A] {
+ override def p(a : A) = pp(a)
+ override def retainOnly(p0 : A => Boolean): Unit =
+ Set.this.retainOnly(e => !p(e) || p0(e))
+ override def add(a : A) = {
+ if (!p(a)) throw new IllegalArgumentException
+ else Set.this.add(a)
+ }
+ }
+ override def projection : Set.Projection[A] = new Set.Projection[A] {
+ override def add(a: A): Boolean = Set.this.add(a)
+ override def elements = Set.this.elements
+ override def size = Set.this.size
+ override def has(a : A) : Boolean = Set.this.has(a)
+ }
+}
+
+object Set {
+ trait Projection[A] extends Collection.Projection[A] with Set[A] {
+ override def filter(p : A => Boolean) : Projection[A] = new Filter(p);
+ override def projection = this
+ }
+ def apply[T](set : java.util.Set[T]) = new SetWrapper[T] {
+ val underlying = set
+ }
+}
diff --git a/src/library/scala/collection/jcl/SetWrapper.scala b/src/library/scala/collection/jcl/SetWrapper.scala
new file mode 100644
index 0000000000..5aeaf57a1b
--- /dev/null
+++ b/src/library/scala/collection/jcl/SetWrapper.scala
@@ -0,0 +1,22 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.collection.jcl;
+
+/** Used to wrap Java sets.
+ *
+ * @author Sean McDirmid
+ */
+trait SetWrapper[A] extends Set[A] with CollectionWrapper[A] {
+ def underlying: java.util.Set[A];
+ override def isEmpty = super[CollectionWrapper].isEmpty;
+ override def clear() = super[CollectionWrapper].clear;
+ override def size = underlying.size;
+}
diff --git a/src/library/scala/collection/jcl/Sorted.scala b/src/library/scala/collection/jcl/Sorted.scala
new file mode 100644
index 0000000000..7bbe49da75
--- /dev/null
+++ b/src/library/scala/collection/jcl/Sorted.scala
@@ -0,0 +1,46 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.collection.jcl;
+
+/** Any collection (including maps) whose keys (or elements) are ordered.
+ *
+ * @author Sean McDirmid
+ */
+trait Sorted[K,A] extends scala.collection.Sorted[K,A] with Ranged[K,A] {
+ override protected type SortedSelf <: Sorted[K,A];
+ /** return as a projection the set of keys in this collection */
+ override def keySet : SortedSet[K];
+
+ /** Creates a ranged projection of this collection. Any mutations in the
+ * ranged projection will update this collection and vice versa. Keys
+ * are garuanteed to be consistent between the collection and its projection.
+ *
+ * @param from The lower-bound (inclusive) of the ranged projection.
+ * None
if there is no lower bound.
+ * @param until The upper-bound (exclusive) of the ranged projection.
+ * None
if there is no upper bound.
+ */
+ override def rangeImpl(from: Option[K], until: Option[K]) : SortedSelf;
+
+ /** Create a range projection of this collection with no lower-bound.
+ ** @param to The upper-bound (inclusive) of the ranged projection.
+ **/
+ final override def to(to : K): SortedSelf = {
+ // tough!
+ val i = keySet.from(to).elements;
+ if (!i.hasNext) return this.asInstanceOf[SortedSelf];
+ val next = i.next;
+ if (next == to) {
+ if (!i.hasNext) return this.asInstanceOf[SortedSelf];
+ else return until(i.next);
+ } else return until(next);
+ }
+}
diff --git a/src/library/scala/collection/jcl/SortedMap.scala b/src/library/scala/collection/jcl/SortedMap.scala
new file mode 100644
index 0000000000..be5591e7b8
--- /dev/null
+++ b/src/library/scala/collection/jcl/SortedMap.scala
@@ -0,0 +1,103 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.collection.jcl;
+
+object SortedMap {
+ trait Projection[K,E] extends Map.Projection[K,E] with SortedMap[K,E] {
+ override def projection = this
+ }
+ def apply[T,E](map0 : java.util.SortedMap[T,E]) = new SortedMapWrapper[T,E] {
+ val underlying = map0
+ }
+}
+/** A map whose keys are sorted.
+ *
+ * @author Sean McDirmid
+ */
+trait SortedMap[K,E] extends scala.collection.SortedMap[K,E] with Map[K,E] with Sorted[K,Tuple2[K,E]] {
+ final protected type SortedSelf = SortedMap[K,E];
+ override def compare(k0 : K, k1 : K) : Int;
+ override def firstKey : K = elements.next._1;
+ override def lastKey : K = {
+ val i = elements;
+ var last : K = i.next._1;
+ while (i.hasNext) last = i.next._1;
+ last;
+ }
+ override def rangeImpl(from : Option[K], until : Option[K]) : SortedMap[K,E] = Range(from, until);
+ override def keySet : SortedSet.Projection[K] = new KeySet;
+
+ override def projection : SortedMap.Projection[K,E] = new SortedMap.Projection[K,E] {
+ override def elements = SortedMap.this.elements
+ override def size = SortedMap.this.size
+ override def get(k : K) = SortedMap.this.get(k)
+ override def put(k : K, e : E) = SortedMap.this.put(k, e)
+ override def compare(k0 : K, k1 : K) = SortedMap.this.compare(k0, k1)
+ }
+
+ override def lense[F](f : E => F, g : F => E) : jcl.SortedMap.Projection[K,F] = new Lense[F](f,g);
+
+ protected class Lense[F](f : E => F, g : F => E) extends super.Lense[F](f,g) with SortedMap.Projection[K,F] {
+ def compare(k0 : K, k1 : K) = SortedMap.this.compare(k0, k1);
+ override def filterKeys(p : K => Boolean) : SortedMap.Projection[K,F] =
+ SortedMap.this.projection.filterKeys(p).lense(f,g);
+ override def lense[G](f0 : F => G, g0 : G => F) : jcl.SortedMap.Projection[K,G] =
+ SortedMap.this.lense[G]({x:E => f0(f(x))}, {y:G => g(g0(y))});
+ override def rangeImpl(from : Option[K], until : Option[K]) =
+ SortedMap.this.rangeImpl(from,until).lense(f,g);
+ }
+ protected class KeySet extends super.KeySet with SortedSet.Projection[K] {
+ def compare(k0 : K, k1 : K) = SortedMap.this.compare(k0,k1);
+ override def firstKey = SortedMap.this.firstKey;
+ override def lastKey = SortedMap.this.lastKey;
+ override def rangeImpl(from : Option[K], until : Option[K]) =
+ SortedMap.this.rangeImpl(from,until).keySet;
+ }
+ override def filterKeys(p : K => Boolean) : SortedMap.Projection[K,E] = new Filter(p);
+ protected class Filter(p : K => Boolean) extends super.Filter(p) with SortedMap.Projection[K,E] {
+ def compare(k0 : K, k1 : K) = SortedMap.this.compare(k0,k1);
+ override def filterKeys(p0 : K => Boolean) : SortedMap.Projection[K,E] =
+ SortedMap.this.filterKeys(k => p(k) && p0(k));
+ override def rangeImpl(from : Option[K], until : Option[K]) : SortedMap.Projection[K,E] =
+ SortedMap.this.Range(from, until).projection.filterKeys(p);
+ }
+ protected def Range(from : Option[K], until : Option[K]) : SortedMap.Projection[K,E] = new Range(from,until);
+ protected class Range(from : Option[K], until : Option[K]) extends super.Filter(key => {
+ ((from == None || (compare(from.get,key) <= 0)) &&
+ (until == None || (compare(key,until.get) < 0)));
+ }) with SortedMap.Projection[K,E] {
+ def compare(k0 : K, k1 : K) = SortedMap.this.compare(k0,k1);
+ private def contains0(key : K) =
+ (from == None || (compare(from.get,key) <= 0)) &&
+ (until == None || (compare(key,until.get) < 0));
+
+ override def contains(key : K) = SortedMap.this.contains(key) && contains0(key);
+ override def get(key : K) = if (!contains0(key)) None else SortedMap.this.get(key);
+ override def put(key : K, elem : E) = {
+ if (!contains0(key)) throw new IllegalArgumentException;
+ SortedMap.this.put(key, elem);
+ }
+ override def rangeImpl(from : Option[K], until : Option[K]) : SortedMap[K,E] = {
+ if (this.from != None && from == None) return rangeImpl(this.from, until);
+ if (this.until != None && until == None) return rangeImpl(from, this.until);
+ if (from != None && compare(this.from.get, from.get) > 0) return rangeImpl(this.from, until);
+ if (until != None && compare(this.until.get, until.get) < 0) return rangeImpl(from, this.until);
+ SortedMap.this.Range(from, until);
+ }
+ override def filterKeys(p : K => Boolean) : SortedMap.Projection[K,E] = new Filter(p);
+ protected class Filter(p : K => Boolean) extends super.Filter(p) with SortedMap.Projection[K,E] {
+ //def compare(k0 : K, k1 : K) = Range.this.compare(k0, k1);
+ override def filterKeys(p0 : K => Boolean) = Range.this.projection.filterKeys(k => p(k) && p0(k));
+ override def rangeImpl(from : Option[K], until : Option[K]) : SortedMap.Projection[K,E] =
+ Range.this.rangeImpl(from,until).projection.filterKeys(p);
+ }
+ }
+}
diff --git a/src/library/scala/collection/jcl/SortedMapWrapper.scala b/src/library/scala/collection/jcl/SortedMapWrapper.scala
new file mode 100644
index 0000000000..c706a4fec9
--- /dev/null
+++ b/src/library/scala/collection/jcl/SortedMapWrapper.scala
@@ -0,0 +1,39 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.collection.jcl;
+
+/** A sorted map that wraps an underlying Java sorted map.
+ *
+ * @author Sean McDirmid
+ */
+trait SortedMapWrapper[K,E] extends SortedMap[K,E] with MapWrapper[K,E] {
+ override def underlying : java.util.SortedMap[K,E];
+ /** the comparator function of this sorted map is defined in terms
+ * of the underlying sorted map's comparator.
+ */
+ def compare(k0 : K, k1 : K) = underlying.comparator.compare(k0,k1);
+ override def firstKey = underlying.firstKey.asInstanceOf[K];
+ override def lastKey = underlying.lastKey.asInstanceOf[K];
+ override def keySet : SortedSet.Projection[K] = new KeySet;
+ override protected def Range(from : Option[K], until : Option[K]) = new Range(from,until);
+ protected class Range(from : Option[K], until : Option[K]) extends super.Range(from,until) with SortedMapWrapper[K,E] {
+ val underlying = Tuple2(from,until) match {
+ case Tuple2(None,None) => throw new IllegalArgumentException;
+ case Tuple2(Some(from),None) => SortedMapWrapper.this.underlying.tailMap(from);
+ case Tuple2(None,Some(until)) => SortedMapWrapper.this.underlying.headMap(until);
+ case Tuple2(Some(from),Some(until)) => SortedMapWrapper.this.underlying.subMap(from,until);
+ }
+ override def compare(k0 : K, k1 : K) = super[SortedMapWrapper].compare(k0, k1);
+ }
+ protected class KeySet extends super[SortedMap].KeySet with SetWrapper[K] with SortedSet.Projection[K] {
+ val underlying = SortedMapWrapper.this.underlying.keySet;
+ }
+}
diff --git a/src/library/scala/collection/jcl/SortedSet.scala b/src/library/scala/collection/jcl/SortedSet.scala
new file mode 100644
index 0000000000..5050a1c36a
--- /dev/null
+++ b/src/library/scala/collection/jcl/SortedSet.scala
@@ -0,0 +1,99 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.collection.jcl;
+import Predef._
+
+object SortedSet {
+ trait Projection[A] extends Set.Projection[A] with SortedSet[A] {
+ override def projection = this
+ override def filter(p : A => Boolean) : Projection[A] = new Filter(p);
+ }
+ def apply[T](set : java.util.SortedSet[T]) = new SortedSetWrapper[T] {
+ val underlying = set
+ }
+
+}
+
+/** Analogous to a Java sorted set.
+ *
+ * @author Sean McDirmid
+ */
+trait SortedSet[A] extends scala.collection.SortedSet[A] with jcl.Set[A] with Sorted[A,A] {
+ final protected type SortedSelf = SortedSet[A];
+ override def keySet = this;
+ def compare(a0 : A, a1 : A) : Int;
+ override def firstKey : A = {
+ val i = elements;
+ if (i.hasNext) i.next;
+ else throw new NoSuchElementException;
+ }
+ override def subsetOf(that : scala.collection.Set[A]) = super[SortedSet].subsetOf(that);
+ override def hasAll(that : Iterable[A]) = super[Sorted].hasAll(that.elements);
+
+ override def lastKey : A = {
+ var last : A = null.asInstanceOf[A];
+ val i = elements;
+ while (i.hasNext) last = i.next;
+ if (last == null) throw new NoSuchElementException;
+ else last;
+ }
+ override def rangeImpl(from : Option[A], until : Option[A]) : SortedSet[A] = new Range(from, until);
+ override def projection : SortedSet.Projection[A] = new SortedSet.Projection[A] {
+ override def compare(a0 : A, a1 : A) = SortedSet.this.compare(a0, a1)
+ override def add(a: A): Boolean = SortedSet.this.add(a)
+ override def elements = SortedSet.this.elements
+ override def size = SortedSet.this.size
+ override def has(a : A) : Boolean = SortedSet.this.has(a)
+ }
+
+ protected class Filter(pp : A => Boolean) extends super.Filter(pp) with SortedSet.Projection[A] {
+ override def p(a : A) = pp(a)
+ def compare(a0 : A, a1 : A) : Int = SortedSet.this.compare(a0, a1);
+ override def filter(p0 : A => Boolean) = SortedSet.this.projection.filter(k => p(k) && p0(k));
+ }
+ protected class Range(from : Option[A], until : Option[A]) extends Filter(key => {
+ (from == None || (compare(from.get,key) <= 0)) &&
+ (until == None || (compare(key,until.get) < 0));
+ }) with SortedSet.Projection[A] {
+ if (from == None && until == None) throw new IllegalArgumentException;
+ if (from != None && until != None && !(SortedSet.this.compare(from.get, until.get) < 0))
+ throw new IllegalArgumentException;
+ //override def elements : MutableIterator[A] =
+ // new RangeIterator(SortedSet.this.elements.buffered0);
+ private def contains1(key : A) =
+ (from == None || (compare(from.get,key) <= 0)) &&
+ (until == None || (compare(key,until.get) < 0));
+ override def has(elem : A) = contains1(elem) && SortedSet.this.has(elem);
+ override def rangeImpl(from : Option[A], until : Option[A]) : SortedSet[A] = {
+ if (this.from != None && from == None) return rangeImpl(this.from, until);
+ if (this.until != None && until == None) return rangeImpl(from, this.until);
+ if (from != None && compare(this.from.get, from.get) > 0) return rangeImpl(this.from, until);
+ if (until != None && compare(this.until.get, until.get) < 0) return rangeImpl(from, this.until);
+ SortedSet.this.rangeImpl(from, until);
+ }
+ /*
+ class RangeIterator(underlying : MutableIterator[A]#Buffered) extends MutableIterator[A] {
+ if (from != None)
+ underlying.seekNext(a => compare(from.get, a) <= 0);
+
+ private def okNext(a : A) =
+ if (until == None) true;
+ else compare(a, until.get) < 0;
+
+ def hasNext = underlying.hasNext && okNext(underlying.peekNext);
+ def next = underlying.seekNext(okNext) match {
+ case Some(result) => underlying.next; result;
+ case None => throw new NoSuchElementException;
+ }
+ def remove = underlying.remove;
+ }*/
+ }
+}
diff --git a/src/library/scala/collection/jcl/SortedSetWrapper.scala b/src/library/scala/collection/jcl/SortedSetWrapper.scala
new file mode 100644
index 0000000000..39b066bfd7
--- /dev/null
+++ b/src/library/scala/collection/jcl/SortedSetWrapper.scala
@@ -0,0 +1,39 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.collection.jcl;
+
+/** + * A wrapper around a Java sorted set. + *
+ *+ * The comparator of the sorted set matches the comparator of this set. + *
+ * + * @author Sean McDirmid + */ +trait SortedSetWrapper[A] extends SortedSet[A] with SetWrapper[A] { + def underlying : java.util.SortedSet[A]; + /** delegates to the comparator of the underlying Java sorted set */ + override def compare(a0 : A, a1 : A) = underlying.comparator.compare(a0, a1); + override def firstKey = underlying.first.asInstanceOf[A]; + override def lastKey = underlying.last .asInstanceOf[A]; + override def rangeImpl(from : Option[A], until : Option[A]) : SortedSet[A] = new Range(from,until); + protected class Range(from : Option[A], until : Option[A]) extends super.Range(from, until) with SortedSetWrapper[A] { + val underlying = Tuple2(from,until) match { + case Tuple2(None,Some(until)) => SortedSetWrapper.this.underlying.headSet(until); + case Tuple2(Some(from),None) => SortedSetWrapper.this.underlying.tailSet(from); + case Tuple2(Some(from),Some(until)) => SortedSetWrapper.this.underlying.subSet(from,until); + case _ => throw new IllegalArgumentException; + } + override def elements : MutableIterator[A] = super[SortedSetWrapper].elements; + } + override def toString = super.toString; +} diff --git a/src/library/scala/collection/jcl/Tests.scala b/src/library/scala/collection/jcl/Tests.scala new file mode 100644 index 0000000000..a3007d8e1b --- /dev/null +++ b/src/library/scala/collection/jcl/Tests.scala @@ -0,0 +1,79 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id$ + +package scala.collection.jcl; + +import java.lang.Integer; + +private[jcl] object Tests { + + def main(args : Array[String]) : Unit = { + hashSet; + treeSet; + treeMap; + } + + def treeSet : Unit = { + val set = new TreeSet[String]; + set + "aaa" + "bbb" + "ccc" + "ddd" + "eee" + "fff"; + Console.println(set); + val rset : SortedSet[String] = set.range("b", "e"); + Console.println(rset); + rset + "bad"; + Console.println(rset); + Console.println(set); + val fset : SortedSet[String] = rset.projection.filter(_.endsWith("d")); + Console.println(fset); + fset += "cd"; + Console.println(set); + //set.projection.map(_.length).retain(x => x == 3); + Console.println(set); + Console.println(rset); + Console.println(fset); + } + + def treeMap : Unit = { + val map = new TreeMap[String,Integer]; + map + ("bb" -> 3) + ("cc" -> 4) + ("aa" -> 2) + ("dd" -> 5); + //Console.println(map); + val rmap : SortedMap[String,Integer] = map.range("b", "d"); + rmap + ("bad" -> 10); + Console.println(rmap); + //Console.println(map); + val fmap : SortedMap[String,Integer] = rmap.projection.filterKeys(k => k.length == 2); + Console.println(fmap); + } + + def hashSet = { + val set = new HashSet[String]; + set + "hello" + "world" + "you" + "to"; + Console.println(set); + val fset = set.projection.filter(s => s.length <= 3); + Console.println(fset); + fset += "xxx"; + Console.println(set); + try { + fset += "xxxx"; + throw new Error; + } catch { + case e : IllegalArgumentException => + case _ => throw new Error; + } + //val mset : MutableIterable[Int] = set // set.projection.map(s => s.length); + //Console.println(mset); + //mset.retain(n => n < 5); + Console.println(set); + val set1 = new HashSet[String] + "1" + "2" + "3"; + set ++ (set1); + Console.println(set); + set.transform(s => "x_" + s); + Console.println(set); + } +} diff --git a/src/library/scala/collection/jcl/TreeMap.scala b/src/library/scala/collection/jcl/TreeMap.scala new file mode 100644 index 0000000000..c01584851d --- /dev/null +++ b/src/library/scala/collection/jcl/TreeMap.scala @@ -0,0 +1,24 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2006-2008, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id$ + +package scala.collection.jcl + +/** A sorted map that is backed by a Java tree map. + * + * @author Sean McDirmid + */ +class TreeMap[K <% Ordered[K], E] extends SortedMapWrapper[K, E] { tm => + val underlying = (new java.util.TreeMap[K, E](new Comparator[K])) + override def clone: TreeMap[K, E] = + new TreeMap[K, E] { + override val underlying = + tm.underlying.clone().asInstanceOf[java.util.TreeMap[K, E]] + } +} diff --git a/src/library/scala/collection/jcl/TreeSet.scala b/src/library/scala/collection/jcl/TreeSet.scala new file mode 100644 index 0000000000..e708349763 --- /dev/null +++ b/src/library/scala/collection/jcl/TreeSet.scala @@ -0,0 +1,26 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2006-2008, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id$ + +package scala.collection.jcl + +/** Creates a sorted set that is backed by an underlying Java tree set. + * Elements of the sorted set are ordered with respect to the ordered + * view bound ofA
.
+ *
+ * @author Sean McDirmid
+ */
+class TreeSet[A <% Ordered[A]] extends SortedSetWrapper[A] { ts =>
+ val underlying = new java.util.TreeSet[A](new Comparator[A])
+ override def clone: TreeSet[A] =
+ new TreeSet[A] {
+ override val underlying =
+ ts.underlying.clone().asInstanceOf[java.util.TreeSet[A]]
+ }
+}
diff --git a/src/library/scala/collection/jcl/WeakHashMap.scala b/src/library/scala/collection/jcl/WeakHashMap.scala
new file mode 100644
index 0000000000..1d8ff4207e
--- /dev/null
+++ b/src/library/scala/collection/jcl/WeakHashMap.scala
@@ -0,0 +1,31 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2008, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.collection.jcl
+
+/** + * A map that is backed by a Java weak hash map, whose keys are maintained + * as weak references. + *
+ *+ * Because keys are weak references, the garbage collector can collect + * them if they are not referred to elsewhere. + *
+ *+ * Useful for implementing caches. + *
+ * + * @author Sean McDirmid + */ +class WeakHashMap[K, E](override val underlying: java.util.WeakHashMap[K, E]) extends MapWrapper[K, E] { + def this() = this(new java.util.WeakHashMap[K, E]) + override def clone: WeakHashMap[K, E] = + throw new CloneNotSupportedException("The underlying map doesn't implement the Cloneable interface") +} diff --git a/src/library/scala/collection/mutable/JavaMapAdaptor.scala b/src/library/scala/collection/mutable/JavaMapAdaptor.scala new file mode 100644 index 0000000000..b912057c28 --- /dev/null +++ b/src/library/scala/collection/mutable/JavaMapAdaptor.scala @@ -0,0 +1,69 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2006, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id$ + + +package scala.collection.mutable + + +/** This class can be used as an adaptor to create mutable maps from + * Java classes that implementat thejava.util.Map
interface.
+ *
+ * @author Matthias Zenger
+ * @version 1.0, 21/07/2003
+ * @deprecated Use scala.collection.jcl.Map(jmap)
instead
+ */
+@deprecated class JavaMapAdaptor[A, B](jmap: java.util.Map[A, B]) extends Map[A, B] {
+
+ def size: Int = jmap.size()
+
+ def get(key: A): Option[B] =
+ if (jmap.containsKey(key)) Some(jmap.get(key).asInstanceOf[B]) else None
+
+ override def isEmpty: Boolean = jmap.isEmpty()
+
+ override def apply(key: A): B = jmap.get(key).asInstanceOf[B]
+
+ override def contains(key: A): Boolean = jmap.containsKey(key)
+
+ override def isDefinedAt(key: A) = jmap.containsKey(key)
+
+ override def keys: Iterator[A] = new Iterator[A] {
+ val iter = jmap.keySet().iterator()
+ def hasNext = iter.hasNext()
+ def next = iter.next().asInstanceOf[A]
+ }
+
+ override def values: Iterator[B] = new Iterator[B] {
+ val iter = jmap.values().iterator()
+ def hasNext = iter.hasNext()
+ def next = iter.next().asInstanceOf[B]
+ }
+
+ def elements: Iterator[(A, B)] = new Iterator[(A, B)] {
+ val iter = jmap.keySet().iterator()
+ def hasNext = iter.hasNext()
+ def next = {
+ val key = iter.next().asInstanceOf[A]
+ (key, apply(key))
+ }
+ }
+
+ def update(key: A, value: B): Unit = { val x = jmap.put(key, value); }
+
+ def -= (key: A): Unit = { val x = jmap.remove(key); }
+
+ override def clear(): Unit = jmap.clear()
+
+ override def clone(): Map[A, B] = {
+ val res = new HashMap[A, B]
+ res ++= this
+ res
+ }
+}
diff --git a/src/library/scala/collection/mutable/JavaSetAdaptor.scala b/src/library/scala/collection/mutable/JavaSetAdaptor.scala
new file mode 100644
index 0000000000..f3a6f3386d
--- /dev/null
+++ b/src/library/scala/collection/mutable/JavaSetAdaptor.scala
@@ -0,0 +1,47 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2006, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+
+package scala.collection.mutable
+
+
+/** This class can be used as an adaptor to create mutable sets from
+ * Java classes that implement interface java.util.Set
.
+ *
+ * @author Matthias Zenger
+ * @version 1.0, 19/09/2003
+ * @deprecated Use scala.collection.jcl.Set(jmap)
instead
+ */
+@deprecated class JavaSetAdaptor[A](jset: java.util.Set[A]) extends Set[A] {
+
+ def size: Int = jset.size()
+
+ override def isEmpty: Boolean = jset.isEmpty()
+
+ def contains(elem: A): Boolean = jset.contains(elem)
+
+ def elements: Iterator[A] = new Iterator[A] {
+ val iter = jset.iterator()
+ def hasNext = iter.hasNext()
+ def next = iter.next().asInstanceOf[A]
+ }
+
+ def +=(elem: A): Unit = { val x = jset.add(elem); }
+
+ def -=(elem: A): Unit = { val x = jset.remove(elem); }
+
+ override def clear(): Unit = jset.clear()
+
+ override def clone(): Set[A] = {
+ val res = new HashSet[A]
+ res ++= this
+ res
+ }
+}
diff --git a/src/library/scala/concurrent/ops.scala b/src/library/scala/concurrent/ops.scala
new file mode 100644
index 0000000000..0d3c485300
--- /dev/null
+++ b/src/library/scala/concurrent/ops.scala
@@ -0,0 +1,78 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+
+package scala.concurrent
+
+
+import java.lang.Thread
+
+/** The object ops
...
+ *
+ * @author Martin Odersky, Stepan Koltsov
+ * @version 1.0, 12/03/2003
+ */
+object ops {
+
+ /**
+ * @param p ...
+ */
+ def spawn(p: => Unit) = {
+ val t = new Thread() { override def run() = p }
+ t.start()
+ }
+
+ /**
+ * @param p ...
+ * @return ...
+ */
+ def future[A](p: => A): () => A = {
+ val result = new SyncVar[A]
+ spawn { result setWithCatch p }
+ () => result.get
+ }
+
+ /**
+ * @param xp ...
+ * @param yp ...
+ * @return ...
+ */
+ def par[A, B](xp: => A, yp: => B): (A, B) = {
+ val y = new SyncVar[B]
+ spawn { y setWithCatch yp }
+ (xp, y.get)
+ }
+
+ /**
+ * @param start ...
+ * @param end ...
+ * @param p ...
+ */
+ def replicate(start: Int, end: Int)(p: Int => Unit) {
+ if (start == end)
+ ()
+ else if (start + 1 == end)
+ p(start)
+ else {
+ val mid = (start + end) / 2
+ spawn { replicate(start, mid)(p) }
+ replicate(mid, end)(p)
+ }
+ }
+
+/*
+ def parMap[a,b](f: a => b, xs: Array[a]): Array[b] = {
+ val results = new Array[b](xs.length);
+ replicate(0, xs.length) { i => results(i) = f(xs(i)) }
+ results
+ }
+*/
+
+}
diff --git a/src/library/scala/io/BufferedSource.scala b/src/library/scala/io/BufferedSource.scala
new file mode 100644
index 0000000000..99d8d036ae
--- /dev/null
+++ b/src/library/scala/io/BufferedSource.scala
@@ -0,0 +1,98 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2008, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+
+package scala.io
+
+import java.io.InputStream
+import java.nio.{ByteBuffer, CharBuffer}
+import java.nio.channels.{ByteChannel, Channels, ReadableByteChannel}
+import java.nio.charset.{Charset, CharsetDecoder}
+
+object BufferedSource {
+
+ /** same as fromInputStream(inpStream, Charset.forName(enc), buffer_size, do_reset) */
+ def fromInputStream(inpStream: InputStream, enc: String, buffer_size: Int, do_reset: () => Source): BufferedSource =
+ fromInputStream(inpStream, Charset.forName(enc), buffer_size, do_reset)
+
+ /** same as fromInputStream(inpStream, charSet.newDecoder(), buffer_size, do_reset) */
+ def fromInputStream(inpStream: InputStream, charSet: Charset, buffer_size: Int, do_reset: () => Source): BufferedSource =
+ fromInputStream(inpStream, charSet.newDecoder(), buffer_size, do_reset)
+
+ /** constructs a BufferedSource instance from an input stream, using given decoder */
+ def fromInputStream(inpStream: InputStream, decoder: CharsetDecoder, buffer_size: Int, do_reset: () => Source): BufferedSource = {
+ val byteChannel = Channels.newChannel(inpStream)
+ return new BufferedSource(byteChannel, decoder) {
+ val buf_size = buffer_size
+ override def reset = do_reset()
+ def close { inpStream.close }
+ }
+ }
+}
+
+/** This object provides convenience methods to create an iterable
+ * representation of a source file.
+ *
+ * @author Burak Emir
+ * @version 1.0, 19/08/2004
+ */
+abstract class BufferedSource(byteChannel: ReadableByteChannel, decoder: CharsetDecoder) extends Source {
+
+ val buf_size: Int
+
+ def close: Unit
+
+ val byteBuffer = ByteBuffer.allocate(buf_size)
+ var charBuffer = CharBuffer.allocate(buf_size)
+ byteBuffer.position(byteBuffer.limit())
+ charBuffer.position(charBuffer.limit())
+ decoder.reset()
+ var endOfInput = false
+
+ def fillBuffer() = {
+ byteBuffer.compact()
+ charBuffer.position(0)
+ var num_bytes = byteChannel.read(byteBuffer)
+ while (0 == num_bytes) {
+ Thread.sleep(1); // wait 1 ms for new data
+ num_bytes = byteChannel.read(byteBuffer)
+ }
+ num_bytes match {
+ case -1 =>
+ endOfInput = true;
+ byteBuffer.position(0)
+ decoder.decode(byteBuffer, charBuffer, true)
+ decoder.flush(charBuffer)
+ case num_bytes =>
+ endOfInput = false
+ byteBuffer.flip()
+ decoder.decode(byteBuffer, charBuffer, false)
+ charBuffer.flip()
+ }
+ }
+ override val iter = new Iterator[Char] {
+ var buf_char = {
+ fillBuffer()
+ if (endOfInput) ' ' else charBuffer.get()
+ }
+ def hasNext = { charBuffer.remaining() > 0 || !endOfInput}
+ def next = {
+ val c = buf_char
+ if (charBuffer.remaining() == 0) {
+ fillBuffer()
+ }
+ if (!endOfInput) {
+ buf_char = charBuffer.get()
+ }
+ c
+ }
+ }
+}
+
diff --git a/src/library/scala/io/Source.scala b/src/library/scala/io/Source.scala
new file mode 100644
index 0000000000..90bff94028
--- /dev/null
+++ b/src/library/scala/io/Source.scala
@@ -0,0 +1,400 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2008, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+
+package scala.io
+
+
+import java.io.{BufferedInputStream, File, FileInputStream, InputStream,
+ PrintStream}
+import java.nio.{ByteBuffer, CharBuffer}
+import java.nio.charset.Charset
+import java.net.{URI, URL}
+
+/** This object provides convenience methods to create an iterable
+ * representation of a source file.
+ *
+ * @author Burak Emir
+ * @version 1.0, 19/08/2004
+ */
+object Source {
+
+ val DefaultBufSize = 2048
+
+ val NoReset: () => Source = () => throw new UnsupportedOperationException()
+
+ /** Creates a Source
instance from the given array of bytes,
+ * with empty description.
+ *
+ * @param bytes ...
+ * @return the created Source
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))
+
+ /** Creates a Source
instance from a single character.
+ *
+ * @param c ...
+ * @return the create Source
instance.
+ */
+ def fromChar(c: Char): Source = {
+ val it = Iterator.single(c)
+ new Source {
+ def reset() = fromChar(c)
+ val iter = it
+ }
+ }
+
+ /** creates Source from array of characters, with empty description.
+ *
+ * @param chars ...
+ * @return ...
+ */
+ def fromChars(chars: Array[Char]): Source = {
+ val it = chars.elements
+ new Source {
+ def reset() = fromChars(chars)
+ val iter = it
+ }
+ }
+
+ /** creates Source from string, with empty description.
+ *
+ * @param s ...
+ * @return ...
+ */
+ def fromString(s: String): Source = {
+ val it = s.elements
+ new Source {
+ def reset() = fromString(s)
+ val iter = it
+ }
+ }
+
+ /** creates Source from file with given name, setting its description to
+ * filename.
+ */
+ def fromFile(name: String): Source =
+ fromFile(name, util.Properties.encodingString)
+
+ /** creates Source from file with given name, using given encoding, setting
+ * its description to filename.
+ */
+ def fromFile(name: String, enc: String): Source =
+ fromFile(new File(name), enc)
+
+ /** creates Source
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)
+
+ /** Creates Source from file
, using given character encoding,
+ * setting its description to filename. Input is buffered in a buffer of
+ * size bufferSize
.
+ */
+ def fromFile(file: File, enc: String, bufferSize: Int): Source = {
+ val inpStream = new FileInputStream(file)
+ val size = if (bufferSize > 0) bufferSize else Source.DefaultBufSize
+ setFileDescriptor(file,
+ BufferedSource.fromInputStream(inpStream, enc, size, { () => fromFile(file, enc, size)}))
+ }
+
+ /** This method sets the descr property of the given source to a string of the form "file:"+path
+ * @param file the file whose path we want to describe
+ * @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 ...
+ * @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
+ }
+
+ /** same as fromInputStream(url.openStream(), enc)
+ */
+ def fromURL(url: URL, enc:String): Source =
+ fromInputStream(url.openStream(), enc)
+
+ /** reads data from istream
into a byte array, and calls
+ * fromBytes
with given encoding enc
.
+ * If maxlen
is given, reads not more bytes than maxlen
;
+ * if maxlen
was not given, or was <= 0
, then
+ * whole istream
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, Source.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)
+ }
+
+ /** same as BufferedSource.fromInputStream(is, enc, Source.DefaultBufSize)
+ */
+ def fromInputStream(is: InputStream, enc: String): Source =
+ BufferedSource.fromInputStream(is, enc, Source.DefaultBufSize, { () => fromInputStream(is, enc) })
+
+ /** same as BufferedSource.fromInputStream(is, "utf-8", Source.DefaultBufSize) */
+ def fromInputStream(is: InputStream): Source =
+ BufferedSource.fromInputStream(is, "utf-8", Source.DefaultBufSize, { () => fromInputStream(is) })
+
+}
+
+/** The class Source
implements an iterable representation
+ * of source files. Calling method reset
returns an identical,
+ * resetted source.
+ *
+ * @author Burak Emir
+ * @version 1.0
+ */
+abstract class Source extends Iterator[Char] {
+
+ // ------ protected values
+
+ /** the actual iterator */
+ protected val iter: Iterator[Char]
+
+ protected var cline = 1
+ protected var ccol = 1
+
+ // ------ public values
+
+ /** position of last character returned by next*/
+ var pos = 0
+
+ /** the last character returned by next.
+ * the value before the first call to next is undefined.
+ */
+ var ch: Char = _
+
+ /** description of this source, default empty */
+ var descr: String = ""
+
+ var nerrors = 0
+ var nwarnings = 0
+
+ /** default col increment for tabs '\t', set to 4 initially
+ */
+ var tabinc = 4
+
+ //
+ // -- methods
+ //
+
+ /** convenience method, returns given line (not including newline)
+ * from Source.
+ *
+ * @param line the line index, first line is 1
+ * @return the character string of the specified line.
+ * @throws scala.compat.Platform.IllegalArgumentException
+ *
+ */
+ def getLine(line: Int): String = { // faster than getLines.drop(line).next
+ // todo: should @throws scala.compat.Platform.IndexOutOfBoundsException
+ if (line < 1) throw new IllegalArgumentException(line.toString);
+ val buf = new StringBuilder()
+ val it = reset
+ var i = 0
+
+ while (it.hasNext && i < (line-1))
+ if ('\n' == it.next)
+ i += 1;
+
+ if (!it.hasNext) // this should not happen
+ throw new IllegalArgumentException(
+ "line " + line + " does not exist"
+ );
+
+ var ch = it.next
+ while (it.hasNext && '\n' != ch) {
+ buf append ch
+ ch = it.next
+ }
+
+ if ('\n' != ch)
+ buf append ch
+
+ val res = buf.toString()
+ buf setLength 0 // hopefully help collector to deallocate StringBuilder
+ res
+ }
+
+ /** returns an iterator who returns lines (including newline character).
+ * a line ends in \n.
+ */
+ def getLines: Iterator[String] = new Iterator[String] {
+ val buf = new StringBuilder
+ def next = {
+ var ch = iter.next
+ while(ch != '\n' && iter.hasNext) {
+ buf append ch
+ ch = iter.next
+ }
+ buf.append(ch)
+ val res = buf.toString()
+ buf setLength 0 // clean things up for next call of "next"
+ res
+ }
+ def hasNext = iter.hasNext
+ }
+ /** Returns true
if this source has more characters.
+ */
+ def hasNext = iter.hasNext
+
+ /** returns next character and has the following side-effects: updates
+ * position (ccol and cline) and assigns the character to ch
+ */
+ def next = {
+ ch = iter.next
+ pos = Position.encode(cline,ccol)
+ ch match {
+ case '\n' =>
+ ccol = 1
+ cline += 1
+ case '\t' =>
+ ccol += tabinc
+ case _ =>
+ ccol += 1
+ }
+ ch
+ }
+
+ /** Reports an error message to console.
+ *
+ * @param pos ...
+ * @param msg the error message to report
+ */
+ def reportError(pos: Int, msg: String) {
+ reportError(pos, msg, java.lang.System.out)
+ }
+
+ /** Reports an error message to the output stream out
.
+ *
+ * @param pos ...
+ * @param msg the error message to report
+ * @param out ...
+ */
+ def reportError(pos: Int, msg: String, out: PrintStream) {
+ nerrors = nerrors + 1
+ report(pos, msg, out)
+ }
+
+ /**
+ * @param pos ...
+ * @param msg the error message to report
+ * @param out ...
+ */
+ def report(pos: Int, msg: String, out: PrintStream) {
+ val buf = new StringBuilder
+ val line = Position.line(pos)
+ val col = Position.column(pos)
+ buf.append(descr + ":" + line + ":" + col + ": " + msg)
+ buf.append(getLine(line))
+ var i = 1
+ while (i < col) {
+ buf.append(' ')
+ i += 1
+ }
+ buf.append('^')
+ out.println(buf.toString)
+ }
+
+ /** Reports a warning message to java.lang.System.out
.
+ *
+ * @param pos ...
+ * @param msg the warning message to report
+ */
+ def reportWarning(pos: Int, msg: String) {
+ reportWarning(pos, msg, java.lang.System.out)
+ }
+
+ /**
+ * @param pos ...
+ * @param msg the warning message to report
+ * @param out ...
+ */
+ def reportWarning(pos: Int, msg: String, out: PrintStream) {
+ nwarnings = nwarnings + 1
+ report(pos, "warning! " + msg, out)
+ }
+
+ /** the actual reset method */
+ def reset(): Source
+
+}
diff --git a/src/library/scala/reflect/BeanInfo.scala b/src/library/scala/reflect/BeanInfo.scala
new file mode 100644
index 0000000000..a5ea0fb975
--- /dev/null
+++ b/src/library/scala/reflect/BeanInfo.scala
@@ -0,0 +1,22 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2008, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.reflect
+
+/** + * This attribute indicates that a JavaBean-compliant BeanInfo + * class should be generated for this attributed Scala class. + * A val becomes a read-only property. A var becomes a read-write + * property. A def becomes a method. + *
+ * + * @author Ross Judson (rjudson@managedobjects.com) + */ +class BeanInfo extends Annotation diff --git a/src/library/scala/reflect/BeanProperty.scala b/src/library/scala/reflect/BeanProperty.scala new file mode 100644 index 0000000000..4a09578df9 --- /dev/null +++ b/src/library/scala/reflect/BeanProperty.scala @@ -0,0 +1,33 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2007, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id$ + + +package scala.reflect + +/**+ * This attribute adds a setter and a getter method, following the + * Java Bean convention (first letter of the property is capitalized) + * used by popular Java web frameworks. For example: + *
+ * @BeanProperty + * var status = ""+ *
+ * adds the following methods to the generated code + *
+ * def setStatus(s: String) { this.status = s } + * def getStatus: String = this.status + *+ *
+ * However, you cannot call setStatus
from
+ * Scala,
+ * you should use the normal Scala access and assignment.
+ *
equals
method that overrides the
+ * default equals because Java's boxed primitives are utterly broken. This equals
+ * is inserted instead of a normal equals by the Scala compiler (in the
+ * ICode phase, method genEqEqPrimitive
) only when either
+ * side of the comparison is a subclass of AnyVal
, of
+ * java.lang.Number
, of java.lang.Character
or
+ * is exactly Any
or AnyRef
. */
+ public static boolean equals(Object a, Object b) {
+ if (a == null || b == null)
+ return a == b;
+ if (a.equals(b))
+ return true;
+ if (a instanceof Number || a instanceof Character || b instanceof Number || b instanceof Character) {
+ int acode = typeCode(a);
+ int bcode = typeCode(b);
+ int maxcode = (acode < bcode) ? bcode : acode;
+ if (maxcode <= INT) {
+ int aa = (acode == CHAR) ? ((Character) a).charValue() : ((Number) a).intValue();
+ int bb = (bcode == CHAR) ? ((Character) b).charValue() : ((Number) b).intValue();
+ return aa == bb;
+ }
+ if (maxcode <= LONG) {
+ long aa = (acode == CHAR) ? ((Character) a).charValue() : ((Number) a).longValue();
+ long bb = (bcode == CHAR) ? ((Character) b).charValue() : ((Number) b).longValue();
+ return aa == bb;
+ }
+ if (maxcode <= FLOAT) {
+ float aa = (acode == CHAR) ? ((Character) a).charValue() : ((Number) a).floatValue();
+ float bb = (bcode == CHAR) ? ((Character) b).charValue() : ((Number) b).floatValue();
+ return aa == bb;
+ }
+ if (maxcode <= DOUBLE) {
+ double aa = (acode == CHAR) ? ((Character) a).charValue() : ((Number) a).doubleValue();
+ double bb = (bcode == CHAR) ? ((Character) b).charValue() : ((Number) b).doubleValue();
+ return aa == bb;
+ }
+ return b.equals(a);
+ }
+ return false;
+ }
+
+/* OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS */
+
+ /** arg1 + arg2 */
+ public static Object add(Object arg1, Object arg2) throws NoSuchMethodException {
+ int code1 = typeCode(arg1);
+ int code2 = typeCode(arg2);
+ int maxcode = (code1 < code2) ? code2 : code1;
+ if (maxcode <= INT) {
+ int val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).intValue();
+ int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
+ return boxToInteger(val1 + val2);
+ }
+ if (maxcode <= LONG) {
+ long val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).longValue();
+ long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
+ return boxToLong(val1 + val2);
+ }
+ if (maxcode <= FLOAT) {
+ float val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).floatValue();
+ float val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).floatValue();
+ return boxToFloat(val1 + val2);
+ }
+ if (maxcode <= DOUBLE) {
+ double val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).doubleValue();
+ double val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).doubleValue();
+ return boxToDouble(val1 + val2);
+ }
+ throw new NoSuchMethodException();
+ }
+
+ /** arg1 - arg2 */
+ public static Object subtract(Object arg1, Object arg2) throws NoSuchMethodException {
+ int code1 = typeCode(arg1);
+ int code2 = typeCode(arg2);
+ int maxcode = (code1 < code2) ? code2 : code1;
+ if (maxcode <= INT) {
+ int val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).intValue();
+ int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
+ return boxToInteger(val1 - val2);
+ }
+ if (maxcode <= LONG) {
+ long val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).longValue();
+ long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
+ return boxToLong(val1 - val2);
+ }
+ if (maxcode <= FLOAT) {
+ float val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).floatValue();
+ float val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).floatValue();
+ return boxToFloat(val1 - val2);
+ }
+ if (maxcode <= DOUBLE) {
+ double val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).doubleValue();
+ double val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).doubleValue();
+ return boxToDouble(val1 - val2);
+ }
+ throw new NoSuchMethodException();
+ }
+
+ /** arg1 * arg2 */
+ public static Object multiply(Object arg1, Object arg2) throws NoSuchMethodException {
+ int code1 = typeCode(arg1);
+ int code2 = typeCode(arg2);
+ int maxcode = (code1 < code2) ? code2 : code1;
+ if (maxcode <= INT) {
+ int val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).intValue();
+ int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
+ return boxToInteger(val1 * val2);
+ }
+ if (maxcode <= LONG) {
+ long val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).longValue();
+ long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
+ return boxToLong(val1 * val2);
+ }
+ if (maxcode <= FLOAT) {
+ float val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).floatValue();
+ float val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).floatValue();
+ return boxToFloat(val1 * val2);
+ }
+ if (maxcode <= DOUBLE) {
+ double val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).doubleValue();
+ double val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).doubleValue();
+ return boxToDouble(val1 * val2);
+ }
+ throw new NoSuchMethodException();
+ }
+
+ /** arg1 / arg2 */
+ public static Object divide(Object arg1, Object arg2) throws NoSuchMethodException {
+ int code1 = typeCode(arg1);
+ int code2 = typeCode(arg2);
+ int maxcode = (code1 < code2) ? code2 : code1;
+ if (maxcode <= INT) {
+ int val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).intValue();
+ int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
+ return boxToInteger(val1 / val2);
+ }
+ if (maxcode <= LONG) {
+ long val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).longValue();
+ long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
+ return boxToLong(val1 / val2);
+ }
+ if (maxcode <= FLOAT) {
+ float val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).floatValue();
+ float val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).floatValue();
+ return boxToFloat(val1 / val2);
+ }
+ if (maxcode <= DOUBLE) {
+ double val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).doubleValue();
+ double val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).doubleValue();
+ return boxToDouble(val1 / val2);
+ }
+ throw new NoSuchMethodException();
+ }
+
+ /** arg1 % arg2 */
+ public static Object takeModulo(Object arg1, Object arg2) throws NoSuchMethodException {
+ int code1 = typeCode(arg1);
+ int code2 = typeCode(arg2);
+ int maxcode = (code1 < code2) ? code2 : code1;
+ if (maxcode <= INT) {
+ int val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).intValue();
+ int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
+ return boxToInteger(val1 % val2);
+ }
+ if (maxcode <= LONG) {
+ long val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).longValue();
+ long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
+ return boxToLong(val1 % val2);
+ }
+ if (maxcode <= FLOAT) {
+ float val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).floatValue();
+ float val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).floatValue();
+ return boxToFloat(val1 % val2);
+ }
+ if (maxcode <= DOUBLE) {
+ double val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).doubleValue();
+ double val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).doubleValue();
+ return boxToDouble(val1 % val2);
+ }
+ throw new NoSuchMethodException();
+ }
+
+ /** arg1 >> arg2 */
+ public static Object shiftSignedRight(Object arg1, Object arg2) throws NoSuchMethodException {
+ int code1 = typeCode(arg1);
+ int code2 = typeCode(arg2);
+ if (code1 <= INT) {
+ int val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).intValue();
+ if (code2 <= INT) {
+ int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
+ return boxToInteger(val1 >> val2);
+ }
+ if (code2 <= LONG) {
+ long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
+ return boxToInteger(val1 >> val2);
+ }
+ }
+ if (code1 <= LONG) {
+ long val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).longValue();
+ if (code2 <= INT) {
+ int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
+ return boxToLong(val1 >> val2);
+ }
+ if (code2 <= LONG) {
+ long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
+ return boxToLong(val1 >> val2);
+ }
+ }
+ throw new NoSuchMethodException();
+ }
+
+ /** arg1 << arg2 */
+ public static Object shiftSignedLeft(Object arg1, Object arg2) throws NoSuchMethodException {
+ int code1 = typeCode(arg1);
+ int code2 = typeCode(arg2);
+ if (code1 <= INT) {
+ int val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).intValue();
+ if (code2 <= INT) {
+ int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
+ return boxToInteger(val1 << val2);
+ }
+ if (code2 <= LONG) {
+ long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
+ return boxToInteger(val1 << val2);
+ }
+ }
+ if (code1 <= LONG) {
+ long val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).longValue();
+ if (code2 <= INT) {
+ int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
+ return boxToLong(val1 << val2);
+ }
+ if (code2 <= LONG) {
+ long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
+ return boxToLong(val1 << val2);
+ }
+ }
+ throw new NoSuchMethodException();
+ }
+
+ /** arg1 >>> arg2 */
+ public static Object shiftLogicalRight(Object arg1, Object arg2) throws NoSuchMethodException {
+ int code1 = typeCode(arg1);
+ int code2 = typeCode(arg2);
+ if (code1 <= INT) {
+ int val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).intValue();
+ if (code2 <= INT) {
+ int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
+ return boxToInteger(val1 >>> val2);
+ }
+ if (code2 <= LONG) {
+ long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
+ return boxToInteger(val1 >>> val2);
+ }
+ }
+ if (code1 <= LONG) {
+ long val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).longValue();
+ if (code2 <= INT) {
+ int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
+ return boxToLong(val1 >>> val2);
+ }
+ if (code2 <= LONG) {
+ long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
+ return boxToLong(val1 >>> val2);
+ }
+ }
+ throw new NoSuchMethodException();
+ }
+
+ /** -arg */
+ public static Object negate(Object arg) throws NoSuchMethodException {
+ int code = typeCode(arg);
+ if (code <= INT) {
+ int val = (code == CHAR) ? ((Character) arg).charValue() : ((Number) arg).intValue();
+ return boxToInteger(-val);
+ }
+ if (code <= LONG) {
+ long val = (code == CHAR) ? ((Character) arg).charValue() : ((Number) arg).longValue();
+ return boxToLong(-val);
+ }
+ if (code <= FLOAT) {
+ float val = (code == CHAR) ? ((Character) arg).charValue() : ((Number) arg).floatValue();
+ return boxToFloat(-val);
+ }
+ if (code <= DOUBLE) {
+ double val = (code == CHAR) ? ((Character) arg).charValue() : ((Number) arg).doubleValue();
+ return boxToDouble(-val);
+ }
+ throw new NoSuchMethodException();
+ }
+
+ /** +arg */
+ public static Object positive(Object arg) throws NoSuchMethodException {
+ int code = typeCode(arg);
+ if (code <= INT) {
+ int val = (code == CHAR) ? ((Character) arg).charValue() : ((Number) arg).intValue();
+ return boxToInteger(+val);
+ }
+ if (code <= LONG) {
+ long val = (code == CHAR) ? ((Character) arg).charValue() : ((Number) arg).longValue();
+ return boxToLong(+val);
+ }
+ if (code <= FLOAT) {
+ float val = (code == CHAR) ? ((Character) arg).charValue() : ((Number) arg).floatValue();
+ return boxToFloat(+val);
+ }
+ if (code <= DOUBLE) {
+ double val = (code == CHAR) ? ((Character) arg).charValue() : ((Number) arg).doubleValue();
+ return boxToDouble(+val);
+ }
+ throw new NoSuchMethodException();
+ }
+
+ /** arg1 & arg2 */
+ public static Object takeAnd(Object arg1, Object arg2) throws NoSuchMethodException {
+ if ((arg1 instanceof Boolean) || (arg2 instanceof Boolean)) {
+ if (!((arg1 instanceof Boolean) && (arg2 instanceof Boolean))) {
+ throw new NoSuchMethodException();
+ }
+ return boxToBoolean(((Boolean) arg1).booleanValue() & ((Boolean) arg2).booleanValue());
+ }
+ int code1 = typeCode(arg1);
+ int code2 = typeCode(arg2);
+ int maxcode = (code1 < code2) ? code2 : code1;
+ if (maxcode <= INT) {
+ int val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).intValue();
+ int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
+ return boxToInteger(val1 & val2);
+ }
+ if (maxcode <= LONG) {
+ long val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).longValue();
+ long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
+ return boxToLong(val1 & val2);
+ }
+ throw new NoSuchMethodException();
+ }
+
+ /** arg1 | arg2 */
+ public static Object takeOr(Object arg1, Object arg2) throws NoSuchMethodException {
+ if ((arg1 instanceof Boolean) || (arg2 instanceof Boolean)) {
+ if (!((arg1 instanceof Boolean) && (arg2 instanceof Boolean))) {
+ throw new NoSuchMethodException();
+ }
+ return boxToBoolean(((Boolean) arg1).booleanValue() | ((Boolean) arg2).booleanValue());
+ }
+ int code1 = typeCode(arg1);
+ int code2 = typeCode(arg2);
+ int maxcode = (code1 < code2) ? code2 : code1;
+ if (maxcode <= INT) {
+ int val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).intValue();
+ int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
+ return boxToInteger(val1 | val2);
+ }
+ if (maxcode <= LONG) {
+ long val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).longValue();
+ long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
+ return boxToLong(val1 | val2);
+ }
+ throw new NoSuchMethodException();
+ }
+
+ /** arg1 ^ arg2 */
+ public static Object takeXor(Object arg1, Object arg2) throws NoSuchMethodException {
+ if ((arg1 instanceof Boolean) || (arg2 instanceof Boolean)) {
+ if (!((arg1 instanceof Boolean) && (arg2 instanceof Boolean))) {
+ throw new NoSuchMethodException();
+ }
+ return boxToBoolean(((Boolean) arg1).booleanValue() ^ ((Boolean) arg2).booleanValue());
+ }
+ int code1 = typeCode(arg1);
+ int code2 = typeCode(arg2);
+ int maxcode = (code1 < code2) ? code2 : code1;
+ if (maxcode <= INT) {
+ int val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).intValue();
+ int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
+ return boxToInteger(val1 ^ val2);
+ }
+ if (maxcode <= LONG) {
+ long val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).longValue();
+ long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
+ return boxToLong(val1 ^ val2);
+ }
+ throw new NoSuchMethodException();
+ }
+
+ /** arg1 && arg2 */
+ public static Object takeConditionalAnd(Object arg1, Object arg2) throws NoSuchMethodException {
+ if ((arg1 instanceof Boolean) && (arg2 instanceof Boolean)) {
+ return boxToBoolean(((Boolean) arg1).booleanValue() && ((Boolean) arg2).booleanValue());
+ }
+ throw new NoSuchMethodException();
+ }
+
+ /** arg1 || arg2 */
+ public static Object takeConditionalOr(Object arg1, Object arg2) throws NoSuchMethodException {
+ if ((arg1 instanceof Boolean) && (arg2 instanceof Boolean)) {
+ return boxToBoolean(((Boolean) arg1).booleanValue() || ((Boolean) arg2).booleanValue());
+ }
+ throw new NoSuchMethodException();
+ }
+
+ /** ~arg */
+ public static Object complement(Object arg) throws NoSuchMethodException {
+ int code = typeCode(arg);
+ if (code <= INT) {
+ int val = (code == CHAR) ? ((Character) arg).charValue() : ((Number) arg).intValue();
+ return boxToInteger(~val);
+ }
+ if (code <= LONG) {
+ long val = (code == CHAR) ? ((Character) arg).charValue() : ((Number) arg).longValue();
+ return boxToLong(~val);
+ }
+ throw new NoSuchMethodException();
+ }
+
+ /** !arg */
+ public static Object takeNot(Object arg) throws NoSuchMethodException {
+ if (arg instanceof Boolean) {
+ return boxToBoolean(!((Boolean) arg).booleanValue());
+ }
+ throw new NoSuchMethodException();
+ }
+
+ public static Object testEqual(Object arg1, Object arg2) throws NoSuchMethodException {
+ return boxToBoolean(arg1 == arg2);
+ }
+
+ public static Object testNotEqual(Object arg1, Object arg2) throws NoSuchMethodException {
+ return boxToBoolean(arg1 != arg2);
+ }
+
+ public static Object testLessThan(Object arg1, Object arg2) throws NoSuchMethodException {
+ int code1 = typeCode(arg1);
+ int code2 = typeCode(arg2);
+ int maxcode = (code1 < code2) ? code2 : code1;
+ if (maxcode <= INT) {
+ int val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).intValue();
+ int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
+ return boxToBoolean(val1 < val2);
+ }
+ if (maxcode <= LONG) {
+ long val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).longValue();
+ long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
+ return boxToBoolean(val1 < val2);
+ }
+ if (maxcode <= FLOAT) {
+ float val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).floatValue();
+ float val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).floatValue();
+ return boxToBoolean(val1 < val2);
+ }
+ if (maxcode <= DOUBLE) {
+ double val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).doubleValue();
+ double val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).doubleValue();
+ return boxToBoolean(val1 < val2);
+ }
+ throw new NoSuchMethodException();
+ }
+
+ public static Object testLessOrEqualThan(Object arg1, Object arg2) throws NoSuchMethodException {
+ int code1 = typeCode(arg1);
+ int code2 = typeCode(arg2);
+ int maxcode = (code1 < code2) ? code2 : code1;
+ if (maxcode <= INT) {
+ int val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).intValue();
+ int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
+ return boxToBoolean(val1 <= val2);
+ }
+ if (maxcode <= LONG) {
+ long val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).longValue();
+ long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
+ return boxToBoolean(val1 <= val2);
+ }
+ if (maxcode <= FLOAT) {
+ float val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).floatValue();
+ float val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).floatValue();
+ return boxToBoolean(val1 <= val2);
+ }
+ if (maxcode <= DOUBLE) {
+ double val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).doubleValue();
+ double val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).doubleValue();
+ return boxToBoolean(val1 <= val2);
+ }
+ throw new NoSuchMethodException();
+ }
+
+ public static Object testGreaterOrEqualThan(Object arg1, Object arg2) throws NoSuchMethodException {
+ int code1 = typeCode(arg1);
+ int code2 = typeCode(arg2);
+ int maxcode = (code1 < code2) ? code2 : code1;
+ if (maxcode <= INT) {
+ int val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).intValue();
+ int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
+ return boxToBoolean(val1 >= val2);
+ }
+ if (maxcode <= LONG) {
+ long val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).longValue();
+ long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
+ return boxToBoolean(val1 >= val2);
+ }
+ if (maxcode <= FLOAT) {
+ float val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).floatValue();
+ float val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).floatValue();
+ return boxToBoolean(val1 >= val2);
+ }
+ if (maxcode <= DOUBLE) {
+ double val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).doubleValue();
+ double val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).doubleValue();
+ return boxToBoolean(val1 >= val2);
+ }
+ throw new NoSuchMethodException();
+ }
+
+ public static Object testGreaterThan(Object arg1, Object arg2) throws NoSuchMethodException {
+ int code1 = typeCode(arg1);
+ int code2 = typeCode(arg2);
+ int maxcode = (code1 < code2) ? code2 : code1;
+ if (maxcode <= INT) {
+ int val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).intValue();
+ int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();
+ return boxToBoolean(val1 > val2);
+ }
+ if (maxcode <= LONG) {
+ long val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).longValue();
+ long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();
+ return boxToBoolean(val1 > val2);
+ }
+ if (maxcode <= FLOAT) {
+ float val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).floatValue();
+ float val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).floatValue();
+ return boxToBoolean(val1 > val2);
+ }
+ if (maxcode <= DOUBLE) {
+ double val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).doubleValue();
+ double val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).doubleValue();
+ return boxToBoolean(val1 > val2);
+ }
+ throw new NoSuchMethodException();
+ }
+
+ /** arg.toChar */
+ public static Character toCharacter(Object arg) throws NoSuchMethodException {
+ if (arg instanceof Character) return (Character)arg;
+ if (arg instanceof Byte) return boxToCharacter((char)unboxToByte(arg));
+ if (arg instanceof Short) return boxToCharacter((char)unboxToShort(arg));
+ if (arg instanceof Integer) return boxToCharacter((char)unboxToInt(arg));
+ if (arg instanceof Long) return boxToCharacter((char)unboxToLong(arg));
+ if (arg instanceof Float) return boxToCharacter((char)unboxToFloat(arg));
+ if (arg instanceof Double) return boxToCharacter((char)unboxToDouble(arg));
+ throw new NoSuchMethodException();
+ }
+
+ /** arg.toByte */
+ public static Byte toByte(Object arg) throws NoSuchMethodException {
+ if (arg instanceof Character) return boxToByte((byte)unboxToChar(arg));
+ if (arg instanceof Byte) return (Byte)arg;
+ if (arg instanceof Short) return boxToByte((byte)unboxToShort(arg));
+ if (arg instanceof Integer) return boxToByte((byte)unboxToInt(arg));
+ if (arg instanceof Long) return boxToByte((byte)unboxToLong(arg));
+ if (arg instanceof Float) return boxToByte((byte)unboxToFloat(arg));
+ if (arg instanceof Double) return boxToByte((byte)unboxToDouble(arg));
+ throw new NoSuchMethodException();
+ }
+
+ /** arg.toShort */
+ public static Short toShort(Object arg) throws NoSuchMethodException {
+ if (arg instanceof Character) return boxToShort((short)unboxToChar(arg));
+ if (arg instanceof Byte) return boxToShort((short)unboxToByte(arg));
+ if (arg instanceof Short) return (Short)arg;
+ if (arg instanceof Integer) return boxToShort((short)unboxToInt(arg));
+ if (arg instanceof Long) return boxToShort((short)unboxToLong(arg));
+ if (arg instanceof Float) return boxToShort((short)unboxToFloat(arg));
+ if (arg instanceof Double) return boxToShort((short)unboxToDouble(arg));
+ throw new NoSuchMethodException();
+ }
+
+ /** arg.toInt */
+ public static Integer toInteger(Object arg) throws NoSuchMethodException {
+ if (arg instanceof Character) return boxToInteger((int)unboxToChar(arg));
+ if (arg instanceof Byte) return boxToInteger((int)unboxToByte(arg));
+ if (arg instanceof Short) return boxToInteger((int)unboxToShort(arg));
+ if (arg instanceof Integer) return (Integer)arg;
+ if (arg instanceof Long) return boxToInteger((int)unboxToLong(arg));
+ if (arg instanceof Float) return boxToInteger((int)unboxToFloat(arg));
+ if (arg instanceof Double) return boxToInteger((int)unboxToDouble(arg));
+ throw new NoSuchMethodException();
+ }
+
+ /** arg.toLong */
+ public static Long toLong(Object arg) throws NoSuchMethodException {
+ if (arg instanceof Character) return boxToLong((long)unboxToChar(arg));
+ if (arg instanceof Byte) return boxToLong((long)unboxToByte(arg));
+ if (arg instanceof Short) return boxToLong((long)unboxToShort(arg));
+ if (arg instanceof Integer) return boxToLong((long)unboxToInt(arg));
+ if (arg instanceof Long) return (Long)arg;
+ if (arg instanceof Float) return boxToLong((long)unboxToFloat(arg));
+ if (arg instanceof Double) return boxToLong((long)unboxToDouble(arg));
+ throw new NoSuchMethodException();
+ }
+
+ /** arg.toFloat */
+ public static Float toFloat(Object arg) throws NoSuchMethodException {
+ if (arg instanceof Character) return boxToFloat((float)unboxToChar(arg));
+ if (arg instanceof Byte) return boxToFloat((float)unboxToByte(arg));
+ if (arg instanceof Short) return boxToFloat((float)unboxToShort(arg));
+ if (arg instanceof Integer) return boxToFloat((float)unboxToInt(arg));
+ if (arg instanceof Long) return boxToFloat((float)unboxToLong(arg));
+ if (arg instanceof Float) return (Float)arg;
+ if (arg instanceof Double) return boxToFloat((float)unboxToDouble(arg));
+ throw new NoSuchMethodException();
+ }
+
+ /** arg.toDouble */
+ public static Double toDouble(Object arg) throws NoSuchMethodException {
+ if (arg instanceof Character) return boxToDouble((double)unboxToChar(arg));
+ if (arg instanceof Byte) return boxToDouble((double)unboxToByte(arg));
+ if (arg instanceof Short) return boxToDouble((double)unboxToShort(arg));
+ if (arg instanceof Integer) return boxToDouble((double)unboxToInt(arg));
+ if (arg instanceof Long) return boxToDouble((double)unboxToLong(arg));
+ if (arg instanceof Float) return boxToDouble((double)unboxToFloat(arg));
+ if (arg instanceof Double) return (Double)arg;
+ throw new NoSuchMethodException();
+ }
+
+}
diff --git a/src/library/scala/runtime/ByteRef.java b/src/library/scala/runtime/ByteRef.java
new file mode 100644
index 0000000000..1e67f18a1f
--- /dev/null
+++ b/src/library/scala/runtime/ByteRef.java
@@ -0,0 +1,21 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2008, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+
+package scala.runtime;
+
+
+public class ByteRef implements java.io.Serializable {
+ private static final long serialVersionUID = -100666928446877072L;
+
+ public byte elem;
+ public ByteRef(byte elem) { this.elem = elem; }
+ public String toString() { return Byte.toString(elem); }
+}
diff --git a/src/library/scala/runtime/CharRef.java b/src/library/scala/runtime/CharRef.java
new file mode 100644
index 0000000000..a64b59dfd7
--- /dev/null
+++ b/src/library/scala/runtime/CharRef.java
@@ -0,0 +1,21 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2008, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+
+package scala.runtime;
+
+
+public class CharRef implements java.io.Serializable {
+ private static final long serialVersionUID = 6537214938268005702L;
+
+ public char elem;
+ public CharRef(char elem) { this.elem = elem; }
+ public String toString() { return Character.toString(elem); }
+}
diff --git a/src/library/scala/runtime/DoubleRef.java b/src/library/scala/runtime/DoubleRef.java
new file mode 100644
index 0000000000..086429e03e
--- /dev/null
+++ b/src/library/scala/runtime/DoubleRef.java
@@ -0,0 +1,21 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2008, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+
+package scala.runtime;
+
+
+public class DoubleRef implements java.io.Serializable {
+ private static final long serialVersionUID = 8304402127373655534L;
+
+ public double elem;
+ public DoubleRef(double elem) { this.elem = elem; }
+ public String toString() { return Double.toString(elem); }
+}
diff --git a/src/library/scala/runtime/ExceptionHandling.java b/src/library/scala/runtime/ExceptionHandling.java
new file mode 100644
index 0000000000..0fcc1e2b1c
--- /dev/null
+++ b/src/library/scala/runtime/ExceptionHandling.java
@@ -0,0 +1,26 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+
+package scala.runtime;
+
+
+public abstract class ExceptionHandling {
+
+ public static Throwable tryCatch(Runnable runnable) {
+ try {
+ runnable.run();
+ return null;
+ } catch (Throwable exception) {
+ return exception;
+ }
+ }
+
+}
diff --git a/src/library/scala/runtime/FloatRef.java b/src/library/scala/runtime/FloatRef.java
new file mode 100644
index 0000000000..2160f54977
--- /dev/null
+++ b/src/library/scala/runtime/FloatRef.java
@@ -0,0 +1,21 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2008, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+
+package scala.runtime;
+
+
+public class FloatRef implements java.io.Serializable {
+ private static final long serialVersionUID = -5793980990371366933L;
+
+ public float elem;
+ public FloatRef(float elem) { this.elem = elem; }
+ public String toString() { return Float.toString(elem); }
+}
diff --git a/src/library/scala/runtime/IntRef.java b/src/library/scala/runtime/IntRef.java
new file mode 100644
index 0000000000..3ad9ad69e5
--- /dev/null
+++ b/src/library/scala/runtime/IntRef.java
@@ -0,0 +1,21 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2008, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+
+package scala.runtime;
+
+
+public class IntRef implements java.io.Serializable {
+ private static final long serialVersionUID = 1488197132022872888L;
+
+ public int elem;
+ public IntRef(int elem) { this.elem = elem; }
+ public String toString() { return Integer.toString(elem); }
+}
diff --git a/src/library/scala/runtime/LongRef.java b/src/library/scala/runtime/LongRef.java
new file mode 100644
index 0000000000..31b9cd3b55
--- /dev/null
+++ b/src/library/scala/runtime/LongRef.java
@@ -0,0 +1,21 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2008, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+
+package scala.runtime;
+
+
+public class LongRef implements java.io.Serializable {
+ private static final long serialVersionUID = -3567869820105829499L;
+
+ public long elem;
+ public LongRef(long elem) { this.elem = elem; }
+ public String toString() { return Long.toString(elem); }
+}
diff --git a/src/library/scala/runtime/ObjectRef.java b/src/library/scala/runtime/ObjectRef.java
new file mode 100644
index 0000000000..1154c1dd26
--- /dev/null
+++ b/src/library/scala/runtime/ObjectRef.java
@@ -0,0 +1,21 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2008, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+
+package scala.runtime;
+
+
+public class ObjectRef implements java.io.Serializable {
+ private static final long serialVersionUID = -9055728157600312291L;
+
+ public Object elem;
+ public ObjectRef(Object elem) { this.elem = elem; }
+ public String toString() { return "" + elem; }
+}
diff --git a/src/library/scala/runtime/RichChar.scala b/src/library/scala/runtime/RichChar.scala
new file mode 100644
index 0000000000..d06aa62a57
--- /dev/null
+++ b/src/library/scala/runtime/RichChar.scala
@@ -0,0 +1,71 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+
+package scala.runtime
+
+
+import java.lang.Character
+import Predef.NoSuchElementException
+
+/** + * For example, in the following code + *
+ *+ * object test extends Application { + * Console.println(+ *'\40' .isWhitespace) + * Console.println('\011'.isWhitespace) + * Console.println('1'.asDigit == 1) + * Console.println('A'.asDigit == 10) + * }
+ * the implicit conversions are performed using the predefined view
+ * Predef.charWrapper
.
+ *
x
in radians.
+ */
+ def toRadians: Double = Math.toRadians(x)
+
+ /** Converts an angle measured in radians to an approximately equivalent
+ * angle measured in degrees.
+ *
+ * @param x angle, in radians
+ * @return the measurement of the angle x
in degrees.
+ */
+ def toDegrees: Double = Math.toDegrees(x)
+
+ // isNaN is provided by the implicit conversion to java.lang.Double
+ // def isNaN: Boolean = java.lang.Double.isNaN(x)
+ def isInfinity: Boolean = java.lang.Double.isInfinite(x)
+ def isPosInfinity: Boolean = isInfinity && x > 0.0
+ def isNegInfinity: Boolean = isInfinity && x < 0.0
+
+}
diff --git a/src/library/scala/runtime/RichFloat.scala b/src/library/scala/runtime/RichFloat.scala
new file mode 100644
index 0000000000..482ec3fbc0
--- /dev/null
+++ b/src/library/scala/runtime/RichFloat.scala
@@ -0,0 +1,56 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+
+package scala.runtime
+
+
+import Predef._
+
+final class RichFloat(x: Float) extends Proxy with Ordered[Float] {
+
+ // Proxy.self
+ def self: Any = x
+
+ // Ordered[Float].compare
+ //def compare(y: Float): Int = if (x < y) -1 else if (x > y) 1 else 0
+ def compare(y: Float): Int = java.lang.Float.compare(x, y)
+
+ def min(y: Float) = Math.min(x, y)
+ def max(y: Float) = Math.max(x, y)
+ def abs: Float = Math.abs(x)
+
+ def round: Int = Math.round(x)
+ def ceil: Float = Math.ceil(x).toFloat
+ def floor: Float = Math.floor(x).toFloat
+
+ /** Converts an angle measured in degrees to an approximately equivalent
+ * angle measured in radians.
+ *
+ * @param x an angle, in degrees
+ * @return the measurement of the angle x
in radians.
+ */
+ def toRadians: Float = Math.toRadians(x).toFloat
+
+ /** Converts an angle measured in radians to an approximately equivalent
+ * angle measured in degrees.
+ *
+ * @param x angle, in radians
+ * @return the measurement of the angle x
in degrees.
+ */
+ def toDegrees: Float = Math.toDegrees(x).toFloat
+
+ // isNaN is provided by the implicit conversion to java.lang.Float
+ // def isNaN: Boolean = java.lang.Float.isNaN(x)
+ def isInfinity: Boolean = java.lang.Float.isInfinite(x)
+ def isPosInfinity: Boolean = isInfinity && x > 0.0f
+ def isNegInfinity: Boolean = isInfinity && x < 0.0f
+
+}
diff --git a/src/library/scala/runtime/RichInt.scala b/src/library/scala/runtime/RichInt.scala
new file mode 100644
index 0000000000..73b13afa28
--- /dev/null
+++ b/src/library/scala/runtime/RichInt.scala
@@ -0,0 +1,39 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2008, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+
+package scala.runtime
+
+
+final class RichInt(start: Int) extends Proxy with Ordered[Int] {
+
+ // Proxy
+ def self: Any = start
+
+ // Ordered[Int]
+ def compare(that: Int): Int = if (start < that) -1 else if (start > that) 1 else 0
+
+ /** See Iterator.range
. */
+ def until(end: Int): Range = new Range(start, end, 1)
+
+ /** See Iterator.range
. */
+ def until(end: Int, step: Int): Range = new Range(start, end, step)
+
+ /** like until
, but includes the last index */
+ 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
+ def abs: Int = if (start < 0) -start else start
+
+ def toBinaryString: String = java.lang.Integer.toBinaryString(start)
+ def toHexString: String = java.lang.Integer.toHexString(start)
+ def toOctalString: String = java.lang.Integer.toOctalString(start)
+}
diff --git a/src/library/scala/runtime/RichLong.scala b/src/library/scala/runtime/RichLong.scala
new file mode 100644
index 0000000000..7e835f10c3
--- /dev/null
+++ b/src/library/scala/runtime/RichLong.scala
@@ -0,0 +1,30 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2008, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+
+package scala.runtime
+
+
+final class RichLong(x: Long) extends Proxy with Ordered[Long] {
+
+ // Proxy.self
+ def self: Any = x
+
+ // Ordered[Long].compare
+ def compare(y: Long): Int = if (x < y) -1 else if (x > y) 1 else 0
+
+ def min(y: Long): Long = if (x < y) x else y
+ def max(y: Long): Long = if (x > y) x else y
+ def abs: Long = if (x < 0) -x else x
+
+ def toBinaryString: String = java.lang.Long.toBinaryString(x)
+ def toHexString: String = java.lang.Long.toHexString(x)
+ def toOctalString: String = java.lang.Long.toOctalString(x)
+}
diff --git a/src/library/scala/runtime/RichString.scala b/src/library/scala/runtime/RichString.scala
new file mode 100644
index 0000000000..192cf62ebb
--- /dev/null
+++ b/src/library/scala/runtime/RichString.scala
@@ -0,0 +1,245 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2008, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+
+package scala.runtime
+
+import Predef._
+import scala.util.matching.Regex
+
+final class RichString(val self: String) extends Proxy with CharSequence with RandomAccessSeq[Char] with Ordered[String] {
+ import RichString._
+ override def apply(n: Int) = self charAt n
+ override def length = self.length
+ override def toString = self
+ override def mkString = self
+
+ override def slice(from: Int, until: Int): RichString = {
+ val len = self.length
+ new RichString(
+ if (from >= until || from >= len)
+ ""
+ else {
+ val from0 = if (from < 0) 0 else from
+ val until0 = if (until > len) len else until
+ self.substring(from0, until0)
+ }
+ )
+ }
+
+ //override def ++ [B >: A](that: Iterable[B]): Seq[B] = {
+ override def ++[B >: Char](that: Iterable[B]): RandomAccessSeq[B] = that match {
+ case that: RichString => new RichString(self + that.self)
+ case that => super.++(that)
+ }
+
+ override def take(until: Int): RichString = slice(0, until)
+
+ override def drop(from: Int): RichString = slice(from, self.length)
+
+ override def startsWith[B](that: Seq[B]) = that match {
+ case that: RichString => self startsWith that.self
+ case that => super.startsWith(that)
+ }
+
+ override def endsWith[B](that: Seq[B]) = that match {
+ case that: RichString => self endsWith that.self
+ case that => super.endsWith(that)
+ }
+
+ override def indexOf[B](that: Seq[B]) = that match {
+ case that: RichString => self indexOf that.self
+ case that => super.indexOf(that)
+ }
+
+ override def containsSlice[B](that: Seq[B]) = that match {
+ case that: RichString => self contains that.self
+ case that => super.containsSlice(that)
+ }
+
+ override def reverse: RichString = {
+ val buf = new StringBuilder
+ var i = self.length - 1
+ while (i >= 0) {
+ buf append (self charAt i)
+ i -= 1
+ }
+ new RichString(buf.toString)
+ }
+
+ def charAt(index: Int) = self.charAt(index)
+
+ def subSequence(start: Int, end: Int): CharSequence =
+ new RichString(self.substring(start, end))
+
+ /** return n times the current string
+ */
+ def * (n: Int): String = {
+ val buf = new StringBuilder
+ for (i <- 0 until n) buf append self
+ buf.toString
+ }
+
+ override def compare(other: String) = self compareTo other
+
+ private def isLineBreak(c: Char) = c == LF || c == FF
+
+ /** + * Strip trailing line end character from this string if it has one. + * A line end character is one of + *
+ *+ * If a line feed character LF is preceded by a carriage return CR + * (0x0D hex), the CR character is also stripped (Windows convention). + *
+ */ + def stripLineEnd: String = { + val len = self.length + if (len == 0) self + else { + val last = apply(len - 1) + if (isLineBreak(last)) + self.substring(0, if (last == LF && len >= 2 && apply(len - 2) == CR) len - 2 else len - 1) + else + self + } + } + + /**+ * Return all lines in this string in an iterator, including trailing + * line end characters. + *
+ *+ * The number of strings returned is one greater than the number of line + * end characters in this string. For an empty string, a single empty + * line is returned. A line end character is one of + *
+ *.stripLineEnd
to all lines
+ * returned by linesWithSeparators
.
+ */
+ def lines: Iterator[String] =
+ linesWithSeparators map (line => new RichString(line).stripLineEnd)
+
+ /** Returns this string with first character converted to upper case */
+ def capitalize: String =
+ if (self == null) null
+ else if (self.length == 0) ""
+ else {
+ val chars = self.toCharArray
+ chars(0) = chars(0).toUpperCase
+ new String(chars)
+ }
+
+ /** + * For every line in this string: + *
+ *
+ * Strip a leading prefix consisting of blanks or control characters
+ * followed by marginChar
from the line.
+ *
+ */
+ def stripMargin(marginChar: Char): String = {
+ val buf = new StringBuilder
+ for (line <- linesWithSeparators) {
+ val len = line.length
+ var index = 0
+ while (index < len && line.charAt(index) <= ' ') index += 1
+ buf append
+ (if (index < len && line.charAt(index) == marginChar) line.substring(index + 1) else line)
+ }
+ buf.toString
+ }
+
+ /** + * For every line in this string: + *
+ *
+ * Strip a leading prefix consisting of blanks or control characters
+ * followed by |
from the line.
+ *
+ */
+ def stripMargin: String = stripMargin('|')
+
+ // NB. "\\Q" + '\\' + "\\E" works on Java 1.5 and newer, but not on Java 1.4
+ private def escape(ch: Char): String = ch match {
+ case '\\' => "\\\\"
+ case _ => "\\Q"+ch+"\\E"
+ }
+
+ @throws(classOf[java.util.regex.PatternSyntaxException])
+ def split(separator: Char): Array[String] = self.split(escape(separator))
+
+ @throws(classOf[java.util.regex.PatternSyntaxException])
+ def split(separators: Array[Char]): Array[String] = {
+ val re = separators.foldLeft("[")(_+escape(_)) + "]"
+ self.split(re)
+ }
+
+ /** You can follow a string with `.r', turning
+ * it into a Regex. E.g.
+ *
+ * """A\w*""".r is the regular expression for identifiers starting with `A'.
+ */
+ def r: Regex = new Regex(self)
+
+ def toBoolean: Boolean = parseBoolean(self)
+ def toByte: Byte = java.lang.Byte.parseByte(self)
+ def toShort: Short = java.lang.Short.parseShort(self)
+ def toInt: Int = java.lang.Integer.parseInt(self)
+ def toLong: Long = java.lang.Long.parseLong(self)
+ def toFloat: Float = java.lang.Float.parseFloat(self)
+ def toDouble: Double = java.lang.Double.parseDouble(self)
+
+ override def toArray: Array[Char] = {
+ val result = new Array[Char](length)
+ self.getChars(0, length, result, 0)
+ result
+ }
+}
+
+object RichString {
+ // just statics for rich string.
+ private final val LF: Char = 0x0A
+ private final val FF: Char = 0x0C
+ private final val CR: Char = 0x0D
+ private final val SU: Char = 0x1A
+
+ private def parseBoolean(s: String): Boolean =
+ if (s != null) s.toLowerCase match {
+ case "true" => true
+ case "false" => false
+ case _ => throw new NumberFormatException("For input string: \""+s+"\"")
+ }
+ else
+ throw new NumberFormatException("For input string: \"null\"")
+}
diff --git a/src/library/scala/runtime/ShortRef.java b/src/library/scala/runtime/ShortRef.java
new file mode 100644
index 0000000000..b471056260
--- /dev/null
+++ b/src/library/scala/runtime/ShortRef.java
@@ -0,0 +1,20 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2008, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+
+package scala.runtime;
+
+
+public class ShortRef implements java.io.Serializable {
+ private static final long serialVersionUID = 4218441291229072313L;
+
+ public short elem;
+ public ShortRef(short elem) { this.elem = elem; }
+}
diff --git a/src/library/scala/runtime/StringAdd.scala b/src/library/scala/runtime/StringAdd.scala
new file mode 100644
index 0000000000..272e2cbb08
--- /dev/null
+++ b/src/library/scala/runtime/StringAdd.scala
@@ -0,0 +1,41 @@
+/* *\
+** ________ ___ __ ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ |_| **
+** **
+\* */
+
+// $Id$
+
+
+package scala.runtime
+
+
+import Predef._
+
+object StringAdd {
+ // Needed for the format hack. Can be removed once we drop 1.4
+ lazy val formatMethod: java.lang.reflect.Method = {
+ val paramTypes = Array[Class[T] forSome { type T }](classOf[String], classOf[Array[Object]])
+ classOf[String].getDeclaredMethod("format", paramTypes)
+ }
+}
+final class StringAdd(self: Any) {
+
+ def +(other: String) = self.toString + other
+
+ /** Returns string formatted according to given format
string.
+ * Format strings are as for String.format
+ * (@see java.lang.String.format).
+ * Only works on Java 1.5 or higher!
+ */
+ def formatted(format: String): String = {
+ // This should be:
+ // String.format(format, Array(self.asInstanceOf[Object]))
+ // However, the line above does not compile on Java 1.4 because String.format exists only in 1.5
+ // Therefore, we do the following hack:
+ val args = Array(self.asInstanceOf[Object])
+ StringAdd.formatMethod.invoke(null, Array[Object](format, args)).asInstanceOf[String]
+ }
+}
diff --git a/src/library/scala/util/DynamicVariable.scala b/src/library/scala/util/DynamicVariable.scala
new file mode 100644
index 0000000000..552e946250
--- /dev/null
+++ b/src/library/scala/util/DynamicVariable.scala
@@ -0,0 +1,84 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2008, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+
+package scala.util
+
+
+import Predef._
+import java.lang.InheritableThreadLocal
+
+/** + * DynamicVariables provide a binding mechanism where the current + * value is found through dynamic scope, but where + * access to the variable itself is resolved through static + * scope. + *
+ *
+ * The current value can be retrieved with the
+ * value
method. New values should be
+ * pushed using the withValue
method.
+ * Values pushed via withValue
only
+ * stay valid while the withValue
's
+ * second argument, a parameterless closure,
+ * executes. When the second argument finishes,
+ * the variable reverts to the previous value.
+ *
+ * Usage of withValue
looks like this:
+ *
+ *+ * someDynamicVariable.withValue(newValue) { + * // ... code called in here that calls value ... + * // ... will be given back the newValue ... + * } + *
+ * Each thread gets its own stack of bindings. When a + * new thread is created, the fluid gets a copy of + * the stack of bindings from the parent thread, and + * from then on the bindings for the new thread + * are independent of those for the original thread. + *
+ * + * @author Lex Spoon + * @version 1.1, 2007-5-21 + */ +class DynamicVariable[T](init: T) { + private val tl = new InheritableThreadLocal[T] { + override def initialValue = init.asInstanceOf[T with AnyRef] + } + + /** Retrieve the current value */ + def value: T = tl.get.asInstanceOf[T] + + + /** Set the value of the variable while executing the specified + * thunk. + * + * @param newval The value to which to set the fluid + * @param thunk The code to evaluate under the new setting + */ + def withValue[S](newval: T)(thunk: =>S): S = { + val oldval = value + tl.set(newval) + + try { thunk } finally { + tl.set(oldval) + } + } + + /** Change the currently bound value, discarding the old value. + * UsuallywithValue()
gives better semantics.
+ */
+ def value_=(newval: T) = { tl.set(newval) }
+
+ override def toString: String = "DynamicVariable(" + value +")"
+}
diff --git a/src/library/scala/util/Properties.scala b/src/library/scala/util/Properties.scala
new file mode 100644
index 0000000000..2fa885dc3a
--- /dev/null
+++ b/src/library/scala/util/Properties.scala
@@ -0,0 +1,57 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2008, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.util
+
+/** A utility to load the library properties from a Java properties file
+ * included in the jar.
+ *
+ * @author Stephane Micheloud
+ */
+object Properties {
+
+ /** The name of the properties file */
+ private val propFilename = "/library.properties"
+
+ /** The loaded properties */
+ private val props = {
+ val props = new java.util.Properties
+ val stream = classOf[Application].getResourceAsStream(propFilename)
+ if (stream != null)
+ props.load(stream)
+ props
+ }
+
+ /** The version number of the jar this was loaded from, or
+ * "(unknown)" if it cannot be determined.
+ */
+ val versionString: String = {
+ val defaultString = "(unknown)"
+ "version " + props.getProperty("version.number")
+ }
+
+ val copyrightString: String = {
+ val defaultString = "(c) 2002-2008 LAMP/EPFL"
+ props.getProperty("copyright.string", defaultString)
+ }
+
+ val encodingString: String = {
+ val defaultString = "UTF8" //"ISO-8859-1"
+ props.getProperty("file.encoding", defaultString)
+ }
+
+ private val writer = new java.io.PrintWriter(Console.err, true)
+
+ val versionMsg = "Scala library " + versionString + " -- " + copyrightString
+
+ def main(args: Array[String]) {
+ writer.println(versionMsg)
+ }
+}
diff --git a/src/library/scala/util/matching/Regex.scala b/src/library/scala/util/matching/Regex.scala
new file mode 100644
index 0000000000..32fc300bf1
--- /dev/null
+++ b/src/library/scala/util/matching/Regex.scala
@@ -0,0 +1,274 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2007-2008, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+
+package scala.util.matching
+
+import java.util.regex.{Pattern, Matcher}
+
+/** This class provides methods for creating and using regular expressions.
+ * It is based on the regular expressions of the JDK since 1.4.
+ *
+ * @author Thibaud Hottelier
+ * @author Philipp Haller
+ * @author Martin Odersky
+ * @version 1.1, 29/01/2008
+ *
+ * @param regex A string representing a regular expression
+ * @param groupNames A mapping from names to indices in capture groups
+ */
+class Regex(regex: String, groupNames: String*) {
+
+ import Regex._
+
+ /** The compiled pattern */
+ val pattern = Pattern.compile(regex)
+
+ /** Tries to match target (whole match) and returns
+ * the matches.
+ *
+ * @param target The string to match
+ * @return The matches
+ */
+ def unapplySeq(target: Any): Option[List[String]] = target match {
+ case s: java.lang.CharSequence =>
+ val m = pattern.matcher(s)
+ if (m.matches) Some((1 to m.groupCount).toList map m.group)
+ else None
+ case Match(s) =>
+ unapplySeq(s)
+ case _ =>
+ None
+ }
+
+ /** Return all matches of this regexp in given character sequence as an iterator
+ */
+ def findAllIn(source: CharSequence) = new Regex.MatchIterator(source, this, groupNames)
+
+ /** Return optionally first matching string of this regexp in given character sequence,
+ * None if it does not exist.
+ */
+ def findFirstIn(source: CharSequence): Option[String] = {
+ val m = pattern.matcher(source)
+ if (m.find) Some(m.group) else None
+ }
+
+ /** Return optionally first match of this regexp in given character sequence,
+ * None if it does not exist.
+ */
+ def findFirstMatchIn(source: CharSequence): Option[Match] = {
+ val m = pattern.matcher(source)
+ if (m.find) Some(new Match(source, m, groupNames)) else None
+ }
+
+ /** Return optionally match of this regexp at the beginning of the
+ * given character sequence, or None if regexp matches no prefix
+ * of the character sequence.
+ */
+ def findPrefixOf(source: CharSequence): Option[String] = {
+ val m = pattern.matcher(source)
+ if (m.lookingAt) Some(m.group) else None
+ }
+
+ /** Return optionally match of this regexp at the beginning of the
+ * given character sequence, or None if regexp matches no prefix
+ * of the character sequence.
+ */
+ def findPrefixMatchOf(source: CharSequence): Option[Match] = {
+ val m = pattern.matcher(source)
+ if (m.lookingAt) Some(new Match(source, m, groupNames)) else None
+ }
+
+ /** Replaces all matches by a string.
+ *
+ * @param target The string to match
+ * @param replacement The string that will replace each match
+ * @return The resulting string
+ */
+ def replaceAllIn(target: CharSequence, replacement: String): String = {
+ val m = pattern.matcher(target)
+ m.replaceAll(replacement)
+ }
+
+ /** Replaces the first match by a string.
+ *
+ * @param target The string to match
+ * @param replacement The string that will replace the match
+ * @return The resulting string
+ */
+ def replaceFirstIn(target: CharSequence, replacement: String): String = {
+ val m = pattern.matcher(target)
+ m.replaceFirst(replacement)
+ }
+
+ /** The string defining the regular expression */
+ override def toString = regex
+}
+
+/** This object defines inner classes that describe
+ * regex matches. The class hirrachy is as follows.
+ *
+ * MatchData
+ * | \
+ * MatchIterator Match
+ */
+object Regex {
+
+ /** This class provides methods to access
+ * the details of a match.
+ */
+ trait MatchData {
+
+ /** The source from where the match originated */
+ val source: CharSequence
+
+ /** The names of the groups, or some empty sequence if one defined */
+ val groupNames: Seq[String]
+
+ /** The index of the first matched character */
+ def start: Int
+
+ /** The index of the first matched character in group i
*/
+ def start(i: Int): Int
+
+ /** The index of the last matched character */
+ def end: Int
+
+ /** The number of subgroups */
+ def groupCount: Int
+
+ /** The index following the last matched character in group i
*/
+ def end(i: Int): Int
+
+ /** The matched string */
+ def matched: String = source.subSequence(start, end).toString
+
+ /** The matched string in group i
*/
+ def group(i: Int): String = source.subSequence(start(i), end(i)).toString
+
+ /** All matched subgroups, i.e. not including group(0) */
+ def subgroups: List[String] = (1 to groupCount).toList map group
+
+ /** The char sequence before first character of match */
+ def before: CharSequence = source.subSequence(0, start)
+
+ /** The char sequence before first character of match in group i
*/
+ def before(i: Int): CharSequence = source.subSequence(0, start(i))
+
+ /** Returns char sequence after last character of match */
+ def after: CharSequence = source.subSequence(end)
+
+ /** The char sequence after last character of match in group i
*/
+ def after(i: Int): CharSequence = source.subSequence(end(i))
+
+ private lazy val nameToIndex: Map[String, Int] = Map() ++ ("" :: groupNames.toList).zipWithIndex
+
+ /** Returns the group with given name
+ *
+ * @param id The group name
+ * @return The requested group
+ * @throws NoSuchElementException
if the requested
+ * group name is not defined
+ */
+ def group(id: String): String = nameToIndex.get(id) match {
+ case None => throw new NoSuchElementException("group name "+id+" not defined")
+ case Some(index) => group(index)
+ }
+
+ /** The matched string; equivalent to matched.toString
*/
+ override def toString = matched
+
+ }
+
+ /** A case class for a succesful match.
+ */
+ class Match(val source: CharSequence,
+ matcher: Matcher,
+ val groupNames: Seq[String]) extends MatchData {
+
+ /** The index of the first matched character */
+ val start = matcher.start
+
+ /** The index following the last matched character */
+ val end = matcher.end
+
+ /** The number of subgroups */
+ def groupCount = matcher.groupCount
+
+ private lazy val starts: Array[Int] =
+ ((1 to groupCount) map matcher.start).toArray
+ private lazy val ends: Array[Int] =
+ ((1 to groupCount) map matcher.end).toArray
+
+ /** The index of the first matched character in group i
*/
+ def start(i: Int) = starts(i)
+
+ /** The index following the last matched character in group i
*/
+ def end(i: Int) = ends(i)
+
+ /** The match itself with matcher-dependent lazy vals forced,
+ * so that match is valid even once matcher is advanced
+ */
+ def force: this.type = { starts; ends; this }
+ }
+
+ /** An extractor object for Matches, yielding the matched string */
+ object Match {
+ def unapply(m: Match): Some[String] = Some(m.matched)
+ }
+
+ /** A class to step through a sequence of regex matches
+ */
+ class MatchIterator(val source: CharSequence, val regex: Regex, val groupNames: Seq[String])
+ extends Iterator[String] with MatchData { self =>
+
+ private val matcher = regex.pattern.matcher(source)
+ private var nextSeen = false
+
+ /** Is there another match? */
+ def hasNext: Boolean = {
+ if (!nextSeen) nextSeen = matcher.find()
+ nextSeen
+ }
+
+ /** The next matched substring of `source' */
+ def next: String = {
+ if (!hasNext) throw new NoSuchElementException
+ nextSeen = false
+ matcher.group
+ }
+
+ override def toString = super[Iterator].toString
+
+ /** The index of the first matched character */
+ def start: Int = matcher.start
+
+ /** The index of the first matched character in group i
*/
+ def start(i: Int): Int = matcher.start(i)
+
+ /** The index of the last matched character */
+ def end: Int = matcher.end
+
+ /** The index following the last matched character in group i
*/
+ def end(i: Int): Int = matcher.end(i)
+
+ /** The number of subgroups */
+ def groupCount = matcher.groupCount
+
+ /** Convert to an iterator that yields MatchData elements instead of Strings */
+ def matchData = new Iterator[Match] {
+ def hasNext = self.hasNext
+ def next = { self.next; new Match(source, matcher, groupNames).force }
+ }
+ }
+}
+
+
+
diff --git a/src/library/scala/util/parsing/CharInputStreamIterator.scala b/src/library/scala/util/parsing/CharInputStreamIterator.scala
new file mode 100644
index 0000000000..b58650e025
--- /dev/null
+++ b/src/library/scala/util/parsing/CharInputStreamIterator.scala
@@ -0,0 +1,52 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+
+package scala.util.parsing
+
+
+import java.io.InputStream
+import java.io.{IOException, EOFException}
+
+/** This class ...
+ *
+ * @author Burak Emir
+ * @version 1.0
+ *
+ * @deprecated use classes from
+ * scala.util.parsing.input
instead.
+ */
+@deprecated
+class CharInputStreamIterator(in: InputStream) extends Iterator[Char] {
+
+ private var ch: Int = _
+ private var chSet = false
+ private var error: IOException = null
+
+ private def lookahead() {
+ try {
+ ch = in.read(); chSet = ch >= 0
+ } catch {
+ case ex: EOFException => ch = -1
+ case ex: IOException => ch = 1; error = ex
+ }
+ }
+
+ def hasNext: Boolean = {
+ if (!chSet) lookahead()
+ chSet
+ }
+
+ def next(): Char = {
+ if (!chSet) lookahead()
+ chSet = false
+ ch.asInstanceOf[Char]
+ }
+}
diff --git a/src/library/scala/util/parsing/combinator/RegexParsers.scala b/src/library/scala/util/parsing/combinator/RegexParsers.scala
new file mode 100644
index 0000000000..37b5f1d10c
--- /dev/null
+++ b/src/library/scala/util/parsing/combinator/RegexParsers.scala
@@ -0,0 +1,84 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.util.parsing.combinator
+
+import java.util.regex.Pattern
+import scala.util.matching.Regex
+import scala.util.parsing.input._
+
+trait RegexParsers extends Parsers {
+
+ type Elem = Char
+
+ protected val whiteSpace = """\s+""".r
+
+ def skipWhitespace = whiteSpace.toString.length > 0
+
+ protected def handleWhiteSpace(source: CharSequence, offset: Int): Int =
+ if (skipWhitespace)
+ (whiteSpace findPrefixMatchOf (source subSequence offset)) match {
+ case Some(matched) => offset + matched.end
+ case None => offset
+ }
+ else
+ offset
+
+ /** A parser that matches a literal string */
+ implicit def literal(s: String): Parser[String] = new Parser[String] {
+ def apply(in: Input) = {
+ val source = in.source
+ val offset = in.offset
+ val start = handleWhiteSpace(source, offset)
+ var i = 0
+ var j = start
+ while (i < s.length && source.isDefinedAt(j) && s.charAt(i) == source.charAt(j)) {
+ i += 1
+ j += 1
+ }
+ if (i == s.length)
+ Success(source.subSequence(start, j).toString, in.drop(j - offset))
+ else
+ Failure("`"+s+"' expected but `"+in.first+"' found", in.drop(start - offset))
+ }
+ }
+
+ /** A parser that matches a regex string */
+ implicit def regex(r: Regex): Parser[String] = new Parser[String] {
+ def apply(in: Input) = {
+ val source = in.source
+ val offset = in.offset
+ val start = handleWhiteSpace(source, offset)
+ (r findPrefixMatchOf (source subSequence start)) match {
+ case Some(matched) =>
+ Success(source.subSequence(start, start + matched.end).toString,
+ in.drop(start + matched.end - offset))
+ case None =>
+ Failure("string matching regex `+r+' expected but `"+in.first+"' found", in.drop(start - offset))
+ }
+ }
+ }
+
+ /** Parse some prefix of character sequence `in' with parser `p' */
+ def parse[T](p: Parser[T], in: CharSequence): ParseResult[T] =
+ p(new CharSequenceReader(in))
+
+ /** Parse some prefix of reader `in' with parser `p' */
+ def parse[T](p: Parser[T], in: Reader[Char]): ParseResult[T] =
+ p(in)
+
+ /** Parse all of character sequence `in' with parser `p' */
+ def parseAll[T](p: Parser[T], in: CharSequence): ParseResult[T] =
+ parse(phrase(p), in)
+
+ /** Parse all of reader `in' with parser `p' */
+ def parseAll[T](p: Parser[T], in: Reader[Char]): ParseResult[T] =
+ parse(phrase(p), in)
+}
diff --git a/src/library/scala/util/parsing/input/StreamReader.scala b/src/library/scala/util/parsing/input/StreamReader.scala
new file mode 100644
index 0000000000..f997590f18
--- /dev/null
+++ b/src/library/scala/util/parsing/input/StreamReader.scala
@@ -0,0 +1,74 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.util.parsing.input
+
+import java.io.BufferedReader
+
+/** An object to create a StreamReader from a java.io.Reader
.
+ *
+ * @param in the java.io.Reader
that provides the underlying
+ * stream of characters for this Reader.
+ *
+ * @author Miles Sabin
+ */
+object StreamReader {
+ final val EofCh = '\032'
+
+ def apply(in: java.io.Reader): StreamReader = {
+ new StreamReader(new LazyCharSequence(in), 0, 1)
+ }
+}
+
+/** A character array reader reads a stream of characters (keeping track of
+ * their positions) from an array.
+ *
+ * NOTE:
+ * StreamReaders do not really fulfill the new contract for readers, which
+ * requires a `source' CharSequence representing the full input.
+ * Instead source is treated line by line.
+ * As a consequence, regex matching cannot extend beyond a single lines
+ * when a StreamReader are used for input.
+ *
+ * @param bin the underlying java.io.BufferedReader
+ * @param sourceLine the line at column `col' in the stream
+ * @param line the 1-based line number of the character returned by `first'
+ * @param column the 1-based column number of the character returned by `first'
+ *
+ * @author Miles Sabin
+ */
+sealed class StreamReader(source: CharSequence, offset: Int, lnum: Int) extends CharSequenceReader(source, offset) {
+ import StreamReader._
+
+ override def rest: CharSequenceReader =
+ if (offset == source.length) this
+ else if (source(offset) == '\n') new StreamReader(source.subSequence(offset + 1), 0, lnum + 1)
+ else new StreamReader(source, offset + 1, lnum)
+
+ private def nextEol = {
+ var i = offset
+ while (i < source.length && source(i) != '\n' && source(i) != EofCh) i += 1
+ i
+ }
+
+ override def drop(n: Int): StreamReader = {
+ val eolPos = nextEol
+ if (eolPos < offset + n && eolPos < source.length)
+ new StreamReader(source.subSequence(eolPos + 1), 0, lnum + 1).drop(offset + n - (eolPos + 1))
+ else
+ new StreamReader(source, offset + n, lnum)
+ }
+
+ override def pos: Position = new Position {
+ def line = lnum
+ def column = offset + 1
+ def lineContents = source.subSequence(0, nextEol).toString
+ }
+}
diff --git a/src/library/scala/xml/Parsing.scala b/src/library/scala/xml/Parsing.scala
new file mode 100644
index 0000000000..9f2934a7b5
--- /dev/null
+++ b/src/library/scala/xml/Parsing.scala
@@ -0,0 +1,105 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+
+package scala.xml
+
+
+/** The object Parsing
...
+ *
+ * @author Burak Emir
+ * @version 1.0
+ *
+ * @deprecated use either parsing.TokenTests
or
+ * Utilty
(helper functions for parsing XML fragments).
+ */
+object Parsing {
+
+ /** (#x20 | #x9 | #xD | #xA)*/ + final def isSpace(ch: Char): Boolean = ch match { + case '\u0009' | '\u000A' | '\u000D' | '\u0020' => true + case _ => false + } + + /**
(#x20 | #x9 | #xD | #xA)+*/ + final def isSpace(cs: Seq[Char]): Boolean = { + val it = cs.elements + it.hasNext && it.forall { isSpace } + } + + /**
NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' + * | CombiningChar | Extender+ * + * see [4] and Appendix B of XML 1.0 specification + */ + def isNameChar(ch: Char) = isNameStart(ch) || (ch match { + case '.' | '-' | ':' => true + case _ => java.lang.Character.getType(ch).asInstanceOf[Byte] match { + case java.lang.Character.COMBINING_SPACING_MARK => true // Mc + case java.lang.Character.ENCLOSING_MARK => true // Me + case java.lang.Character.NON_SPACING_MARK => true // Mn + case java.lang.Character.MODIFIER_LETTER => true // Lm + case java.lang.Character.DECIMAL_DIGIT_NUMBER => true // Nd + case _ => false + } + }); + + /**
NameStart ::= ( Letter | '_' )+ * where Letter means in one of the Unicode general + * categories { Ll, Lu, Lo, Lt, Nl } + * + * We do not allow a name to start with ':'. + * see [3] and Appendix B of XML 1.0 specification + */ + def isNameStart(ch: Char) = + java.lang.Character.getType(ch).asInstanceOf[Byte] match { + case java.lang.Character.LOWERCASE_LETTER => true + case java.lang.Character.UPPERCASE_LETTER => true + case java.lang.Character.OTHER_LETTER => true + case java.lang.Character.TITLECASE_LETTER => true + case java.lang.Character.LETTER_NUMBER => true + case _ => ch == '_' + } + + /**
Name ::= ( Letter | '_' ) (NameChar)*+ * + * see [5] of XML 1.0 specification + */ + def isName(s: String): Boolean = + if (s.length() > 0) { + val z: Seq[Char] = s + val y = z.elements + if (isNameStart(y.next)) { + while (y.hasNext && isNameChar(y.next)) {} + !y.hasNext + } else false + } else false + + def isPubIDChar(c: Char) = c match { + case '\u0020' | '\u000D' | '\u000A' => true + case _ if + ('0' < c && c < '9')||('a' < c && c < 'z')||('A' < c && c < 'Z') => true + case '-' | '\''| '(' | ')' | '+' | ',' | '.' | '/' | ':' | '=' | + '?' | ';' | '!' | '*' | '#' | '@' | '$' | '_' | '%' => true + case _ => false + } + + def checkSysID(s: String): Boolean = + s.indexOf('"') == -1 || s.indexOf('\'') == -1 + + def checkPubID(s: String): Boolean = + if (s.length() > 0) { + val z:Seq[Char] = s + val y = z.elements + while (y.hasNext && isPubIDChar(y.next)) {} + !y.hasNext + } else true + +} diff --git a/src/library/scala/xml/PrettyPrinter.scala b/src/library/scala/xml/PrettyPrinter.scala new file mode 100644 index 0000000000..05c612ce81 --- /dev/null +++ b/src/library/scala/xml/PrettyPrinter.scala @@ -0,0 +1,308 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2007, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id$ + + +package scala.xml + +import scala.collection.Map + +/** Class for pretty printing. After instantiating, you can use the + * toPrettyXML methods to convert XML to a formatted string. The class + * can be reused to pretty print any number of XML nodes. + * + * @author Burak Emir + * @version 1.0 + * + * @param width the width to fit the output into + * @step indentation + */ +class PrettyPrinter( width:Int, step:Int ) { + + class BrokenException() extends java.lang.Exception + + class Item + case object Break extends Item { + override def toString() = "\\" + } + case class Box(col: Int, s: String) extends Item + case class Para(s: String) extends Item + + protected var items: List[Item] = Nil + + protected var cur = 0 + //protected var pmap:Map[String,String] = _ + + protected def reset() = { + cur = 0 + items = Nil + } + + /** Try to cut at whitespace. + * + * @param s ... + * @param ind ... + * @return ... + */ + protected def cut(s: String, ind: Int): List[Item] = { + val tmp = width - cur + if (s.length < tmp) + return List(Box(ind, s)) + val sb = new StringBuilder() + var i = s.indexOf(' ') + if (i > tmp || i == -1) throw new BrokenException() // cannot break + + var last: List[Int] = Nil + while (i != -1 && i < tmp) { + last = i::last + i = s.indexOf(' ', i+1) + } + var res: List[Item] = Nil + while (Nil != last) try { + val b = Box(ind, s.substring(0, last.head)) + cur = ind + res = b :: Break :: cut(s.substring(last.head, s.length), ind) + // backtrack + last = last.tail + } catch { + case _:BrokenException => last = last.tail + } + throw new BrokenException() + } + + /** Try to make indented box, if possible, else para. + * + * @param ind ... + * @param s ... + * @return ... + */ + protected def makeBox(ind: Int, s: String) = { + if (cur < ind) + cur == ind + if (cur + s.length > width) { // fits in this line + items = Box(ind, s) :: items + cur += s.length + } else try { + for (b <- cut(s, ind).elements) // break it up + items = b :: items + } catch { + case _:BrokenException => makePara(ind, s) // give up, para + } + } + + // dont respect indent in para, but afterwards + protected def makePara(ind: Int, s: String) = { + items = Break::Para(s)::Break::items + cur = ind + } + + // respect indent + protected def makeBreak() = { // using wrapping here... + items = Break :: items + cur = 0 + } + + /** + * @param n ... + * @return ... + */ + protected def leafTag(n: Node) = { + val sb = new StringBuilder("<") + n.nameToString(sb) + //Utility.appendPrefixedName( n.prefix, n.label, pmap, sb ); + n.attributes.toString(sb) + //Utility.attr2xml( n.scope, n.attributes, pmap, sb ); + sb.append("/>") + sb.toString() + } + + protected def startTag(n: Node, pscope: NamespaceBinding): (String, Int) = { + val sb = new StringBuilder("<") + n.nameToString(sb) //Utility.appendPrefixedName( n.prefix, n.label, pmap, sb ); + val i = sb.length + 1 + n.attributes.toString(sb) + n.scope.toString(sb, pscope) + sb.append('>') + (sb.toString(), i) + } + + protected def endTag(n: Node) = { + val sb = new StringBuilder("") + n.nameToString(sb) //Utility.appendPrefixedName( n.prefix, n.label, pmap, sb ); + sb.append('>') + sb.toString() + } + + protected def childrenAreLeaves(n: Node): Boolean = { + val it = n.child.elements + while (it.hasNext) + it.next match { + case _:Atom[_] | _:Comment | _:EntityRef | _:ProcInstr => + case _:Node => + return false + } + true + } + + protected def fits(test: String) = + test.length < width - cur + + /** @param tail: what we'd like to sqeeze in */ + protected def traverse(node: Node, pscope: NamespaceBinding, ind: Int): Unit = node match { + + case Text(s) if s.trim() == "" => + ; + case _:Atom[_] | _:Comment | _:EntityRef | _:ProcInstr => + makeBox( ind, node.toString().trim() ) + case g @ Group(xs) => + traverse(xs.elements, pscope, ind) + case _ => + val test = { + val sb = new StringBuilder() + Utility.toXML(node, pscope, sb, false) + if (node.attribute("http://www.w3.org/XML/1998/namespace", "space") == "preserve") + sb.toString() + else + TextBuffer.fromString(sb.toString()).toText(0)._data + } + if (childrenAreLeaves(node) && fits(test)) { + makeBox(ind, test) + } else { + val (stg, len2) = startTag(node, pscope) + val etg = endTag(node) + if (stg.length < width - cur) { // start tag fits + makeBox(ind, stg) + makeBreak() + traverse(node.child.elements, node.scope, ind + step) + makeBox(ind, etg) + } else if (len2 < width - cur) { + //
Text
implements an XML node for text (PCDATA).
+ * It is used in both non-bound and bound XML representations.
+ *
+ * @author Burak Emir
+ *
+ * @param text the text contained in this node, may not be null.
+ */
+case class Text(_data: String) extends Atom[String](_data) {
+
+ if (null == data)
+ throw new java.lang.NullPointerException("tried to construct Text with null")
+
+ final override def equals(x: Any) = x match {
+ case s:String => s.equals(data)
+ case s:Text => data == s.data
+ case _ => false
+ }
+
+ /** Returns text, with some characters escaped according to the XML
+ * specification.
+ *
+ * @param sb ...
+ * @return ...
+ */
+ override def toString(sb: StringBuilder) =
+ Utility.escape(data, sb)
+
+}
diff --git a/src/library/scala/xml/Unparsed.scala b/src/library/scala/xml/Unparsed.scala
new file mode 100644
index 0000000000..6bda932b89
--- /dev/null
+++ b/src/library/scala/xml/Unparsed.scala
@@ -0,0 +1,35 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+
+package scala.xml
+
+/** An XML node for unparsed content. It will be output verbatim, all bets
+ * are off regarding wellformedness etc.
+ *
+ * @author Burak Emir
+ * @param _data content in this node, may not be null.
+ */
+case class Unparsed(_data: String) extends Atom[String](_data) {
+
+ if (null == data)
+ throw new java.lang.NullPointerException("tried to construct Unparsed with null")
+
+ final override def equals(x: Any) = x match {
+ case s:String => s.equals(data)
+ case s:Text => data == s.data
+ case s:Unparsed => data == s.data
+ case _ => false
+ }
+
+ /** returns text, with some characters escaped according to XML spec */
+ override def toString(sb: StringBuilder) = sb append data
+
+}
diff --git a/src/library/scala/xml/XML.scala b/src/library/scala/xml/XML.scala
new file mode 100644
index 0000000000..675d4dcbb7
--- /dev/null
+++ b/src/library/scala/xml/XML.scala
@@ -0,0 +1,158 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+
+package scala.xml
+
+
+import Predef._
+import scala.xml.parsing.NoBindingFactoryAdapter
+import org.xml.sax.InputSource
+import java.io.{File, FileDescriptor, FileInputStream, FileOutputStream}
+import java.io.{InputStream, Reader, StringReader, Writer}
+
+/** The object XML
provides constants, and functions to load
+ * and save XML elements. Use this when data binding is not desired, i.e.
+ * when XML is handled using Symbol
nodes.
+ *
+ * @author Burak Emir
+ * @version 1.0, 25/04/2005
+ */
+object XML {
+
+ val xml = "xml"
+ val xmlns = "xmlns"
+ val namespace = "http://www.w3.org/XML/1998/namespace"
+ val preserve = "preserve"
+ val space = "space"
+ val lang = "lang"
+ val encoding = "ISO-8859-1"
+
+ // functions for generic xml loading, saving
+
+ /** loads XML from given file, using XML parser in JDK. */
+ final def loadFile(file: File): Elem =
+ new NoBindingFactoryAdapter().loadXML(new InputSource(
+ new FileInputStream(file)
+ ))
+
+ /** loads XML from given file descriptor, using XML parser in JDK.
+ *
+ * @param fileDesc ...
+ * @return ...
+ */
+ final def loadFile(fileDesc: FileDescriptor): Elem =
+ new NoBindingFactoryAdapter().loadXML(new InputSource(
+ new FileInputStream(fileDesc)
+ ))
+
+ /** loads XML from given file, using XML parser in JDK. */
+ final def loadFile(fileName: String): Elem =
+ new NoBindingFactoryAdapter().loadXML(new InputSource(
+ new FileInputStream(fileName)
+ ));
+
+ /** loads XML from given InputStream, using XML parser in JDK. */
+ final def load( is:InputStream ): Elem =
+ new NoBindingFactoryAdapter().loadXML(new InputSource(is))
+
+ /** loads XML from given Reader, using XML parser in JDK. */
+ final def load(reader: Reader): Elem =
+ new NoBindingFactoryAdapter().loadXML(new InputSource(reader))
+
+ /** loads XML from given sysID, using XML parser in JDK. */
+ final def load(sysID: String): Elem =
+ new NoBindingFactoryAdapter().loadXML(new InputSource(sysID))
+
+ /** loads XML from a given input source, using XML parser in JDK.
+ *
+ * @param source ...
+ * @return ...
+ */
+ final def load(source: InputSource): Elem =
+ new NoBindingFactoryAdapter().loadXML(source)
+
+ /** loads XML from a string, using XML parser in JDK. */
+ final def loadString(string: String): Elem =
+ load(new StringReader(string))
+
+ /** Saves XML to filename with encoding ISO-8859-1 without xml-decl without
+ * doctype
.
+ *
+ * @param filename ...
+ * @param node ...
+ */
+ final def save(filename: String, node: Node): Unit =
+ save(filename, node, encoding)
+
+ /** saves XML to filename with given encoding, without xml-decl without
+ * doctype
.
+ *
+ * @param filename ...
+ * @param node ...
+ * @param enc ...
+ */
+ final def save(filename: String, node: Node, enc: String): Unit =
+ saveFull(filename, node, enc, false, null);
+
+ /** saves a node to a file with given filename using encoding iso-8859-1
+ * optionally with xmldecl and doctype declaration.
+ *
+ * @param filename the filename
+ * @param node the xml node we want to write
+ * @param xmlDecl if true, write xml declaration
+ * @param doctype if not null, write doctype declaration
+ */
+ final def saveFull(filename: String, node: Node, xmlDecl: Boolean, doctype: dtd.DocType): Unit =
+ saveFull(filename, node, encoding, xmlDecl, doctype)
+
+ /** Saves a node to a file with given filename using given encoding
+ * optionally with xmldecl and doctype declaration.
+ *
+ * @param filename the filename
+ * @param node the xml node we want to write
+ * @param enc encoding to use
+ * @param xmlDecl if true, write xml declaration
+ * @param doctype if not null, write doctype declaration
+ */
+
+ final def saveFull(filename: String, node: Node, enc: String, xmlDecl: Boolean, doctype: dtd.DocType) {
+ var fos: FileOutputStream = null
+ var w: Writer = null
+ try {
+ // using NIO classes of JDK 1.4
+ import java.io.{FileOutputStream, Writer}
+ import java.nio.channels.{Channels, FileChannel}
+
+ fos = new FileOutputStream(filename)
+ w = Channels.newWriter(fos.getChannel(), enc)
+ write(w, node, enc, xmlDecl, doctype)
+ } finally {
+ w.close()
+ fos.close()
+ }
+ }
+
+ /** Writes the given node using writer, optionally with xml decl and doctype.
+ * It's the caller's responsibility to close the writer.
+ *
+ * @param w the writer
+ * @param node the xml node we want to write
+ * @param enc the string to be used in xmlDecl
+ * @param xmlDecl if true, write xml declaration
+ * @param doctype if not null, write doctype declaration
+ */
+ final def write(w: java.io.Writer, node: Node, enc: String, xmlDecl: Boolean, doctype: dtd.DocType) {
+ /* TODO: optimize by giving writer parameter to toXML*/
+ if (xmlDecl) w.write("\n")
+ if (doctype ne null) w.write( doctype.toString() + "\n")
+ w.write(Utility.toXML(node))
+ }
+}
diff --git a/src/library/scala/xml/include/XIncludeException.scala b/src/library/scala/xml/include/XIncludeException.scala
new file mode 100644
index 0000000000..5563d68c38
--- /dev/null
+++ b/src/library/scala/xml/include/XIncludeException.scala
@@ -0,0 +1,64 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.xml.include
+
+/**
+ *
+ * XIncludeException
is the generic superclass
+ * for all checked exceptions that may be thrown as a result
+ * of a violation of XInclude's rules.
+ *
+ * Constructs an XIncludeException
with the specified detail
+ * message. The error message string message
can later be
+ * retrieved by the {@link java.lang.Throwable#getMessage}
+ * method of class java.lang.Throwable
.
+ *
null
as its error detail message.
+ */
+ def this() = this(null)
+
+ private var rootCause: Throwable = null
+
+ /**
+ * When an IOException
, MalformedURLException
+ * or other generic exception is thrown while processing an XML document
+ * for XIncludes, it is customarily replaced
+ * by some form of XIncludeException
.
+ * This method allows you to store the original exception.
+ *
+ * @param nestedException the underlying exception which
+ caused the XIncludeException to be thrown
+ */
+ def setRootCause(nestedException: Throwable ) {
+ this.rootCause = nestedException
+ }
+
+ /**
+ * When an IOException
, MalformedURLException
+ * or other generic exception is thrown while processing an XML document
+ * for XIncludes, it is customarily replaced
+ * by some form of XIncludeException
.
+ * This method allows you to retrieve the original exception.
+ * It returns null if no such exception caused this XIncludeException
.
+ *
+ * @return Throwable the underlying exception which caused the
+ * XIncludeException
to be thrown
+ */
+ def getRootCause(): Throwable = this.rootCause
+
+}
diff --git a/src/library/scala/xml/include/parsing/ConstructingParser.scala b/src/library/scala/xml/include/parsing/ConstructingParser.scala
new file mode 100644
index 0000000000..b7c88c79ec
--- /dev/null
+++ b/src/library/scala/xml/include/parsing/ConstructingParser.scala
@@ -0,0 +1,67 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2006, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+
+package scala.xml.parsing
+
+import java.io.File
+
+import scala.io.Source
+
+object ConstructingParser {
+
+ def fromFile(inp: File, preserveWS: Boolean) = {
+ val p = new ConstructingParser(Source.fromFile(inp), preserveWS)
+ p.nextch
+ p
+ }
+
+ def fromSource(inp: Source, preserveWS: Boolean) = {
+ val p = new ConstructingParser(inp, preserveWS)
+ p.nextch
+ p
+ }
+}
+
+/** An xml parser. parses XML and invokes callback methods of a MarkupHandler.
+ * Don't forget to call next.ch on a freshly instantiated parser in order to
+ * initialize it. If you get the parser from the object method, initialization
+ * is already done for you.
+ *
+ *+object parseFromURL { + def main(args:Array[String]): Unit = { + val url = args(0); + val src = scala.io.Source.fromURL(url); + val cpa = scala.xml.parsing.ConstructingParser.fromSource(src, false); // fromSource initializes automatically + val doc = cpa.document(); + + // let's see what it is + val ppr = new scala.xml.PrettyPrinter(80,5); + val ele = doc.docElem; + Console.println("finished parsing"); + val out = ppr.format(ele); + Console.println(out); + } +} ++ */ +class ConstructingParser(inp: Source, presWS:Boolean) +extends ConstructingHandler +with ExternalSources +with MarkupParser { + + // default impl. of Logged + override def log(msg: String): Unit = {} + + val preserveWS = presWS + val input = inp +} + diff --git a/src/library/scala/xml/include/parsing/ExternalSources.scala b/src/library/scala/xml/include/parsing/ExternalSources.scala new file mode 100644 index 0000000000..cbfee413e6 --- /dev/null +++ b/src/library/scala/xml/include/parsing/ExternalSources.scala @@ -0,0 +1,82 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2007, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id$ + + +package scala.xml.parsing + +import java.net.URL + +import scala.io.Source + +/** + * @author Burak Emir + * @version 1.0 + */ +trait ExternalSources { self: ExternalSources with MarkupParser with MarkupHandler => + + private def externalSourceFromURL(url: URL): Source = { + import java.io.{BufferedReader, InputStreamReader} + val in = + new BufferedReader( + new InputStreamReader( + url.openStream())) + + //@todo: replace this hack with proper Source implementation + + val str = new StringBuilder() + var inputLine: String = null + + //while (inputLine = in.readLine()) != null) { + while ({inputLine = in.readLine(); inputLine} ne null) { + // Console.println(inputLine) // DEBUG + str.append(inputLine) + str.append('\n') // readable output + } + in.close() + + class MyClass extends Source { + + def newIter = new Iterator[Char] { + var i = -1 + private val len = str.length-1 + def hasNext = i < len + def next = { i += 1; str.charAt(i) } + } + + val iter = newIter + + def reset: Source = new MyClass + + /*override var*/ descr = url.toExternalForm() + } + + new MyClass + } + + /** ... + * + * @param systemId ... + * @return ... + */ + def externalSource(systemId: String): Source = { + if (systemId startsWith "http:") + return externalSourceFromURL(new URL(systemId)) + + var fileStr = input.descr + + if (input.descr startsWith "file:") { + fileStr = input.descr.substring(5, input.descr.length) + } else + fileStr = fileStr.substring(0, + fileStr.lastIndexOf(java.io.File.separator)+1) + Source.fromFile(fileStr + systemId) + } + +} diff --git a/src/library/scala/xml/include/parsing/FactoryAdapter.scala b/src/library/scala/xml/include/parsing/FactoryAdapter.scala new file mode 100644 index 0000000000..32c58c3ff6 --- /dev/null +++ b/src/library/scala/xml/include/parsing/FactoryAdapter.scala @@ -0,0 +1,321 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2007, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id$ + + +package scala.xml.parsing + +import java.io.{InputStream, Reader, File, FileDescriptor, FileInputStream} +import scala.collection.mutable.{HashMap,Stack} + +import org.xml.sax.{Attributes, InputSource} + +import org.xml.sax.SAXException +import org.xml.sax.SAXNotRecognizedException +import org.xml.sax.SAXNotSupportedException +import org.xml.sax.SAXParseException +import org.xml.sax.helpers.DefaultHandler + +import javax.xml.parsers.SAXParserFactory +import javax.xml.parsers.ParserConfigurationException +import javax.xml.parsers.SAXParser + + +/** SAX adapter class, for use with Java SAX parser. Keeps track of + * namespace bindings, without relying on namespace handling of the + * underlying SAX parser. + */ +abstract class FactoryAdapter extends DefaultHandler() { + + val buffer = new StringBuilder() + val attribStack = new Stack[MetaData] + val hStack = new Stack[Node] // [ element ] contains siblings + val tagStack = new Stack[String] + var scopeStack = new Stack[NamespaceBinding] + + var curTag : String = null + var capture: Boolean = false + + // abstract methods + + /** Tests if an XML element contains text. + * @return true if element named
localName
contains text.
+ */
+ def nodeContainsText(localName: String): Boolean // abstract
+
+ /** creates an new non-text(tree) node.
+ * @param elemName
+ * @param attribs
+ * @param chIter
+ * @return a new XML element.
+ */
+ def createNode(pre: String, elemName: String, attribs: MetaData,
+ scope: NamespaceBinding, chIter: List[Node]): Node //abstract
+
+ /** creates a Text node.
+ * @param text
+ * @return a new Text node.
+ */
+ def createText(text: String): Text // abstract
+
+ /** creates a new processing instruction node.
+ */
+ def createProcInstr(target: String, data: String): Seq[ProcInstr]
+
+ //
+ // ContentHandler methods
+ //
+
+ val normalizeWhitespace = false
+
+ /** Characters.
+ * @param ch
+ * @param offset
+ * @param length
+ */
+ override def characters(ch: Array[Char], offset: Int, length: Int): Unit = {
+ if (capture) {
+ if (normalizeWhitespace) {
+ // normalizing whitespace is not compliant, but useful */
+ var i: Int = offset
+ var ws = false
+ while (i < offset + length) {
+ if (ch(i).isWhitespace) {
+ if (!ws) {
+ buffer.append(' ')
+ ws = true
+ }
+ } else {
+ buffer.append(ch(i))
+ ws = false
+ }
+ i += 1
+ }
+ } else { // compliant:report every character
+ buffer.append(ch, offset, length)
+ }
+ }
+ }
+
+ //var elemCount = 0; //STATISTICS
+
+ /* ContentHandler methods */
+
+ /* Start prefix mapping - use default impl.
+ def startPrefixMapping( prefix:String , uri:String ):Unit = {}
+ */
+
+ /* Start element. */
+ override def startElement(uri: String, _localName: String,
+ qname: String, attributes: Attributes): Unit = {
+ /*elemCount = elemCount + 1; STATISTICS */
+ captureText()
+ //Console.println("FactoryAdapter::startElement("+uri+","+_localName+","+qname+","+attributes+")");
+ tagStack.push(curTag)
+ curTag = qname; //localName ;
+
+ val colon = qname.indexOf(':'.asInstanceOf[Int])
+ val localName = if(-1 == colon) qname else qname.substring(colon+1,qname.length())
+
+ //Console.println("FactoryAdapter::startElement - localName ="+localName);
+
+ capture = nodeContainsText(localName)
+
+ hStack.push(null)
+ var m: MetaData = Null
+
+ var scpe = scopeStack.top
+ for (i <- List.range(0, attributes.getLength())) {
+ //val attrType = attributes.getType(i); // unused for now
+ val qname = attributes.getQName(i)
+ val value = attributes.getValue(i)
+ val colon = qname.indexOf(':'.asInstanceOf[Int])
+ if (-1 != colon) { // prefixed attribute
+ val pre = qname.substring(0, colon)
+ val key = qname.substring(colon+1, qname.length())
+ if ("xmlns" /*XML.xmlns*/ == pre)
+ scpe = value.length() match {
+ case 0 => new NamespaceBinding(key, null, scpe)
+ case _ => new NamespaceBinding(key, value, scpe)
+ }
+ else
+ m = new PrefixedAttribute(pre, key, Text(value), m)
+ } else if ("xmlns" /*XML.xmlns*/ == qname)
+ scpe = value.length() match {
+ case 0 => new NamespaceBinding(null, null, scpe)
+ case _ => new NamespaceBinding(null, value, scpe)
+ }
+ else
+ m = new UnprefixedAttribute(qname, Text(value), m)
+ }
+ scopeStack.push(scpe)
+ attribStack.push(m)
+ ()
+ } // startElement(String,String,String,Attributes)
+
+
+ /** captures text, possibly normalizing whitespace
+ */
+ def captureText(): Unit = {
+ if (capture) {
+ val text = buffer.toString()
+ if (text.length() > 0 && !text.equals(" ")) {
+ hStack.push(createText(text))
+ }
+ }
+ buffer.setLength(0)
+ }
+
+ /** End element.
+ * @param uri
+ * @param localName
+ * @param qname
+ * @throws org.xml.sax.SAXException if ..
+ */
+ override def endElement(uri: String , _localName: String , qname: String): Unit = {
+ captureText()
+
+ val metaData = attribStack.pop
+
+ // reverse order to get it right
+ var v: List[Node] = Nil
+ var child: Node = hStack.pop
+ while (child ne null) {
+ v = child::v
+ child = hStack.pop
+ }
+
+ val colon = qname.indexOf(':'.asInstanceOf[Int])
+ val localName =
+ if (-1 == colon) qname
+ else qname.substring(colon+1, qname.length())
+
+ val scp = scopeStack.pop
+ // create element
+ val pre = if (-1 == colon) null else qname.substring(0, colon)
+ rootElem = createNode(pre, localName, metaData, scp, v)
+
+ hStack.push(rootElem)
+
+ // set
+ curTag = tagStack.pop
+
+ capture =
+ if (curTag ne null) nodeContainsText(curTag) // root level
+ else false
+ } // endElement(String,String,String)
+
+ /** Processing instruction.
+ */
+ override def processingInstruction(target: String, data: String) {
+ for (pi <- createProcInstr(target, data))
+ hStack.push(pi)
+ }
+
+ //
+ // ErrorHandler methods
+ //
+
+ /** Warning.*/
+ override def warning(ex: SAXParseException): Unit = {
+ // ignore warning, crimson warns even for entity resolution!
+ //printError("Warning", ex);
+ }
+
+ /** Error. */
+ override def error(ex: SAXParseException): Unit =
+ printError("Error", ex)
+
+ /** Fatal error.*/
+ override def fatalError(ex: SAXParseException): Unit =
+ printError("Fatal Error", ex)
+
+ //
+ // Protected methods
+ //
+
+ /** Prints the error message */
+ protected def printError(errtype: String, ex: SAXParseException): Unit =
+ Console.withOut(Console.err) {
+ Console.print("[")
+ Console.print(errtype)
+ Console.print("] ")
+
+ var systemId = ex.getSystemId()
+ if (systemId ne null) {
+ val index = systemId.lastIndexOf('/'.asInstanceOf[Int])
+ if (index != -1)
+ systemId = systemId.substring(index + 1)
+ //Console.print(systemId)
+ }
+
+ Console.print(':')
+ Console.print(ex.getLineNumber())
+ Console.print(':')
+ Console.print(ex.getColumnNumber())
+ Console.print(": ")
+ Console.print(ex.getMessage())
+ Console.println
+ Console.flush
+ }
+
+ var rootElem: Node = null:Node
+
+ //FactoryAdapter
+ // MAIN
+ //
+
+ /** load XML document
+ * @param source
+ * @return a new XML document object
+ */
+ def loadXML(source: InputSource): Node = {
+ // create parser
+ val parser: SAXParser = try {
+ val f = SAXParserFactory.newInstance()
+ f.setNamespaceAware(false)
+ f.newSAXParser()
+ } catch {
+ case e: Exception =>
+ Console.err.println("error: Unable to instantiate parser")
+ throw e
+ }
+
+ // parse file
+ scopeStack.push(TopScope)
+ parser.parse(source, this)
+ scopeStack.pop
+ return rootElem
+ } // loadXML
+
+ /** loads XML from given file */
+ def loadFile(file: File): Node =
+ loadXML(new InputSource(new FileInputStream(file)))
+
+ /** loads XML from given file descriptor */
+ def loadFile(fileDesc: FileDescriptor): Node =
+ loadXML(new InputSource(new FileInputStream(fileDesc)))
+
+ /** loads XML from given file */
+ def loadFile(fileName: String): Node =
+ loadXML(new InputSource(new FileInputStream(fileName)))
+
+ /** loads XML from given InputStream */
+ def load(is: InputStream): Node =
+ loadXML(new InputSource(is))
+
+ /** loads XML from given Reader */
+ def load(reader: Reader): Node =
+ loadXML(new InputSource(reader))
+
+ /** loads XML from given sysID */
+ def load(sysID: String): Node =
+ loadXML(new InputSource(sysID))
+
+}
diff --git a/src/library/scala/xml/include/parsing/FatalError.scala b/src/library/scala/xml/include/parsing/FatalError.scala
new file mode 100644
index 0000000000..2768becb8b
--- /dev/null
+++ b/src/library/scala/xml/include/parsing/FatalError.scala
@@ -0,0 +1,15 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2006, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+
+package scala.xml.parsing;
+
+
+case class FatalError(msg:String) extends java.lang.RuntimeException(msg);
diff --git a/src/library/scala/xml/include/parsing/MarkupParser.scala b/src/library/scala/xml/include/parsing/MarkupParser.scala
new file mode 100644
index 0000000000..541cc65ac2
--- /dev/null
+++ b/src/library/scala/xml/include/parsing/MarkupParser.scala
@@ -0,0 +1,1215 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+
+package scala.xml.parsing
+
+import scala.io.Source
+import scala.xml.dtd._
+
+/**
+ * An XML parser.
+ *
+ * Parses XML 1.0, invokes callback methods of a MarkupHandler
+ * and returns whatever the markup handler returns. Use
+ * ConstructingParser
if you just want to parse XML to
+ * construct instances of scala.xml.Node
.
+ *
+ * While XML elements are returned, DTD declarations - if handled - are
+ * collected using side-effects.
+ *
+ * @author Burak Emir
+ * @version 1.0
+ */
+trait MarkupParser extends AnyRef with TokenTests { self: MarkupParser with MarkupHandler =>
+
+ val input: Source
+
+ /** if true, does not remove surplus whitespace */
+ val preserveWS: Boolean
+
+ def externalSource(systemLiteral: String): Source
+
+ //
+ // variables, values
+ //
+
+ var curInput: Source = input
+
+ /** the handler of the markup, returns this */
+ private val handle: MarkupHandler = this
+
+ /** stack of inputs */
+ var inpStack: List[Source] = Nil
+
+ /** holds the position in the source file */
+ var pos: Int = _
+
+
+ /* used when reading external subset */
+ var extIndex = -1
+
+ /** holds temporary values of pos */
+ var tmppos: Int = _
+
+ /** holds the next character */
+ var ch: Char = _
+
+ /** character buffer, for names */
+ protected val cbuf = new StringBuilder()
+
+ var dtd: DTD = null
+
+ protected var doc: Document = null
+
+ var eof: Boolean = false
+
+ //
+ // methods
+ //
+
+ /** <? prolog ::= xml S ... ?>
+ */
+ def xmlProcInstr(): MetaData = {
+ xToken("xml")
+ xSpace
+ val (md,scp) = xAttributes(TopScope)
+ if (scp != TopScope)
+ reportSyntaxError("no xmlns definitions here, please.");
+ xToken('?')
+ xToken('>')
+ md
+ }
+
+ /** <? prolog ::= xml S?
+ * // this is a bit more lenient than necessary...
+ */
+ def prolog(): Tuple3[Option[String], Option[String], Option[Boolean]] = {
+
+ //Console.println("(DEBUG) prolog")
+ var n = 0
+ var info_ver: Option[String] = None
+ var info_enc: Option[String] = None
+ var info_stdl: Option[Boolean] = None
+
+ var m = xmlProcInstr()
+
+ xSpaceOpt
+
+ m("version") match {
+ case null => ;
+ case Text("1.0") => info_ver = Some("1.0"); n += 1
+ case _ => reportSyntaxError("cannot deal with versions != 1.0")
+ }
+
+ m("encoding") match {
+ case null => ;
+ case Text(enc) =>
+ if (!isValidIANAEncoding(enc))
+ reportSyntaxError("\"" + enc + "\" is not a valid encoding")
+ else {
+ info_enc = Some(enc)
+ n += 1
+ }
+ }
+ m("standalone") match {
+ case null => ;
+ case Text("yes") => info_stdl = Some(true); n += 1
+ case Text("no") => info_stdl = Some(false); n += 1
+ case _ => reportSyntaxError("either 'yes' or 'no' expected")
+ }
+
+ if (m.length - n != 0) {
+ reportSyntaxError("VersionInfo EncodingDecl? SDDecl? or '?>' expected!");
+ }
+ //Console.println("[MarkupParser::prolog] finished parsing prolog!");
+ Tuple3(info_ver,info_enc,info_stdl)
+ }
+
+ /** prolog, but without standalone */
+ def textDecl(): Tuple2[Option[String],Option[String]] = {
+
+ var info_ver: Option[String] = None
+ var info_enc: Option[String] = None
+
+ var m = xmlProcInstr()
+ var n = 0
+
+ m("version") match {
+ case null => ;
+ case Text("1.0") => info_ver = Some("1.0"); n += 1
+ case _ => reportSyntaxError("cannot deal with versions != 1.0")
+ }
+
+ m("encoding") match {
+ case null => ;
+ case Text(enc) =>
+ if (!isValidIANAEncoding(enc))
+ reportSyntaxError("\"" + enc + "\" is not a valid encoding")
+ else {
+ info_enc = Some(enc)
+ n += 1
+ }
+ }
+
+ if (m.length - n != 0) {
+ reportSyntaxError("VersionInfo EncodingDecl? or '?>' expected!");
+ }
+ //Console.println("[MarkupParser::textDecl] finished parsing textdecl");
+ Tuple2(info_ver, info_enc);
+ }
+
+ /**
+ *[22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?
+ *[23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
+ *[24] VersionInfo ::= S 'version' Eq ("'" VersionNum "'" | '"' VersionNum '"')
+ *[25] Eq ::= S? '=' S?
+ *[26] VersionNum ::= '1.0'
+ *[27] Misc ::= Comment | PI | S
+ */
+
+ def document(): Document = {
+
+ //Console.println("(DEBUG) document")
+ doc = new Document()
+
+ this.dtd = null
+ var info_prolog: Tuple3[Option[String], Option[String], Option[Boolean]] = Tuple3(None, None, None);
+ if ('<' != ch) {
+ reportSyntaxError("< expected")
+ return null
+ }
+
+ nextch // is prolog ?
+ var children: NodeSeq = null
+ if ('?' == ch) {
+ //Console.println("[MarkupParser::document] starts with xml declaration");
+ nextch;
+ info_prolog = prolog()
+ doc.version = info_prolog._1
+ doc.encoding = info_prolog._2
+ doc.standAlone = info_prolog._3
+
+ children = content(TopScope) // DTD handled as side effect
+ } else {
+ //Console.println("[MarkupParser::document] does not start with xml declaration");
+ //
+
+ val ts = new NodeBuffer();
+ content1(TopScope, ts); // DTD handled as side effect
+ ts &+ content(TopScope);
+ children = NodeSeq.fromSeq(ts);
+ }
+ //Console.println("[MarkupParser::document] children now: "+children.toList);
+ var elemCount = 0;
+ var theNode: Node = null;
+ for (c <- children) c match {
+ case _:ProcInstr => ;
+ case _:Comment => ;
+ case _:EntityRef => // todo: fix entities, shouldn't be "special"
+ reportSyntaxError("no entity references alllowed here");
+ case s:SpecialNode =>
+ if (s.toString().trim().length > 0) //non-empty text nodes not allowed
+ elemCount = elemCount + 2;
+ case m:Node =>
+ elemCount = elemCount + 1;
+ theNode = m;
+ }
+ if (1 != elemCount) {
+ reportSyntaxError("document must contain exactly one element")
+ Console.println(children.toList)
+ }
+
+ doc.children = children
+ doc.docElem = theNode
+ doc
+ }
+
+ /** append Unicode character to name buffer*/
+ protected def putChar(c: Char) = cbuf.append(c)
+
+ //var xEmbeddedBlock = false;
+
+ /** this method assign the next character to ch and advances in input */
+ def nextch {
+ if (curInput.hasNext) {
+ ch = curInput.next
+ pos = curInput.pos
+ } else {
+ val ilen = inpStack.length;
+ //Console.println(" ilen = "+ilen+ " extIndex = "+extIndex);
+ if ((ilen != extIndex) && (ilen > 0)) {
+ /** for external source, inpStack == Nil ! need notify of eof! */
+ pop()
+ } else {
+ eof = true
+ ch = 0.asInstanceOf[Char]
+ }
+ }
+ }
+
+ //final val enableEmbeddedExpressions: Boolean = false;
+
+ /** munch expected XML token, report syntax error for unexpected
+ */
+ def xToken(that: Char) {
+ if (ch == that)
+ nextch
+ else {
+ reportSyntaxError("'" + that + "' expected instead of '" + ch + "'")
+ error("FATAL")
+ }
+ }
+
+ def xToken(that: Seq[Char]): Unit = {
+ val it = that.elements;
+ while (it.hasNext)
+ xToken(it.next);
+ }
+
+ /** parse attribute and create namespace scope, metadata
+ * [41] Attributes ::= { S Name Eq AttValue }
+ */
+ def xAttributes(pscope:NamespaceBinding): (MetaData,NamespaceBinding) = {
+ var scope: NamespaceBinding = pscope
+ var aMap: MetaData = Null
+ while (isNameStart(ch)) {
+ val pos = this.pos
+
+ val qname = xName
+ val _ = xEQ
+ val value = xAttributeValue()
+
+ Utility.prefix(qname) match {
+ case Some("xmlns") =>
+ val prefix = qname.substring(6 /*xmlns:*/ , qname.length);
+ scope = new NamespaceBinding(prefix, value, scope);
+
+ case Some(prefix) =>
+ val key = qname.substring(prefix.length+1, qname.length);
+ aMap = new PrefixedAttribute(prefix, key, Text(value), aMap);
+
+ case _ =>
+ if( qname == "xmlns" )
+ scope = new NamespaceBinding(null, value, scope);
+ else
+ aMap = new UnprefixedAttribute(qname, Text(value), aMap);
+ }
+
+ if ((ch != '/') && (ch != '>') && ('?' != ch))
+ xSpace;
+ }
+
+ if(!aMap.wellformed(scope))
+ reportSyntaxError( "double attribute");
+
+ (aMap,scope)
+ }
+
+ /** attribute value, terminated by either ' or ". value may not contain <.
+ * AttValue ::= `'` { _ } `'`
+ * | `"` { _ } `"`
+ */
+ def xAttributeValue(): String = {
+ val endch = ch
+ nextch
+ while (ch != endch) {
+ if ('<' == ch)
+ reportSyntaxError( "'<' not allowed in attrib value" );
+ putChar(ch)
+ nextch
+ }
+ nextch
+ val str = cbuf.toString()
+ cbuf.length = 0
+
+ // well-formedness constraint
+ normalizeAttributeValue(str)
+ }
+
+ /** entity value, terminated by either ' or ". value may not contain <.
+ * AttValue ::= `'` { _ } `'`
+ * | `"` { _ } `"`
+ */
+ def xEntityValue(): String = {
+ val endch = ch
+ nextch
+ while (ch != endch) {
+ putChar(ch)
+ nextch
+ }
+ nextch
+ val str = cbuf.toString()
+ cbuf.length = 0
+ str
+ }
+
+
+ /** parse a start or empty tag.
+ * [40] STag ::= '<' Name { S Attribute } [S]
+ * [44] EmptyElemTag ::= '<' Name { S Attribute } [S]
+ */
+ protected def xTag(pscope:NamespaceBinding): Tuple3[String, MetaData, NamespaceBinding] = {
+ val qname = xName
+
+ xSpaceOpt
+ val (aMap: MetaData, scope: NamespaceBinding) = {
+ if (isNameStart(ch))
+ xAttributes(pscope)
+ else
+ (Null, pscope)
+ }
+ (qname, aMap, scope)
+ }
+
+ /** [42] '<' xmlEndTag ::= '<' '/' Name S? '>'
+ */
+ def xEndTag(n: String) = {
+ xToken('/')
+ val m = xName
+ if (n != m)
+ reportSyntaxError("expected closing tag of " + n/* +", not "+m*/);
+ xSpaceOpt
+ xToken('>')
+ }
+
+ /** '<! CharData ::= [CDATA[ ( {char} - {char}"]]>"{char} ) ']]>'
+ *
+ * see [15]
+ */
+ def xCharData: NodeSeq = {
+ xToken("[CDATA[")
+ val pos1 = pos
+ val sb: StringBuilder = new StringBuilder()
+ while (true) {
+ if (ch==']' &&
+ { sb.append(ch); nextch; ch == ']' } &&
+ { sb.append(ch); nextch; ch == '>' } ) {
+ sb.length = sb.length - 2
+ nextch;
+ return handle.text( pos1, sb.toString() );
+ } else sb.append( ch );
+ nextch;
+ }
+ throw FatalError("this cannot happen");
+ };
+
+ /** CharRef ::= "&#" '0'..'9' {'0'..'9'} ";"
+ * | "&#x" '0'..'9'|'A'..'F'|'a'..'f' { hexdigit } ";"
+ *
+ * see [66]
+ */
+ def xCharRef(ch: () => Char, nextch: () => Unit): String = {
+ Utility.parseCharRef(ch, nextch, reportSyntaxError _)
+ /*
+ val hex = (ch() == 'x') && { nextch(); true };
+ val base = if (hex) 16 else 10;
+ var i = 0;
+ while (ch() != ';') {
+ ch() match {
+ case '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' =>
+ i = i * base + Character.digit( ch(), base );
+ case 'a' | 'b' | 'c' | 'd' | 'e' | 'f'
+ | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' =>
+ if (! hex)
+ reportSyntaxError("hex char not allowed in decimal char ref\n"
+ +"Did you mean to write ?");
+ else
+ i = i * base + Character.digit(ch(), base);
+ case _ =>
+ reportSyntaxError("character '" + ch() + " not allowed in char ref\n");
+ }
+ nextch();
+ }
+ new String(Array(i.asInstanceOf[char]))
+ */
+ }
+
+
+ /** Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
+ *
+ * see [15]
+ */
+ def xComment: NodeSeq = {
+ val sb: StringBuilder = new StringBuilder()
+ xToken('-')
+ xToken('-')
+ while (true) {
+ if (ch == '-' && { sb.append(ch); nextch; ch == '-' }) {
+ sb.length = sb.length - 1
+ nextch
+ xToken('>')
+ return handle.comment(pos, sb.toString())
+ } else sb.append(ch)
+ nextch
+ }
+ throw FatalError("this cannot happen")
+ }
+
+ /* todo: move this into the NodeBuilder class */
+ def appendText(pos: Int, ts: NodeBuffer, txt: String): Unit = {
+ if (preserveWS)
+ ts &+ handle.text(pos, txt);
+ else
+ for (t <- TextBuffer.fromString(txt).toText) {
+ ts &+ handle.text(pos, t.text);
+ }
+ }
+
+ /** '<' content1 ::= ... */
+ def content1(pscope: NamespaceBinding, ts: NodeBuffer): Unit =
+ ch match {
+ case '!' =>
+ nextch
+ if ('[' == ch) // CDATA
+ ts &+ xCharData
+ else if ('D' == ch) // doctypedecl, parse DTD // @todo REMOVE HACK
+ parseDTD()
+ else // comment
+ ts &+ xComment
+ case '?' => // PI
+ nextch
+ ts &+ xProcInstr
+ case _ =>
+ ts &+ element1(pscope) // child
+ }
+
+ /** content1 ::= '<' content1 | '&' charref ... */
+ def content(pscope: NamespaceBinding): NodeSeq = {
+ var ts = new NodeBuffer
+ var exit = eof
+ while (! exit) {
+ //Console.println("in content, ch = '"+ch+"' line="+scala.io.Position.line(pos));
+ /* if( xEmbeddedBlock ) {
+ ts.append( xEmbeddedExpr );
+ } else {*/
+ tmppos = pos;
+ exit = eof;
+ if(!eof)
+ ch match {
+ case '<' => // another tag
+ //Console.println("before ch = '"+ch+"' line="+scala.io.Position.line(pos)+" pos="+pos);
+ nextch;
+ //Console.println("after ch = '"+ch+"' line="+scala.io.Position.line(pos)+" pos="+pos);
+
+ if('/' ==ch)
+ exit = true; // end tag
+ else
+ content1(pscope, ts)
+ //case '{' =>
+/* if( xCheckEmbeddedBlock ) {
+ ts.appendAll(xEmbeddedExpr);
+ } else {*/
+ // val str = new StringBuilder("{");
+ // str.append(xText);
+ // appendText(tmppos, ts, str.toString());
+ /*}*/
+ // postcond: xEmbeddedBlock == false!
+ case '&' => // EntityRef or CharRef
+ nextch;
+ ch match {
+ case '#' => // CharacterRef
+ nextch;
+ val theChar = handle.text( tmppos,
+ xCharRef ({ ()=> ch },{ () => nextch }) );
+ xToken(';');
+ ts &+ theChar ;
+ case _ => // EntityRef
+ val n = xName
+ xToken(';')
+ n match {
+ case "lt" => ts &+ '<'
+ case "gt" => ts &+ '>'
+ case "amp" => ts &+ '&'
+ case "quot" => ts &+ '"'
+ case _ =>
+ /*
+ ts + handle.entityRef( tmppos, n ) ;
+ */
+ push(n)
+ }
+ }
+ case _ => // text content
+ //Console.println("text content?? pos = "+pos);
+ appendText(tmppos, ts, xText);
+ // here xEmbeddedBlock might be true
+ }
+ /*}*/
+ }
+ val list = ts.toList
+ // 2do: optimize seq repr.
+ new NodeSeq {
+ val theSeq = list
+ }
+ } // content(NamespaceBinding)
+
+ /** externalID ::= SYSTEM S syslit
+ * PUBLIC S pubid S syslit
+ */
+
+ def externalID(): ExternalID = ch match {
+ case 'S' =>
+ nextch
+ xToken("YSTEM")
+ xSpace
+ val sysID = systemLiteral()
+ new SystemID(sysID)
+ case 'P' =>
+ nextch; xToken("UBLIC")
+ xSpace
+ val pubID = pubidLiteral()
+ xSpace
+ val sysID = systemLiteral()
+ new PublicID(pubID, sysID)
+ }
+
+
+ /** parses document type declaration and assigns it to instance variable
+ * dtd.
+ *
+ * <! parseDTD ::= DOCTYPE name ... >
+ */
+ def parseDTD(): Unit = { // dirty but fast
+ //Console.println("(DEBUG) parseDTD");
+ var extID: ExternalID = null
+ if (this.dtd ne null)
+ reportSyntaxError("unexpected character (DOCTYPE already defined");
+ xToken("DOCTYPE")
+ xSpace
+ val n = xName
+ xSpace
+ //external ID
+ if ('S' == ch || 'P' == ch) {
+ extID = externalID()
+ xSpaceOpt
+ }
+
+ /* parse external subset of DTD
+ */
+
+ if ((null != extID) && isValidating) {
+
+ pushExternal(extID.systemId)
+ //val extSubsetSrc = externalSource( extID.systemId );
+
+ extIndex = inpStack.length
+ /*
+ .indexOf(':') != -1) { // assume URI
+ Source.fromFile(new java.net.URI(extID.systemLiteral));
+ } else {
+ Source.fromFile(extID.systemLiteral);
+ }
+ */
+ //Console.println("I'll print it now");
+ //val old = curInput;
+ //tmppos = curInput.pos;
+ //val oldch = ch;
+ //curInput = extSubsetSrc;
+ //pos = 0;
+ //nextch;
+
+ extSubset()
+
+ pop()
+
+ extIndex = -1
+
+ //curInput = old;
+ //pos = curInput.pos;
+ //ch = curInput.ch;
+ //eof = false;
+ //while(extSubsetSrc.hasNext)
+ //Console.print(extSubsetSrc.next);
+
+ //Console.println("returned from external, current ch = "+ch )
+ }
+
+ if ('[' == ch) { // internal subset
+ nextch
+ /* TODO */
+ //Console.println("hello");
+ intSubset()
+ //while(']' != ch)
+ // nextch;
+ // TODO: do the DTD parsing?? ?!?!?!?!!
+ xToken(']')
+ xSpaceOpt
+ }
+ xToken('>')
+ this.dtd = new DTD {
+ /*override var*/ externalID = extID
+ /*override val */decls = handle.decls.reverse
+ }
+ //this.dtd.initializeEntities();
+ if (doc ne null)
+ doc.dtd = this.dtd
+
+ handle.endDTD(n)
+ }
+
+ def element(pscope: NamespaceBinding): NodeSeq = {
+ xToken('<')
+ element1(pscope)
+ }
+
+ /** '<' element ::= xmlTag1 '>' { xmlExpr | '{' simpleExpr '}' } ETag
+ * | xmlTag1 '/' '>'
+ */
+ def element1(pscope: NamespaceBinding): NodeSeq = {
+ val pos = this.pos
+ val Tuple3(qname, aMap, scope) = xTag(pscope)
+ val Tuple2(pre, local) = Utility.prefix(qname) match {
+ case Some(p) => (p,qname.substring(p.length+1, qname.length))
+ case _ => (null,qname)
+ }
+ val ts = {
+ if (ch == '/') { // empty element
+ xToken('/')
+ xToken('>')
+ handle.elemStart(pos, pre, local, aMap, scope)
+ NodeSeq.Empty
+ }
+ else { // element with content
+ xToken('>')
+ handle.elemStart(pos, pre, local, aMap, scope)
+ val tmp = content(scope)
+ xEndTag(qname)
+ tmp
+ }
+ }
+ val res = handle.elem(pos, pre, local, aMap, scope, ts)
+ handle.elemEnd(pos, pre, local)
+ res
+ }
+
+ //def xEmbeddedExpr: MarkupType;
+
+ /** Name ::= (Letter | '_' | ':') (NameChar)*
+ *
+ * see [5] of XML 1.0 specification
+ */
+ def xName: String = {
+ if (isNameStart(ch)) {
+ while (isNameChar(ch)) {
+ putChar(ch)
+ nextch
+ }
+ val n = cbuf.toString().intern()
+ cbuf.length = 0
+ n
+ } else {
+ reportSyntaxError("name expected")
+ ""
+ }
+ }
+
+ /** scan [S] '=' [S]*/
+ def xEQ = { xSpaceOpt; xToken('='); xSpaceOpt }
+
+ /** skip optional space S? */
+ def xSpaceOpt = while (isSpace(ch) && !eof) { nextch; }
+
+ /** scan [3] S ::= (#x20 | #x9 | #xD | #xA)+ */
+ def xSpace =
+ if (isSpace(ch)) { nextch; xSpaceOpt }
+ else reportSyntaxError("whitespace expected")
+
+ /** '<?' ProcInstr ::= Name [S ({Char} - ({Char}'>?' {Char})]'?>'
+ *
+ * see [15]
+ */
+ def xProcInstr: NodeSeq = {
+ val sb:StringBuilder = new StringBuilder()
+ val n = xName
+ if (isSpace(ch)) {
+ xSpace
+ while (true) {
+ if (ch == '?' && { sb.append( ch ); nextch; ch == '>' }) {
+ sb.length = sb.length - 1;
+ nextch;
+ return handle.procInstr(tmppos, n, sb.toString);
+ } else
+ sb.append(ch);
+ nextch
+ }
+ };
+ xToken('?')
+ xToken('>')
+ handle.procInstr(tmppos, n, sb.toString)
+ }
+
+ /** parse character data.
+ * precondition: xEmbeddedBlock == false (we are not in a scala block)
+ */
+ def xText: String = {
+ //if( xEmbeddedBlock ) throw FatalError("internal error: encountered embedded block"); // assert
+
+ /*if( xCheckEmbeddedBlock )
+ return ""
+ else {*/
+ //Console.println("in xText! ch = '"+ch+"'");
+ var exit = false;
+ while (! exit) {
+ //Console.println("LOOP in xText! ch = '"+ch+"' + pos="+pos);
+ putChar(ch);
+ val opos = pos;
+ nextch;
+
+ //Console.println("STILL LOOP in xText! ch = '"+ch+"' + pos="+pos+" opos="+opos);
+
+
+ exit = eof || /*{ nextch; xCheckEmbeddedBlock }||*/( ch == '<' ) || ( ch == '&' );
+ }
+ val str = cbuf.toString();
+ cbuf.length = 0;
+ str
+ /*}*/
+ }
+
+ /** attribute value, terminated by either ' or ". value may not contain <.
+ * AttValue ::= `'` { _ } `'`
+ * | `"` { _ } `"`
+ */
+ def systemLiteral(): String = {
+ val endch = ch
+ if (ch != '\'' && ch != '"')
+ reportSyntaxError("quote ' or \" expected");
+ nextch
+ while (ch != endch) {
+ putChar(ch)
+ nextch
+ }
+ nextch
+ val str = cbuf.toString()
+ cbuf.length = 0
+ str
+ }
+
+
+ /* [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'" */
+ def pubidLiteral(): String = {
+ val endch = ch
+ if (ch!='\'' && ch != '"')
+ reportSyntaxError("quote ' or \" expected");
+ nextch
+ while (ch != endch) {
+ putChar(ch)
+ //Console.println("hello '"+ch+"'"+isPubIDChar(ch));
+ if (!isPubIDChar(ch))
+ reportSyntaxError("char '"+ch+"' is not allowed in public id");
+ nextch
+ }
+ nextch
+ val str = cbuf.toString()
+ cbuf.length = 0
+ str
+ }
+
+ //
+ // dtd parsing
+ //
+
+ def extSubset(): Unit = {
+ var textdecl:Tuple2[Option[String],Option[String]] = null;
+ if (ch=='<') {
+ nextch
+ if (ch=='?') {
+ nextch
+ textdecl = textDecl()
+ } else
+ markupDecl1()
+ }
+ while (!eof)
+ markupDecl()
+ }
+
+ def markupDecl1() = {
+ def doInclude() = {
+ xToken('['); while(']' != ch) markupDecl(); nextch // ']'
+ }
+ def doIgnore() = {
+ xToken('['); while(']' != ch) nextch; nextch; // ']'
+ }
+ if ('?' == ch) {
+ nextch
+ xProcInstr // simply ignore processing instructions!
+ } else {
+ xToken('!')
+ ch match {
+ case '-' =>
+ xComment // ignore comments
+
+ case 'E' =>
+ nextch
+ if ('L' == ch) {
+ nextch
+ elementDecl()
+ } else
+ entityDecl()
+
+ case 'A' =>
+ nextch
+ attrDecl()
+
+ case 'N' =>
+ nextch
+ notationDecl()
+
+ case '[' if inpStack.length >= extIndex =>
+ nextch
+ xSpaceOpt
+ ch match {
+ case '%' =>
+ nextch
+ val ent = xName
+ xToken(';')
+ xSpaceOpt
+ /*
+ Console.println("hello, pushing!");
+ {
+ val test = replacementText(ent);
+ while(test.hasNext)
+ Console.print(test.next);
+ } */
+ push(ent)
+ xSpaceOpt
+ //Console.println("hello, getting name");
+ val stmt = xName
+ //Console.println("hello, got name");
+ xSpaceOpt
+ //Console.println("how can we be eof = "+eof);
+
+ // eof = true because not external?!
+ //if(!eof)
+ // error("expected only INCLUDE or IGNORE");
+
+ //pop();
+
+ //Console.println("hello, popped");
+ stmt match {
+ // parameter entity
+ case "INCLUDE" =>
+ doInclude()
+ case "IGNORE" =>
+ doIgnore()
+ }
+ case 'I' =>
+ nextch
+ ch match {
+ case 'G' =>
+ nextch
+ xToken("NORE")
+ xSpaceOpt
+ doIgnore()
+ case 'N' =>
+ nextch
+ xToken("NCLUDE")
+ doInclude()
+ }
+ }
+ xToken(']')
+ xToken('>')
+
+ case _ =>
+ curInput.reportError(pos, "unexpected character '"+ch+"', expected some markupdecl")
+ while (ch!='>')
+ nextch
+ }
+ }
+ }
+
+ def markupDecl(): Unit = ch match {
+ case '%' => // parameter entity reference
+ nextch
+ val ent = xName
+ xToken(';')
+ if (!isValidating)
+ handle.peReference(ent) // n-v: just create PE-reference
+ else
+ push(ent) // v: parse replacementText
+
+ //peReference
+ case '<' =>
+ nextch
+ markupDecl1()
+ case _ if isSpace(ch) =>
+ xSpace
+ case _ =>
+ reportSyntaxError("markupdecl: unexpected character '"+ch+"' #" + ch.asInstanceOf[Int])
+ nextch
+ }
+
+ /** "rec-xml/#ExtSubset" pe references may not occur within markup
+ declarations
+ */
+ def intSubset() {
+ //Console.println("(DEBUG) intSubset()")
+ xSpace
+ while (']' != ch)
+ markupDecl()
+ }
+
+ /** <! element := ELEMENT
+ */
+ def elementDecl() {
+ xToken("EMENT")
+ xSpace
+ val n = xName
+ xSpace
+ while ('>' != ch) {
+ //Console.println("["+ch+"]")
+ putChar(ch)
+ nextch
+ }
+ //Console.println("END["+ch+"]")
+ nextch
+ val cmstr = cbuf.toString()
+ cbuf.length = 0
+ handle.elemDecl(n, cmstr)
+ }
+
+ /** <! attlist := ATTLIST
+ */
+ def attrDecl() = {
+ xToken("TTLIST")
+ xSpace
+ val n = xName
+ xSpace
+ var attList: List[AttrDecl] = Nil
+ // later: find the elemDecl for n
+ while ('>' != ch) {
+ val aname = xName
+ //Console.println("attribute name: "+aname);
+ var defdecl: DefaultDecl = null
+ xSpace
+ // could be enumeration (foo,bar) parse this later :-/
+ while ('"' != ch && '\'' != ch && '#' != ch && '<' != ch) {
+ if (!isSpace(ch))
+ cbuf.append(ch);
+ nextch;
+ }
+ val atpe = cbuf.toString()
+ cbuf.length = 0
+ //Console.println("attr type: "+atpe);
+ ch match {
+ case '\'' | '"' =>
+ val defValue = xAttributeValue() // default value
+ defdecl = DEFAULT(false, defValue)
+
+ case '#' =>
+ nextch
+ xName match {
+ case "FIXED" =>
+ xSpace
+ val defValue = xAttributeValue() // default value
+ defdecl = DEFAULT(true, defValue)
+ case "IMPLIED" =>
+ defdecl = IMPLIED
+ case "REQUIRED" =>
+ defdecl = REQUIRED
+ }
+ case _ =>
+ }
+ xSpaceOpt
+
+ attList = AttrDecl(aname, atpe, defdecl) :: attList
+ cbuf.length = 0
+ }
+ nextch
+ handle.attListDecl(n, attList.reverse)
+ }
+
+ /** <! element := ELEMENT
+ */
+ def entityDecl() = {
+ //Console.println("entityDecl()")
+ var isParameterEntity = false
+ var entdef: EntityDef = null
+ xToken("NTITY")
+ xSpace
+ if ('%' == ch) {
+ nextch
+ isParameterEntity = true
+ xSpace
+ }
+ val n = xName
+ xSpace
+ ch match {
+ case 'S' | 'P' => //sy
+ val extID = externalID()
+ if (isParameterEntity) {
+ xSpaceOpt
+ xToken('>')
+ handle.parameterEntityDecl(n, ExtDef(extID))
+ } else { // notation?
+ xSpace
+ if ('>' != ch) {
+ xToken("NDATA")
+ xSpace
+ val notat = xName
+ xSpaceOpt
+ xToken('>')
+ handle.unparsedEntityDecl(n, extID, notat)
+ } else {
+ nextch
+ handle.parsedEntityDecl(n, ExtDef(extID))
+ }
+ }
+
+ case '"' | '\'' =>
+ val av = xEntityValue()
+ xSpaceOpt
+ xToken('>')
+ if (isParameterEntity)
+ handle.parameterEntityDecl(n, IntDef(av))
+ else
+ handle.parsedEntityDecl(n, IntDef(av))
+ }
+ {}
+ } // entityDecl
+
+ /** 'N' notationDecl ::= "OTATION"
+ */
+ def notationDecl() {
+ xToken("OTATION")
+ xSpace
+ val notat = xName
+ xSpace
+ val extID = if (ch == 'S') {
+ externalID();
+ }
+ else if (ch == 'P') {
+ /** PublicID (without system, only used in NOTATION) */
+ nextch
+ xToken("UBLIC")
+ xSpace
+ val pubID = pubidLiteral()
+ xSpaceOpt
+ val sysID = if (ch != '>')
+ systemLiteral()
+ else
+ null;
+ new PublicID(pubID, sysID);
+ } else {
+ reportSyntaxError("PUBLIC or SYSTEM expected");
+ error("died parsing notationdecl")
+ }
+ xSpaceOpt
+ xToken('>')
+ handle.notationDecl(notat, extID)
+ }
+
+ /**
+ * report a syntax error
+ */
+ def reportSyntaxError(pos: Int, str: String) {
+ curInput.reportError(pos, str)
+ //error("MarkupParser::synerr") // DEBUG
+ }
+
+ def reportSyntaxError(str: String): Unit = reportSyntaxError(pos, str)
+
+ /**
+ * report a syntax error
+ */
+ def reportValidationError(pos: Int, str: String) {
+ curInput.reportError(pos, str)
+ }
+
+ def push(entityName: String) {
+ //Console.println("BEFORE PUSHING "+ch)
+ //Console.println("BEFORE PUSHING "+pos)
+ //Console.print("[PUSHING "+entityName+"]")
+ if (!eof)
+ inpStack = curInput :: inpStack
+
+ curInput = replacementText(entityName)
+ nextch
+ }
+
+ /*
+ def push(src:Source) = {
+ curInput = src
+ nextch
+ }
+ */
+
+ def pushExternal(systemId: String) {
+ //Console.print("BEFORE PUSH, curInput = $"+curInput.descr)
+ //Console.println(" stack = "+inpStack.map { x => "$"+x.descr })
+
+ //Console.print("[PUSHING EXTERNAL "+systemId+"]")
+ if (!eof)
+ inpStack = curInput :: inpStack
+
+ curInput = externalSource(systemId)
+
+ //Console.print("AFTER PUSH, curInput = $"+curInput.descr)
+ //Console.println(" stack = "+inpStack.map { x => "$"+x.descr })
+
+ nextch
+ }
+
+ def pop() {
+ curInput = inpStack.head
+ inpStack = inpStack.tail
+ ch = curInput.ch
+ pos = curInput.pos
+ eof = false // must be false, because of places where entity refs occur
+ //Console.println("\n AFTER POP, curInput = $"+curInput.descr);
+ //Console.println(inpStack.map { x => x.descr });
+ }
+
+ /** for the moment, replace only character references
+ * see spec 3.3.3
+ * precond: cbuf empty
+ */
+ def normalizeAttributeValue(attval: String): String = {
+ val s: Seq[Char] = attval
+ val it = s.elements
+ while (it.hasNext) {
+ it.next match {
+ case ' '|'\t'|'\n'|'\r' =>
+ cbuf.append(' ');
+ case '&' => it.next match {
+ case '#' =>
+ var c = it.next
+ val s = xCharRef ({ () => c }, { () => c = it.next })
+ cbuf.append(s)
+ case nchar =>
+ val nbuf = new StringBuilder()
+ var d = nchar
+ do {
+ nbuf.append(d)
+ d = it.next
+ } while(d != ';');
+ nbuf.toString() match {
+ case "lt" => cbuf.append('<')
+ case "gt" => cbuf.append('>')
+ case "amp" => cbuf.append('&')
+ case "apos" => cbuf.append('\'')
+ case "quot" => cbuf.append('"')
+ case "quote" => cbuf.append('"')
+ case name =>
+ cbuf.append('&')
+ cbuf.append(name)
+ cbuf.append(';')
+ }
+ }
+ case c =>
+ cbuf.append(c)
+ }
+ }
+ val name = cbuf.toString()
+ cbuf.length = 0
+ name
+ }
+
+}
diff --git a/src/library/scala/xml/include/parsing/NoBindingFactoryAdapter.scala b/src/library/scala/xml/include/parsing/NoBindingFactoryAdapter.scala
new file mode 100644
index 0000000000..be71e55fef
--- /dev/null
+++ b/src/library/scala/xml/include/parsing/NoBindingFactoryAdapter.scala
@@ -0,0 +1,62 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2006, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+
+package scala.xml.parsing;
+
+
+import scala.xml.factory.NodeFactory;
+import org.xml.sax.InputSource;
+
+/** nobinding adaptor providing callbacks to parser to create elements.
+* implements hash-consing
+*/
+class NoBindingFactoryAdapter extends FactoryAdapter with NodeFactory[Elem] {
+
+ // -- FactoryAdapter methods
+
+ /** returns true. Every XML node may contain text that the application needs
+ **/
+ def nodeContainsText( label:java.lang.String ): Boolean = true;
+
+
+ // methods for NodeFactory[Elem]
+
+ /** constructs an instance of scala.xml.Elem */
+ protected def create(pre: String, label: String, attrs: MetaData, scpe: NamespaceBinding, children:Seq[Node]): Elem = {
+ Elem( pre, label, attrs, scpe, children:_* );
+ }
+
+ // -- methods for FactoryAdapter
+
+ /** creates a node. never creates the same node twice, using hash-consing
+ */
+ def createNode(pre:String, label: String, attrs: MetaData, scpe: NamespaceBinding, children: List[Node] ): Elem = {
+ //Console.println("NoBindingFactoryAdapter::createNode("+pre+","+label+","+attrs+","+scpe+","+children+")");
+ Elem( pre, label, attrs, scpe, children:_* );
+ //makeNode(pre, label, attrs, scpe, children);
+ }
+
+ /** creates a text node
+ */
+ def createText( text:String ) =
+ Text( text );
+
+ /** create a processing instruction
+ */
+ def createProcInstr(target: String, data: String) =
+ makeProcInstr(target, data)
+
+ /** loads an XML document, returning a Symbol node.
+ */
+ override def loadXML( source:InputSource ):Elem =
+ super.loadXML( source ).asInstanceOf[ Elem ];
+
+}
diff --git a/src/library/scala/xml/include/parsing/TokenTests.scala b/src/library/scala/xml/include/parsing/TokenTests.scala
new file mode 100644
index 0000000000..d56b9bb7d7
--- /dev/null
+++ b/src/library/scala/xml/include/parsing/TokenTests.scala
@@ -0,0 +1,146 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2006, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+
+package scala.xml.parsing;
+
+
+/**
+ * Helper functions for parsing XML fragments
+ */
+trait TokenTests {
+
+ /** (#x20 | #x9 | #xD | #xA) */
+ final def isSpace( ch:Char ): Boolean = ch match {
+ case '\u0009' | '\u000A' | '\u000D' | '\u0020' => true
+ case _ => false;
+ }
+
+ /** (#x20 | #x9 | #xD | #xA)+ */
+ final def isSpace(cs: Seq[Char]): Boolean = {
+ val it = cs.elements;
+ it.hasNext && it.forall { isSpace };
+ }
+
+ /** NameChar ::= Letter | Digit | '.' | '-' | '_' | ':'
+ * | CombiningChar | Extender
+ *
+ * see [4] and Appendix B of XML 1.0 specification
+ */
+ def isNameChar(ch: Char) = isNameStart(ch) || (ch match {
+ case '.' | '-' | ':' => true;
+ case _ => java.lang.Character.getType( ch ).asInstanceOf[Byte] match {
+ case java.lang.Character.COMBINING_SPACING_MARK => true; // Mc
+ case java.lang.Character.ENCLOSING_MARK => true; // Me
+ case java.lang.Character.NON_SPACING_MARK => true; // Mn
+ case java.lang.Character.MODIFIER_LETTER => true; // Lm
+ case java.lang.Character.DECIMAL_DIGIT_NUMBER => true; // Nd
+ case _ => false;
+ }
+ });
+
+ /** NameStart ::= ( Letter | '_' )
+ * where Letter means in one of the Unicode general
+ * categories { Ll, Lu, Lo, Lt, Nl }
+ *
+ * We do not allow a name to start with ':'.
+ * see [3] and Appendix B of XML 1.0 specification
+ */
+ def isNameStart(ch: Char) =
+ java.lang.Character.getType(ch).asInstanceOf[Byte] match {
+ case java.lang.Character.LOWERCASE_LETTER => true;
+ case java.lang.Character.UPPERCASE_LETTER => true;
+ case java.lang.Character.OTHER_LETTER => true;
+ case java.lang.Character.TITLECASE_LETTER => true;
+ case java.lang.Character.LETTER_NUMBER => true;
+ case _ => ch match {
+ case '_' => true
+ case _ => false;
+ }
+ }
+
+ /** Name ::= ( Letter | '_' ) (NameChar)*
+ *
+ * see [5] of XML 1.0 specification
+ */
+ def isName(s: String): Boolean = {
+ if( s.length() > 0 ) {
+ val y = s.elements;
+ if (isNameStart(y.next)) {
+ while (y.hasNext && isNameChar(y.next)) {};
+ !y.hasNext
+ } else false;
+ } else false;
+ }
+
+ def isPubIDChar(ch: Char): Boolean = {
+ //Console.println("char: '" + ch + "'");
+ ch match {
+ case '\u0020' | '\u000D' | '\u000A' => true;
+ case _ if
+ (('0' <= ch && ch <= '9') || ('a' <= ch && ch <= 'z') ||
+ ('A' <= ch && ch <= 'Z')) => true;
+ case '-' | '\''| '(' | ')' | '+' | ',' | '.' |
+ '/' | ':' | '=' | '?' | ';' | '!' | '*' |
+ '#' | '@' | '$' | '_' | '%' => true
+ case _ =>
+ //Console.println("false: '" + ch + "'");
+ false;
+ }
+ }
+
+ /**
+ * Returns true if the encoding name is a valid IANA encoding.
+ * This method does not verify that there is a decoder available
+ * for this encoding, only that the characters are valid for an
+ * IANA encoding name.
+ *
+ * @param ianaEncoding The IANA encoding name.
+ */
+ def isValidIANAEncoding(ianaEncoding: Seq[Char]): Boolean = {
+ val it = ianaEncoding.elements;
+ if (!it.hasNext)
+ return false;
+
+ var c = it.next;
+ if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
+ while (it.hasNext) {
+ c = it.next;
+ if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z') &&
+ (c < '0' || c > '9') && c != '.' && c != '_' &&
+ c != '-') {
+ return false;
+ }
+ }
+ return true;
+ } else
+ return false;
+ } // isValidIANAEncoding(String): Boolean
+
+ def checkSysID( s:String ): Boolean = {
+ s.indexOf('"'.asInstanceOf[Int]) == -1 || s.indexOf('\''.asInstanceOf[Int]) == -1
+ }
+
+ def checkPubID(s: String): Boolean = {
+ //Console.println("checkPubID of \""+s+"\"");
+ if (s.length() > 0) {
+ val y = s.elements;
+ var c = ' ';
+ while (y.hasNext && isPubIDChar(c)) {
+ //Console.println(c);
+ c = y.next
+ };
+ !y.hasNext
+ }
+ else
+ true
+ }
+
+}
diff --git a/src/library/scala/xml/include/persistent/CachedFileStorage.scala b/src/library/scala/xml/include/persistent/CachedFileStorage.scala
new file mode 100644
index 0000000000..137286492a
--- /dev/null
+++ b/src/library/scala/xml/include/persistent/CachedFileStorage.scala
@@ -0,0 +1,123 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.xml.persistent
+
+import java.io.{File, FileOutputStream}
+import java.nio.ByteBuffer
+import java.nio.channels.Channels
+
+/** + * Mutable storage of immutable xml trees. Everything is kept in memory, + * with a thread periodically checking for changes and writing to file. + * To ensure atomicity, two files are used, filename1 and '$'+filename1. + * The implementation switches between the two, deleting the older one + * after a complete dump of the database has been written. + *
+ * + * @author Burak Emir + */ +abstract class CachedFileStorage(private val file1: File) +extends java.lang.Thread with scala.util.logging.Logged { + + private val file2 = new File(file1.getParent, file1.getName+"$") + + /** either equals file1 or file2, references the next file in which updates will be stored + */ + private var theFile: File = null + + private def switch = { theFile = if (theFile == file1) file2 else file1; } + + /** this storage modified since last modification check */ + protected var dirty = false + + /** period between modification checks, in milliseconds */ + protected val interval = 1000 + + /** finds and loads the storage file. subclasses should call this method + * prior to any other, but only once, to obtain the initial sequence of nodes. + */ + protected def initialNodes: Iterator[Node] = (file1.exists, file2.exists) match { + case (false,false) => + theFile = file1 + Iterator.empty + case (true, true ) if (file1.lastModified < file2.lastModified) => + theFile = file2 + load + case (true, _ ) => + theFile = file1 + load + case _ => + theFile = file2 + load + } + + /** returns an iterator over the nodes in this storage */ + def nodes: Iterator[Node] + + /** adds a node, setting this.dirty to true as a side effect */ + def += (e: Node): Unit + + /** removes a tree, setting this.dirty to true as a side effect */ + def -= (e: Node): Unit + + /* loads and parses XML from file */ + private def load: Iterator[Node] = { + import scala.io.Source + import scala.xml.parsing.ConstructingParser + log("[load]\nloading "+theFile) + val src = Source.fromFile( theFile ) + log("parsing "+theFile) + val res = ConstructingParser.fromSource(src,false).document.docElem(0) + switch + log("[load done]") + res.child.elements + } + + /** saves the XML to file */ + private def save = if (this.dirty) { + log("[save]\ndeleting "+theFile); + theFile.delete(); + log("creating new "+theFile); + theFile.createNewFile(); + val fos = new FileOutputStream(theFile) + val c = fos.getChannel() + + // @todo: optimize + val storageNode =+ * A pull parser that offers to view an XML document as a series of events. + * Please note that this API might change. Here's how to use this class + *
+ * import scala.xml._ + * import scala.xml.pull._ + * import scala.io.Source + * + * object reader { + * val src = Source.fromString("+ * + * @author Burak Emir + */ +class XMLEventReader extends Iterator[XMLEvent] { + + var src:Source = null + def getSource = this.src + def initialize(src: Source): this.type = { + this.src = src + this.parserThread = new Thread(new Parser()) + this.parserThread.start() + this + } + + // -- this part of the class is for communication with the thread + var xmlEvent: XMLEvent = null + var continue: Boolean = true + + def myresume = synchronized { + while (continue) { + wait() + } + continue = true + notifyAll + } + def getAndClearEvent: XMLEvent = synchronized { + while (xmlEvent eq null) { + wait() + } + val r = xmlEvent + xmlEvent = null + r + } + def setEvent(e: XMLEvent) { + xmlEvent = e + } + + def doNotify() = synchronized { + XMLEventReader.this.continue = false + notifyAll() + while (!XMLEventReader.this.continue) wait(); + NodeSeq.Empty + } + + // iterator methods + + def next: XMLEvent = { + myresume + val r = getAndClearEvent + r + } + + def hasNext = true + + var parserThread: Thread = null + + class Parser extends MarkupHandler with MarkupParser with ExternalSources with Runnable { + + val preserveWS = true + val input = XMLEventReader.this.getSource + + override def elemStart(pos: Int, pre: String, label: String, attrs: MetaData, scope: NamespaceBinding) { + setEvent(ElemStart(pre, label, attrs, scope)); doNotify + } + + override def elemEnd(pos: Int, pre: String, label: String) { + setEvent(ElemEnd(pre, label)); doNotify + } + + final def elem(pos: Int, pre: String, label: String, attrs: MetaData, pscope: NamespaceBinding, nodes: NodeSeq): NodeSeq = + NodeSeq.Empty + + def procInstr(pos: Int, target: String, txt: String): NodeSeq = { + setEvent(ElemStart(null, "comm", null, null)); doNotify + } + + def comment(pos: Int, txt: String): NodeSeq = { + setEvent(ElemStart(null, "comm", null, null)); doNotify + } + + def entityRef(pos: Int, n: String): NodeSeq = { + setEvent(ElemStart(null, "eref", null, null)); doNotify + } + + def text(pos: Int, txt:String): NodeSeq = { + setEvent(ElemStart(null, "tex", null, null)); doNotify + } + + override def run() { + curInput = input + this.nextch + doNotify() + this.document() + } + } +} diff --git a/src/library/scala/xml/include/sax/EncodingHeuristics.scala b/src/library/scala/xml/include/sax/EncodingHeuristics.scala new file mode 100644 index 0000000000..adab470106 --- /dev/null +++ b/src/library/scala/xml/include/sax/EncodingHeuristics.scala @@ -0,0 +1,177 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2007, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id$ + +package scala.xml.include.sax + +import java.io.{IOException, InputStreamReader, InputStream} + +/** + *") + * val er = new XMLEventReader().initialize(src) + * + * def main(args: Array[String]) { + * Console.println(er.next) + * Console.println(er.next) + * } + * } + *
+ * EncodingHeuristics
reads from a stream
+ * (which should be buffered) and attempts to guess
+ * what the encoding of the text in the stream is.
+ * Byte order marks are stripped from the stream.
+ * If it fails to determine the type of the encoding,
+ * it returns the default UTF-8.
+ *
+ * Translated from Elliotte Rusty Harold's Java source + *
+ * + * @author Burak Emir + */ +object EncodingHeuristics { + + /** + *+ * This utility method ????. + *
+ * + * @param inInputStream
to read from.
+ * @return String The name of the encoding.
+ * @throws IOException if the stream cannot be reset back to where it was when
+ * the method was invoked.
+ */
+ def readEncodingFromStream(in: InputStream): String = {
+ //System.err.println("EncodingHeuristics::readEncodingFromStream");
+ // This may fail if there are a lot of space characters before the end
+ // of the encoding declaration
+ in.mark(1024)
+ var ret: String = null
+ try {
+ // lots of things can go wrong here. If any do, I just return null
+ // so that we'll fall back on the encoding declaration or the
+ // UTF-8 default
+ val byte1 = in.read()
+ val byte2 = in.read()
+ if (byte1 == 0xFE && byte2 == 0xFF) {
+ // don't reset because the byte order mark should not be included????
+ ret = "UnicodeBig"; // name for big-endian????
+ }
+ else if (byte1 == 0xFF && byte2 == 0xFE) {
+ // don't reset because the byte order mark should not be included????
+ // will the reader throw away the byte order mark or will it return it????
+ ret = "UnicodeLittle"
+ }
+
+ /* In accordance with the Character Model [Character Model],
+ when the text format is a Unicode encoding, the XInclude
+ processor must fail the inclusion when the text in the
+ selected range is non-normalized. When transcoding characters
+ to a Unicode encoding from a legacy encoding, a normalizing transcoder must be used. */
+
+ val byte3 = in.read()
+ // check for UTF-8 byte order mark
+ if (byte1 == 0xEF && byte2 == 0xBB && byte3 == 0xBF) {
+ // don't reset because the byte order mark should not be included????
+ // in general what happens if text document includes non-XML legal chars????
+ ret = "UTF-8";
+ }
+
+ val byte4 = in.read();
+ if (byte1 == 0x00 && byte2 == 0x00 && byte3 == 0xFE && byte4 == 0xFF) {
+ // don't reset because the byte order mark should not be included????
+ ret = "UCS-4"; // right name for big-endian UCS-4 in Java 1.4????
+ }
+ else if (byte1 == 0x00 && byte2 == 0x00 && byte3 == 0xFF && byte4 == 0xFE) {
+ // don't reset because the byte order mark should not be included????
+ ret = "UCS-4"; // right name for little-endian UCS-4 in Java 1.4????
+ }
+
+ // no byte order mark present; first character must be
+ // less than sign or white space
+ // Let's look for less-than signs first
+ if (byte1 == 0x00 && byte2 == 0x00 && byte3 == 0x00 && byte4 == '<') {
+ in.reset()
+ ret = "UCS-4" // right name for big-endian UCS-4 in Java 1.4????
+ }
+ else if (byte1 == '<' && byte2 == 0x00 && byte3 == 0x00 && byte4 == 0x00) {
+ in.reset()
+ ret = "UCS-4" // right name for little-endian UCS-4 in Java 1.4????
+ }
+ else if (byte1 == 0x00 && byte2 == '<' && byte3 == 0x00 && byte4 == '?') {
+ in.reset()
+ ret = "UnicodeBigUnmarked"
+ }
+ else if (byte1 == '<' && byte2 == 0x00 && byte3 == '?' && byte4 == 0x00) {
+ in.reset()
+ ret = "UnicodeLittleUnmarked"
+ }
+ else if (byte1 == '<' && byte2 == '?' && byte3 == 'x' && byte4 == 'm') {
+ // ASCII compatible, must read encoding declaration
+ // 1024 bytes will be far enough to read most XML declarations
+ val data = new Array[Byte](1024)
+ data(0) = byte1.asInstanceOf[Byte]
+ data(1) = byte2.asInstanceOf[Byte]
+ data(2) = byte3.asInstanceOf[Byte]
+ data(3) = byte4.asInstanceOf[Byte]
+ val length = in.read(data, 4, 1020) + 4;
+ // Use Latin-1 (ISO-8859-1) because it's ASCII compatible and
+ // all byte sequences are legal Latin-1 sequences so I don't have
+ // to worry about encoding errors if I slip past the
+ // end of the XML/text declaration
+ val declaration = new String(data, 0, length, "8859_1");
+ // if any of these throw a StringIndexOutOfBoundsException
+ // we just fall into the catch bloclk and return null
+ // since this can't be well-formed XML
+ var position = declaration.indexOf("encoding") + 8;
+ var c: Char = '\0' // bogus init value
+ // get rid of white space before equals sign
+ do {
+ c = declaration.charAt(position)
+ position += 1
+ } while (c == ' ' || c == '\t' || c == '\r' || c == '\n') ;
+ if (c != '=') { // malformed
+ in.reset()
+ ret = "UTF-8"
+ }
+ // get rid of white space after equals sign
+ do {
+ c = declaration.charAt(position)
+ position += 1
+ } while (c == ' ' || c == '\t' || c == '\r' || c == '\n') ;
+ var delimiter: Char = c
+ if (delimiter != '\'' && delimiter != '"') { // malformed
+ in.reset()
+ ret = "UTF-8"
+ }
+ // now positioned to read encoding name
+ val encodingName = new StringBuffer()
+ do {
+ c = declaration.charAt(position)
+ position += 1
+ encodingName.append(c)
+ } while(c != delimiter)
+ encodingName.setLength(encodingName.length() - 1) // rm delim
+ in.reset()
+ ret = encodingName.toString()
+ }
+ else if (byte1 == 0x4C && byte2 == 0x6F && byte3 == 0xA7 && byte4 == 0x94) {
+ // EBCDIC compatible, must read encoding declaration
+ // ????
+ }
+
+ } catch {
+ case e: Exception =>
+ in.reset()
+ ret = "UTF-8"
+ }
+
+ // no XML or text declaration present
+ //System.err.println("exit EncodingHeuristics::readEncodingFromStream");
+
+ if (ret != null)
+ ret
+ else {
+ in.reset()
+ "UTF-8"
+ }
+ }
+}
diff --git a/src/library/scala/xml/include/sax/XIncludeFilter.scala b/src/library/scala/xml/include/sax/XIncludeFilter.scala
new file mode 100644
index 0000000000..19dc5ecead
--- /dev/null
+++ b/src/library/scala/xml/include/sax/XIncludeFilter.scala
@@ -0,0 +1,422 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.xml.include.sax
+
+import org.xml.sax.Attributes
+import org.xml.sax.SAXException
+import org.xml.sax.XMLReader
+import org.xml.sax.EntityResolver
+import org.xml.sax.Locator
+import org.xml.sax.helpers.XMLReaderFactory
+import org.xml.sax.helpers.XMLFilterImpl
+import org.xml.sax.helpers.NamespaceSupport
+import org.xml.sax.helpers.AttributesImpl
+
+import java.net.URL
+import java.net.URLConnection
+import java.net.MalformedURLException
+import java.io.UnsupportedEncodingException
+import java.io.IOException
+import java.io.InputStream
+import java.io.BufferedInputStream
+import java.io.InputStreamReader
+import java.util.Stack
+
+/**
+ * + * This is a SAX filter which resolves all XInclude include elements + * before passing them on to the client application. Currently this + * class has the following known deviation from the XInclude specification: + *
+ *+ * Furthermore, I would definitely use a new instance of this class + * for each document you want to process. I doubt it can be used + * successfully on multiple documents. Furthermore, I can virtually + * guarantee that this class is not thread safe. You have been + * warned. + *
+ * + *+ * Since this class is not designed to be subclassed, and since + * I have not yet considered how that might affect the methods + * herein or what other protected methods might be needed to support + * subclasses, I have declared this class final. I may remove this + * restriction later, though the use-case for subclassing is weak. + * This class is designed to have its functionality extended via a + * a horizontal chain of filters, not a + * vertical hierarchy of sub and superclasses. + *
+ * + *+ * To use this class: + *
+ *XIncludeFilter
object with a known base URLXMLReader
object from which the raw document will
+ * be read to the setParent()
method of this object. ContentHandler
object to the
+ * setContentHandler()
method of this object. This is the
+ * object which will receive events from the parsed and included
+ * document.
+ * LexicalHandler
object as the value of this object's
+ * http://xml.org/sax/properties/lexical-handler property.
+ * Also make sure your LexicalHandler
asks this object
+ * for the status of each comment using insideIncludeElement
+ * before doing anything with the comment.
+ * parse()
methode.g.
+ *XIncludeFilter includer = new XIncludeFilter(base);
+ * includer.setParent(parser);
+ * includer.setContentHandler(new SAXXIncluder(System.out));
+ * includer.parse(args[i]);
+ *
+ *
+ * translated from Elliotte Rusty Harold's Java source
+ * @author Burak Emir
+ */
+class XIncludeFilter extends XMLFilterImpl {
+
+ final val XINCLUDE_NAMESPACE = "http://www.w3.org/2001/XInclude";
+
+ private val bases = new Stack[URL]();
+ private val locators = new Stack[Locator]();
+
+/* private EntityResolver resolver;
+
+ public XIncludeFilter() {
+ this(null);
+ }
+
+ public XIncludeFilter(EntityResolver resolver) {
+ this.resolver = resolver;
+ } */
+
+
+ // what if this isn't called????
+ // do I need to check this in startDocument() and push something
+ // there????
+ override def setDocumentLocator(locator: Locator) {
+ locators.push(locator)
+ val base = locator.getSystemId()
+ try {
+ bases.push(new URL(base))
+ }
+ catch {
+ case e:MalformedURLException =>
+ throw new UnsupportedOperationException("Unrecognized SYSTEM ID: " + base)
+ }
+ super.setDocumentLocator(locator)
+ }
+
+
+ // necessary to throw away contents of non-empty XInclude elements
+ private var level = 0
+
+ /**
+ * + * This utility method returns true if and only if this reader is + * currently inside a non-empty include element. (This is + * not the same as being inside the node set which replaces + * the include element.) This is primarily needed for comments + * inside include elements. It must be checked by the actual + * LexicalHandler to see whether a comment is passed or not. + *
+ * + * @return boolean + */ + def insideIncludeElement(): Boolean = level != 0 + + override def startElement(uri: String, localName: String, qName: String, atts1: Attributes) { + var atts = atts1 + if (level == 0) { // We're not inside an xi:include element + + // Adjust bases stack by pushing either the new + // value of xml:base or the base of the parent + val base = atts.getValue(NamespaceSupport.XMLNS, "base") + val parentBase = bases.peek().asInstanceOf[URL] + var currentBase = parentBase + if (base != null) { + try { + currentBase = new URL(parentBase, base) + } + catch { + case e: MalformedURLException => + throw new SAXException("Malformed base URL: " + + currentBase, e) + } + } + bases.push(currentBase); + + if (uri.equals(XINCLUDE_NAMESPACE) && localName.equals("include")) { + // include external document + val href = atts.getValue("href") + // Verify that there is an href attribute + if (href==null) { + throw new SAXException("Missing href attribute") + } + + var parse = atts.getValue("parse") + if (parse == null) parse = "xml" + + if (parse.equals("text")) { + val encoding = atts.getValue("encoding"); + includeTextDocument(href, encoding); + } + else if (parse.equals("xml")) { + includeXMLDocument(href); + } + // Need to check this also in DOM and JDOM???? + else { + throw new SAXException( + "Illegal value for parse attribute: " + parse); + } + level += 1 + } + else { + if (atRoot) { + // add xml:base attribute if necessary + val attsImpl = new AttributesImpl(atts) + attsImpl.addAttribute(NamespaceSupport.XMLNS, "base", + "xml:base", "CDATA", currentBase.toExternalForm()) + atts = attsImpl + atRoot = false + } + super.startElement(uri, localName, qName, atts) + } + } + } + + override def endElement(uri: String, localName: String, qName: String) { + if (uri.equals(XINCLUDE_NAMESPACE) + && localName.equals("include")) { + level -= 1; + } + else if (level == 0) { + bases.pop() + super.endElement(uri, localName, qName) + } + } + + private var depth = 0; + + override def startDocument() { + level = 0 + if (depth == 0) super.startDocument() + depth += 1 + } + + override def endDocument() { + locators.pop() + bases.pop(); // pop the URL for the document itself + depth -= 1 + if (depth == 0) super.endDocument() + } + + // how do prefix mappings move across documents???? + override def startPrefixMapping(prefix: String , uri: String) { + if (level == 0) super.startPrefixMapping(prefix, uri) + } + + override def endPrefixMapping(prefix: String) { + if (level == 0) super.endPrefixMapping(prefix) + } + + override def characters(ch: Array[Char], start: Int, length: Int) { + if (level == 0) super.characters(ch, start, length) + } + + override def ignorableWhitespace(ch: Array[Char], start: Int, length: Int) { + if (level == 0) super.ignorableWhitespace(ch, start, length) + } + + override def processingInstruction(target: String, data: String) { + if (level == 0) super.processingInstruction(target, data) + } + + override def skippedEntity(name: String) { + if (level == 0) super.skippedEntity(name) + } + + // convenience method for error messages + private def getLocation(): String = { + var locationString = "" + val locator = locators.peek().asInstanceOf[Locator] + var publicID = "" + var systemID = "" + var column = -1 + var line = -1 + if (locator != null) { + publicID = locator.getPublicId() + systemID = locator.getSystemId() + line = locator.getLineNumber() + column = locator.getColumnNumber() + } + locationString = (" in document included from " + publicID + + " at " + systemID + + " at line " + line + ", column " + column); + + locationString + } + + /** + *
+ * This utility method reads a document at a specified URL
+ * and fires off calls to characters()
.
+ * It's used to include files with parse="text"
+ *
+ * This utility method reads a document at a specified URL
+ * and fires off calls to various ContentHandler
methods.
+ * It's used to include files with parse="xml"
+ *
ContentHandler
+ * that writes its XML document onto an output stream after resolving
+ * all xinclude:include
elements.
+ *
+ * + * based on Eliotte Rusty Harold's SAXXIncluder + *
+ */ +class XIncluder(outs:OutputStream, encoding:String) extends Object +with ContentHandler with LexicalHandler { + + var out = new OutputStreamWriter(outs, encoding) + + def setDocumentLocator(locator: Locator) {} + + def startDocument() { + try { + out.write("\r\n"); + } + catch { + case e:IOException => + throw new SAXException("Write failed", e) + } + } + + def endDocument() { + try { + out.flush() + } + catch { + case e:IOException => + throw new SAXException("Flush failed", e) + } + } + + def startPrefixMapping(prefix: String , uri: String) {} + + def endPrefixMapping(prefix: String) {} + + def startElement(namespaceURI: String, localName: String, qualifiedName: String, atts: Attributes) = { + try { + out.write("<" + qualifiedName); + var i = 0; while (i < atts.getLength()) { + out.write(" "); + out.write(atts.getQName(i)); + out.write("='"); + val value = atts.getValue(i); + // @todo Need to use character references if the encoding + // can't support the character + out.write(xml.Utility.escape(value)) + out.write("'"); + i += 1 + } + out.write(">") + } + catch { + case e:IOException => + throw new SAXException("Write failed", e) + } + } + + def endElement(namespaceURI: String, localName:String, qualifiedName: String) { + try { + out.write("" + qualifiedName + ">") + } + catch { + case e: IOException => + throw new SAXException("Write failed", e) + } + } + + // need to escape characters that are not in the given + // encoding using character references???? + def characters(ch: Array[Char], start: Int, length: Int) { + try { + var i = 0; while (i < length) { + val c = ch(start+i); + if (c == '&') out.write("&"); + else if (c == '<') out.write("<"); + // This next fix is normally not necessary. + // However, it is required if text contains ]]> + // (The end CDATA section delimiter) + else if (c == '>') out.write(">"); + else out.write(c); + i = i+1; + } + } + catch { + case e: IOException => + throw new SAXException("Write failed", e); + } + } + + def ignorableWhitespace(ch: Array[Char], start: Int , length: Int) { + this.characters(ch, start, length) + } + + // do I need to escape text in PI???? + def processingInstruction(target: String, data: String) { + try { + out.write("" + target + " " + data + "?>") + } + catch { + case e:IOException => + throw new SAXException("Write failed", e) + } + } + + def skippedEntity(name: String) { + try { + out.write("&" + name + ";") + } + catch { + case e:IOException => + throw new SAXException("Write failed", e) + } + } + + // LexicalHandler methods + private var inDTD: Boolean = false + private val entities = new Stack[String]() + + def startDTD(name: String, publicID: String, systemID: String) { + inDTD = true + // if this is the source document, output a DOCTYPE declaration + if (entities.size() == 0) { + var id = "" + if (publicID != null) id = " PUBLIC \"" + publicID + "\" \"" + systemID + '"'; + else if (systemID != null) id = " SYSTEM \"" + systemID + '"'; + try { + out.write("\r\n") + } + catch { + case e:IOException => + throw new SAXException("Error while writing DOCTYPE", e) + } + } + } + def endDTD() {} + + def startEntity(name: String) { + entities.push(name) + } + + def endEntity(name: String) { + entities.pop() + } + + def startCDATA() {} + def endCDATA() {} + + // Just need this reference so we can ask if a comment is + // inside an include element or not + private var filter: XIncludeFilter = null + + def setFilter(filter: XIncludeFilter) { + this.filter = filter + } + + def comment(ch: Array[Char], start: Int, length: Int) { + if (!inDTD && !filter.insideIncludeElement()) { + try { + out.write("") + } + catch { + case e: IOException => + throw new SAXException("Write failed", e) + } + } + } +} -- cgit v1.2.3