Skip to content

Commit a858b3e

Browse files
committed
Add TernaryTreeIterator
1 parent 324d733 commit a858b3e

File tree

1 file changed

+195
-0
lines changed

1 file changed

+195
-0
lines changed
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
package com.itextpdf.layout.hyphenation;
2+
3+
import java.util.Enumeration;
4+
import java.util.Stack;
5+
6+
class TernaryTreeIterator implements Enumeration {
7+
8+
/**
9+
* current node index
10+
*/
11+
int cur;
12+
13+
/**
14+
* current key
15+
*/
16+
String curkey;
17+
18+
TernaryTree tt;
19+
20+
private class Item {
21+
/** parent */
22+
char parent;
23+
/** child */
24+
char child;
25+
26+
/** default constructor */
27+
public Item() {
28+
parent = 0;
29+
child = 0;
30+
}
31+
32+
/**
33+
* Construct item.
34+
* @param p a char
35+
* @param c a char
36+
*/
37+
public Item(char p, char c) {
38+
parent = p;
39+
child = c;
40+
}
41+
42+
public Item(Item i) {
43+
this.parent = i.parent;
44+
this.child = i.child;
45+
}
46+
}
47+
48+
/**
49+
* Node stack
50+
*/
51+
Stack ns;
52+
53+
/**
54+
* key stack implemented with a StringBuffer
55+
*/
56+
StringBuffer ks;
57+
58+
/** default constructor */
59+
public TernaryTreeIterator(TernaryTree tt) {
60+
this.tt = tt;
61+
cur = -1;
62+
ns = new Stack();
63+
ks = new StringBuffer();
64+
rewind();
65+
}
66+
67+
/** rewind iterator */
68+
public void rewind() {
69+
ns.removeAllElements();
70+
ks.setLength(0);
71+
cur = tt.root;
72+
run();
73+
}
74+
75+
/** @return next element */
76+
public Object nextElement() {
77+
String res = curkey;
78+
cur = up();
79+
run();
80+
return res;
81+
}
82+
83+
/** @return value */
84+
public char getValue() {
85+
if (cur >= 0) {
86+
return tt.eq[cur];
87+
}
88+
return 0;
89+
}
90+
91+
/** @return true if more elements */
92+
public boolean hasMoreElements() {
93+
return (cur != -1);
94+
}
95+
96+
/**
97+
* traverse upwards
98+
*/
99+
private int up() {
100+
Item i = new Item();
101+
int res = 0;
102+
103+
if (ns.empty()) {
104+
return -1;
105+
}
106+
107+
if (cur != 0 && tt.sc[cur] == 0) {
108+
return tt.lo[cur];
109+
}
110+
111+
boolean climb = true;
112+
113+
while (climb) {
114+
i = (Item)ns.pop();
115+
i.child++;
116+
switch (i.child) {
117+
case 1:
118+
if (tt.sc[i.parent] != 0) {
119+
res = tt.eq[i.parent];
120+
ns.push(new Item(i));
121+
ks.append(tt.sc[i.parent]);
122+
} else {
123+
i.child++;
124+
ns.push(new Item(i));
125+
res = tt.hi[i.parent];
126+
}
127+
climb = false;
128+
break;
129+
130+
case 2:
131+
res = tt.hi[i.parent];
132+
ns.push(new Item(i));
133+
if (ks.length() > 0) {
134+
ks.setLength(ks.length() - 1); // pop
135+
}
136+
climb = false;
137+
break;
138+
139+
default:
140+
if (ns.empty()) {
141+
return -1;
142+
}
143+
climb = true;
144+
break;
145+
}
146+
}
147+
return res;
148+
}
149+
150+
/**
151+
* traverse the tree to find next key
152+
*/
153+
private int run() {
154+
if (cur == -1) {
155+
return -1;
156+
}
157+
158+
boolean leaf = false;
159+
while (true) {
160+
// first go down on low branch until leaf or compressed branch
161+
while (cur != 0) {
162+
if (tt.sc[cur] == 0xFFFF) {
163+
leaf = true;
164+
break;
165+
}
166+
ns.push(new Item((char)cur, '\u0000'));
167+
if (tt.sc[cur] == 0) {
168+
leaf = true;
169+
break;
170+
}
171+
cur = tt.lo[cur];
172+
}
173+
if (leaf) {
174+
break;
175+
}
176+
// nothing found, go up one node and try again
177+
cur = up();
178+
if (cur == -1) {
179+
return -1;
180+
}
181+
}
182+
// The current node should be a data node and
183+
// the key should be in the key stack (at least partially)
184+
StringBuffer buf = new StringBuffer(ks.toString());
185+
if (tt.sc[cur] == 0xFFFF) {
186+
int p = tt.lo[cur];
187+
while (tt.kv.get(p) != 0) {
188+
buf.append(tt.kv.get(p++));
189+
}
190+
}
191+
curkey = buf.toString();
192+
return 0;
193+
}
194+
195+
}

0 commit comments

Comments
 (0)