1package eu.siacs.conversations.crypto.sasl;
2
3import java.util.ArrayList;
4import java.util.Arrays;
5import java.util.Iterator;
6import java.util.List;
7import java.util.NoSuchElementException;
8
9/**
10 * A tokenizer for GS2 header strings
11 */
12public final class Tokenizer implements Iterator<String>, Iterable<String> {
13 private final List<String> parts;
14 private int index;
15
16 public Tokenizer(final byte[] challenge) {
17 final String challengeString = new String(challenge);
18 parts = new ArrayList<>(Arrays.asList(challengeString.split(",")));
19 index = 0;
20 }
21
22 /**
23 * Returns true if there is at least one more element, false otherwise.
24 *
25 * @see #next
26 */
27 @Override
28 public boolean hasNext() {
29 return parts.size() != index + 1;
30 }
31
32 /**
33 * Returns the next object and advances the iterator.
34 *
35 * @return the next object.
36 * @throws java.util.NoSuchElementException if there are no more elements.
37 * @see #hasNext
38 */
39 @Override
40 public String next() {
41 if (hasNext()) {
42 return parts.get(index++);
43 } else {
44 throw new NoSuchElementException("No such element. Size is: " + parts.size());
45 }
46 }
47
48 /**
49 * Removes the last object returned by {@code next} from the collection.
50 * This method can only be called once between each call to {@code next}.
51 *
52 * @throws UnsupportedOperationException if removing is not supported by the collection being
53 * iterated.
54 * @throws IllegalStateException if {@code next} has not been called, or {@code remove} has
55 * already been called after the last call to {@code next}.
56 */
57 @Override
58 public void remove() {
59 if(index <= 0) {
60 throw new IllegalStateException("You can't delete an element before first next() method call");
61 }
62 parts.remove(--index);
63 }
64
65 /**
66 * Returns an {@link java.util.Iterator} for the elements in this object.
67 *
68 * @return An {@code Iterator} instance.
69 */
70 @Override
71 public Iterator<String> iterator() {
72 return parts.iterator();
73 }
74}