private Node insert(String suggestion, int i, Node n) { if (n == null) { n = new Node(); n.first = suggestion; n.end = suggestion.length(); nodeCount++; } else if (suggestion.charAt(i) < n.first.charAt(i)) n.left = insert(suggestion, i, n.left); else if (suggestion.charAt(i) > n.first.charAt(i)) n.right = insert(suggestion, i, n.right); else { while (++i < n.end) { if (i == suggestion.length() || suggestion.charAt(i) != n.first.charAt(i)) { Node mid = new Node(); mid.first = n.first; mid.end = n.end; mid.count = n.count; mid.mid = n.mid; n.mid = mid; n.end = i; nodeCount++; break; } } if (n.count < maxArrayLength) n.count++; if (i < suggestion.length()) n.mid = insert(suggestion, i, n.mid); } return n; }
public T pop() { T result = top.item; if (!top.end()) { top = top.next; } return result; }
Node parse_(byte[] expression) { Node result = null; Node expr = null; int wholeTermStart = index; int subtermStart = index; boolean subtermComplete = false; while (index < expression.length) { switch (expression[index++]) { case '&': { expr = processTerm(subtermStart, index - 1, expr, expression); if (result != null) { if (!result.type.equals(NodeType.AND)) throw new BadArgumentException( "cannot mix & and |", new String(expression, UTF_8), index - 1); } else { result = new Node(NodeType.AND, wholeTermStart); } result.add(expr); expr = null; subtermStart = index; subtermComplete = false; break; } case '|': { expr = processTerm(subtermStart, index - 1, expr, expression); if (result != null) { if (!result.type.equals(NodeType.OR)) throw new BadArgumentException( "cannot mix | and &", new String(expression, UTF_8), index - 1); } else { result = new Node(NodeType.OR, wholeTermStart); } result.add(expr); expr = null; subtermStart = index; subtermComplete = false; break; } case '(': { parens++; if (subtermStart != index - 1 || expr != null) throw new BadArgumentException( "expression needs & or |", new String(expression, UTF_8), index - 1); expr = parse_(expression); subtermStart = index; subtermComplete = false; break; } case ')': { parens--; Node child = processTerm(subtermStart, index - 1, expr, expression); if (child == null && result == null) throw new BadArgumentException( "empty expression not allowed", new String(expression, UTF_8), index); if (result == null) return child; if (result.type == child.type) for (Node c : child.children) result.add(c); else result.add(child); result.end = index - 1; return result; } case '"': { if (subtermStart != index - 1) throw new BadArgumentException( "expression needs & or |", new String(expression, UTF_8), index - 1); while (index < expression.length && expression[index] != '"') { if (expression[index] == '\\') { index++; if (expression[index] != '\\' && expression[index] != '"') throw new BadArgumentException( "invalid escaping within quotes", new String(expression, UTF_8), index - 1); } index++; } if (index == expression.length) throw new BadArgumentException( "unclosed quote", new String(expression, UTF_8), subtermStart); if (subtermStart + 1 == index) throw new BadArgumentException( "empty term", new String(expression, UTF_8), subtermStart); index++; subtermComplete = true; break; } default: { if (subtermComplete) throw new BadArgumentException( "expression needs & or |", new String(expression, UTF_8), index - 1); byte c = expression[index - 1]; if (!Authorizations.isValidAuthChar(c)) throw new BadArgumentException( "bad character (" + c + ")", new String(expression, UTF_8), index - 1); } } } Node child = processTerm(subtermStart, index, expr, expression); if (result != null) { result.add(child); result.end = index; } else result = child; if (result.type != NodeType.TERM) if (result.children.size() < 2) throw new BadArgumentException("missing term", new String(expression, UTF_8), index); return result; }