95 * Construct a new set-of-integer attribute with the given members in
96 * string form.
97 *
98 * @param members Set members in string form. If null, an empty set is
99 * constructed.
100 *
101 * @exception IllegalArgumentException
102 * (Unchecked exception) Thrown if <CODE>members</CODE> does not
103 * obey the proper syntax.
104 */
105 protected SetOfIntegerSyntax(String members) {
106 this.members = parse (members);
107 }
108
109 /**
110 * Parse the given string, returning canonical array form.
111 */
112 private static int[][] parse(String members) {
113 // Create vector to hold int[] elements, each element being one range
114 // parsed out of members.
115 Vector theRanges = new Vector();
116
117 // Run state machine over members.
118 int n = (members == null ? 0 : members.length());
119 int i = 0;
120 int state = 0;
121 int lb = 0;
122 int ub = 0;
123 char c;
124 int digit;
125 while (i < n) {
126 c = members.charAt(i ++);
127 switch (state) {
128
129 case 0: // Before first integer in first group
130 if (Character.isWhitespace(c)) {
131 state = 0;
132 }
133 else if ((digit = Character.digit(c, 10)) != -1) {
134 lb = digit;
135 state = 1;
226 case 2: // After first integer in a group
227 accumulate(theRanges, lb, lb);
228 break;
229 case 4: // In second integer in a group
230 case 5: // After second integer in a group
231 accumulate(theRanges, lb, ub);
232 break;
233 case 3: // Before second integer in a group
234 case 6: // Before first integer in second or later group
235 throw new IllegalArgumentException();
236 }
237
238 // Return canonical array form.
239 return canonicalArrayForm (theRanges);
240 }
241
242 /**
243 * Accumulate the given range (lb .. ub) into the canonical array form
244 * into the given vector of int[] objects.
245 */
246 private static void accumulate(Vector ranges, int lb,int ub) {
247 // Make sure range is non-null.
248 if (lb <= ub) {
249 // Stick range at the back of the vector.
250 ranges.add(new int[] {lb, ub});
251
252 // Work towards the front of the vector to integrate the new range
253 // with the existing ranges.
254 for (int j = ranges.size()-2; j >= 0; -- j) {
255 // Get lower and upper bounds of the two ranges being compared.
256 int[] rangea = (int[]) ranges.elementAt (j);
257 int lba = rangea[0];
258 int uba = rangea[1];
259 int[] rangeb = (int[]) ranges.elementAt (j+1);
260 int lbb = rangeb[0];
261 int ubb = rangeb[1];
262
263 /* If the two ranges overlap or are adjacent, coalesce them.
264 * The two ranges overlap if the larger lower bound is less
265 * than or equal to the smaller upper bound. The two ranges
266 * are adjacent if the larger lower bound is one greater
267 * than the smaller upper bound.
268 */
269 if (Math.max(lba, lbb) - Math.min(uba, ubb) <= 1) {
270 // The coalesced range is from the smaller lower bound to
271 // the larger upper bound.
272 ranges.setElementAt(new int[]
273 {Math.min(lba, lbb),
274 Math.max(uba, ubb)}, j);
275 ranges.remove (j+1);
276 } else if (lba > lbb) {
277
278 /* If the two ranges don't overlap and aren't adjacent but
279 * are out of order, swap them.
280 */
281 ranges.setElementAt (rangeb, j);
282 ranges.setElementAt (rangea, j+1);
283 } else {
284 /* If the two ranges don't overlap and aren't adjacent and
285 * aren't out of order, we're done early.
286 */
287 break;
288 }
289 }
290 }
291 }
292
293 /**
294 * Convert the given vector of int[] objects to canonical array form.
295 */
296 private static int[][] canonicalArrayForm(Vector ranges) {
297 return (int[][]) ranges.toArray (new int[ranges.size()][]);
298 }
299
300 /**
301 * Construct a new set-of-integer attribute with the given members in
302 * array form.
303 *
304 * @param members Set members in array form. If null, an empty set is
305 * constructed.
306 *
307 * @exception NullPointerException
308 * (Unchecked exception) Thrown if any element of
309 * <CODE>members</CODE> is null.
310 * @exception IllegalArgumentException
311 * (Unchecked exception) Thrown if any element of
312 * <CODE>members</CODE> is not a length-one or length-two array or if
313 * any non-null range in <CODE>members</CODE> has a lower bound less
314 * than zero.
315 */
316 protected SetOfIntegerSyntax(int[][] members) {
317 this.members = parse (members);
318 }
319
320 /**
321 * Parse the given array form, returning canonical array form.
322 */
323 private static int[][] parse(int[][] members) {
324 // Create vector to hold int[] elements, each element being one range
325 // parsed out of members.
326 Vector ranges = new Vector();
327
328 // Process all integer groups in members.
329 int n = (members == null ? 0 : members.length);
330 for (int i = 0; i < n; ++ i) {
331 // Get lower and upper bounds of the range.
332 int lb, ub;
333 if (members[i].length == 1) {
334 lb = ub = members[i][0];
335 } else if (members[i].length == 2) {
336 lb = members[i][0];
337 ub = members[i][1];
338 } else {
339 throw new IllegalArgumentException();
340 }
341
342 // Verify valid bounds.
343 if (lb <= ub && lb < 0) {
344 throw new IllegalArgumentException();
345 }
346
|
95 * Construct a new set-of-integer attribute with the given members in
96 * string form.
97 *
98 * @param members Set members in string form. If null, an empty set is
99 * constructed.
100 *
101 * @exception IllegalArgumentException
102 * (Unchecked exception) Thrown if <CODE>members</CODE> does not
103 * obey the proper syntax.
104 */
105 protected SetOfIntegerSyntax(String members) {
106 this.members = parse (members);
107 }
108
109 /**
110 * Parse the given string, returning canonical array form.
111 */
112 private static int[][] parse(String members) {
113 // Create vector to hold int[] elements, each element being one range
114 // parsed out of members.
115 Vector<int[]> theRanges = new Vector<>();
116
117 // Run state machine over members.
118 int n = (members == null ? 0 : members.length());
119 int i = 0;
120 int state = 0;
121 int lb = 0;
122 int ub = 0;
123 char c;
124 int digit;
125 while (i < n) {
126 c = members.charAt(i ++);
127 switch (state) {
128
129 case 0: // Before first integer in first group
130 if (Character.isWhitespace(c)) {
131 state = 0;
132 }
133 else if ((digit = Character.digit(c, 10)) != -1) {
134 lb = digit;
135 state = 1;
226 case 2: // After first integer in a group
227 accumulate(theRanges, lb, lb);
228 break;
229 case 4: // In second integer in a group
230 case 5: // After second integer in a group
231 accumulate(theRanges, lb, ub);
232 break;
233 case 3: // Before second integer in a group
234 case 6: // Before first integer in second or later group
235 throw new IllegalArgumentException();
236 }
237
238 // Return canonical array form.
239 return canonicalArrayForm (theRanges);
240 }
241
242 /**
243 * Accumulate the given range (lb .. ub) into the canonical array form
244 * into the given vector of int[] objects.
245 */
246 private static void accumulate(Vector<int[]> ranges, int lb,int ub) {
247 // Make sure range is non-null.
248 if (lb <= ub) {
249 // Stick range at the back of the vector.
250 ranges.add(new int[] {lb, ub});
251
252 // Work towards the front of the vector to integrate the new range
253 // with the existing ranges.
254 for (int j = ranges.size()-2; j >= 0; -- j) {
255 // Get lower and upper bounds of the two ranges being compared.
256 int[] rangea = ranges.elementAt (j);
257 int lba = rangea[0];
258 int uba = rangea[1];
259 int[] rangeb = ranges.elementAt (j+1);
260 int lbb = rangeb[0];
261 int ubb = rangeb[1];
262
263 /* If the two ranges overlap or are adjacent, coalesce them.
264 * The two ranges overlap if the larger lower bound is less
265 * than or equal to the smaller upper bound. The two ranges
266 * are adjacent if the larger lower bound is one greater
267 * than the smaller upper bound.
268 */
269 if (Math.max(lba, lbb) - Math.min(uba, ubb) <= 1) {
270 // The coalesced range is from the smaller lower bound to
271 // the larger upper bound.
272 ranges.setElementAt(new int[]
273 {Math.min(lba, lbb),
274 Math.max(uba, ubb)}, j);
275 ranges.remove (j+1);
276 } else if (lba > lbb) {
277
278 /* If the two ranges don't overlap and aren't adjacent but
279 * are out of order, swap them.
280 */
281 ranges.setElementAt (rangeb, j);
282 ranges.setElementAt (rangea, j+1);
283 } else {
284 /* If the two ranges don't overlap and aren't adjacent and
285 * aren't out of order, we're done early.
286 */
287 break;
288 }
289 }
290 }
291 }
292
293 /**
294 * Convert the given vector of int[] objects to canonical array form.
295 */
296 private static int[][] canonicalArrayForm(Vector<int[]> ranges) {
297 return ranges.toArray (new int[ranges.size()][]);
298 }
299
300 /**
301 * Construct a new set-of-integer attribute with the given members in
302 * array form.
303 *
304 * @param members Set members in array form. If null, an empty set is
305 * constructed.
306 *
307 * @exception NullPointerException
308 * (Unchecked exception) Thrown if any element of
309 * <CODE>members</CODE> is null.
310 * @exception IllegalArgumentException
311 * (Unchecked exception) Thrown if any element of
312 * <CODE>members</CODE> is not a length-one or length-two array or if
313 * any non-null range in <CODE>members</CODE> has a lower bound less
314 * than zero.
315 */
316 protected SetOfIntegerSyntax(int[][] members) {
317 this.members = parse (members);
318 }
319
320 /**
321 * Parse the given array form, returning canonical array form.
322 */
323 private static int[][] parse(int[][] members) {
324 // Create vector to hold int[] elements, each element being one range
325 // parsed out of members.
326 Vector<int[]> ranges = new Vector<>();
327
328 // Process all integer groups in members.
329 int n = (members == null ? 0 : members.length);
330 for (int i = 0; i < n; ++ i) {
331 // Get lower and upper bounds of the range.
332 int lb, ub;
333 if (members[i].length == 1) {
334 lb = ub = members[i][0];
335 } else if (members[i].length == 2) {
336 lb = members[i][0];
337 ub = members[i][1];
338 } else {
339 throw new IllegalArgumentException();
340 }
341
342 // Verify valid bounds.
343 if (lb <= ub && lb < 0) {
344 throw new IllegalArgumentException();
345 }
346
|