001    package com.oxygenxml.validate.nvdl;
002    
003    /**
004     * Utility class. Stores a set of integers.
005     * The set is stored in an array and sorted.
006     */
007    class IntSet {
008      /**
009       * Initial size.
010       */
011      static private final int INIT_SIZE = 4;
012      /**
013       * An int array with the values.
014       */
015      private int[] v = null;
016      
017      /**
018       * The number of stored values.
019       */
020      private int len = 0;
021    
022      /**
023       * Add a new value.
024       * @param n The value to be added.
025       */
026      void add(int n) {
027        if (v == null) {
028          v = new int[INIT_SIZE];
029          v[0] = n;
030          len = 1;
031          return;
032        }
033        if (len == v.length) {
034          int[] newv = new int[len*2];
035          System.arraycopy(v, 0, newv, 0, len);
036          v = newv;
037        }
038        if (n > v[len - 1]) {
039          v[len++] = n;
040          return;
041        }
042        int i = 0;
043        for (; i < len; i++) {
044          if (n <= v[i]) {
045            if (n == v[i])
046              return;
047            break;
048          }
049        }
050        for (int j = len; j >= i; j--)
051          v[j + 1] = v[j];
052        v[i] = n;
053        ++len;
054      }
055    
056      /**
057       * Adds all the values from another set - union.
058       * @param is The other integer set.
059       */
060      void addAll(IntSet is) {
061        if (is.len == 0)
062          return;
063        int[] newv = new int[len + is.len];
064        int i = 0, j = 0, k = 0;
065        while (i < len && j < is.len) {
066          if (v[i] < is.v[j])
067            newv[k++] = v[i++];
068          else if (is.v[j] < v[i])
069            newv[k++] = is.v[j++];
070          else {
071            newv[k++] = v[i++];
072            j++;
073          }
074        }
075        while (i < len)
076          newv[k++] = v[i++];
077        while (j < is.len)
078          newv[k++] = is.v[j++];
079        v = newv;
080        len = k;
081      }
082    
083      /**
084       * Get the number of values in this set.
085       * @return
086       */
087      int size() {
088        return len;
089      }
090    
091      /**
092       * Get the ith value from the set.
093       * @param i The index in the set, zero based.
094       * @return The value at position i.
095       */
096      int get(int i) {
097       if (i >= len)
098         throw new IndexOutOfBoundsException();
099        try {
100          return v[i];
101        }
102        catch (NullPointerException e) {
103          throw new IndexOutOfBoundsException();
104        }
105      }
106    }