/* */ package com.ibm.icu.impl; /* */ /* */ import com.ibm.icu.lang.UCharacter; /* */ import java.util.Iterator; /* */ import java.util.LinkedList; /* */ import java.util.List; /* */ import java.util.ListIterator; /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public class TextTrieMap<V> /* */ { /* 22 */ private TextTrieMap<V>.Node _root = new Node(null); /* */ /* */ /* */ boolean _ignoreCase; /* */ /* */ /* */ /* */ public TextTrieMap(boolean ignoreCase) /* */ { /* 31 */ this._ignoreCase = ignoreCase; /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ public TextTrieMap<V> put(CharSequence text, V val) /* */ { /* 41 */ CharIterator chitr = new CharIterator(text, 0, this._ignoreCase); /* 42 */ this._root.add(chitr, val); /* 43 */ return this; /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public Iterator<V> get(String text) /* */ { /* 56 */ return get(text, 0); /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public Iterator<V> get(String text, int start) /* */ { /* 71 */ return get(text, start, null); /* */ } /* */ /* */ public Iterator<V> get(String text, int start, int[] matchLen) { /* 75 */ LongestMatchHandler<V> handler = new LongestMatchHandler(null); /* 76 */ find(text, start, handler); /* 77 */ if ((matchLen != null) && (matchLen.length > 0)) { /* 78 */ matchLen[0] = handler.getMatchLength(); /* */ } /* 80 */ return handler.getMatches(); /* */ } /* */ /* */ public void find(String text, ResultHandler<V> handler) { /* 84 */ find(text, 0, handler); /* */ } /* */ /* */ public void find(String text, int offset, ResultHandler<V> handler) { /* 88 */ CharIterator chitr = new CharIterator(text, offset, this._ignoreCase); /* 89 */ find(this._root, chitr, handler); /* */ } /* */ /* */ private synchronized void find(TextTrieMap<V>.Node node, CharIterator chitr, ResultHandler<V> handler) { /* 93 */ Iterator<V> values = node.values(); /* 94 */ if ((values != null) && /* 95 */ (!handler.handlePrefixMatch(chitr.processedLength(), values))) { /* 96 */ return; /* */ } /* */ /* */ /* 100 */ TextTrieMap<V>.Node nextMatch = node.findMatch(chitr); /* 101 */ if (nextMatch != null) { /* 102 */ find(nextMatch, chitr, handler); /* */ } /* */ } /* */ /* */ public static class CharIterator implements Iterator<Character> /* */ { /* */ private boolean _ignoreCase; /* */ private CharSequence _text; /* */ private int _nextIdx; /* */ private int _startIdx; /* */ private Character _remainingChar; /* */ /* */ CharIterator(CharSequence text, int offset, boolean ignoreCase) { /* 115 */ this._text = text; /* 116 */ this._nextIdx = (this._startIdx = offset); /* 117 */ this._ignoreCase = ignoreCase; /* */ } /* */ /* */ /* */ /* */ public boolean hasNext() /* */ { /* 124 */ if ((this._nextIdx == this._text.length()) && (this._remainingChar == null)) { /* 125 */ return false; /* */ } /* 127 */ return true; /* */ } /* */ /* */ /* */ /* */ public Character next() /* */ { /* 134 */ if ((this._nextIdx == this._text.length()) && (this._remainingChar == null)) { /* 135 */ return null; /* */ } /* */ Character next; /* 138 */ if (this._remainingChar != null) { /* 139 */ Character next = this._remainingChar; /* 140 */ this._remainingChar = null; /* */ } /* 142 */ else if (this._ignoreCase) { /* 143 */ int cp = UCharacter.foldCase(Character.codePointAt(this._text, this._nextIdx), true); /* 144 */ this._nextIdx += Character.charCount(cp); /* */ /* 146 */ char[] chars = Character.toChars(cp); /* 147 */ Character next = Character.valueOf(chars[0]); /* 148 */ if (chars.length == 2) { /* 149 */ this._remainingChar = Character.valueOf(chars[1]); /* */ } /* */ } else { /* 152 */ next = Character.valueOf(this._text.charAt(this._nextIdx)); /* 153 */ this._nextIdx += 1; /* */ } /* */ /* 156 */ return next; /* */ } /* */ /* */ /* */ /* */ public void remove() /* */ { /* 163 */ throw new UnsupportedOperationException("remove() not supproted"); /* */ } /* */ /* */ public int nextIndex() { /* 167 */ return this._nextIdx; /* */ } /* */ /* */ public int processedLength() { /* 171 */ if (this._remainingChar != null) { /* 172 */ throw new IllegalStateException("In the middle of surrogate pair"); /* */ } /* 174 */ return this._nextIdx - this._startIdx; /* */ } /* */ } /* */ /* */ /* */ /* */ /* */ /* */ public static abstract interface ResultHandler<V> /* */ { /* */ public abstract boolean handlePrefixMatch(int paramInt, Iterator<V> paramIterator); /* */ } /* */ /* */ /* */ /* */ /* */ /* */ private static class LongestMatchHandler<V> /* */ implements TextTrieMap.ResultHandler<V> /* */ { /* 194 */ private Iterator<V> matches = null; /* 195 */ private int length = 0; /* */ /* */ public boolean handlePrefixMatch(int matchLength, Iterator<V> values) { /* 198 */ if (matchLength > this.length) { /* 199 */ this.length = matchLength; /* 200 */ this.matches = values; /* */ } /* 202 */ return true; /* */ } /* */ /* */ public Iterator<V> getMatches() { /* 206 */ return this.matches; /* */ } /* */ /* */ public int getMatchLength() { /* 210 */ return this.length; /* */ } /* */ } /* */ /* */ /* */ private class Node /* */ { /* */ private char[] _text; /* */ /* */ private List<V> _values; /* */ private List<TextTrieMap<V>.Node> _children; /* */ /* */ private Node() {} /* */ /* */ private Node(List<V> text, List<TextTrieMap<V>.Node> values) /* */ { /* 226 */ this._text = text; /* 227 */ this._values = values; /* 228 */ this._children = children; /* */ } /* */ /* */ public Iterator<V> values() { /* 232 */ if (this._values == null) { /* 233 */ return null; /* */ } /* 235 */ return this._values.iterator(); /* */ } /* */ /* */ public void add(TextTrieMap.CharIterator chitr, V value) { /* 239 */ StringBuilder buf = new StringBuilder(); /* 240 */ while (chitr.hasNext()) { /* 241 */ buf.append(chitr.next()); /* */ } /* 243 */ add(TextTrieMap.toCharArray(buf), 0, value); /* */ } /* */ /* */ public TextTrieMap<V>.Node findMatch(TextTrieMap.CharIterator chitr) { /* 247 */ if (this._children == null) { /* 248 */ return null; /* */ } /* 250 */ if (!chitr.hasNext()) { /* 251 */ return null; /* */ } /* 253 */ TextTrieMap<V>.Node match = null; /* 254 */ Character ch = chitr.next(); /* 255 */ for (TextTrieMap<V>.Node child : this._children) { /* 256 */ if (ch.charValue() < child._text[0]) { /* */ break; /* */ } /* 259 */ if (ch.charValue() == child._text[0]) { /* 260 */ if (!child.matchFollowing(chitr)) break; /* 261 */ match = child; break; /* */ } /* */ } /* */ /* */ /* 266 */ return match; /* */ } /* */ /* */ private void add(char[] text, int offset, V value) { /* 270 */ if (text.length == offset) { /* 271 */ this._values = addValue(this._values, value); /* 272 */ return; /* */ } /* */ /* 275 */ if (this._children == null) { /* 276 */ this._children = new LinkedList(); /* 277 */ TextTrieMap<V>.Node child = new Node(TextTrieMap.this, TextTrieMap.subArray(text, offset), addValue(null, value), null); /* 278 */ this._children.add(child); /* 279 */ return; /* */ } /* */ /* */ /* 283 */ ListIterator<TextTrieMap<V>.Node> litr = this._children.listIterator(); /* 284 */ while (litr.hasNext()) { /* 285 */ TextTrieMap<V>.Node next = (Node)litr.next(); /* 286 */ if (text[offset] < next._text[0]) { /* 287 */ litr.previous(); /* 288 */ break; /* */ } /* 290 */ if (text[offset] == next._text[0]) { /* 291 */ int matchLen = next.lenMatches(text, offset); /* 292 */ if (matchLen == next._text.length) /* */ { /* 294 */ next.add(text, offset + matchLen, value); /* */ } /* */ else { /* 297 */ next.split(matchLen); /* 298 */ next.add(text, offset + matchLen, value); /* */ } /* 300 */ return; /* */ } /* */ } /* */ /* 304 */ litr.add(new Node(TextTrieMap.this, TextTrieMap.subArray(text, offset), addValue(null, value), null)); /* */ } /* */ /* */ private boolean matchFollowing(TextTrieMap.CharIterator chitr) { /* 308 */ boolean matched = true; /* 309 */ int idx = 1; /* 310 */ while (idx < this._text.length) { /* 311 */ if (!chitr.hasNext()) { /* 312 */ matched = false; /* 313 */ break; /* */ } /* 315 */ Character ch = chitr.next(); /* 316 */ if (ch.charValue() != this._text[idx]) { /* 317 */ matched = false; /* 318 */ break; /* */ } /* 320 */ idx++; /* */ } /* 322 */ return matched; /* */ } /* */ /* */ private int lenMatches(char[] text, int offset) { /* 326 */ int textLen = text.length - offset; /* 327 */ int limit = this._text.length < textLen ? this._text.length : textLen; /* 328 */ int len = 0; /* 329 */ while ((len < limit) && /* 330 */ (this._text[len] == text[(offset + len)])) /* */ { /* */ /* 333 */ len++; /* */ } /* 335 */ return len; /* */ } /* */ /* */ private void split(int offset) /* */ { /* 340 */ char[] childText = TextTrieMap.subArray(this._text, offset); /* 341 */ this._text = TextTrieMap.subArray(this._text, 0, offset); /* */ /* */ /* 344 */ TextTrieMap<V>.Node child = new Node(TextTrieMap.this, childText, this._values, this._children); /* 345 */ this._values = null; /* */ /* 347 */ this._children = new LinkedList(); /* 348 */ this._children.add(child); /* */ } /* */ /* */ private List<V> addValue(List<V> list, V value) { /* 352 */ if (list == null) { /* 353 */ list = new LinkedList(); /* */ } /* 355 */ list.add(value); /* 356 */ return list; /* */ } /* */ } /* */ /* */ private static char[] toCharArray(CharSequence text) { /* 361 */ char[] array = new char[text.length()]; /* 362 */ for (int i = 0; i < array.length; i++) { /* 363 */ array[i] = text.charAt(i); /* */ } /* 365 */ return array; /* */ } /* */ /* */ private static char[] subArray(char[] array, int start) { /* 369 */ if (start == 0) { /* 370 */ return array; /* */ } /* 372 */ char[] sub = new char[array.length - start]; /* 373 */ System.arraycopy(array, start, sub, 0, sub.length); /* 374 */ return sub; /* */ } /* */ /* */ private static char[] subArray(char[] array, int start, int limit) { /* 378 */ if ((start == 0) && (limit == array.length)) { /* 379 */ return array; /* */ } /* 381 */ char[] sub = new char[limit - start]; /* 382 */ System.arraycopy(array, start, sub, 0, limit - start); /* 383 */ return sub; /* */ } /* */ } /* Location: C:\Users\Ethan\Desktop\FontZip\FontTool\sfnttool.jar!\com\ibm\icu\impl\TextTrieMap.class * Java compiler version: 5 (49.0) * JD-Core Version: 0.7.1 */