summaryrefslogtreecommitdiff
path: root/platform/android/viewer/src/com/artifex
diff options
context:
space:
mode:
Diffstat (limited to 'platform/android/viewer/src/com/artifex')
-rw-r--r--platform/android/viewer/src/com/artifex/mupdfdemo/ArrayDeque.java1578
-rw-r--r--platform/android/viewer/src/com/artifex/mupdfdemo/AsyncTask.java1088
-rw-r--r--platform/android/viewer/src/com/artifex/mupdfdemo/Deque.java846
-rw-r--r--platform/android/viewer/src/com/artifex/mupdfdemo/MuPDFActivity.java2
-rw-r--r--platform/android/viewer/src/com/artifex/mupdfdemo/OutlineActivityData.java2
-rw-r--r--platform/android/viewer/src/com/artifex/mupdfdemo/OutlineAdapter.java4
-rw-r--r--platform/android/viewer/src/com/artifex/mupdfdemo/OutlineItem.java6
-rw-r--r--platform/android/viewer/src/com/artifex/mupdfdemo/PageView.java20
-rw-r--r--platform/android/viewer/src/com/artifex/mupdfdemo/ReaderView.java84
-rw-r--r--platform/android/viewer/src/com/artifex/mupdfdemo/SearchTask.java2
-rw-r--r--platform/android/viewer/src/com/artifex/mupdfdemo/SearchTaskResult.java2
11 files changed, 1817 insertions, 1817 deletions
diff --git a/platform/android/viewer/src/com/artifex/mupdfdemo/ArrayDeque.java b/platform/android/viewer/src/com/artifex/mupdfdemo/ArrayDeque.java
index 4f06ea41..c8549058 100644
--- a/platform/android/viewer/src/com/artifex/mupdfdemo/ArrayDeque.java
+++ b/platform/android/viewer/src/com/artifex/mupdfdemo/ArrayDeque.java
@@ -62,794 +62,794 @@ import java.util.Stack;
* @param <E> the type of elements held in this collection
*/
public class ArrayDeque<E> extends AbstractCollection<E>
- implements Deque<E>, Cloneable, java.io.Serializable
+ implements Deque<E>, Cloneable, java.io.Serializable
{
- /**
- * The array in which the elements of the deque are stored.
- * The capacity of the deque is the length of this array, which is
- * always a power of two. The array is never allowed to become
- * full, except transiently within an addX method where it is
- * resized (see doubleCapacity) immediately upon becoming full,
- * thus avoiding head and tail wrapping around to equal each
- * other. We also guarantee that all array cells not holding
- * deque elements are always null.
- */
- private transient Object[] elements;
-
- /**
- * The index of the element at the head of the deque (which is the
- * element that would be removed by remove() or pop()); or an
- * arbitrary number equal to tail if the deque is empty.
- */
- private transient int head;
-
- /**
- * The index at which the next element would be added to the tail
- * of the deque (via addLast(E), add(E), or push(E)).
- */
- private transient int tail;
-
- /**
- * The minimum capacity that we'll use for a newly created deque.
- * Must be a power of 2.
- */
- private static final int MIN_INITIAL_CAPACITY = 8;
-
- // ****** Array allocation and resizing utilities ******
-
- /**
- * Allocate empty array to hold the given number of elements.
- *
- * @param numElements the number of elements to hold
- */
- private void allocateElements(int numElements) {
- int initialCapacity = MIN_INITIAL_CAPACITY;
- // Find the best power of two to hold elements.
- // Tests "<=" because arrays aren't kept full.
- if (numElements >= initialCapacity) {
- initialCapacity = numElements;
- initialCapacity |= (initialCapacity >>> 1);
- initialCapacity |= (initialCapacity >>> 2);
- initialCapacity |= (initialCapacity >>> 4);
- initialCapacity |= (initialCapacity >>> 8);
- initialCapacity |= (initialCapacity >>> 16);
- initialCapacity++;
-
- if (initialCapacity < 0) // Too many elements, must back off
- initialCapacity >>>= 1;// Good luck allocating 2 ^ 30 elements
- }
- elements = new Object[initialCapacity];
- }
-
- /**
- * Double the capacity of this deque. Call only when full, i.e.,
- * when head and tail have wrapped around to become equal.
- */
- private void doubleCapacity() {
- // assert head == tail;
- int p = head;
- int n = elements.length;
- int r = n - p; // number of elements to the right of p
- int newCapacity = n << 1;
- if (newCapacity < 0)
- throw new IllegalStateException("Sorry, deque too big");
- Object[] a = new Object[newCapacity];
- System.arraycopy(elements, p, a, 0, r);
- System.arraycopy(elements, 0, a, r, p);
- elements = a;
- head = 0;
- tail = n;
- }
-
- /**
- * Copies the elements from our element array into the specified array,
- * in order (from first to last element in the deque). It is assumed
- * that the array is large enough to hold all elements in the deque.
- *
- * @return its argument
- */
- private <T> T[] copyElements(T[] a) {
- if (head < tail) {
- System.arraycopy(elements, head, a, 0, size());
- } else if (head > tail) {
- int headPortionLen = elements.length - head;
- System.arraycopy(elements, head, a, 0, headPortionLen);
- System.arraycopy(elements, 0, a, headPortionLen, tail);
- }
- return a;
- }
-
- /**
- * Constructs an empty array deque with an initial capacity
- * sufficient to hold 16 elements.
- */
- public ArrayDeque() {
- elements = new Object[16];
- }
-
- /**
- * Constructs an empty array deque with an initial capacity
- * sufficient to hold the specified number of elements.
- *
- * @param numElements lower bound on initial capacity of the deque
- */
- public ArrayDeque(int numElements) {
- allocateElements(numElements);
- }
-
- /**
- * Constructs a deque containing the elements of the specified
- * collection, in the order they are returned by the collection's
- * iterator. (The first element returned by the collection's
- * iterator becomes the first element, or <i>front</i> of the
- * deque.)
- *
- * @param c the collection whose elements are to be placed into the deque
- * @throws NullPointerException if the specified collection is null
- */
- public ArrayDeque(Collection<? extends E> c) {
- allocateElements(c.size());
- addAll(c);
- }
-
- // The main insertion and extraction methods are addFirst,
- // addLast, pollFirst, pollLast. The other methods are defined in
- // terms of these.
-
- /**
- * Inserts the specified element at the front of this deque.
- *
- * @param e the element to add
- * @throws NullPointerException if the specified element is null
- */
- public void addFirst(E e) {
- if (e == null)
- throw new NullPointerException("e == null");
- elements[head = (head - 1) & (elements.length - 1)] = e;
- if (head == tail)
- doubleCapacity();
- }
-
- /**
- * Inserts the specified element at the end of this deque.
- *
- * <p>This method is equivalent to {@link #add}.
- *
- * @param e the element to add
- * @throws NullPointerException if the specified element is null
- */
- public void addLast(E e) {
- if (e == null)
- throw new NullPointerException("e == null");
- elements[tail] = e;
- if ( (tail = (tail + 1) & (elements.length - 1)) == head)
- doubleCapacity();
- }
-
- /**
- * Inserts the specified element at the front of this deque.
- *
- * @param e the element to add
- * @return <tt>true</tt> (as specified by {@link Deque#offerFirst})
- * @throws NullPointerException if the specified element is null
- */
- public boolean offerFirst(E e) {
- addFirst(e);
- return true;
- }
-
- /**
- * Inserts the specified element at the end of this deque.
- *
- * @param e the element to add
- * @return <tt>true</tt> (as specified by {@link Deque#offerLast})
- * @throws NullPointerException if the specified element is null
- */
- public boolean offerLast(E e) {
- addLast(e);
- return true;
- }
-
- /**
- * @throws NoSuchElementException {@inheritDoc}
- */
- public E removeFirst() {
- E x = pollFirst();
- if (x == null)
- throw new NoSuchElementException();
- return x;
- }
-
- /**
- * @throws NoSuchElementException {@inheritDoc}
- */
- public E removeLast() {
- E x = pollLast();
- if (x == null)
- throw new NoSuchElementException();
- return x;
- }
-
- public E pollFirst() {
- int h = head;
- @SuppressWarnings("unchecked") E result = (E) elements[h];
- // Element is null if deque empty
- if (result == null)
- return null;
- elements[h] = null; // Must null out slot
- head = (h + 1) & (elements.length - 1);
- return result;
- }
-
- public E pollLast() {
- int t = (tail - 1) & (elements.length - 1);
- @SuppressWarnings("unchecked") E result = (E) elements[t];
- if (result == null)
- return null;
- elements[t] = null;
- tail = t;
- return result;
- }
-
- /**
- * @throws NoSuchElementException {@inheritDoc}
- */
- public E getFirst() {
- @SuppressWarnings("unchecked") E result = (E) elements[head];
- if (result == null)
- throw new NoSuchElementException();
- return result;
- }
-
- /**
- * @throws NoSuchElementException {@inheritDoc}
- */
- public E getLast() {
- @SuppressWarnings("unchecked")
- E result = (E) elements[(tail - 1) & (elements.length - 1)];
- if (result == null)
- throw new NoSuchElementException();
- return result;
- }
-
- public E peekFirst() {
- @SuppressWarnings("unchecked") E result = (E) elements[head];
- // elements[head] is null if deque empty
- return result;
- }
-
- public E peekLast() {
- @SuppressWarnings("unchecked")
- E result = (E) elements[(tail - 1) & (elements.length - 1)];
- return result;
- }
-
- /**
- * Removes the first occurrence of the specified element in this
- * deque (when traversing the deque from head to tail).
- * If the deque does not contain the element, it is unchanged.
- * More formally, removes the first element <tt>e</tt> such that
- * <tt>o.equals(e)</tt> (if such an element exists).
- * Returns <tt>true</tt> if this deque contained the specified element
- * (or equivalently, if this deque changed as a result of the call).
- *
- * @param o element to be removed from this deque, if present
- * @return <tt>true</tt> if the deque contained the specified element
- */
- public boolean removeFirstOccurrence(Object o) {
- if (o == null)
- return false;
- int mask = elements.length - 1;
- int i = head;
- Object x;
- while ( (x = elements[i]) != null) {
- if (o.equals(x)) {
- delete(i);
- return true;
- }
- i = (i + 1) & mask;
- }
- return false;
- }
-
- /**
- * Removes the last occurrence of the specified element in this
- * deque (when traversing the deque from head to tail).
- * If the deque does not contain the element, it is unchanged.
- * More formally, removes the last element <tt>e</tt> such that
- * <tt>o.equals(e)</tt> (if such an element exists).
- * Returns <tt>true</tt> if this deque contained the specified element
- * (or equivalently, if this deque changed as a result of the call).
- *
- * @param o element to be removed from this deque, if present
- * @return <tt>true</tt> if the deque contained the specified element
- */
- public boolean removeLastOccurrence(Object o) {
- if (o == null)
- return false;
- int mask = elements.length - 1;
- int i = (tail - 1) & mask;
- Object x;
- while ( (x = elements[i]) != null) {
- if (o.equals(x)) {
- delete(i);
- return true;
- }
- i = (i - 1) & mask;
- }
- return false;
- }
-
- // *** Queue methods ***
-
- /**
- * Inserts the specified element at the end of this deque.
- *
- * <p>This method is equivalent to {@link #addLast}.
- *
- * @param e the element to add
- * @return <tt>true</tt> (as specified by {@link Collection#add})
- * @throws NullPointerException if the specified element is null
- */
- public boolean add(E e) {
- addLast(e);
- return true;
- }
-
- /**
- * Inserts the specified element at the end of this deque.
- *
- * <p>This method is equivalent to {@link #offerLast}.
- *
- * @param e the element to add
- * @return <tt>true</tt> (as specified by {@link Queue#offer})
- * @throws NullPointerException if the specified element is null
- */
- public boolean offer(E e) {
- return offerLast(e);
- }
-
- /**
- * Retrieves and removes the head of the queue represented by this deque.
- *
- * This method differs from {@link #poll poll} only in that it throws an
- * exception if this deque is empty.
- *
- * <p>This method is equivalent to {@link #removeFirst}.
- *
- * @return the head of the queue represented by this deque
- * @throws NoSuchElementException {@inheritDoc}
- */
- public E remove() {
- return removeFirst();
- }
-
- /**
- * Retrieves and removes the head of the queue represented by this deque
- * (in other words, the first element of this deque), or returns
- * <tt>null</tt> if this deque is empty.
- *
- * <p>This method is equivalent to {@link #pollFirst}.
- *
- * @return the head of the queue represented by this deque, or
- * <tt>null</tt> if this deque is empty
- */
- public E poll() {
- return pollFirst();
- }
-
- /**
- * Retrieves, but does not remove, the head of the queue represented by
- * this deque. This method differs from {@link #peek peek} only in
- * that it throws an exception if this deque is empty.
- *
- * <p>This method is equivalent to {@link #getFirst}.
- *
- * @return the head of the queue represented by this deque
- * @throws NoSuchElementException {@inheritDoc}
- */
- public E element() {
- return getFirst();
- }
-
- /**
- * Retrieves, but does not remove, the head of the queue represented by
- * this deque, or returns <tt>null</tt> if this deque is empty.
- *
- * <p>This method is equivalent to {@link #peekFirst}.
- *
- * @return the head of the queue represented by this deque, or
- * <tt>null</tt> if this deque is empty
- */
- public E peek() {
- return peekFirst();
- }
-
- // *** Stack methods ***
-
- /**
- * Pushes an element onto the stack represented by this deque. In other
- * words, inserts the element at the front of this deque.
- *
- * <p>This method is equivalent to {@link #addFirst}.
- *
- * @param e the element to push
- * @throws NullPointerException if the specified element is null
- */
- public void push(E e) {
- addFirst(e);
- }
-
- /**
- * Pops an element from the stack represented by this deque. In other
- * words, removes and returns the first element of this deque.
- *
- * <p>This method is equivalent to {@link #removeFirst()}.
- *
- * @return the element at the front of this deque (which is the top
- * of the stack represented by this deque)
- * @throws NoSuchElementException {@inheritDoc}
- */
- public E pop() {
- return removeFirst();
- }
-
- private void checkInvariants() {
- // assert elements[tail] == null;
- // assert head == tail ? elements[head] == null :
- // (elements[head] != null &&
- // elements[(tail - 1) & (elements.length - 1)] != null);
- // assert elements[(head - 1) & (elements.length - 1)] == null;
- }
-
- /**
- * Removes the element at the specified position in the elements array,
- * adjusting head and tail as necessary. This can result in motion of
- * elements backwards or forwards in the array.
- *
- * <p>This method is called delete rather than remove to emphasize
- * that its semantics differ from those of {@link List#remove(int)}.
- *
- * @return true if elements moved backwards
- */
- private boolean delete(int i) {
- //checkInvariants();
- final Object[] elements = this.elements;
- final int mask = elements.length - 1;
- final int h = head;
- final int t = tail;
- final int front = (i - h) & mask;
- final int back = (t - i) & mask;
-
- // Invariant: head <= i < tail mod circularity
- if (front >= ((t - h) & mask))
- throw new ConcurrentModificationException();
-
- // Optimize for least element motion
- if (front < back) {
- if (h <= i) {
- System.arraycopy(elements, h, elements, h + 1, front);
- } else { // Wrap around
- System.arraycopy(elements, 0, elements, 1, i);
- elements[0] = elements[mask];
- System.arraycopy(elements, h, elements, h + 1, mask - h);
- }
- elements[h] = null;
- head = (h + 1) & mask;
- return false;
- } else {
- if (i < t) { // Copy the null tail as well
- System.arraycopy(elements, i + 1, elements, i, back);
- tail = t - 1;
- } else { // Wrap around
- System.arraycopy(elements, i + 1, elements, i, mask - i);
- elements[mask] = elements[0];
- System.arraycopy(elements, 1, elements, 0, t);
- tail = (t - 1) & mask;
- }
- return true;
- }
- }
-
- // *** Collection Methods ***
-
- /**
- * Returns the number of elements in this deque.
- *
- * @return the number of elements in this deque
- */
- public int size() {
- return (tail - head) & (elements.length - 1);
- }
-
- /**
- * Returns <tt>true</tt> if this deque contains no elements.
- *
- * @return <tt>true</tt> if this deque contains no elements
- */
- public boolean isEmpty() {
- return head == tail;
- }
-
- /**
- * Returns an iterator over the elements in this deque. The elements
- * will be ordered from first (head) to last (tail). This is the same
- * order that elements would be dequeued (via successive calls to
- * {@link #remove} or popped (via successive calls to {@link #pop}).
- *
- * @return an iterator over the elements in this deque
- */
- public Iterator<E> iterator() {
- return new DeqIterator();
- }
-
- public Iterator<E> descendingIterator() {
- return new DescendingIterator();
- }
-
- private class DeqIterator implements Iterator<E> {
- /**
- * Index of element to be returned by subsequent call to next.
- */
- private int cursor = head;
-
- /**
- * Tail recorded at construction (also in remove), to stop
- * iterator and also to check for comodification.
- */
- private int fence = tail;
-
- /**
- * Index of element returned by most recent call to next.
- * Reset to -1 if element is deleted by a call to remove.
- */
- private int lastRet = -1;
-
- public boolean hasNext() {
- return cursor != fence;
- }
-
- public E next() {
- if (cursor == fence)
- throw new NoSuchElementException();
- @SuppressWarnings("unchecked") E result = (E) elements[cursor];
- // This check doesn't catch all possible comodifications,
- // but does catch the ones that corrupt traversal
- if (tail != fence || result == null)
- throw new ConcurrentModificationException();
- lastRet = cursor;
- cursor = (cursor + 1) & (elements.length - 1);
- return result;
- }
-
- public void remove() {
- if (lastRet < 0)
- throw new IllegalStateException();
- if (delete(lastRet)) { // if left-shifted, undo increment in next()
- cursor = (cursor - 1) & (elements.length - 1);
- fence = tail;
- }
- lastRet = -1;
- }
- }
-
- private class DescendingIterator implements Iterator<E> {
- /*
- * This class is nearly a mirror-image of DeqIterator, using
- * tail instead of head for initial cursor, and head instead of
- * tail for fence.
- */
- private int cursor = tail;
- private int fence = head;
- private int lastRet = -1;
-
- public boolean hasNext() {
- return cursor != fence;
- }
-
- public E next() {
- if (cursor == fence)
- throw new NoSuchElementException();
- cursor = (cursor - 1) & (elements.length - 1);
- @SuppressWarnings("unchecked") E result = (E) elements[cursor];
- if (head != fence || result == null)
- throw new ConcurrentModificationException();
- lastRet = cursor;
- return result;
- }
-
- public void remove() {
- if (lastRet < 0)
- throw new IllegalStateException();
- if (!delete(lastRet)) {
- cursor = (cursor + 1) & (elements.length - 1);
- fence = head;
- }
- lastRet = -1;
- }
- }
-
- /**
- * Returns <tt>true</tt> if this deque contains the specified element.
- * More formally, returns <tt>true</tt> if and only if this deque contains
- * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>.
- *
- * @param o object to be checked for containment in this deque
- * @return <tt>true</tt> if this deque contains the specified element
- */
- public boolean contains(Object o) {
- if (o == null)
- return false;
- int mask = elements.length - 1;
- int i = head;
- Object x;
- while ( (x = elements[i]) != null) {
- if (o.equals(x))
- return true;
- i = (i + 1) & mask;
- }
- return false;
- }
-
- /**
- * Removes a single instance of the specified element from this deque.
- * If the deque does not contain the element, it is unchanged.
- * More formally, removes the first element <tt>e</tt> such that
- * <tt>o.equals(e)</tt> (if such an element exists).
- * Returns <tt>true</tt> if this deque contained the specified element
- * (or equivalently, if this deque changed as a result of the call).
- *
- * <p>This method is equivalent to {@link #removeFirstOccurrence}.
- *
- * @param o element to be removed from this deque, if present
- * @return <tt>true</tt> if this deque contained the specified element
- */
- public boolean remove(Object o) {
- return removeFirstOccurrence(o);
- }
-
- /**
- * Removes all of the elements from this deque.
- * The deque will be empty after this call returns.
- */
- public void clear() {
- int h = head;
- int t = tail;
- if (h != t) { // clear all cells
- head = tail = 0;
- int i = h;
- int mask = elements.length - 1;
- do {
- elements[i] = null;
- i = (i + 1) & mask;
- } while (i != t);
- }
- }
-
- /**
- * Returns an array containing all of the elements in this deque
- * in proper sequence (from first to last element).
- *
- * <p>The returned array will be "safe" in that no references to it are
- * maintained by this deque. (In other words, this method must allocate
- * a new array). The caller is thus free to modify the returned array.
- *
- * <p>This method acts as bridge between array-based and collection-based
- * APIs.
- *
- * @return an array containing all of the elements in this deque
- */
- public Object[] toArray() {
- return copyElements(new Object[size()]);
- }
-
- /**
- * Returns an array containing all of the elements in this deque in
- * proper sequence (from first to last element); the runtime type of the
- * returned array is that of the specified array. If the deque fits in
- * the specified array, it is returned therein. Otherwise, a new array
- * is allocated with the runtime type of the specified array and the
- * size of this deque.
- *
- * <p>If this deque fits in the specified array with room to spare
- * (i.e., the array has more elements than this deque), the element in
- * the array immediately following the end of the deque is set to
- * <tt>null</tt>.
- *
- * <p>Like the {@link #toArray()} method, this method acts as bridge between
- * array-based and collection-based APIs. Further, this method allows
- * precise control over the runtime type of the output array, and may,
- * under certain circumstances, be used to save allocation costs.
- *
- * <p>Suppose <tt>x</tt> is a deque known to contain only strings.
- * The following code can be used to dump the deque into a newly
- * allocated array of <tt>String</tt>:
- *
- * <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
- *
- * Note that <tt>toArray(new Object[0])</tt> is identical in function to
- * <tt>toArray()</tt>.
- *
- * @param a the array into which the elements of the deque are to
- * be stored, if it is big enough; otherwise, a new array of the
- * same runtime type is allocated for this purpose
- * @return an array containing all of the elements in this deque
- * @throws ArrayStoreException if the runtime type of the specified array
- * is not a supertype of the runtime type of every element in
- * this deque
- * @throws NullPointerException if the specified array is null
- */
- @SuppressWarnings("unchecked")
- public <T> T[] toArray(T[] a) {
- int size = size();
- if (a.length < size)
- a = (T[])java.lang.reflect.Array.newInstance(
- a.getClass().getComponentType(), size);
- copyElements(a);
- if (a.length > size)
- a[size] = null;
- return a;
- }
-
- // *** Object methods ***
-
- /**
- * Returns a copy of this deque.
- *
- * @return a copy of this deque
- */
- public ArrayDeque<E> clone() {
- try {
- @SuppressWarnings("unchecked")
- ArrayDeque<E> result = (ArrayDeque<E>) super.clone();
- result.elements = Arrays.copyOf(elements, elements.length);
- return result;
-
- } catch (CloneNotSupportedException e) {
- throw new AssertionError();
- }
- }
-
- /**
- * Appease the serialization gods.
- */
- private static final long serialVersionUID = 2340985798034038923L;
-
- /**
- * Serialize this deque.
- *
- * @serialData The current size (<tt>int</tt>) of the deque,
- * followed by all of its elements (each an object reference) in
- * first-to-last order.
- */
- private void writeObject(java.io.ObjectOutputStream s)
- throws java.io.IOException {
- s.defaultWriteObject();
-
- // Write out size
- s.writeInt(size());
-
- // Write out elements in order.
- int mask = elements.length - 1;
- for (int i = head; i != tail; i = (i + 1) & mask)
- s.writeObject(elements[i]);
- }
-
- /**
- * Deserialize this deque.
- */
- private void readObject(java.io.ObjectInputStream s)
- throws java.io.IOException, ClassNotFoundException {
- s.defaultReadObject();
-
- // Read in size and allocate array
- int size = s.readInt();
- allocateElements(size);
- head = 0;
- tail = size;
-
- // Read in all elements in the proper order.
- for (int i = 0; i < size; i++)
- elements[i] = s.readObject();
- }
+ /**
+ * The array in which the elements of the deque are stored.
+ * The capacity of the deque is the length of this array, which is
+ * always a power of two. The array is never allowed to become
+ * full, except transiently within an addX method where it is
+ * resized (see doubleCapacity) immediately upon becoming full,
+ * thus avoiding head and tail wrapping around to equal each
+ * other. We also guarantee that all array cells not holding
+ * deque elements are always null.
+ */
+ private transient Object[] elements;
+
+ /**
+ * The index of the element at the head of the deque (which is the
+ * element that would be removed by remove() or pop()); or an
+ * arbitrary number equal to tail if the deque is empty.
+ */
+ private transient int head;
+
+ /**
+ * The index at which the next element would be added to the tail
+ * of the deque (via addLast(E), add(E), or push(E)).
+ */
+ private transient int tail;
+
+ /**
+ * The minimum capacity that we'll use for a newly created deque.
+ * Must be a power of 2.
+ */
+ private static final int MIN_INITIAL_CAPACITY = 8;
+
+ // ****** Array allocation and resizing utilities ******
+
+ /**
+ * Allocate empty array to hold the given number of elements.
+ *
+ * @param numElements the number of elements to hold
+ */
+ private void allocateElements(int numElements) {
+ int initialCapacity = MIN_INITIAL_CAPACITY;
+ // Find the best power of two to hold elements.
+ // Tests "<=" because arrays aren't kept full.
+ if (numElements >= initialCapacity) {
+ initialCapacity = numElements;
+ initialCapacity |= (initialCapacity >>> 1);
+ initialCapacity |= (initialCapacity >>> 2);
+ initialCapacity |= (initialCapacity >>> 4);
+ initialCapacity |= (initialCapacity >>> 8);
+ initialCapacity |= (initialCapacity >>> 16);
+ initialCapacity++;
+
+ if (initialCapacity < 0) // Too many elements, must back off
+ initialCapacity >>>= 1; // Good luck allocating 2 ^ 30 elements
+ }
+ elements = new Object[initialCapacity];
+ }
+
+ /**
+ * Double the capacity of this deque. Call only when full, i.e.,
+ * when head and tail have wrapped around to become equal.
+ */
+ private void doubleCapacity() {
+ // assert head == tail;
+ int p = head;
+ int n = elements.length;
+ int r = n - p; // number of elements to the right of p
+ int newCapacity = n << 1;
+ if (newCapacity < 0)
+ throw new IllegalStateException("Sorry, deque too big");
+ Object[] a = new Object[newCapacity];
+ System.arraycopy(elements, p, a, 0, r);
+ System.arraycopy(elements, 0, a, r, p);
+ elements = a;
+ head = 0;
+ tail = n;
+ }
+
+ /**
+ * Copies the elements from our element array into the specified array,
+ * in order (from first to last element in the deque). It is assumed
+ * that the array is large enough to hold all elements in the deque.
+ *
+ * @return its argument
+ */
+ private <T> T[] copyElements(T[] a) {
+ if (head < tail) {
+ System.arraycopy(elements, head, a, 0, size());
+ } else if (head > tail) {
+ int headPortionLen = elements.length - head;
+ System.arraycopy(elements, head, a, 0, headPortionLen);
+ System.arraycopy(elements, 0, a, headPortionLen, tail);
+ }
+ return a;
+ }
+
+ /**
+ * Constructs an empty array deque with an initial capacity
+ * sufficient to hold 16 elements.
+ */
+ public ArrayDeque() {
+ elements = new Object[16];
+ }
+
+ /**
+ * Constructs an empty array deque with an initial capacity
+ * sufficient to hold the specified number of elements.
+ *
+ * @param numElements lower bound on initial capacity of the deque
+ */
+ public ArrayDeque(int numElements) {
+ allocateElements(numElements);
+ }
+
+ /**
+ * Constructs a deque containing the elements of the specified
+ * collection, in the order they are returned by the collection's
+ * iterator. (The first element returned by the collection's
+ * iterator becomes the first element, or <i>front</i> of the
+ * deque.)
+ *
+ * @param c the collection whose elements are to be placed into the deque
+ * @throws NullPointerException if the specified collection is null
+ */
+ public ArrayDeque(Collection<? extends E> c) {
+ allocateElements(c.size());
+ addAll(c);
+ }
+
+ // The main insertion and extraction methods are addFirst,
+ // addLast, pollFirst, pollLast. The other methods are defined in
+ // terms of these.
+
+ /**
+ * Inserts the specified element at the front of this deque.
+ *
+ * @param e the element to add
+ * @throws NullPointerException if the specified element is null
+ */
+ public void addFirst(E e) {
+ if (e == null)
+ throw new NullPointerException("e == null");
+ elements[head = (head - 1) & (elements.length - 1)] = e;
+ if (head == tail)
+ doubleCapacity();
+ }
+
+ /**
+ * Inserts the specified element at the end of this deque.
+ *
+ * <p>This method is equivalent to {@link #add}.
+ *
+ * @param e the element to add
+ * @throws NullPointerException if the specified element is null
+ */
+ public void addLast(E e) {
+ if (e == null)
+ throw new NullPointerException("e == null");
+ elements[tail] = e;
+ if ( (tail = (tail + 1) & (elements.length - 1)) == head)
+ doubleCapacity();
+ }
+
+ /**
+ * Inserts the specified element at the front of this deque.
+ *
+ * @param e the element to add
+ * @return <tt>true</tt> (as specified by {@link Deque#offerFirst})
+ * @throws NullPointerException if the specified element is null
+ */
+ public boolean offerFirst(E e) {
+ addFirst(e);
+ return true;
+ }
+
+ /**
+ * Inserts the specified element at the end of this deque.
+ *
+ * @param e the element to add
+ * @return <tt>true</tt> (as specified by {@link Deque#offerLast})
+ * @throws NullPointerException if the specified element is null
+ */
+ public boolean offerLast(E e) {
+ addLast(e);
+ return true;
+ }
+
+ /**
+ * @throws NoSuchElementException {@inheritDoc}
+ */
+ public E removeFirst() {
+ E x = pollFirst();
+ if (x == null)
+ throw new NoSuchElementException();
+ return x;
+ }
+
+ /**
+ * @throws NoSuchElementException {@inheritDoc}
+ */
+ public E removeLast() {
+ E x = pollLast();
+ if (x == null)
+ throw new NoSuchElementException();
+ return x;
+ }
+
+ public E pollFirst() {
+ int h = head;
+ @SuppressWarnings("unchecked") E result = (E) elements[h];
+ // Element is null if deque empty
+ if (result == null)
+ return null;
+ elements[h] = null; // Must null out slot
+ head = (h + 1) & (elements.length - 1);
+ return result;
+ }
+
+ public E pollLast() {
+ int t = (tail - 1) & (elements.length - 1);
+ @SuppressWarnings("unchecked") E result = (E) elements[t];
+ if (result == null)
+ return null;
+ elements[t] = null;
+ tail = t;
+ return result;
+ }
+
+ /**
+ * @throws NoSuchElementException {@inheritDoc}
+ */
+ public E getFirst() {
+ @SuppressWarnings("unchecked") E result = (E) elements[head];
+ if (result == null)
+ throw new NoSuchElementException();
+ return result;
+ }
+
+ /**
+ * @throws NoSuchElementException {@inheritDoc}
+ */
+ public E getLast() {
+ @SuppressWarnings("unchecked")
+ E result = (E) elements[(tail - 1) & (elements.length - 1)];
+ if (result == null)
+ throw new NoSuchElementException();
+ return result;
+ }
+
+ public E peekFirst() {
+ @SuppressWarnings("unchecked") E result = (E) elements[head];
+ // elements[head] is null if deque empty
+ return result;
+ }
+
+ public E peekLast() {
+ @SuppressWarnings("unchecked")
+ E result = (E) elements[(tail - 1) & (elements.length - 1)];
+ return result;
+ }
+
+ /**
+ * Removes the first occurrence of the specified element in this
+ * deque (when traversing the deque from head to tail).
+ * If the deque does not contain the element, it is unchanged.
+ * More formally, removes the first element <tt>e</tt> such that
+ * <tt>o.equals(e)</tt> (if such an element exists).
+ * Returns <tt>true</tt> if this deque contained the specified element
+ * (or equivalently, if this deque changed as a result of the call).
+ *
+ * @param o element to be removed from this deque, if present
+ * @return <tt>true</tt> if the deque contained the specified element
+ */
+ public boolean removeFirstOccurrence(Object o) {
+ if (o == null)
+ return false;
+ int mask = elements.length - 1;
+ int i = head;
+ Object x;
+ while ( (x = elements[i]) != null) {
+ if (o.equals(x)) {
+ delete(i);
+ return true;
+ }
+ i = (i + 1) & mask;
+ }
+ return false;
+ }
+
+ /**
+ * Removes the last occurrence of the specified element in this
+ * deque (when traversing the deque from head to tail).
+ * If the deque does not contain the element, it is unchanged.
+ * More formally, removes the last element <tt>e</tt> such that
+ * <tt>o.equals(e)</tt> (if such an element exists).
+ * Returns <tt>true</tt> if this deque contained the specified element
+ * (or equivalently, if this deque changed as a result of the call).
+ *
+ * @param o element to be removed from this deque, if present
+ * @return <tt>true</tt> if the deque contained the specified element
+ */
+ public boolean removeLastOccurrence(Object o) {
+ if (o == null)
+ return false;
+ int mask = elements.length - 1;
+ int i = (tail - 1) & mask;
+ Object x;
+ while ( (x = elements[i]) != null) {
+ if (o.equals(x)) {
+ delete(i);
+ return true;
+ }
+ i = (i - 1) & mask;
+ }
+ return false;
+ }
+
+ // *** Queue methods ***
+
+ /**
+ * Inserts the specified element at the end of this deque.
+ *
+ * <p>This method is equivalent to {@link #addLast}.
+ *
+ * @param e the element to add
+ * @return <tt>true</tt> (as specified by {@link Collection#add})
+ * @throws NullPointerException if the specified element is null
+ */
+ public boolean add(E e) {
+ addLast(e);
+ return true;
+ }
+
+ /**
+ * Inserts the specified element at the end of this deque.
+ *
+ * <p>This method is equivalent to {@link #offerLast}.
+ *
+ * @param e the element to add
+ * @return <tt>true</tt> (as specified by {@link Queue#offer})
+ * @throws NullPointerException if the specified element is null
+ */
+ public boolean offer(E e) {
+ return offerLast(e);
+ }
+
+ /**
+ * Retrieves and removes the head of the queue represented by this deque.
+ *
+ * This method differs from {@link #poll poll} only in that it throws an
+ * exception if this deque is empty.
+ *
+ * <p>This method is equivalent to {@link #removeFirst}.
+ *
+ * @return the head of the queue represented by this deque
+ * @throws NoSuchElementException {@inheritDoc}
+ */
+ public E remove() {
+ return removeFirst();
+ }
+
+ /**
+ * Retrieves and removes the head of the queue represented by this deque
+ * (in other words, the first element of this deque), or returns
+ * <tt>null</tt> if this deque is empty.
+ *
+ * <p>This method is equivalent to {@link #pollFirst}.
+ *
+ * @return the head of the queue represented by this deque, or
+ * <tt>null</tt> if this deque is empty
+ */
+ public E poll() {
+ return pollFirst();
+ }
+
+ /**
+ * Retrieves, but does not remove, the head of the queue represented by
+ * this deque. This method differs from {@link #peek peek} only in
+ * that it throws an exception if this deque is empty.
+ *
+ * <p>This method is equivalent to {@link #getFirst}.
+ *
+ * @return the head of the queue represented by this deque
+ * @throws NoSuchElementException {@inheritDoc}
+ */
+ public E element() {
+ return getFirst();
+ }
+
+ /**
+ * Retrieves, but does not remove, the head of the queue represented by
+ * this deque, or returns <tt>null</tt> if this deque is empty.
+ *
+ * <p>This method is equivalent to {@link #peekFirst}.
+ *
+ * @return the head of the queue represented by this deque, or
+ * <tt>null</tt> if this deque is empty
+ */
+ public E peek() {
+ return peekFirst();
+ }
+
+ // *** Stack methods ***
+
+ /**
+ * Pushes an element onto the stack represented by this deque. In other
+ * words, inserts the element at the front of this deque.
+ *
+ * <p>This method is equivalent to {@link #addFirst}.
+ *
+ * @param e the element to push
+ * @throws NullPointerException if the specified element is null
+ */
+ public void push(E e) {
+ addFirst(e);
+ }
+
+ /**
+ * Pops an element from the stack represented by this deque. In other
+ * words, removes and returns the first element of this deque.
+ *
+ * <p>This method is equivalent to {@link #removeFirst()}.
+ *
+ * @return the element at the front of this deque (which is the top
+ * of the stack represented by this deque)
+ * @throws NoSuchElementException {@inheritDoc}
+ */
+ public E pop() {
+ return removeFirst();
+ }
+
+ private void checkInvariants() {
+ // assert elements[tail] == null;
+ // assert head == tail ? elements[head] == null :
+ // (elements[head] != null &&
+ // elements[(tail - 1) & (elements.length - 1)] != null);
+ // assert elements[(head - 1) & (elements.length - 1)] == null;
+ }
+
+ /**
+ * Removes the element at the specified position in the elements array,
+ * adjusting head and tail as necessary. This can result in motion of
+ * elements backwards or forwards in the array.
+ *
+ * <p>This method is called delete rather than remove to emphasize
+ * that its semantics differ from those of {@link List#remove(int)}.
+ *
+ * @return true if elements moved backwards
+ */
+ private boolean delete(int i) {
+ //checkInvariants();
+ final Object[] elements = this.elements;
+ final int mask = elements.length - 1;
+ final int h = head;
+ final int t = tail;
+ final int front = (i - h) & mask;
+ final int back = (t - i) & mask;
+
+ // Invariant: head <= i < tail mod circularity
+ if (front >= ((t - h) & mask))
+ throw new ConcurrentModificationException();
+
+ // Optimize for least element motion
+ if (front < back) {
+ if (h <= i) {
+ System.arraycopy(elements, h, elements, h + 1, front);
+ } else { // Wrap around
+ System.arraycopy(elements, 0, elements, 1, i);
+ elements[0] = elements[mask];
+ System.arraycopy(elements, h, elements, h + 1, mask - h);
+ }
+ elements[h] = null;
+ head = (h + 1) & mask;
+ return false;
+ } else {
+ if (i < t) { // Copy the null tail as well
+ System.arraycopy(elements, i + 1, elements, i, back);
+ tail = t - 1;
+ } else { // Wrap around
+ System.arraycopy(elements, i + 1, elements, i, mask - i);
+ elements[mask] = elements[0];
+ System.arraycopy(elements, 1, elements, 0, t);
+ tail = (t - 1) & mask;
+ }
+ return true;
+ }
+ }
+
+ // *** Collection Methods ***
+
+ /**
+ * Returns the number of elements in this deque.
+ *
+ * @return the number of elements in this deque
+ */
+ public int size() {
+ return (tail - head) & (elements.length - 1);
+ }
+
+ /**
+ * Returns <tt>true</tt> if this deque contains no elements.
+ *
+ * @return <tt>true</tt> if this deque contains no elements
+ */
+ public boolean isEmpty() {
+ return head == tail;
+ }
+
+ /**
+ * Returns an iterator over the elements in this deque. The elements
+ * will be ordered from first (head) to last (tail). This is the same
+ * order that elements would be dequeued (via successive calls to
+ * {@link #remove} or popped (via successive calls to {@link #pop}).
+ *
+ * @return an iterator over the elements in this deque
+ */
+ public Iterator<E> iterator() {
+ return new DeqIterator();
+ }
+
+ public Iterator<E> descendingIterator() {
+ return new DescendingIterator();
+ }
+
+ private class DeqIterator implements Iterator<E> {
+ /**
+ * Index of element to be returned by subsequent call to next.
+ */
+ private int cursor = head;
+
+ /**
+ * Tail recorded at construction (also in remove), to stop
+ * iterator and also to check for comodification.
+ */
+ private int fence = tail;
+
+ /**
+ * Index of element returned by most recent call to next.
+ * Reset to -1 if element is deleted by a call to remove.
+ */
+ private int lastRet = -1;
+
+ public boolean hasNext() {
+ return cursor != fence;
+ }
+
+ public E next() {
+ if (cursor == fence)
+ throw new NoSuchElementException();
+ @SuppressWarnings("unchecked") E result = (E) elements[cursor];
+ // This check doesn't catch all possible comodifications,
+ // but does catch the ones that corrupt traversal
+ if (tail != fence || result == null)
+ throw new ConcurrentModificationException();
+ lastRet = cursor;
+ cursor = (cursor + 1) & (elements.length - 1);
+ return result;
+ }
+
+ public void remove() {
+ if (lastRet < 0)
+ throw new IllegalStateException();
+ if (delete(lastRet)) { // if left-shifted, undo increment in next()
+ cursor = (cursor - 1) & (elements.length - 1);
+ fence = tail;
+ }
+ lastRet = -1;
+ }
+ }
+
+ private class DescendingIterator implements Iterator<E> {
+ /*
+ * This class is nearly a mirror-image of DeqIterator, using
+ * tail instead of head for initial cursor, and head instead of
+ * tail for fence.
+ */
+ private int cursor = tail;
+ private int fence = head;
+ private int lastRet = -1;
+
+ public boolean hasNext() {
+ return cursor != fence;
+ }
+
+ public E next() {
+ if (cursor == fence)
+ throw new NoSuchElementException();
+ cursor = (cursor - 1) & (elements.length - 1);
+ @SuppressWarnings("unchecked") E result = (E) elements[cursor];
+ if (head != fence || result == null)
+ throw new ConcurrentModificationException();
+ lastRet = cursor;
+ return result;
+ }
+
+ public void remove() {
+ if (lastRet < 0)
+ throw new IllegalStateException();
+ if (!delete(lastRet)) {
+ cursor = (cursor + 1) & (elements.length - 1);
+ fence = head;
+ }
+ lastRet = -1;
+ }
+ }
+
+ /**
+ * Returns <tt>true</tt> if this deque contains the specified element.
+ * More formally, returns <tt>true</tt> if and only if this deque contains
+ * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>.
+ *
+ * @param o object to be checked for containment in this deque
+ * @return <tt>true</tt> if this deque contains the specified element
+ */
+ public boolean contains(Object o) {
+ if (o == null)
+ return false;
+ int mask = elements.length - 1;
+ int i = head;
+ Object x;
+ while ( (x = elements[i]) != null) {
+ if (o.equals(x))
+ return true;
+ i = (i + 1) & mask;
+ }
+ return false;
+ }
+
+ /**
+ * Removes a single instance of the specified element from this deque.
+ * If the deque does not contain the element, it is unchanged.
+ * More formally, removes the first element <tt>e</tt> such that
+ * <tt>o.equals(e)</tt> (if such an element exists).
+ * Returns <tt>true</tt> if this deque contained the specified element
+ * (or equivalently, if this deque changed as a result of the call).
+ *
+ * <p>This method is equivalent to {@link #removeFirstOccurrence}.
+ *
+ * @param o element to be removed from this deque, if present
+ * @return <tt>true</tt> if this deque contained the specified element
+ */
+ public boolean remove(Object o) {
+ return removeFirstOccurrence(o);
+ }
+
+ /**
+ * Removes all of the elements from this deque.
+ * The deque will be empty after this call returns.
+ */
+ public void clear() {
+ int h = head;
+ int t = tail;
+ if (h != t) { // clear all cells
+ head = tail = 0;
+ int i = h;
+ int mask = elements.length - 1;
+ do {
+ elements[i] = null;
+ i = (i + 1) & mask;
+ } while (i != t);
+ }
+ }
+
+ /**
+ * Returns an array containing all of the elements in this deque
+ * in proper sequence (from first to last element).
+ *
+ * <p>The returned array will be "safe" in that no references to it are
+ * maintained by this deque. (In other words, this method must allocate
+ * a new array). The caller is thus free to modify the returned array.
+ *
+ * <p>This method acts as bridge between array-based and collection-based
+ * APIs.
+ *
+ * @return an array containing all of the elements in this deque
+ */
+ public Object[] toArray() {
+ return copyElements(new Object[size()]);
+ }
+
+ /**
+ * Returns an array containing all of the elements in this deque in
+ * proper sequence (from first to last element); the runtime type of the
+ * returned array is that of the specified array. If the deque fits in
+ * the specified array, it is returned therein. Otherwise, a new array
+ * is allocated with the runtime type of the specified array and the
+ * size of this deque.
+ *
+ * <p>If this deque fits in the specified array with room to spare
+ * (i.e., the array has more elements than this deque), the element in
+ * the array immediately following the end of the deque is set to
+ * <tt>null</tt>.
+ *
+ * <p>Like the {@link #toArray()} method, this method acts as bridge between
+ * array-based and collection-based APIs. Further, this method allows
+ * precise control over the runtime type of the output array, and may,
+ * under certain circumstances, be used to save allocation costs.
+ *
+ * <p>Suppose <tt>x</tt> is a deque known to contain only strings.
+ * The following code can be used to dump the deque into a newly
+ * allocated array of <tt>String</tt>:
+ *
+ * <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
+ *
+ * Note that <tt>toArray(new Object[0])</tt> is identical in function to
+ * <tt>toArray()</tt>.
+ *
+ * @param a the array into which the elements of the deque are to
+ * be stored, if it is big enough; otherwise, a new array of the
+ * same runtime type is allocated for this purpose
+ * @return an array containing all of the elements in this deque
+ * @throws ArrayStoreException if the runtime type of the specified array
+ * is not a supertype of the runtime type of every element in
+ * this deque
+ * @throws NullPointerException if the specified array is null
+ */
+ @SuppressWarnings("unchecked")
+ public <T> T[] toArray(T[] a) {
+ int size = size();
+ if (a.length < size)
+ a = (T[])java.lang.reflect.Array.newInstance(
+ a.getClass().getComponentType(), size);
+ copyElements(a);
+ if (a.length > size)
+ a[size] = null;
+ return a;
+ }
+
+ // *** Object methods ***
+
+ /**
+ * Returns a copy of this deque.
+ *
+ * @return a copy of this deque
+ */
+ public ArrayDeque<E> clone() {
+ try {
+ @SuppressWarnings("unchecked")
+ ArrayDeque<E> result = (ArrayDeque<E>) super.clone();
+ result.elements = Arrays.copyOf(elements, elements.length);
+ return result;
+
+ } catch (CloneNotSupportedException e) {
+ throw new AssertionError();
+ }
+ }
+
+ /**
+ * Appease the serialization gods.
+ */
+ private static final long serialVersionUID = 2340985798034038923L;
+
+ /**
+ * Serialize this deque.
+ *
+ * @serialData The current size (<tt>int</tt>) of the deque,
+ * followed by all of its elements (each an object reference) in
+ * first-to-last order.
+ */
+ private void writeObject(java.io.ObjectOutputStream s)
+ throws java.io.IOException {
+ s.defaultWriteObject();
+
+ // Write out size
+ s.writeInt(size());
+
+ // Write out elements in order.
+ int mask = elements.length - 1;
+ for (int i = head; i != tail; i = (i + 1) & mask)
+ s.writeObject(elements[i]);
+ }
+
+ /**
+ * Deserialize this deque.
+ */
+ private void readObject(java.io.ObjectInputStream s)
+ throws java.io.IOException, ClassNotFoundException {
+ s.defaultReadObject();
+
+ // Read in size and allocate array
+ int size = s.readInt();
+ allocateElements(size);
+ head = 0;
+ tail = size;
+
+ // Read in all elements in the proper order.
+ for (int i = 0; i < size; i++)
+ elements[i] = s.readObject();
+ }
}
diff --git a/platform/android/viewer/src/com/artifex/mupdfdemo/AsyncTask.java b/platform/android/viewer/src/com/artifex/mupdfdemo/AsyncTask.java
index b370794c..f2dcf70a 100644
--- a/platform/android/viewer/src/com/artifex/mupdfdemo/AsyncTask.java
+++ b/platform/android/viewer/src/com/artifex/mupdfdemo/AsyncTask.java
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -67,25 +67,25 @@ import android.os.Message;
* <p>Here is an example of subclassing:</p>
* <pre class="prettyprint">
* private class DownloadFilesTask extends AsyncTask&lt;URL, Integer, Long&gt; {
- * protected Long doInBackground(URL... urls) {
- * int count = urls.length;
- * long totalSize = 0;
- * for (int i = 0; i < count; i++) {
- * totalSize += Downloader.downloadFile(urls[i]);
- * publishProgress((int) ((i / (float) count) * 100));
- * // Escape early if cancel() is called
- * if (isCancelled()) break;
- * }
- * return totalSize;
- * }
+ * protected Long doInBackground(URL... urls) {
+ * int count = urls.length;
+ * long totalSize = 0;
+ * for (int i = 0; i < count; i++) {
+ * totalSize += Downloader.downloadFile(urls[i]);
+ * publishProgress((int) ((i / (float) count) * 100));
+ * // Escape early if cancel() is called
+ * if (isCancelled()) break;
+ * }
+ * return totalSize;
+ * }
*
- * protected void onProgressUpdate(Integer... progress) {
- * setProgressPercent(progress[0]);
- * }
+ * protected void onProgressUpdate(Integer... progress) {
+ * setProgressPercent(progress[0]);
+ * }
*
- * protected void onPostExecute(Long result) {
- * showDialog("Downloaded " + result + " bytes");
- * }
+ * protected void onPostExecute(Long result) {
+ * showDialog("Downloaded " + result + " bytes");
+ * }
* }
* </pre>
*
@@ -97,12 +97,12 @@ import android.os.Message;
* <h2>AsyncTask's generic types</h2>
* <p>The three types used by an asynchronous task are the following:</p>
* <ol>
- * <li><code>Params</code>, the type of the parameters sent to the task upon
- * execution.</li>
- * <li><code>Progress</code>, the type of the progress units published during
- * the background computation.</li>
- * <li><code>Result</code>, the type of the result of the background
- * computation.</li>
+ * <li><code>Params</code>, the type of the parameters sent to the task upon
+ * execution.</li>
+ * <li><code>Progress</code>, the type of the progress units published during
+ * the background computation.</li>
+ * <li><code>Result</code>, the type of the result of the background
+ * computation.</li>
* </ol>
* <p>Not all types are always used by an asynchronous task. To mark a type as unused,
* simply use the type {@link Void}:</p>
@@ -113,25 +113,25 @@ import android.os.Message;
* <h2>The 4 steps</h2>
* <p>When an asynchronous task is executed, the task goes through 4 steps:</p>
* <ol>
- * <li>{@link #onPreExecute()}, invoked on the UI thread before the task
- * is executed. This step is normally used to setup the task, for instance by
- * showing a progress bar in the user interface.</li>
- * <li>{@link #doInBackground}, invoked on the background thread
- * immediately after {@link #onPreExecute()} finishes executing. This step is used
- * to perform background computation that can take a long time. The parameters
- * of the asynchronous task are passed to this step. The result of the computation must
- * be returned by this step and will be passed back to the last step. This step
- * can also use {@link #publishProgress} to publish one or more units
- * of progress. These values are published on the UI thread, in the
- * {@link #onProgressUpdate} step.</li>
- * <li>{@link #onProgressUpdate}, invoked on the UI thread after a
- * call to {@link #publishProgress}. The timing of the execution is
- * undefined. This method is used to display any form of progress in the user
- * interface while the background computation is still executing. For instance,
- * it can be used to animate a progress bar or show logs in a text field.</li>
- * <li>{@link #onPostExecute}, invoked on the UI thread after the background
- * computation finishes. The result of the background computation is passed to
- * this step as a parameter.</li>
+ * <li>{@link #onPreExecute()}, invoked on the UI thread before the task
+ * is executed. This step is normally used to setup the task, for instance by
+ * showing a progress bar in the user interface.</li>
+ * <li>{@link #doInBackground}, invoked on the background thread
+ * immediately after {@link #onPreExecute()} finishes executing. This step is used
+ * to perform background computation that can take a long time. The parameters
+ * of the asynchronous task are passed to this step. The result of the computation must
+ * be returned by this step and will be passed back to the last step. This step
+ * can also use {@link #publishProgress} to publish one or more units
+ * of progress. These values are published on the UI thread, in the
+ * {@link #onProgressUpdate} step.</li>
+ * <li>{@link #onProgressUpdate}, invoked on the UI thread after a
+ * call to {@link #publishProgress}. The timing of the execution is
+ * undefined. This method is used to display any form of progress in the user
+ * interface while the background computation is still executing. For instance,
+ * it can be used to animate a progress bar or show logs in a text field.</li>
+ * <li>{@link #onPostExecute}, invoked on the UI thread after the background
+ * computation finishes. The result of the background computation is passed to
+ * this step as a parameter.</li>
* </ol>
*
* <h2>Cancelling a task</h2>
@@ -147,24 +147,24 @@ import android.os.Message;
* <p>There are a few threading rules that must be followed for this class to
* work properly:</p>
* <ul>
- * <li>The AsyncTask class must be loaded on the UI thread. This is done
- * automatically as of {@link android.os.Build.VERSION_CODES#JELLY_BEAN}.</li>
- * <li>The task instance must be created on the UI thread.</li>
- * <li>{@link #execute} must be invoked on the UI thread.</li>
- * <li>Do not call {@link #onPreExecute()}, {@link #onPostExecute},
- * {@link #doInBackground}, {@link #onProgressUpdate} manually.</li>
- * <li>The task can be executed only once (an exception will be thrown if
- * a second execution is attempted.)</li>
+ * <li>The AsyncTask class must be loaded on the UI thread. This is done
+ * automatically as of {@link android.os.Build.VERSION_CODES#JELLY_BEAN}.</li>
+ * <li>The task instance must be created on the UI thread.</li>
+ * <li>{@link #execute} must be invoked on the UI thread.</li>
+ * <li>Do not call {@link #onPreExecute()}, {@link #onPostExecute},
+ * {@link #doInBackground}, {@link #onProgressUpdate} manually.</li>
+ * <li>The task can be executed only once (an exception will be thrown if
+ * a second execution is attempted.)</li>
* </ul>
*
* <h2>Memory observability</h2>
* <p>AsyncTask guarantees that all callback calls are synchronized in such a way that the following
* operations are safe without explicit synchronizations.</p>
* <ul>
- * <li>Set member fields in the constructor or {@link #onPreExecute}, and refer to them
- * in {@link #doInBackground}.
- * <li>Set member fields in {@link #doInBackground}, and refer to them in
- * {@link #onProgressUpdate} and {@link #onPostExecute}.
+ * <li>Set member fields in the constructor or {@link #onPreExecute}, and refer to them
+ * in {@link #doInBackground}.
+ * <li>Set member fields in {@link #doInBackground}, and refer to them in
+ * {@link #onProgressUpdate} and {@link #onPostExecute}.
* </ul>
*
* <h2>Order of execution</h2>
@@ -178,493 +178,493 @@ import android.os.Message;
* {@link #THREAD_POOL_EXECUTOR}.</p>
*/
public abstract class AsyncTask<Params, Progress, Result> {
- private static final String LOG_TAG = "AsyncTask";
-
- private static final int CORE_POOL_SIZE = 5;
- private static final int MAXIMUM_POOL_SIZE = 128;
- private static final int KEEP_ALIVE = 1;
-
- private static final ThreadFactory sThreadFactory = new ThreadFactory() {
- private final AtomicInteger mCount = new AtomicInteger(1);
-
- public Thread newThread(Runnable r) {
- return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
- }
- };
-
- private static final BlockingQueue<Runnable> sPoolWorkQueue =
- new LinkedBlockingQueue<Runnable>(10);
-
- /**
- * An {@link Executor} that can be used to execute tasks in parallel.
- */
- public static final Executor THREAD_POOL_EXECUTOR
- = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
- TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
-
- /**
- * An {@link Executor} that executes tasks one at a time in serial
- * order. This serialization is global to a particular process.
- */
- public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
-
- private static final int MESSAGE_POST_RESULT = 0x1;
- private static final int MESSAGE_POST_PROGRESS = 0x2;
-
- private static final InternalHandler sHandler = new InternalHandler();
-
- private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
- private final WorkerRunnable<Params, Result> mWorker;
- private final FutureTask<Result> mFuture;
-
- private volatile Status mStatus = Status.PENDING;
-
- private final AtomicBoolean mCancelled = new AtomicBoolean();
- private final AtomicBoolean mTaskInvoked = new AtomicBoolean();
-
- private static class SerialExecutor implements Executor {
- final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
- Runnable mActive;
-
- public synchronized void execute(final Runnable r) {
- mTasks.offer(new Runnable() {
- public void run() {
- try {
- r.run();
- } finally {
- scheduleNext();
- }
- }
- });
- if (mActive == null) {
- scheduleNext();
- }
- }
-
- protected synchronized void scheduleNext() {
- if ((mActive = mTasks.poll()) != null) {
- THREAD_POOL_EXECUTOR.execute(mActive);
- }
- }
- }
-
- /**
- * Indicates the current status of the task. Each status will be set only once
- * during the lifetime of a task.
- */
- public enum Status {
- /**
- * Indicates that the task has not been executed yet.
- */
- PENDING,
- /**
- * Indicates that the task is running.
- */
- RUNNING,
- /**
- * Indicates that {@link AsyncTask#onPostExecute} has finished.
- */
- FINISHED,
- }
-
- /** @hide Used to force static handler to be created. */
- public static void init() {
- sHandler.getLooper();
- }
-
- /** @hide */
- public static void setDefaultExecutor(Executor exec) {
- sDefaultExecutor = exec;
- }
-
- /**
- * Creates a new asynchronous task. This constructor must be invoked on the UI thread.
- */
- public AsyncTask() {
- mWorker = new WorkerRunnable<Params, Result>() {
- public Result call() throws Exception {
- mTaskInvoked.set(true);
-
- Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
- //noinspection unchecked
- return postResult(doInBackground(mParams));
- }
- };
-
- mFuture = new FutureTask<Result>(mWorker) {
- @Override
- protected void done() {
- try {
- postResultIfNotInvoked(get());
- } catch (InterruptedException e) {
- android.util.Log.w(LOG_TAG, e);
- } catch (ExecutionException e) {
- throw new RuntimeException("An error occured while executing doInBackground()",
- e.getCause());
- } catch (CancellationException e) {
- postResultIfNotInvoked(null);
- }
- }
- };
- }
-
- private void postResultIfNotInvoked(Result result) {
- final boolean wasTaskInvoked = mTaskInvoked.get();
- if (!wasTaskInvoked) {
- postResult(result);
- }
- }
-
- private Result postResult(Result result) {
- @SuppressWarnings("unchecked")
- Message message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
- new AsyncTaskResult<Result>(this, result));
- message.sendToTarget();
- return result;
- }
-
- /**
- * Returns the current status of this task.
- *
- * @return The current status.
- */
- public final Status getStatus() {
- return mStatus;
- }
-
- /**
- * Override this method to perform a computation on a background thread. The
- * specified parameters are the parameters passed to {@link #execute}
- * by the caller of this task.
- *
- * This method can call {@link #publishProgress} to publish updates
- * on the UI thread.
- *
- * @param params The parameters of the task.
- *
- * @return A result, defined by the subclass of this task.
- *
- * @see #onPreExecute()
- * @see #onPostExecute
- * @see #publishProgress
- */
- protected abstract Result doInBackground(Params... params);
-
- /**
- * Runs on the UI thread before {@link #doInBackground}.
- *
- * @see #onPostExecute
- * @see #doInBackground
- */
- protected void onPreExecute() {
- }
-
- /**
- * <p>Runs on the UI thread after {@link #doInBackground}. The
- * specified result is the value returned by {@link #doInBackground}.</p>
- *
- * <p>This method won't be invoked if the task was cancelled.</p>
- *
- * @param result The result of the operation computed by {@link #doInBackground}.
- *
- * @see #onPreExecute
- * @see #doInBackground
- * @see #onCancelled(Object)
- */
- @SuppressWarnings({"UnusedDeclaration"})
- protected void onPostExecute(Result result) {
- }
-
- /**
- * Runs on the UI thread after {@link #publishProgress} is invoked.
- * The specified values are the values passed to {@link #publishProgress}.
- *
- * @param values The values indicating progress.
- *
- * @see #publishProgress
- * @see #doInBackground
- */
- @SuppressWarnings({"UnusedDeclaration"})
- protected void onProgressUpdate(Progress... values) {
- }
-
- /**
- * <p>Runs on the UI thread after {@link #cancel(boolean)} is invoked and
- * {@link #doInBackground(Object[])} has finished.</p>
- *
- * <p>The default implementation simply invokes {@link #onCancelled()} and
- * ignores the result. If you write your own implementation, do not call
- * <code>super.onCancelled(result)</code>.</p>
- *
- * @param result The result, if any, computed in
- * {@link #doInBackground(Object[])}, can be null
- *
- * @see #cancel(boolean)
- * @see #isCancelled()
- */
- @SuppressWarnings({"UnusedParameters"})
- protected void onCancelled(Result result) {
- onCancelled();
- }
-
- /**
- * <p>Applications should preferably override {@link #onCancelled(Object)}.
- * This method is invoked by the default implementation of
- * {@link #onCancelled(Object)}.</p>
- *
- * <p>Runs on the UI thread after {@link #cancel(boolean)} is invoked and
- * {@link #doInBackground(Object[])} has finished.</p>
- *
- * @see #onCancelled(Object)
- * @see #cancel(boolean)
- * @see #isCancelled()
- */
- protected void onCancelled() {
- }
-
- /**
- * Returns <tt>true</tt> if this task was cancelled before it completed
- * normally. If you are calling {@link #cancel(boolean)} on the task,
- * the value returned by this method should be checked periodically from
- * {@link #doInBackground(Object[])} to end the task as soon as possible.
- *
- * @return <tt>true</tt> if task was cancelled before it completed
- *
- * @see #cancel(boolean)
- */
- public final boolean isCancelled() {
- return mCancelled.get();
- }
-
- /**
- * <p>Attempts to cancel execution of this task. This attempt will
- * fail if the task has already completed, already been cancelled,
- * or could not be cancelled for some other reason. If successful,
- * and this task has not started when <tt>cancel</tt> is called,
- * this task should never run. If the task has already started,
- * then the <tt>mayInterruptIfRunning</tt> parameter determines
- * whether the thread executing this task should be interrupted in
- * an attempt to stop the task.</p>
- *
- * <p>Calling this method will result in {@link #onCancelled(Object)} being
- * invoked on the UI thread after {@link #doInBackground(Object[])}
- * returns. Calling this method guarantees that {@link #onPostExecute(Object)}
- * is never invoked. After invoking this method, you should check the
- * value returned by {@link #isCancelled()} periodically from
- * {@link #doInBackground(Object[])} to finish the task as early as
- * possible.</p>
- *
- * @param mayInterruptIfRunning <tt>true</tt> if the thread executing this
- * task should be interrupted; otherwise, in-progress tasks are allowed
- * to complete.
- *
- * @return <tt>false</tt> if the task could not be cancelled,
- * typically because it has already completed normally;
- * <tt>true</tt> otherwise
- *
- * @see #isCancelled()
- * @see #onCancelled(Object)
- */
- public final boolean cancel(boolean mayInterruptIfRunning) {
- mCancelled.set(true);
- return mFuture.cancel(mayInterruptIfRunning);
- }
-
- /**
- * Waits if necessary for the computation to complete, and then
- * retrieves its result.
- *
- * @return The computed result.
- *
- * @throws CancellationException If the computation was cancelled.
- * @throws ExecutionException If the computation threw an exception.
- * @throws InterruptedException If the current thread was interrupted
- * while waiting.
- */
- public final Result get() throws InterruptedException, ExecutionException {
- return mFuture.get();
- }
-
- /**
- * Waits if necessary for at most the given time for the computation
- * to complete, and then retrieves its result.
- *
- * @param timeout Time to wait before cancelling the operation.
- * @param unit The time unit for the timeout.
- *
- * @return The computed result.
- *
- * @throws CancellationException If the computation was cancelled.
- * @throws ExecutionException If the computation threw an exception.
- * @throws InterruptedException If the current thread was interrupted
- * while waiting.
- * @throws TimeoutException If the wait timed out.
- */
- public final Result get(long timeout, TimeUnit unit) throws InterruptedException,
- ExecutionException, TimeoutException {
- return mFuture.get(timeout, unit);
- }
-
- /**
- * Executes the task with the specified parameters. The task returns
- * itself (this) so that the caller can keep a reference to it.
- *
- * <p>Note: this function schedules the task on a queue for a single background
- * thread or pool of threads depending on the platform version. When first
- * introduced, AsyncTasks were executed serially on a single background thread.
- * Starting with {@link android.os.Build.VERSION_CODES#DONUT}, this was changed
- * to a pool of threads allowing multiple tasks to operate in parallel. Starting
- * {@link android.os.Build.VERSION_CODES#HONEYCOMB}, tasks are back to being
- * executed on a single thread to avoid common application errors caused
- * by parallel execution. If you truly want parallel execution, you can use
- * the {@link #executeOnExecutor} version of this method
- * with {@link #THREAD_POOL_EXECUTOR}; however, see commentary there for warnings
- * on its use.
- *
- * <p>This method must be invoked on the UI thread.
- *
- * @param params The parameters of the task.
- *
- * @return This instance of AsyncTask.
- *
- * @throws IllegalStateException If {@link #getStatus()} returns either
- * {@link AsyncTask.Status#RUNNING} or {@link AsyncTask.Status#FINISHED}.
- *
- * @see #executeOnExecutor(java.util.concurrent.Executor, Object[])
- * @see #execute(Runnable)
- */
- public final AsyncTask<Params, Progress, Result> execute(Params... params) {
- return executeOnExecutor(sDefaultExecutor, params);
- }
-
- /**
- * Executes the task with the specified parameters. The task returns
- * itself (this) so that the caller can keep a reference to it.
- *
- * <p>This method is typically used with {@link #THREAD_POOL_EXECUTOR} to
- * allow multiple tasks to run in parallel on a pool of threads managed by
- * AsyncTask, however you can also use your own {@link Executor} for custom
- * behavior.
- *
- * <p><em>Warning:</em> Allowing multiple tasks to run in parallel from
- * a thread pool is generally <em>not</em> what one wants, because the order
- * of their operation is not defined. For example, if these tasks are used
- * to modify any state in common (such as writing a file due to a button click),
- * there are no guarantees on the order of the modifications.
- * Without careful work it is possible in rare cases for the newer version
- * of the data to be over-written by an older one, leading to obscure data
- * loss and stability issues. Such changes are best
- * executed in serial; to guarantee such work is serialized regardless of
- * platform version you can use this function with {@link #SERIAL_EXECUTOR}.
- *
- * <p>This method must be invoked on the UI thread.
- *
- * @param exec The executor to use. {@link #THREAD_POOL_EXECUTOR} is available as a
- * convenient process-wide thread pool for tasks that are loosely coupled.
- * @param params The parameters of the task.
- *
- * @return This instance of AsyncTask.
- *
- * @throws IllegalStateException If {@link #getStatus()} returns either
- * {@link AsyncTask.Status#RUNNING} or {@link AsyncTask.Status#FINISHED}.
- *
- * @see #execute(Object[])
- */
- public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
- Params... params) {
- if (mStatus != Status.PENDING) {
- switch (mStatus) {
- case RUNNING:
- throw new IllegalStateException("Cannot execute task:"
- + " the task is already running.");
- case FINISHED:
- throw new IllegalStateException("Cannot execute task:"
- + " the task has already been executed "
- + "(a task can be executed only once)");
- }
- }
-
- mStatus = Status.RUNNING;
-
- onPreExecute();
-
- mWorker.mParams = params;
- exec.execute(mFuture);
-
- return this;
- }
-
- /**
- * Convenience version of {@link #execute(Object...)} for use with
- * a simple Runnable object. See {@link #execute(Object[])} for more
- * information on the order of execution.
- *
- * @see #execute(Object[])
- * @see #executeOnExecutor(java.util.concurrent.Executor, Object[])
- */
- public static void execute(Runnable runnable) {
- sDefaultExecutor.execute(runnable);
- }
-
- /**
- * This method can be invoked from {@link #doInBackground} to
- * publish updates on the UI thread while the background computation is
- * still running. Each call to this method will trigger the execution of
- * {@link #onProgressUpdate} on the UI thread.
- *
- * {@link #onProgressUpdate} will note be called if the task has been
- * canceled.
- *
- * @param values The progress values to update the UI with.
- *
- * @see #onProgressUpdate
- * @see #doInBackground
- */
- protected final void publishProgress(Progress... values) {
- if (!isCancelled()) {
- sHandler.obtainMessage(MESSAGE_POST_PROGRESS,
- new AsyncTaskResult<Progress>(this, values)).sendToTarget();
- }
- }
-
- private void finish(Result result) {
- if (isCancelled()) {
- onCancelled(result);
- } else {
- onPostExecute(result);
- }
- mStatus = Status.FINISHED;
- }
-
- private static class InternalHandler extends Handler {
- @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
- @Override
- public void handleMessage(Message msg) {
- AsyncTaskResult result = (AsyncTaskResult) msg.obj;
- switch (msg.what) {
- case MESSAGE_POST_RESULT:
- // There is only one result
- result.mTask.finish(result.mData[0]);
- break;
- case MESSAGE_POST_PROGRESS:
- result.mTask.onProgressUpdate(result.mData);
- break;
- }
- }
- }
-
- private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
- Params[] mParams;
- }
-
- @SuppressWarnings({"RawUseOfParameterizedType"})
- private static class AsyncTaskResult<Data> {
- final AsyncTask mTask;
- final Data[] mData;
-
- AsyncTaskResult(AsyncTask task, Data... data) {
- mTask = task;
- mData = data;
- }
- }
+ private static final String LOG_TAG = "AsyncTask";
+
+ private static final int CORE_POOL_SIZE = 5;
+ private static final int MAXIMUM_POOL_SIZE = 128;
+ private static final int KEEP_ALIVE = 1;
+
+ private static final ThreadFactory sThreadFactory = new ThreadFactory() {
+ private final AtomicInteger mCount = new AtomicInteger(1);
+
+ public Thread newThread(Runnable r) {
+ return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
+ }
+ };
+
+ private static final BlockingQueue<Runnable> sPoolWorkQueue =
+ new LinkedBlockingQueue<Runnable>(10);
+
+ /**
+ * An {@link Executor} that can be used to execute tasks in parallel.
+ */
+ public static final Executor THREAD_POOL_EXECUTOR
+ = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
+ TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
+
+ /**
+ * An {@link Executor} that executes tasks one at a time in serial
+ * order. This serialization is global to a particular process.
+ */
+ public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
+
+ private static final int MESSAGE_POST_RESULT = 0x1;
+ private static final int MESSAGE_POST_PROGRESS = 0x2;
+
+ private static final InternalHandler sHandler = new InternalHandler();
+
+ private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
+ private final WorkerRunnable<Params, Result> mWorker;
+ private final FutureTask<Result> mFuture;
+
+ private volatile Status mStatus = Status.PENDING;
+
+ private final AtomicBoolean mCancelled = new AtomicBoolean();
+ private final AtomicBoolean mTaskInvoked = new AtomicBoolean();
+
+ private static class SerialExecutor implements Executor {
+ final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
+ Runnable mActive;
+
+ public synchronized void execute(final Runnable r) {
+ mTasks.offer(new Runnable() {
+ public void run() {
+ try {
+ r.run();
+ } finally {
+ scheduleNext();
+ }
+ }
+ });
+ if (mActive == null) {
+ scheduleNext();
+ }
+ }
+
+ protected synchronized void scheduleNext() {
+ if ((mActive = mTasks.poll()) != null) {
+ THREAD_POOL_EXECUTOR.execute(mActive);
+ }
+ }
+ }
+
+ /**
+ * Indicates the current status of the task. Each status will be set only once
+ * during the lifetime of a task.
+ */
+ public enum Status {
+ /**
+ * Indicates that the task has not been executed yet.
+ */
+ PENDING,
+ /**
+ * Indicates that the task is running.
+ */
+ RUNNING,
+ /**
+ * Indicates that {@link AsyncTask#onPostExecute} has finished.
+ */
+ FINISHED,
+ }
+
+ /** @hide Used to force static handler to be created. */
+ public static void init() {
+ sHandler.getLooper();
+ }
+
+ /** @hide */
+ public static void setDefaultExecutor(Executor exec) {
+ sDefaultExecutor = exec;
+ }
+
+ /**
+ * Creates a new asynchronous task. This constructor must be invoked on the UI thread.
+ */
+ public AsyncTask() {
+ mWorker = new WorkerRunnable<Params, Result>() {
+ public Result call() throws Exception {
+ mTaskInvoked.set(true);
+
+ Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+ //noinspection unchecked
+ return postResult(doInBackground(mParams));
+ }
+ };
+
+ mFuture = new FutureTask<Result>(mWorker) {
+ @Override
+ protected void done() {
+ try {
+ postResultIfNotInvoked(get());
+ } catch (InterruptedException e) {
+ android.util.Log.w(LOG_TAG, e);
+ } catch (ExecutionException e) {
+ throw new RuntimeException("An error occured while executing doInBackground()",
+ e.getCause());
+ } catch (CancellationException e) {
+ postResultIfNotInvoked(null);
+ }
+ }
+ };
+ }
+
+ private void postResultIfNotInvoked(Result result) {
+ final boolean wasTaskInvoked = mTaskInvoked.get();
+ if (!wasTaskInvoked) {
+ postResult(result);
+ }
+ }
+
+ private Result postResult(Result result) {
+ @SuppressWarnings("unchecked")
+ Message message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
+ new AsyncTaskResult<Result>(this, result));
+ message.sendToTarget();
+ return result;
+ }
+
+ /**
+ * Returns the current status of this task.
+ *
+ * @return The current status.
+ */
+ public final Status getStatus() {
+ return mStatus;
+ }
+
+ /**
+ * Override this method to perform a computation on a background thread. The
+ * specified parameters are the parameters passed to {@link #execute}
+ * by the caller of this task.
+ *
+ * This method can call {@link #publishProgress} to publish updates
+ * on the UI thread.
+ *
+ * @param params The parameters of the task.
+ *
+ * @return A result, defined by the subclass of this task.
+ *
+ * @see #onPreExecute()
+ * @see #onPostExecute
+ * @see #publishProgress
+ */
+ protected abstract Result doInBackground(Params... params);
+
+ /**
+ * Runs on the UI thread before {@link #doInBackground}.
+ *
+ * @see #onPostExecute
+ * @see #doInBackground
+ */
+ protected void onPreExecute() {
+ }
+
+ /**
+ * <p>Runs on the UI thread after {@link #doInBackground}. The
+ * specified result is the value returned by {@link #doInBackground}.</p>
+ *
+ * <p>This method won't be invoked if the task was cancelled.</p>
+ *
+ * @param result The result of the operation computed by {@link #doInBackground}.
+ *
+ * @see #onPreExecute
+ * @see #doInBackground
+ * @see #onCancelled(Object)
+ */
+ @SuppressWarnings({"UnusedDeclaration"})
+ protected void onPostExecute(Result result) {
+ }
+
+ /**
+ * Runs on the UI thread after {@link #publishProgress} is invoked.
+ * The specified values are the values passed to {@link #publishProgress}.
+ *
+ * @param values The values indicating progress.
+ *
+ * @see #publishProgress
+ * @see #doInBackground
+ */
+ @SuppressWarnings({"UnusedDeclaration"})
+ protected void onProgressUpdate(Progress... values) {
+ }
+
+ /**
+ * <p>Runs on the UI thread after {@link #cancel(boolean)} is invoked and
+ * {@link #doInBackground(Object[])} has finished.</p>
+ *
+ * <p>The default implementation simply invokes {@link #onCancelled()} and
+ * ignores the result. If you write your own implementation, do not call
+ * <code>super.onCancelled(result)</code>.</p>
+ *
+ * @param result The result, if any, computed in
+ * {@link #doInBackground(Object[])}, can be null
+ *
+ * @see #cancel(boolean)
+ * @see #isCancelled()
+ */
+ @SuppressWarnings({"UnusedParameters"})
+ protected void onCancelled(Result result) {
+ onCancelled();
+ }
+
+ /**
+ * <p>Applications should preferably override {@link #onCancelled(Object)}.
+ * This method is invoked by the default implementation of
+ * {@link #onCancelled(Object)}.</p>
+ *
+ * <p>Runs on the UI thread after {@link #cancel(boolean)} is invoked and
+ * {@link #doInBackground(Object[])} has finished.</p>
+ *
+ * @see #onCancelled(Object)
+ * @see #cancel(boolean)
+ * @see #isCancelled()
+ */
+ protected void onCancelled() {
+ }
+
+ /**
+ * Returns <tt>true</tt> if this task was cancelled before it completed
+ * normally. If you are calling {@link #cancel(boolean)} on the task,
+ * the value returned by this method should be checked periodically from
+ * {@link #doInBackground(Object[])} to end the task as soon as possible.
+ *
+ * @return <tt>true</tt> if task was cancelled before it completed
+ *
+ * @see #cancel(boolean)
+ */
+ public final boolean isCancelled() {
+ return mCancelled.get();
+ }
+
+ /**
+ * <p>Attempts to cancel execution of this task. This attempt will
+ * fail if the task has already completed, already been cancelled,
+ * or could not be cancelled for some other reason. If successful,
+ * and this task has not started when <tt>cancel</tt> is called,
+ * this task should never run. If the task has already started,
+ * then the <tt>mayInterruptIfRunning</tt> parameter determines
+ * whether the thread executing this task should be interrupted in
+ * an attempt to stop the task.</p>
+ *
+ * <p>Calling this method will result in {@link #onCancelled(Object)} being
+ * invoked on the UI thread after {@link #doInBackground(Object[])}
+ * returns. Calling this method guarantees that {@link #onPostExecute(Object)}
+ * is never invoked. After invoking this method, you should check the
+ * value returned by {@link #isCancelled()} periodically from
+ * {@link #doInBackground(Object[])} to finish the task as early as
+ * possible.</p>
+ *
+ * @param mayInterruptIfRunning <tt>true</tt> if the thread executing this
+ * task should be interrupted; otherwise, in-progress tasks are allowed
+ * to complete.
+ *
+ * @return <tt>false</tt> if the task could not be cancelled,
+ * typically because it has already completed normally;
+ * <tt>true</tt> otherwise
+ *
+ * @see #isCancelled()
+ * @see #onCancelled(Object)
+ */
+ public final boolean cancel(boolean mayInterruptIfRunning) {
+ mCancelled.set(true);
+ return mFuture.cancel(mayInterruptIfRunning);
+ }
+
+ /**
+ * Waits if necessary for the computation to complete, and then
+ * retrieves its result.
+ *
+ * @return The computed result.
+ *
+ * @throws CancellationException If the computation was cancelled.
+ * @throws ExecutionException If the computation threw an exception.
+ * @throws InterruptedException If the current thread was interrupted
+ * while waiting.
+ */
+ public final Result get() throws InterruptedException, ExecutionException {
+ return mFuture.get();
+ }
+
+ /**
+ * Waits if necessary for at most the given time for the computation
+ * to complete, and then retrieves its result.
+ *
+ * @param timeout Time to wait before cancelling the operation.
+ * @param unit The time unit for the timeout.
+ *
+ * @return The computed result.
+ *
+ * @throws CancellationException If the computation was cancelled.
+ * @throws ExecutionException If the computation threw an exception.
+ * @throws InterruptedException If the current thread was interrupted
+ * while waiting.
+ * @throws TimeoutException If the wait timed out.
+ */
+ public final Result get(long timeout, TimeUnit unit) throws InterruptedException,
+ ExecutionException, TimeoutException {
+ return mFuture.get(timeout, unit);
+ }
+
+ /**
+ * Executes the task with the specified parameters. The task returns
+ * itself (this) so that the caller can keep a reference to it.
+ *
+ * <p>Note: this function schedules the task on a queue for a single background
+ * thread or pool of threads depending on the platform version. When first
+ * introduced, AsyncTasks were executed serially on a single background thread.
+ * Starting with {@link android.os.Build.VERSION_CODES#DONUT}, this was changed
+ * to a pool of threads allowing multiple tasks to operate in parallel. Starting
+ * {@link android.os.Build.VERSION_CODES#HONEYCOMB}, tasks are back to being
+ * executed on a single thread to avoid common application errors caused
+ * by parallel execution. If you truly want parallel execution, you can use
+ * the {@link #executeOnExecutor} version of this method
+ * with {@link #THREAD_POOL_EXECUTOR}; however, see commentary there for warnings
+ * on its use.
+ *
+ * <p>This method must be invoked on the UI thread.
+ *
+ * @param params The parameters of the task.
+ *
+ * @return This instance of AsyncTask.
+ *
+ * @throws IllegalStateException If {@link #getStatus()} returns either
+ * {@link AsyncTask.Status#RUNNING} or {@link AsyncTask.Status#FINISHED}.
+ *
+ * @see #executeOnExecutor(java.util.concurrent.Executor, Object[])
+ * @see #execute(Runnable)
+ */
+ public final AsyncTask<Params, Progress, Result> execute(Params... params) {
+ return executeOnExecutor(sDefaultExecutor, params);
+ }
+
+ /**
+ * Executes the task with the specified parameters. The task returns
+ * itself (this) so that the caller can keep a reference to it.
+ *
+ * <p>This method is typically used with {@link #THREAD_POOL_EXECUTOR} to
+ * allow multiple tasks to run in parallel on a pool of threads managed by
+ * AsyncTask, however you can also use your own {@link Executor} for custom
+ * behavior.
+ *
+ * <p><em>Warning:</em> Allowing multiple tasks to run in parallel from
+ * a thread pool is generally <em>not</em> what one wants, because the order
+ * of their operation is not defined. For example, if these tasks are used
+ * to modify any state in common (such as writing a file due to a button click),
+ * there are no guarantees on the order of the modifications.
+ * Without careful work it is possible in rare cases for the newer version
+ * of the data to be over-written by an older one, leading to obscure data
+ * loss and stability issues. Such changes are best
+ * executed in serial; to guarantee such work is serialized regardless of
+ * platform version you can use this function with {@link #SERIAL_EXECUTOR}.
+ *
+ * <p>This method must be invoked on the UI thread.
+ *
+ * @param exec The executor to use. {@link #THREAD_POOL_EXECUTOR} is available as a
+ * convenient process-wide thread pool for tasks that are loosely coupled.
+ * @param params The parameters of the task.
+ *
+ * @return This instance of AsyncTask.
+ *
+ * @throws IllegalStateException If {@link #getStatus()} returns either
+ * {@link AsyncTask.Status#RUNNING} or {@link AsyncTask.Status#FINISHED}.
+ *
+ * @see #execute(Object[])
+ */
+ public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
+ Params... params) {
+ if (mStatus != Status.PENDING) {
+ switch (mStatus) {
+ case RUNNING:
+ throw new IllegalStateException("Cannot execute task:"
+ + " the task is already running.");
+ case FINISHED:
+ throw new IllegalStateException("Cannot execute task:"
+ + " the task has already been executed "
+ + "(a task can be executed only once)");
+ }
+ }
+
+ mStatus = Status.RUNNING;
+
+ onPreExecute();
+
+ mWorker.mParams = params;
+ exec.execute(mFuture);
+
+ return this;
+ }
+
+ /**
+ * Convenience version of {@link #execute(Object...)} for use with
+ * a simple Runnable object. See {@link #execute(Object[])} for more
+ * information on the order of execution.
+ *
+ * @see #execute(Object[])
+ * @see #executeOnExecutor(java.util.concurrent.Executor, Object[])
+ */
+ public static void execute(Runnable runnable) {
+ sDefaultExecutor.execute(runnable);
+ }
+
+ /**
+ * This method can be invoked from {@link #doInBackground} to
+ * publish updates on the UI thread while the background computation is
+ * still running. Each call to this method will trigger the execution of
+ * {@link #onProgressUpdate} on the UI thread.
+ *
+ * {@link #onProgressUpdate} will note be called if the task has been
+ * canceled.
+ *
+ * @param values The progress values to update the UI with.
+ *
+ * @see #onProgressUpdate
+ * @see #doInBackground
+ */
+ protected final void publishProgress(Progress... values) {
+ if (!isCancelled()) {
+ sHandler.obtainMessage(MESSAGE_POST_PROGRESS,
+ new AsyncTaskResult<Progress>(this, values)).sendToTarget();
+ }
+ }
+
+ private void finish(Result result) {
+ if (isCancelled()) {
+ onCancelled(result);
+ } else {
+ onPostExecute(result);
+ }
+ mStatus = Status.FINISHED;
+ }
+
+ private static class InternalHandler extends Handler {
+ @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
+ @Override
+ public void handleMessage(Message msg) {
+ AsyncTaskResult result = (AsyncTaskResult) msg.obj;
+ switch (msg.what) {
+ case MESSAGE_POST_RESULT:
+ // There is only one result
+ result.mTask.finish(result.mData[0]);
+ break;
+ case MESSAGE_POST_PROGRESS:
+ result.mTask.onProgressUpdate(result.mData);
+ break;
+ }
+ }
+ }
+
+ private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
+ Params[] mParams;
+ }
+
+ @SuppressWarnings({"RawUseOfParameterizedType"})
+ private static class AsyncTaskResult<Data> {
+ final AsyncTask mTask;
+ final Data[] mData;
+
+ AsyncTaskResult(AsyncTask task, Data... data) {
+ mTask = task;
+ mData = data;
+ }
+ }
}
diff --git a/platform/android/viewer/src/com/artifex/mupdfdemo/Deque.java b/platform/android/viewer/src/com/artifex/mupdfdemo/Deque.java
index ad17bcc0..97aefeab 100644
--- a/platform/android/viewer/src/com/artifex/mupdfdemo/Deque.java
+++ b/platform/android/viewer/src/com/artifex/mupdfdemo/Deque.java
@@ -41,37 +41,37 @@ import java.util.Stack;
* <p>
* <table BORDER CELLPADDING=3 CELLSPACING=1>
* <tr>
- * <td></td>
- * <td ALIGN=CENTER COLSPAN = 2> <b>First Element (Head)</b></td>
- * <td ALIGN=CENTER COLSPAN = 2> <b>Last Element (Tail)</b></td>
+ * <td></td>
+ * <td ALIGN=CENTER COLSPAN = 2> <b>First Element (Head)</b></td>
+ * <td ALIGN=CENTER COLSPAN = 2> <b>Last Element (Tail)</b></td>
* </tr>
* <tr>
- * <td></td>
- * <td ALIGN=CENTER><em>Throws exception</em></td>
- * <td ALIGN=CENTER><em>Special value</em></td>
- * <td ALIGN=CENTER><em>Throws exception</em></td>
- * <td ALIGN=CENTER><em>Special value</em></td>
+ * <td></td>
+ * <td ALIGN=CENTER><em>Throws exception</em></td>
+ * <td ALIGN=CENTER><em>Special value</em></td>
+ * <td ALIGN=CENTER><em>Throws exception</em></td>
+ * <td ALIGN=CENTER><em>Special value</em></td>
* </tr>
* <tr>
- * <td><b>Insert</b></td>
- * <td>{@link #addFirst addFirst(e)}</td>
- * <td>{@link #offerFirst offerFirst(e)}</td>
- * <td>{@link #addLast addLast(e)}</td>
- * <td>{@link #offerLast offerLast(e)}</td>
+ * <td><b>Insert</b></td>
+ * <td>{@link #addFirst addFirst(e)}</td>
+ * <td>{@link #offerFirst offerFirst(e)}</td>
+ * <td>{@link #addLast addLast(e)}</td>
+ * <td>{@link #offerLast offerLast(e)}</td>
* </tr>
* <tr>
- * <td><b>Remove</b></td>
- * <td>{@link #removeFirst removeFirst()}</td>
- * <td>{@link #pollFirst pollFirst()}</td>
- * <td>{@link #removeLast removeLast()}</td>
- * <td>{@link #pollLast pollLast()}</td>
+ * <td><b>Remove</b></td>
+ * <td>{@link #removeFirst removeFirst()}</td>
+ * <td>{@link #pollFirst pollFirst()}</td>
+ * <td>{@link #removeLast removeLast()}</td>
+ * <td>{@link #pollLast pollLast()}</td>
* </tr>
* <tr>
- * <td><b>Examine</b></td>
- * <td>{@link #getFirst getFirst()}</td>
- * <td>{@link #peekFirst peekFirst()}</td>
- * <td>{@link #getLast getLast()}</td>
- * <td>{@link #peekLast peekLast()}</td>
+ * <td><b>Examine</b></td>
+ * <td>{@link #getFirst getFirst()}</td>
+ * <td>{@link #peekFirst peekFirst()}</td>
+ * <td>{@link #getLast getLast()}</td>
+ * <td>{@link #peekLast peekLast()}</td>
* </tr>
* </table>
*
@@ -84,32 +84,32 @@ import java.util.Stack;
* <p>
* <table BORDER CELLPADDING=3 CELLSPACING=1>
* <tr>
- * <td ALIGN=CENTER> <b><tt>Queue</tt> Method</b></td>
- * <td ALIGN=CENTER> <b>Equivalent <tt>Deque</tt> Method</b></td>
+ * <td ALIGN=CENTER> <b><tt>Queue</tt> Method</b></td>
+ * <td ALIGN=CENTER> <b>Equivalent <tt>Deque</tt> Method</b></td>
* </tr>
* <tr>
- * <td>{@link java.util.Queue#add add(e)}</td>
- * <td>{@link #addLast addLast(e)}</td>
+ * <td>{@link java.util.Queue#add add(e)}</td>
+ * <td>{@link #addLast addLast(e)}</td>
* </tr>
* <tr>
- * <td>{@link java.util.Queue#offer offer(e)}</td>
- * <td>{@link #offerLast offerLast(e)}</td>
+ * <td>{@link java.util.Queue#offer offer(e)}</td>
+ * <td>{@link #offerLast offerLast(e)}</td>
* </tr>
* <tr>
- * <td>{@link java.util.Queue#remove remove()}</td>
- * <td>{@link #removeFirst removeFirst()}</td>
+ * <td>{@link java.util.Queue#remove remove()}</td>
+ * <td>{@link #removeFirst removeFirst()}</td>
* </tr>
* <tr>
- * <td>{@link java.util.Queue#poll poll()}</td>
- * <td>{@link #pollFirst pollFirst()}</td>
+ * <td>{@link java.util.Queue#poll poll()}</td>
+ * <td>{@link #pollFirst pollFirst()}</td>
* </tr>
* <tr>
- * <td>{@link java.util.Queue#element element()}</td>
- * <td>{@link #getFirst getFirst()}</td>
+ * <td>{@link java.util.Queue#element element()}</td>
+ * <td>{@link #getFirst getFirst()}</td>
* </tr>
* <tr>
- * <td>{@link java.util.Queue#peek peek()}</td>
- * <td>{@link #peek peekFirst()}</td>
+ * <td>{@link java.util.Queue#peek peek()}</td>
+ * <td>{@link #peek peekFirst()}</td>
* </tr>
* </table>
*
@@ -122,20 +122,20 @@ import java.util.Stack;
* <p>
* <table BORDER CELLPADDING=3 CELLSPACING=1>
* <tr>
- * <td ALIGN=CENTER> <b>Stack Method</b></td>
- * <td ALIGN=CENTER> <b>Equivalent <tt>Deque</tt> Method</b></td>
+ * <td ALIGN=CENTER> <b>Stack Method</b></td>
+ * <td ALIGN=CENTER> <b>Equivalent <tt>Deque</tt> Method</b></td>
* </tr>
* <tr>
- * <td>{@link #push push(e)}</td>
- * <td>{@link #addFirst addFirst(e)}</td>
+ * <td>{@link #push push(e)}</td>
+ * <td>{@link #addFirst addFirst(e)}</td>
* </tr>
* <tr>
- * <td>{@link #pop pop()}</td>
- * <td>{@link #removeFirst removeFirst()}</td>
+ * <td>{@link #pop pop()}</td>
+ * <td>{@link #removeFirst removeFirst()}</td>
* </tr>
* <tr>
- * <td>{@link #peek peek()}</td>
- * <td>{@link #peekFirst peekFirst()}</td>
+ * <td>{@link #peek peek()}</td>
+ * <td>{@link #peekFirst peekFirst()}</td>
* </tr>
* </table>
*
@@ -170,383 +170,383 @@ import java.util.Stack;
*/
public interface Deque<E> extends Queue<E> {
- /**
- * Inserts the specified element at the front of this deque if it is
- * possible to do so immediately without violating capacity restrictions.
- * When using a capacity-restricted deque, it is generally preferable to
- * use method {@link #offerFirst}.
- *
- * @param e the element to add
- * @throws IllegalStateException if the element cannot be added at this
- * time due to capacity restrictions
- * @throws ClassCastException if the class of the specified element
- * prevents it from being added to this deque
- * @throws NullPointerException if the specified element is null and this
- * deque does not permit null elements
- * @throws IllegalArgumentException if some property of the specified
- * element prevents it from being added to this deque
- */
- void addFirst(E e);
-
- /**
- * Inserts the specified element at the end of this deque if it is
- * possible to do so immediately without violating capacity restrictions.
- * When using a capacity-restricted deque, it is generally preferable to
- * use method {@link #offerLast}.
- *
- * <p>This method is equivalent to {@link #add}.
- *
- * @param e the element to add
- * @throws IllegalStateException if the element cannot be added at this
- * time due to capacity restrictions
- * @throws ClassCastException if the class of the specified element
- * prevents it from being added to this deque
- * @throws NullPointerException if the specified element is null and this
- * deque does not permit null elements
- * @throws IllegalArgumentException if some property of the specified
- * element prevents it from being added to this deque
- */
- void addLast(E e);
-
- /**
- * Inserts the specified element at the front of this deque unless it would
- * violate capacity restrictions. When using a capacity-restricted deque,
- * this method is generally preferable to the {@link #addFirst} method,
- * which can fail to insert an element only by throwing an exception.
- *
- * @param e the element to add
- * @return <tt>true</tt> if the element was added to this deque, else
- * <tt>false</tt>
- * @throws ClassCastException if the class of the specified element
- * prevents it from being added to this deque
- * @throws NullPointerException if the specified element is null and this
- * deque does not permit null elements
- * @throws IllegalArgumentException if some property of the specified
- * element prevents it from being added to this deque
- */
- boolean offerFirst(E e);
-
- /**
- * Inserts the specified element at the end of this deque unless it would
- * violate capacity restrictions. When using a capacity-restricted deque,
- * this method is generally preferable to the {@link #addLast} method,
- * which can fail to insert an element only by throwing an exception.
- *
- * @param e the element to add
- * @return <tt>true</tt> if the element was added to this deque, else
- * <tt>false</tt>
- * @throws ClassCastException if the class of the specified element
- * prevents it from being added to this deque
- * @throws NullPointerException if the specified element is null and this
- * deque does not permit null elements
- * @throws IllegalArgumentException if some property of the specified
- * element prevents it from being added to this deque
- */
- boolean offerLast(E e);
-
- /**
- * Retrieves and removes the first element of this deque. This method
- * differs from {@link #pollFirst pollFirst} only in that it throws an
- * exception if this deque is empty.
- *
- * @return the head of this deque
- * @throws NoSuchElementException if this deque is empty
- */
- E removeFirst();
-
- /**
- * Retrieves and removes the last element of this deque. This method
- * differs from {@link #pollLast pollLast} only in that it throws an
- * exception if this deque is empty.
- *
- * @return the tail of this deque
- * @throws NoSuchElementException if this deque is empty
- */
- E removeLast();
-
- /**
- * Retrieves and removes the first element of this deque,
- * or returns <tt>null</tt> if this deque is empty.
- *
- * @return the head of this deque, or <tt>null</tt> if this deque is empty
- */
- E pollFirst();
-
- /**
- * Retrieves and removes the last element of this deque,
- * or returns <tt>null</tt> if this deque is empty.
- *
- * @return the tail of this deque, or <tt>null</tt> if this deque is empty
- */
- E pollLast();
-
- /**
- * Retrieves, but does not remove, the first element of this deque.
- *
- * This method differs from {@link #peekFirst peekFirst} only in that it
- * throws an exception if this deque is empty.
- *
- * @return the head of this deque
- * @throws NoSuchElementException if this deque is empty
- */
- E getFirst();
-
- /**
- * Retrieves, but does not remove, the last element of this deque.
- * This method differs from {@link #peekLast peekLast} only in that it
- * throws an exception if this deque is empty.
- *
- * @return the tail of this deque
- * @throws NoSuchElementException if this deque is empty
- */
- E getLast();
-
- /**
- * Retrieves, but does not remove, the first element of this deque,
- * or returns <tt>null</tt> if this deque is empty.
- *
- * @return the head of this deque, or <tt>null</tt> if this deque is empty
- */
- E peekFirst();
-
- /**
- * Retrieves, but does not remove, the last element of this deque,
- * or returns <tt>null</tt> if this deque is empty.
- *
- * @return the tail of this deque, or <tt>null</tt> if this deque is empty
- */
- E peekLast();
-
- /**
- * Removes the first occurrence of the specified element from this deque.
- * If the deque does not contain the element, it is unchanged.
- * More formally, removes the first element <tt>e</tt> such that
- * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>
- * (if such an element exists).
- * Returns <tt>true</tt> if this deque contained the specified element
- * (or equivalently, if this deque changed as a result of the call).
- *
- * @param o element to be removed from this deque, if present
- * @return <tt>true</tt> if an element was removed as a result of this call
- * @throws ClassCastException if the class of the specified element
- * is incompatible with this deque (optional)
- * @throws NullPointerException if the specified element is null and this
- * deque does not permit null elements (optional)
- */
- boolean removeFirstOccurrence(Object o);
-
- /**
- * Removes the last occurrence of the specified element from this deque.
- * If the deque does not contain the element, it is unchanged.
- * More formally, removes the last element <tt>e</tt> such that
- * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>
- * (if such an element exists).
- * Returns <tt>true</tt> if this deque contained the specified element
- * (or equivalently, if this deque changed as a result of the call).
- *
- * @param o element to be removed from this deque, if present
- * @return <tt>true</tt> if an element was removed as a result of this call
- * @throws ClassCastException if the class of the specified element
- * is incompatible with this deque (optional)
- * @throws NullPointerException if the specified element is null and this
- * deque does not permit null elements (optional)
- */
- boolean removeLastOccurrence(Object o);
-
- // *** Queue methods ***
-
- /**
- * Inserts the specified element into the queue represented by this deque
- * (in other words, at the tail of this deque) if it is possible to do so
- * immediately without violating capacity restrictions, returning
- * <tt>true</tt> upon success and throwing an
- * <tt>IllegalStateException</tt> if no space is currently available.
- * When using a capacity-restricted deque, it is generally preferable to
- * use {@link #offer(Object) offer}.
- *
- * <p>This method is equivalent to {@link #addLast}.
- *
- * @param e the element to add
- * @return <tt>true</tt> (as specified by {@link Collection#add})
- * @throws IllegalStateException if the element cannot be added at this
- * time due to capacity restrictions
- * @throws ClassCastException if the class of the specified element
- * prevents it from being added to this deque
- * @throws NullPointerException if the specified element is null and this
- * deque does not permit null elements
- * @throws IllegalArgumentException if some property of the specified
- * element prevents it from being added to this deque
- */
- boolean add(E e);
-
- /**
- * Inserts the specified element into the queue represented by this deque
- * (in other words, at the tail of this deque) if it is possible to do so
- * immediately without violating capacity restrictions, returning
- * <tt>true</tt> upon success and <tt>false</tt> if no space is currently
- * available. When using a capacity-restricted deque, this method is
- * generally preferable to the {@link #add} method, which can fail to
- * insert an element only by throwing an exception.
- *
- * <p>This method is equivalent to {@link #offerLast}.
- *
- * @param e the element to add
- * @return <tt>true</tt> if the element was added to this deque, else
- * <tt>false</tt>
- * @throws ClassCastException if the class of the specified element
- * prevents it from being added to this deque
- * @throws NullPointerException if the specified element is null and this
- * deque does not permit null elements
- * @throws IllegalArgumentException if some property of the specified
- * element prevents it from being added to this deque
- */
- boolean offer(E e);
-
- /**
- * Retrieves and removes the head of the queue represented by this deque
- * (in other words, the first element of this deque).
- * This method differs from {@link #poll poll} only in that it throws an
- * exception if this deque is empty.
- *
- * <p>This method is equivalent to {@link #removeFirst()}.
- *
- * @return the head of the queue represented by this deque
- * @throws NoSuchElementException if this deque is empty
- */
- E remove();
-
- /**
- * Retrieves and removes the head of the queue represented by this deque
- * (in other words, the first element of this deque), or returns
- * <tt>null</tt> if this deque is empty.
- *
- * <p>This method is equivalent to {@link #pollFirst()}.
- *
- * @return the first element of this deque, or <tt>null</tt> if
- * this deque is empty
- */
- E poll();
-
- /**
- * Retrieves, but does not remove, the head of the queue represented by
- * this deque (in other words, the first element of this deque).
- * This method differs from {@link #peek peek} only in that it throws an
- * exception if this deque is empty.
- *
- * <p>This method is equivalent to {@link #getFirst()}.
- *
- * @return the head of the queue represented by this deque
- * @throws NoSuchElementException if this deque is empty
- */
- E element();
-
- /**
- * Retrieves, but does not remove, the head of the queue represented by
- * this deque (in other words, the first element of this deque), or
- * returns <tt>null</tt> if this deque is empty.
- *
- * <p>This method is equivalent to {@link #peekFirst()}.
- *
- * @return the head of the queue represented by this deque, or
- * <tt>null</tt> if this deque is empty
- */
- E peek();
-
- // *** Stack methods ***
-
- /**
- * Pushes an element onto the stack represented by this deque (in other
- * words, at the head of this deque) if it is possible to do so
- * immediately without violating capacity restrictions, returning
- * <tt>true</tt> upon success and throwing an
- * <tt>IllegalStateException</tt> if no space is currently available.
- *
- * <p>This method is equivalent to {@link #addFirst}.
- *
- * @param e the element to push
- * @throws IllegalStateException if the element cannot be added at this
- * time due to capacity restrictions
- * @throws ClassCastException if the class of the specified element
- * prevents it from being added to this deque
- * @throws NullPointerException if the specified element is null and this
- * deque does not permit null elements
- * @throws IllegalArgumentException if some property of the specified
- * element prevents it from being added to this deque
- */
- void push(E e);
-
- /**
- * Pops an element from the stack represented by this deque. In other
- * words, removes and returns the first element of this deque.
- *
- * <p>This method is equivalent to {@link #removeFirst()}.
- *
- * @return the element at the front of this deque (which is the top
- * of the stack represented by this deque)
- * @throws NoSuchElementException if this deque is empty
- */
- E pop();
-
- // *** Collection methods ***
-
- /**
- * Removes the first occurrence of the specified element from this deque.
- * If the deque does not contain the element, it is unchanged.
- * More formally, removes the first element <tt>e</tt> such that
- * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>
- * (if such an element exists).
- * Returns <tt>true</tt> if this deque contained the specified element
- * (or equivalently, if this deque changed as a result of the call).
- *
- * <p>This method is equivalent to {@link #removeFirstOccurrence}.
- *
- * @param o element to be removed from this deque, if present
- * @return <tt>true</tt> if an element was removed as a result of this call
- * @throws ClassCastException if the class of the specified element
- * is incompatible with this deque (optional)
- * @throws NullPointerException if the specified element is null and this
- * deque does not permit null elements (optional)
- */
- boolean remove(Object o);
-
- /**
- * Returns <tt>true</tt> if this deque contains the specified element.
- * More formally, returns <tt>true</tt> if and only if this deque contains
- * at least one element <tt>e</tt> such that
- * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
- *
- * @param o element whose presence in this deque is to be tested
- * @return <tt>true</tt> if this deque contains the specified element
- * @throws ClassCastException if the type of the specified element
- * is incompatible with this deque (optional)
- * @throws NullPointerException if the specified element is null and this
- * deque does not permit null elements (optional)
- */
- boolean contains(Object o);
-
- /**
- * Returns the number of elements in this deque.
- *
- * @return the number of elements in this deque
- */
- public int size();
-
- /**
- * Returns an iterator over the elements in this deque in proper sequence.
- * The elements will be returned in order from first (head) to last (tail).
- *
- * @return an iterator over the elements in this deque in proper sequence
- */
- Iterator<E> iterator();
-
- /**
- * Returns an iterator over the elements in this deque in reverse
- * sequential order. The elements will be returned in order from
- * last (tail) to first (head).
- *
- * @return an iterator over the elements in this deque in reverse
- * sequence
- */
- Iterator<E> descendingIterator();
+ /**
+ * Inserts the specified element at the front of this deque if it is
+ * possible to do so immediately without violating capacity restrictions.
+ * When using a capacity-restricted deque, it is generally preferable to
+ * use method {@link #offerFirst}.
+ *
+ * @param e the element to add
+ * @throws IllegalStateException if the element cannot be added at this
+ * time due to capacity restrictions
+ * @throws ClassCastException if the class of the specified element
+ * prevents it from being added to this deque
+ * @throws NullPointerException if the specified element is null and this
+ * deque does not permit null elements
+ * @throws IllegalArgumentException if some property of the specified
+ * element prevents it from being added to this deque
+ */
+ void addFirst(E e);
+
+ /**
+ * Inserts the specified element at the end of this deque if it is
+ * possible to do so immediately without violating capacity restrictions.
+ * When using a capacity-restricted deque, it is generally preferable to
+ * use method {@link #offerLast}.
+ *
+ * <p>This method is equivalent to {@link #add}.
+ *
+ * @param e the element to add
+ * @throws IllegalStateException if the element cannot be added at this
+ * time due to capacity restrictions
+ * @throws ClassCastException if the class of the specified element
+ * prevents it from being added to this deque
+ * @throws NullPointerException if the specified element is null and this
+ * deque does not permit null elements
+ * @throws IllegalArgumentException if some property of the specified
+ * element prevents it from being added to this deque
+ */
+ void addLast(E e);
+
+ /**
+ * Inserts the specified element at the front of this deque unless it would
+ * violate capacity restrictions. When using a capacity-restricted deque,
+ * this method is generally preferable to the {@link #addFirst} method,
+ * which can fail to insert an element only by throwing an exception.
+ *
+ * @param e the element to add
+ * @return <tt>true</tt> if the element was added to this deque, else
+ * <tt>false</tt>
+ * @throws ClassCastException if the class of the specified element
+ * prevents it from being added to this deque
+ * @throws NullPointerException if the specified element is null and this
+ * deque does not permit null elements
+ * @throws IllegalArgumentException if some property of the specified
+ * element prevents it from being added to this deque
+ */
+ boolean offerFirst(E e);
+
+ /**
+ * Inserts the specified element at the end of this deque unless it would
+ * violate capacity restrictions. When using a capacity-restricted deque,
+ * this method is generally preferable to the {@link #addLast} method,
+ * which can fail to insert an element only by throwing an exception.
+ *
+ * @param e the element to add
+ * @return <tt>true</tt> if the element was added to this deque, else
+ * <tt>false</tt>
+ * @throws ClassCastException if the class of the specified element
+ * prevents it from being added to this deque
+ * @throws NullPointerException if the specified element is null and this
+ * deque does not permit null elements
+ * @throws IllegalArgumentException if some property of the specified
+ * element prevents it from being added to this deque
+ */
+ boolean offerLast(E e);
+
+ /**
+ * Retrieves and removes the first element of this deque. This method
+ * differs from {@link #pollFirst pollFirst} only in that it throws an
+ * exception if this deque is empty.
+ *
+ * @return the head of this deque
+ * @throws NoSuchElementException if this deque is empty
+ */
+ E removeFirst();
+
+ /**
+ * Retrieves and removes the last element of this deque. This method
+ * differs from {@link #pollLast pollLast} only in that it throws an
+ * exception if this deque is empty.
+ *
+ * @return the tail of this deque
+ * @throws NoSuchElementException if this deque is empty
+ */
+ E removeLast();
+
+ /**
+ * Retrieves and removes the first element of this deque,
+ * or returns <tt>null</tt> if this deque is empty.
+ *
+ * @return the head of this deque, or <tt>null</tt> if this deque is empty
+ */
+ E pollFirst();
+
+ /**
+ * Retrieves and removes the last element of this deque,
+ * or returns <tt>null</tt> if this deque is empty.
+ *
+ * @return the tail of this deque, or <tt>null</tt> if this deque is empty
+ */
+ E pollLast();
+
+ /**
+ * Retrieves, but does not remove, the first element of this deque.
+ *
+ * This method differs from {@link #peekFirst peekFirst} only in that it
+ * throws an exception if this deque is empty.
+ *
+ * @return the head of this deque
+ * @throws NoSuchElementException if this deque is empty
+ */
+ E getFirst();
+
+ /**
+ * Retrieves, but does not remove, the last element of this deque.
+ * This method differs from {@link #peekLast peekLast} only in that it
+ * throws an exception if this deque is empty.
+ *
+ * @return the tail of this deque
+ * @throws NoSuchElementException if this deque is empty
+ */
+ E getLast();
+
+ /**
+ * Retrieves, but does not remove, the first element of this deque,
+ * or returns <tt>null</tt> if this deque is empty.
+ *
+ * @return the head of this deque, or <tt>null</tt> if this deque is empty
+ */
+ E peekFirst();
+
+ /**
+ * Retrieves, but does not remove, the last element of this deque,
+ * or returns <tt>null</tt> if this deque is empty.
+ *
+ * @return the tail of this deque, or <tt>null</tt> if this deque is empty
+ */
+ E peekLast();
+
+ /**
+ * Removes the first occurrence of the specified element from this deque.
+ * If the deque does not contain the element, it is unchanged.
+ * More formally, removes the first element <tt>e</tt> such that
+ * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>
+ * (if such an element exists).
+ * Returns <tt>true</tt> if this deque contained the specified element
+ * (or equivalently, if this deque changed as a result of the call).
+ *
+ * @param o element to be removed from this deque, if present
+ * @return <tt>true</tt> if an element was removed as a result of this call
+ * @throws ClassCastException if the class of the specified element
+ * is incompatible with this deque (optional)
+ * @throws NullPointerException if the specified element is null and this
+ * deque does not permit null elements (optional)
+ */
+ boolean removeFirstOccurrence(Object o);
+
+ /**
+ * Removes the last occurrence of the specified element from this deque.
+ * If the deque does not contain the element, it is unchanged.
+ * More formally, removes the last element <tt>e</tt> such that
+ * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>
+ * (if such an element exists).
+ * Returns <tt>true</tt> if this deque contained the specified element
+ * (or equivalently, if this deque changed as a result of the call).
+ *
+ * @param o element to be removed from this deque, if present
+ * @return <tt>true</tt> if an element was removed as a result of this call
+ * @throws ClassCastException if the class of the specified element
+ * is incompatible with this deque (optional)
+ * @throws NullPointerException if the specified element is null and this
+ * deque does not permit null elements (optional)
+ */
+ boolean removeLastOccurrence(Object o);
+
+ // *** Queue methods ***
+
+ /**
+ * Inserts the specified element into the queue represented by this deque
+ * (in other words, at the tail of this deque) if it is possible to do so
+ * immediately without violating capacity restrictions, returning
+ * <tt>true</tt> upon success and throwing an
+ * <tt>IllegalStateException</tt> if no space is currently available.
+ * When using a capacity-restricted deque, it is generally preferable to
+ * use {@link #offer(Object) offer}.
+ *
+ * <p>This method is equivalent to {@link #addLast}.
+ *
+ * @param e the element to add
+ * @return <tt>true</tt> (as specified by {@link Collection#add})
+ * @throws IllegalStateException if the element cannot be added at this
+ * time due to capacity restrictions
+ * @throws ClassCastException if the class of the specified element
+ * prevents it from being added to this deque
+ * @throws NullPointerException if the specified element is null and this
+ * deque does not permit null elements
+ * @throws IllegalArgumentException if some property of the specified
+ * element prevents it from being added to this deque
+ */
+ boolean add(E e);
+
+ /**
+ * Inserts the specified element into the queue represented by this deque
+ * (in other words, at the tail of this deque) if it is possible to do so
+ * immediately without violating capacity restrictions, returning
+ * <tt>true</tt> upon success and <tt>false</tt> if no space is currently
+ * available. When using a capacity-restricted deque, this method is
+ * generally preferable to the {@link #add} method, which can fail to
+ * insert an element only by throwing an exception.
+ *
+ * <p>This method is equivalent to {@link #offerLast}.
+ *
+ * @param e the element to add
+ * @return <tt>true</tt> if the element was added to this deque, else
+ * <tt>false</tt>
+ * @throws ClassCastException if the class of the specified element
+ * prevents it from being added to this deque
+ * @throws NullPointerException if the specified element is null and this
+ * deque does not permit null elements
+ * @throws IllegalArgumentException if some property of the specified
+ * element prevents it from being added to this deque
+ */
+ boolean offer(E e);
+
+ /**
+ * Retrieves and removes the head of the queue represented by this deque
+ * (in other words, the first element of this deque).
+ * This method differs from {@link #poll poll} only in that it throws an
+ * exception if this deque is empty.
+ *
+ * <p>This method is equivalent to {@link #removeFirst()}.
+ *
+ * @return the head of the queue represented by this deque
+ * @throws NoSuchElementException if this deque is empty
+ */
+ E remove();
+
+ /**
+ * Retrieves and removes the head of the queue represented by this deque
+ * (in other words, the first element of this deque), or returns
+ * <tt>null</tt> if this deque is empty.
+ *
+ * <p>This method is equivalent to {@link #pollFirst()}.
+ *
+ * @return the first element of this deque, or <tt>null</tt> if
+ * this deque is empty
+ */
+ E poll();
+
+ /**
+ * Retrieves, but does not remove, the head of the queue represented by
+ * this deque (in other words, the first element of this deque).
+ * This method differs from {@link #peek peek} only in that it throws an
+ * exception if this deque is empty.
+ *
+ * <p>This method is equivalent to {@link #getFirst()}.
+ *
+ * @return the head of the queue represented by this deque
+ * @throws NoSuchElementException if this deque is empty
+ */
+ E element();
+
+ /**
+ * Retrieves, but does not remove, the head of the queue represented by
+ * this deque (in other words, the first element of this deque), or
+ * returns <tt>null</tt> if this deque is empty.
+ *
+ * <p>This method is equivalent to {@link #peekFirst()}.
+ *
+ * @return the head of the queue represented by this deque, or
+ * <tt>null</tt> if this deque is empty
+ */
+ E peek();
+
+ // *** Stack methods ***
+
+ /**
+ * Pushes an element onto the stack represented by this deque (in other
+ * words, at the head of this deque) if it is possible to do so
+ * immediately without violating capacity restrictions, returning
+ * <tt>true</tt> upon success and throwing an
+ * <tt>IllegalStateException</tt> if no space is currently available.
+ *
+ * <p>This method is equivalent to {@link #addFirst}.
+ *
+ * @param e the element to push
+ * @throws IllegalStateException if the element cannot be added at this
+ * time due to capacity restrictions
+ * @throws ClassCastException if the class of the specified element
+ * prevents it from being added to this deque
+ * @throws NullPointerException if the specified element is null and this
+ * deque does not permit null elements
+ * @throws IllegalArgumentException if some property of the specified
+ * element prevents it from being added to this deque
+ */
+ void push(E e);
+
+ /**
+ * Pops an element from the stack represented by this deque. In other
+ * words, removes and returns the first element of this deque.
+ *
+ * <p>This method is equivalent to {@link #removeFirst()}.
+ *
+ * @return the element at the front of this deque (which is the top
+ * of the stack represented by this deque)
+ * @throws NoSuchElementException if this deque is empty
+ */
+ E pop();
+
+ // *** Collection methods ***
+
+ /**
+ * Removes the first occurrence of the specified element from this deque.
+ * If the deque does not contain the element, it is unchanged.
+ * More formally, removes the first element <tt>e</tt> such that
+ * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>
+ * (if such an element exists).
+ * Returns <tt>true</tt> if this deque contained the specified element
+ * (or equivalently, if this deque changed as a result of the call).
+ *
+ * <p>This method is equivalent to {@link #removeFirstOccurrence}.
+ *
+ * @param o element to be removed from this deque, if present
+ * @return <tt>true</tt> if an element was removed as a result of this call
+ * @throws ClassCastException if the class of the specified element
+ * is incompatible with this deque (optional)
+ * @throws NullPointerException if the specified element is null and this
+ * deque does not permit null elements (optional)
+ */
+ boolean remove(Object o);
+
+ /**
+ * Returns <tt>true</tt> if this deque contains the specified element.
+ * More formally, returns <tt>true</tt> if and only if this deque contains
+ * at least one element <tt>e</tt> such that
+ * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
+ *
+ * @param o element whose presence in this deque is to be tested
+ * @return <tt>true</tt> if this deque contains the specified element
+ * @throws ClassCastException if the type of the specified element
+ * is incompatible with this deque (optional)
+ * @throws NullPointerException if the specified element is null and this
+ * deque does not permit null elements (optional)
+ */
+ boolean contains(Object o);
+
+ /**
+ * Returns the number of elements in this deque.
+ *
+ * @return the number of elements in this deque
+ */
+ public int size();
+
+ /**
+ * Returns an iterator over the elements in this deque in proper sequence.
+ * The elements will be returned in order from first (head) to last (tail).
+ *
+ * @return an iterator over the elements in this deque in proper sequence
+ */
+ Iterator<E> iterator();
+
+ /**
+ * Returns an iterator over the elements in this deque in reverse
+ * sequential order. The elements will be returned in order from
+ * last (tail) to first (head).
+ *
+ * @return an iterator over the elements in this deque in reverse
+ * sequence
+ */
+ Iterator<E> descendingIterator();
}
diff --git a/platform/android/viewer/src/com/artifex/mupdfdemo/MuPDFActivity.java b/platform/android/viewer/src/com/artifex/mupdfdemo/MuPDFActivity.java
index 91b1e8fe..08d32be9 100644
--- a/platform/android/viewer/src/com/artifex/mupdfdemo/MuPDFActivity.java
+++ b/platform/android/viewer/src/com/artifex/mupdfdemo/MuPDFActivity.java
@@ -274,7 +274,7 @@ public class MuPDFActivity extends Activity implements FilePicker.FilePickerSupp
super.onCreate(savedInstanceState);
mAlertBuilder = new AlertDialog.Builder(this);
- gAlertBuilder = mAlertBuilder; // keep a static copy of this that other classes can use
+ gAlertBuilder = mAlertBuilder; // keep a static copy of this that other classes can use
if (core == null) {
core = (MuPDFCore)getLastNonConfigurationInstance();
diff --git a/platform/android/viewer/src/com/artifex/mupdfdemo/OutlineActivityData.java b/platform/android/viewer/src/com/artifex/mupdfdemo/OutlineActivityData.java
index a703e61e..be1386e6 100644
--- a/platform/android/viewer/src/com/artifex/mupdfdemo/OutlineActivityData.java
+++ b/platform/android/viewer/src/com/artifex/mupdfdemo/OutlineActivityData.java
@@ -2,7 +2,7 @@ package com.artifex.mupdfdemo;
public class OutlineActivityData {
public OutlineItem items[];
- public int position;
+ public int position;
static private OutlineActivityData singleton;
static public void set(OutlineActivityData d) {
diff --git a/platform/android/viewer/src/com/artifex/mupdfdemo/OutlineAdapter.java b/platform/android/viewer/src/com/artifex/mupdfdemo/OutlineAdapter.java
index 4251ed8e..c1b22021 100644
--- a/platform/android/viewer/src/com/artifex/mupdfdemo/OutlineAdapter.java
+++ b/platform/android/viewer/src/com/artifex/mupdfdemo/OutlineAdapter.java
@@ -7,11 +7,11 @@ import android.widget.BaseAdapter;
import android.widget.TextView;
public class OutlineAdapter extends BaseAdapter {
- private final OutlineItem mItems[];
+ private final OutlineItem mItems[];
private final LayoutInflater mInflater;
public OutlineAdapter(LayoutInflater inflater, OutlineItem items[]) {
mInflater = inflater;
- mItems = items;
+ mItems = items;
}
public int getCount() {
diff --git a/platform/android/viewer/src/com/artifex/mupdfdemo/OutlineItem.java b/platform/android/viewer/src/com/artifex/mupdfdemo/OutlineItem.java
index 7730991e..0ed041c2 100644
--- a/platform/android/viewer/src/com/artifex/mupdfdemo/OutlineItem.java
+++ b/platform/android/viewer/src/com/artifex/mupdfdemo/OutlineItem.java
@@ -1,14 +1,14 @@
package com.artifex.mupdfdemo;
public class OutlineItem {
- public final int level;
+ public final int level;
public final String title;
- public final int page;
+ public final int page;
OutlineItem(int _level, String _title, int _page) {
level = _level;
title = _title;
- page = _page;
+ page = _page;
}
}
diff --git a/platform/android/viewer/src/com/artifex/mupdfdemo/PageView.java b/platform/android/viewer/src/com/artifex/mupdfdemo/PageView.java
index c897f414..502e0c2b 100644
--- a/platform/android/viewer/src/com/artifex/mupdfdemo/PageView.java
+++ b/platform/android/viewer/src/com/artifex/mupdfdemo/PageView.java
@@ -94,7 +94,7 @@ public abstract class PageView extends ViewGroup {
private static final float INK_THICKNESS = 10.0f;
private static final int BACKGROUND_COLOR = 0xFFFFFFFF;
private static final int PROGRESS_DIALOG_DELAY = 200;
- protected final Context mContext;
+ protected final Context mContext;
protected int mPageNumber;
private Point mParentSize;
protected Point mSize; // Size of page at minimum zoom
@@ -127,7 +127,7 @@ public abstract class PageView extends ViewGroup {
public PageView(Context c, Point parentSize, Bitmap sharedHqBm) {
super(c);
- mContext = c;
+ mContext = c;
mParentSize = parentSize;
setBackgroundColor(BACKGROUND_COLOR);
mEntireBm = Bitmap.createBitmap(parentSize.x, parentSize.y, Config.ARGB_8888);
@@ -201,7 +201,7 @@ public abstract class PageView extends ViewGroup {
public void releaseBitmaps() {
reinit();
- // recycle bitmaps before releasing them.
+ // recycle bitmaps before releasing them.
if (mEntireBm!=null)
mEntireBm.recycle();
@@ -320,16 +320,16 @@ public abstract class PageView extends ViewGroup {
paint.setColor(HIGHLIGHT_COLOR);
for (RectF rect : mSearchBoxes)
canvas.drawRect(rect.left*scale, rect.top*scale,
- rect.right*scale, rect.bottom*scale,
- paint);
+ rect.right*scale, rect.bottom*scale,
+ paint);
}
if (!mIsBlank && mLinks != null && mHighlightLinks) {
paint.setColor(LINK_COLOR);
for (LinkInfo link : mLinks)
canvas.drawRect(link.rect.left*scale, link.rect.top*scale,
- link.rect.right*scale, link.rect.bottom*scale,
- paint);
+ link.rect.right*scale, link.rect.bottom*scale,
+ paint);
}
if (mSelectBox != null && mText != null) {
@@ -536,7 +536,7 @@ public abstract class PageView extends ViewGroup {
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- int w = right-left;
+ int w = right-left;
int h = bottom-top;
if (mEntire != null) {
@@ -556,7 +556,7 @@ public abstract class PageView extends ViewGroup {
if (mPatchViewSize.x != w || mPatchViewSize.y != h) {
// Zoomed since patch was created
mPatchViewSize = null;
- mPatchArea = null;
+ mPatchArea = null;
if (mPatch != null) {
mPatch.setImageBitmap(null);
mPatch.invalidate();
@@ -630,7 +630,7 @@ public abstract class PageView extends ViewGroup {
public void onPostExecute(Void result) {
mPatchViewSize = patchViewSize;
- mPatchArea = patchArea;
+ mPatchArea = patchArea;
mPatch.setImageBitmap(mPatchBm);
mPatch.invalidate();
//requestLayout();
diff --git a/platform/android/viewer/src/com/artifex/mupdfdemo/ReaderView.java b/platform/android/viewer/src/com/artifex/mupdfdemo/ReaderView.java
index f91efa41..bfccdb19 100644
--- a/platform/android/viewer/src/com/artifex/mupdfdemo/ReaderView.java
+++ b/platform/android/viewer/src/com/artifex/mupdfdemo/ReaderView.java
@@ -24,14 +24,14 @@ import android.widget.Scroller;
public class ReaderView
extends AdapterView<Adapter>
implements GestureDetector.OnGestureListener, ScaleGestureDetector.OnScaleGestureListener, Runnable {
- private static final int MOVING_DIAGONALLY = 0;
- private static final int MOVING_LEFT = 1;
- private static final int MOVING_RIGHT = 2;
- private static final int MOVING_UP = 3;
- private static final int MOVING_DOWN = 4;
+ private static final int MOVING_DIAGONALLY = 0;
+ private static final int MOVING_LEFT = 1;
+ private static final int MOVING_RIGHT = 2;
+ private static final int MOVING_UP = 3;
+ private static final int MOVING_DOWN = 4;
- private static final int FLING_MARGIN = 100;
- private static final int GAP = 20;
+ private static final int FLING_MARGIN = 100;
+ private static final int GAP = 20;
private static final float MIN_SCALE = 1.0f;
private static final float MAX_SCALE = 5.0f;
@@ -74,7 +74,7 @@ public class ReaderView
super(context);
mGestureDetector = new GestureDetector(this);
mScaleGestureDetector = new ScaleGestureDetector(context, this);
- mScroller = new Scroller(context);
+ mScroller = new Scroller(context);
mStepper = new Stepper(this, this);
}
@@ -94,7 +94,7 @@ public class ReaderView
{
mGestureDetector = new GestureDetector(this);
mScaleGestureDetector = new ScaleGestureDetector(context, this);
- mScroller = new Scroller(context);
+ mScroller = new Scroller(context);
mStepper = new Stepper(this, this);
}
}
@@ -103,7 +103,7 @@ public class ReaderView
super(context, attrs, defStyle);
mGestureDetector = new GestureDetector(this);
mScaleGestureDetector = new ScaleGestureDetector(context, this);
- mScroller = new Scroller(context);
+ mScroller = new Scroller(context);
mStepper = new Stepper(this, this);
}
@@ -173,7 +173,7 @@ public class ReaderView
// code.
// screenWidth/Height are the actual width/height of the screen. e.g. 480/800
- int screenWidth = getWidth();
+ int screenWidth = getWidth();
int screenHeight = getHeight();
// We might be mid scroll; we want to calculate where we scroll to based on
// where this scroll would end, not where we are now (to allow for people
@@ -181,11 +181,11 @@ public class ReaderView
int remainingX = mScroller.getFinalX() - mScroller.getCurrX();
int remainingY = mScroller.getFinalY() - mScroller.getCurrY();
// right/bottom is in terms of pixels within the scaled document; e.g. 1000
- int top = -(v.getTop() + mYScroll + remainingY);
- int right = screenWidth -(v.getLeft() + mXScroll + remainingX);
+ int top = -(v.getTop() + mYScroll + remainingY);
+ int right = screenWidth -(v.getLeft() + mXScroll + remainingX);
int bottom = screenHeight+top;
// docWidth/Height are the width/height of the scaled document e.g. 2000x3000
- int docWidth = v.getMeasuredWidth();
+ int docWidth = v.getMeasuredWidth();
int docHeight = v.getMeasuredHeight();
int xOffset, yOffset;
@@ -196,7 +196,7 @@ public class ReaderView
View nv = mChildViews.get(mCurrent+1);
if (nv == null) // No page to advance to
return;
- int nextTop = -(nv.getTop() + mYScroll + remainingY);
+ int nextTop = -(nv.getTop() + mYScroll + remainingY);
int nextLeft = -(nv.getLeft() + mXScroll + remainingX);
int nextDocWidth = nv.getMeasuredWidth();
int nextDocHeight = nv.getMeasuredHeight();
@@ -246,7 +246,7 @@ public class ReaderView
// code.
// screenWidth/Height are the actual width/height of the screen. e.g. 480/800
- int screenWidth = getWidth();
+ int screenWidth = getWidth();
int screenHeight = getHeight();
// We might be mid scroll; we want to calculate where we scroll to based on
// where this scroll would end, not where we are now (to allow for people
@@ -254,8 +254,8 @@ public class ReaderView
int remainingX = mScroller.getFinalX() - mScroller.getCurrX();
int remainingY = mScroller.getFinalY() - mScroller.getCurrY();
// left/top is in terms of pixels within the scaled document; e.g. 1000
- int left = -(v.getLeft() + mXScroll + remainingX);
- int top = -(v.getTop() + mYScroll + remainingY);
+ int left = -(v.getLeft() + mXScroll + remainingX);
+ int top = -(v.getTop() + mYScroll + remainingY);
// docWidth/Height are the width/height of the scaled document e.g. 2000x3000
int docHeight = v.getMeasuredHeight();
@@ -273,8 +273,8 @@ public class ReaderView
// Allow for the next page maybe being shorter than the screen is high
yOffset = (prevDocHeight < screenHeight ? ((prevDocHeight - screenHeight)>>1) : 0);
- int prevLeft = -(pv.getLeft() + mXScroll);
- int prevTop = -(pv.getTop() + mYScroll);
+ int prevLeft = -(pv.getLeft() + mXScroll);
+ int prevTop = -(pv.getTop() + mYScroll);
if (prevDocWidth < screenWidth) {
// Previous page is too narrow to fill the screen. Scroll to the bottom, centred.
xOffset = (prevDocWidth - screenWidth)>>1;
@@ -580,9 +580,9 @@ public class ReaderView
catch (java.lang.OutOfMemoryError e) {
System.out.println("Out of memory during layout");
- // we might get an out of memory error.
- // so let's display an alert.
- // TODO: a better message, in resources.
+ // we might get an out of memory error.
+ // so let's display an alert.
+ // TODO: a better message, in resources.
if (!memAlert) {
memAlert = true;
@@ -700,37 +700,37 @@ public class ReaderView
// the views spaced out
cvOffset = subScreenSizeOffset(cv);
if (notPresent) {
- //Main item not already present. Just place it top left
+ // Main item not already present. Just place it top left
cvLeft = cvOffset.x;
- cvTop = cvOffset.y;
+ cvTop = cvOffset.y;
} else {
// Main item already present. Adjust by scroll offsets
cvLeft = cv.getLeft() + mXScroll;
- cvTop = cv.getTop() + mYScroll;
+ cvTop = cv.getTop() + mYScroll;
}
// Scroll values have been accounted for
mXScroll = mYScroll = 0;
- cvRight = cvLeft + cv.getMeasuredWidth();
- cvBottom = cvTop + cv.getMeasuredHeight();
+ cvRight = cvLeft + cv.getMeasuredWidth();
+ cvBottom = cvTop + cv.getMeasuredHeight();
if (!mUserInteracting && mScroller.isFinished()) {
Point corr = getCorrection(getScrollBounds(cvLeft, cvTop, cvRight, cvBottom));
- cvRight += corr.x;
- cvLeft += corr.x;
- cvTop += corr.y;
+ cvRight += corr.x;
+ cvLeft += corr.x;
+ cvTop += corr.y;
cvBottom += corr.y;
} else if (HORIZONTAL_SCROLLING && cv.getMeasuredHeight() <= getHeight()) {
// When the current view is as small as the screen in height, clamp
// it vertically
Point corr = getCorrection(getScrollBounds(cvLeft, cvTop, cvRight, cvBottom));
- cvTop += corr.y;
+ cvTop += corr.y;
cvBottom += corr.y;
} else if (!HORIZONTAL_SCROLLING && cv.getMeasuredWidth() <= getWidth()) {
// When the current view is as small as the screen in width, clamp
// it horizontally
Point corr = getCorrection(getScrollBounds(cvLeft, cvTop, cvRight, cvBottom));
- cvRight += corr.x;
- cvLeft += corr.x;
+ cvRight += corr.x;
+ cvLeft += corr.x;
}
cv.layout(cvLeft, cvTop, cvRight, cvBottom);
@@ -871,14 +871,14 @@ public class ReaderView
// onLayout, so add mXScroll and mYScroll to the current
// positions when calculating the bounds.
return getScrollBounds(v.getLeft() + mXScroll,
- v.getTop() + mYScroll,
- v.getLeft() + v.getMeasuredWidth() + mXScroll,
- v.getTop() + v.getMeasuredHeight() + mYScroll);
+ v.getTop() + mYScroll,
+ v.getLeft() + v.getMeasuredWidth() + mXScroll,
+ v.getTop() + v.getMeasuredHeight() + mYScroll);
}
private Point getCorrection(Rect bounds) {
return new Point(Math.min(Math.max(0,bounds.left),bounds.right),
- Math.min(Math.max(0,bounds.top),bounds.bottom));
+ Math.min(Math.max(0,bounds.top),bounds.bottom));
}
private void postSettle(final View v) {
@@ -926,10 +926,10 @@ public class ReaderView
private static boolean withinBoundsInDirectionOfTravel(Rect bounds, float vx, float vy) {
switch (directionOfTravel(vx, vy)) {
case MOVING_DIAGONALLY: return bounds.contains(0, 0);
- case MOVING_LEFT: return bounds.left <= 0;
- case MOVING_RIGHT: return bounds.right >= 0;
- case MOVING_UP: return bounds.top <= 0;
- case MOVING_DOWN: return bounds.bottom >= 0;
+ case MOVING_LEFT: return bounds.left <= 0;
+ case MOVING_RIGHT: return bounds.right >= 0;
+ case MOVING_UP: return bounds.top <= 0;
+ case MOVING_DOWN: return bounds.bottom >= 0;
default: throw new NoSuchElementException();
}
}
diff --git a/platform/android/viewer/src/com/artifex/mupdfdemo/SearchTask.java b/platform/android/viewer/src/com/artifex/mupdfdemo/SearchTask.java
index d3969f10..7e15f98d 100644
--- a/platform/android/viewer/src/com/artifex/mupdfdemo/SearchTask.java
+++ b/platform/android/viewer/src/com/artifex/mupdfdemo/SearchTask.java
@@ -88,7 +88,7 @@ public abstract class SearchTask {
protected void onPostExecute(SearchTaskResult result) {
progressDialog.cancel();
if (result != null) {
- onTextFound(result);
+ onTextFound(result);
} else {
mAlertBuilder.setTitle(SearchTaskResult.get() == null ? R.string.text_not_found : R.string.no_further_occurrences_found);
AlertDialog alert = mAlertBuilder.create();
diff --git a/platform/android/viewer/src/com/artifex/mupdfdemo/SearchTaskResult.java b/platform/android/viewer/src/com/artifex/mupdfdemo/SearchTaskResult.java
index 8fa3c3a2..6c337fe2 100644
--- a/platform/android/viewer/src/com/artifex/mupdfdemo/SearchTaskResult.java
+++ b/platform/android/viewer/src/com/artifex/mupdfdemo/SearchTaskResult.java
@@ -4,7 +4,7 @@ import android.graphics.RectF;
public class SearchTaskResult {
public final String txt;
- public final int pageNumber;
+ public final int pageNumber;
public final RectF searchBoxes[];
static private SearchTaskResult singleton;