1 47 package com.lowagie.text.pdf; 48 49 import java.util.LinkedList ; 50 import java.util.List ; 51 import java.util.ListIterator ; 52 53 64 public class SequenceList { 65 protected static final int COMMA = 1; 66 protected static final int MINUS = 2; 67 protected static final int NOT = 3; 68 protected static final int TEXT = 4; 69 protected static final int NUMBER = 5; 70 protected static final int END = 6; 71 protected static final char EOT = '\uffff'; 72 73 private static final int FIRST = 0; 74 private static final int DIGIT = 1; 75 private static final int OTHER = 2; 76 private static final int DIGIT2 = 3; 77 private static final String NOT_OTHER = "-,!0123456789"; 78 79 protected char text[]; 80 protected int ptr; 81 protected int number; 82 protected String other; 83 84 protected int low; 85 protected int high; 86 protected boolean odd; 87 protected boolean even; 88 protected boolean inverse; 89 90 protected SequenceList(String range) { 91 ptr = 0; 92 text = range.toCharArray(); 93 } 94 95 protected char nextChar() { 96 while (true) { 97 if (ptr >= text.length) 98 return EOT; 99 char c = text[ptr++]; 100 if (c > ' ') 101 return c; 102 } 103 } 104 105 protected void putBack() { 106 --ptr; 107 if (ptr < 0) 108 ptr = 0; 109 } 110 111 protected int getType() { 112 StringBuffer buf = new StringBuffer (); 113 int state = FIRST; 114 while (true) { 115 char c = nextChar(); 116 if (c == EOT) { 117 if (state == DIGIT) { 118 number = Integer.parseInt(other = buf.toString()); 119 return NUMBER; 120 } 121 else if (state == OTHER) { 122 other = buf.toString().toLowerCase(); 123 return TEXT; 124 } 125 return END; 126 } 127 switch (state) { 128 case FIRST: 129 switch (c) { 130 case '!': 131 return NOT; 132 case '-': 133 return MINUS; 134 case ',': 135 return COMMA; 136 } 137 buf.append(c); 138 if (c >= '0' && c <= '9') 139 state = DIGIT; 140 else 141 state = OTHER; 142 break; 143 case DIGIT: 144 if (c >= '0' && c <= '9') 145 buf.append(c); 146 else { 147 putBack(); 148 number = Integer.parseInt(other = buf.toString()); 149 return NUMBER; 150 } 151 break; 152 case OTHER: 153 if (NOT_OTHER.indexOf(c) < 0) 154 buf.append(c); 155 else { 156 putBack(); 157 other = buf.toString().toLowerCase(); 158 return TEXT; 159 } 160 break; 161 } 162 } 163 } 164 165 private void otherProc() { 166 if (other.equals("odd") || other.equals("o")) { 167 odd = true; 168 even = false; 169 } 170 else if (other.equals("even") || other.equals("e")) { 171 odd = false; 172 even = true; 173 } 174 } 175 176 protected boolean getAttributes() { 177 low = -1; 178 high = -1; 179 odd = even = inverse = false; 180 int state = OTHER; 181 while (true) { 182 int type = getType(); 183 if (type == END || type == COMMA) { 184 if (state == DIGIT) 185 high = low; 186 return (type == END); 187 } 188 switch (state) { 189 case OTHER: 190 switch (type) { 191 case NOT: 192 inverse = true; 193 break; 194 case MINUS: 195 state = DIGIT2; 196 break; 197 default: 198 if (type == NUMBER) { 199 low = number; 200 state = DIGIT; 201 } 202 else 203 otherProc(); 204 break; 205 } 206 break; 207 case DIGIT: 208 switch (type) { 209 case NOT: 210 inverse = true; 211 state = OTHER; 212 high = low; 213 break; 214 case MINUS: 215 state = DIGIT2; 216 break; 217 default: 218 high = low; 219 state = OTHER; 220 otherProc(); 221 break; 222 } 223 break; 224 case DIGIT2: 225 switch (type) { 226 case NOT: 227 inverse = true; 228 state = OTHER; 229 break; 230 case MINUS: 231 break; 232 case NUMBER: 233 high = number; 234 state = OTHER; 235 break; 236 default: 237 state = OTHER; 238 otherProc(); 239 break; 240 } 241 break; 242 } 243 } 244 } 245 246 252 public static List expand(String ranges, int maxNumber) { 253 SequenceList parse = new SequenceList(ranges); 254 LinkedList list = new LinkedList (); 255 boolean sair = false; 256 while (!sair) { 257 sair = parse.getAttributes(); 258 if (parse.low == -1 && parse.high == -1 && !parse.even && !parse.odd) 259 continue; 260 if (parse.low < 1) 261 parse.low = 1; 262 if (parse.high < 1 || parse.high > maxNumber) 263 parse.high = maxNumber; 264 if (parse.low > maxNumber) 265 parse.low = maxNumber; 266 267 int inc = 1; 269 if (parse.inverse) { 270 if (parse.low > parse.high) { 271 int t = parse.low; 272 parse.low = parse.high; 273 parse.high = t; 274 } 275 for (ListIterator it = list.listIterator(); it.hasNext();) { 276 int n = ((Integer )it.next()).intValue(); 277 if (parse.even && (n & 1) == 1) 278 continue; 279 if (parse.odd && (n & 1) == 0) 280 continue; 281 if (n >= parse.low && n <= parse.high) 282 it.remove(); 283 } 284 } 285 else { 286 if (parse.low > parse.high) { 287 inc = -1; 288 if (parse.odd || parse.even) { 289 --inc; 290 if (parse.even) 291 parse.low &= ~1; 292 else 293 parse.low -= ((parse.low & 1) == 1 ? 0 : 1); 294 } 295 for (int k = parse.low; k >= parse.high; k += inc) 296 list.add(new Integer (k)); 297 } 298 else { 299 if (parse.odd || parse.even) { 300 ++inc; 301 if (parse.odd) 302 parse.low |= 1; 303 else 304 parse.low += ((parse.low & 1) == 1 ? 1 : 0); 305 } 306 for (int k = parse.low; k <= parse.high; k += inc) { 307 list.add(new Integer (k)); 308 } 309 } 310 } 311 } 315 return list; 316 } 317 } | Popular Tags |