/* * Decompiled with CFR 0.152. */ package com.google.common.base; import com.google.common.annotations.Beta; import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; import com.google.common.base.AbstractIterator; import com.google.common.base.CharMatcher; import com.google.common.base.Joiner; import com.google.common.base.Preconditions; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.annotation.CheckReturnValue; @GwtCompatible(emulated=true) public final class Splitter { private final CharMatcher trimmer; private final boolean omitEmptyStrings; private final Strategy strategy; private final int limit; private Splitter(Strategy strategy) { this(strategy, false, CharMatcher.NONE, Integer.MAX_VALUE); } private Splitter(Strategy strategy, boolean omitEmptyStrings, CharMatcher trimmer, int limit) { this.strategy = strategy; this.omitEmptyStrings = omitEmptyStrings; this.trimmer = trimmer; this.limit = limit; } public static Splitter on(char separator) { return Splitter.on(CharMatcher.is(separator)); } public static Splitter on(final CharMatcher separatorMatcher) { Preconditions.checkNotNull(separatorMatcher); return new Splitter(new Strategy(){ public SplittingIterator iterator(Splitter splitter, CharSequence toSplit) { return new SplittingIterator(splitter, toSplit){ @Override int separatorStart(int start) { return separatorMatcher.indexIn(this.toSplit, start); } @Override int separatorEnd(int separatorPosition) { return separatorPosition + 1; } }; } }); } public static Splitter on(final String separator) { Preconditions.checkArgument(separator.length() != 0, "The separator may not be the empty string."); return new Splitter(new Strategy(){ public SplittingIterator iterator(Splitter splitter, CharSequence toSplit) { return new SplittingIterator(splitter, toSplit){ @Override public int separatorStart(int start) { int separatorLength = separator.length(); int last = this.toSplit.length() - separatorLength; block0: for (int p = start; p <= last; ++p) { for (int i = 0; i < separatorLength; ++i) { if (this.toSplit.charAt(i + p) != separator.charAt(i)) continue block0; } return p; } return -1; } @Override public int separatorEnd(int separatorPosition) { return separatorPosition + separator.length(); } }; } }); } @GwtIncompatible(value="java.util.regex") public static Splitter on(final Pattern separatorPattern) { Preconditions.checkNotNull(separatorPattern); Preconditions.checkArgument(!separatorPattern.matcher("").matches(), "The pattern may not match the empty string: %s", separatorPattern); return new Splitter(new Strategy(){ public SplittingIterator iterator(Splitter splitter, CharSequence toSplit) { final Matcher matcher = separatorPattern.matcher(toSplit); return new SplittingIterator(splitter, toSplit){ @Override public int separatorStart(int start) { return matcher.find(start) ? matcher.start() : -1; } @Override public int separatorEnd(int separatorPosition) { return matcher.end(); } }; } }); } @GwtIncompatible(value="java.util.regex") public static Splitter onPattern(String separatorPattern) { return Splitter.on(Pattern.compile(separatorPattern)); } public static Splitter fixedLength(final int length) { Preconditions.checkArgument(length > 0, "The length may not be less than 1"); return new Splitter(new Strategy(){ public SplittingIterator iterator(Splitter splitter, CharSequence toSplit) { return new SplittingIterator(splitter, toSplit){ @Override public int separatorStart(int start) { int nextChunkStart = start + length; return nextChunkStart < this.toSplit.length() ? nextChunkStart : -1; } @Override public int separatorEnd(int separatorPosition) { return separatorPosition; } }; } }); } @CheckReturnValue public Splitter omitEmptyStrings() { return new Splitter(this.strategy, true, this.trimmer, this.limit); } @CheckReturnValue public Splitter limit(int limit) { Preconditions.checkArgument(limit > 0, "must be greater than zero: %s", limit); return new Splitter(this.strategy, this.omitEmptyStrings, this.trimmer, limit); } @CheckReturnValue public Splitter trimResults() { return this.trimResults(CharMatcher.WHITESPACE); } @CheckReturnValue public Splitter trimResults(CharMatcher trimmer) { Preconditions.checkNotNull(trimmer); return new Splitter(this.strategy, this.omitEmptyStrings, trimmer, this.limit); } public Iterable split(final CharSequence sequence) { Preconditions.checkNotNull(sequence); return new Iterable(){ @Override public Iterator iterator() { return Splitter.this.splittingIterator(sequence); } public String toString() { return Joiner.on(", ").appendTo(new StringBuilder().append('['), (Iterable)this).append(']').toString(); } }; } private Iterator splittingIterator(CharSequence sequence) { return this.strategy.iterator(this, sequence); } @Beta public List splitToList(CharSequence sequence) { Preconditions.checkNotNull(sequence); Iterator iterator = this.splittingIterator(sequence); ArrayList result = new ArrayList(); while (iterator.hasNext()) { result.add(iterator.next()); } return Collections.unmodifiableList(result); } @CheckReturnValue @Beta public MapSplitter withKeyValueSeparator(String separator) { return this.withKeyValueSeparator(Splitter.on(separator)); } @CheckReturnValue @Beta public MapSplitter withKeyValueSeparator(char separator) { return this.withKeyValueSeparator(Splitter.on(separator)); } @CheckReturnValue @Beta public MapSplitter withKeyValueSeparator(Splitter keyValueSplitter) { return new MapSplitter(this, keyValueSplitter); } private static abstract class SplittingIterator extends AbstractIterator { final CharSequence toSplit; final CharMatcher trimmer; final boolean omitEmptyStrings; int offset = 0; int limit; abstract int separatorStart(int var1); abstract int separatorEnd(int var1); protected SplittingIterator(Splitter splitter, CharSequence toSplit) { this.trimmer = splitter.trimmer; this.omitEmptyStrings = splitter.omitEmptyStrings; this.limit = splitter.limit; this.toSplit = toSplit; } @Override protected String computeNext() { int nextStart = this.offset; while (this.offset != -1) { int end; int start = nextStart; int separatorPosition = this.separatorStart(this.offset); if (separatorPosition == -1) { end = this.toSplit.length(); this.offset = -1; } else { end = separatorPosition; this.offset = this.separatorEnd(separatorPosition); } if (this.offset == nextStart) { ++this.offset; if (this.offset < this.toSplit.length()) continue; this.offset = -1; continue; } while (start < end && this.trimmer.matches(this.toSplit.charAt(start))) { ++start; } while (end > start && this.trimmer.matches(this.toSplit.charAt(end - 1))) { --end; } if (this.omitEmptyStrings && start == end) { nextStart = this.offset; continue; } if (this.limit == 1) { this.offset = -1; for (end = this.toSplit.length(); end > start && this.trimmer.matches(this.toSplit.charAt(end - 1)); --end) { } } else { --this.limit; } return this.toSplit.subSequence(start, end).toString(); } return (String)this.endOfData(); } } private static interface Strategy { public Iterator iterator(Splitter var1, CharSequence var2); } @Beta public static final class MapSplitter { private static final String INVALID_ENTRY_MESSAGE = "Chunk [%s] is not a valid entry"; private final Splitter outerSplitter; private final Splitter entrySplitter; private MapSplitter(Splitter outerSplitter, Splitter entrySplitter) { this.outerSplitter = outerSplitter; this.entrySplitter = Preconditions.checkNotNull(entrySplitter); } public Map split(CharSequence sequence) { LinkedHashMap map = new LinkedHashMap(); for (String entry : this.outerSplitter.split(sequence)) { Iterator entryFields = this.entrySplitter.splittingIterator(entry); Preconditions.checkArgument(entryFields.hasNext(), INVALID_ENTRY_MESSAGE, entry); String key = (String)entryFields.next(); Preconditions.checkArgument(!map.containsKey(key), "Duplicate key [%s] found.", key); Preconditions.checkArgument(entryFields.hasNext(), INVALID_ENTRY_MESSAGE, entry); String value = (String)entryFields.next(); map.put(key, value); Preconditions.checkArgument(!entryFields.hasNext(), INVALID_ENTRY_MESSAGE, entry); } return Collections.unmodifiableMap(map); } } }