Beispiel #1
0
 protected void mergeRanges(Token token) {
   RangeToken tok = (RangeToken) token;
   this.sortRanges();
   tok.sortRanges();
   if (tok.ranges == null) return;
   this.icaseCache = null;
   this.setSorted(true);
   if (this.ranges == null) {
     this.ranges = new int[tok.ranges.length];
     System.arraycopy(tok.ranges, 0, this.ranges, 0, tok.ranges.length);
     return;
   }
   int[] result = new int[this.ranges.length + tok.ranges.length];
   for (int i = 0, j = 0, k = 0; i < this.ranges.length || j < tok.ranges.length; ) {
     if (i >= this.ranges.length) {
       result[k++] = tok.ranges[j++];
       result[k++] = tok.ranges[j++];
     } else if (j >= tok.ranges.length) {
       result[k++] = this.ranges[i++];
       result[k++] = this.ranges[i++];
     } else if (tok.ranges[j] < this.ranges[i]
         || tok.ranges[j] == this.ranges[i] && tok.ranges[j + 1] < this.ranges[i + 1]) {
       result[k++] = tok.ranges[j++];
       result[k++] = tok.ranges[j++];
     } else {
       result[k++] = this.ranges[i++];
       result[k++] = this.ranges[i++];
     }
   }
   this.ranges = result;
 }
Beispiel #2
0
  synchronized RangeToken getCaseInsensitiveToken() {
    if (this.icaseCache != null) return this.icaseCache;

    RangeToken uppers = this.type == Token.RANGE ? Token.createRange() : Token.createNRange();
    for (int i = 0; i < this.ranges.length; i += 2) {
      for (int ch = this.ranges[i]; ch <= this.ranges[i + 1]; ch++) {
        if (ch > 0xffff) uppers.addRange(ch, ch);
        else {
          char uch = Character.toUpperCase((char) ch);
          uppers.addRange(uch, uch);
        }
      }
    }
    RangeToken lowers = this.type == Token.RANGE ? Token.createRange() : Token.createNRange();
    for (int i = 0; i < uppers.ranges.length; i += 2) {
      for (int ch = uppers.ranges[i]; ch <= uppers.ranges[i + 1]; ch++) {
        if (ch > 0xffff) lowers.addRange(ch, ch);
        else {
          char uch = Character.toUpperCase((char) ch);
          lowers.addRange(uch, uch);
        }
      }
    }
    lowers.mergeRanges(uppers);
    lowers.mergeRanges(this);
    lowers.compactRanges();

    this.icaseCache = lowers;
    return lowers;
  }
Beispiel #3
0
 /** for RANGE: Creates complement. for NRANGE: Creates the same meaning RANGE. */
 static Token complementRanges(Token token) {
   if (token.type != RANGE && token.type != NRANGE)
     throw new IllegalArgumentException("Token#complementRanges(): must be RANGE: " + token.type);
   RangeToken tok = (RangeToken) token;
   tok.sortRanges();
   tok.compactRanges();
   int len = tok.ranges.length + 2;
   if (tok.ranges[0] == 0) len -= 2;
   int last = tok.ranges[tok.ranges.length - 1];
   if (last == UTF16_MAX) len -= 2;
   RangeToken ret = Token.createRange();
   ret.ranges = new int[len];
   int wp = 0;
   if (tok.ranges[0] > 0) {
     ret.ranges[wp++] = 0;
     ret.ranges[wp++] = tok.ranges[0] - 1;
   }
   for (int i = 1; i < tok.ranges.length - 2; i += 2) {
     ret.ranges[wp++] = tok.ranges[i] + 1;
     ret.ranges[wp++] = tok.ranges[i + 1] - 1;
   }
   if (last != UTF16_MAX) {
     ret.ranges[wp++] = last + 1;
     ret.ranges[wp] = UTF16_MAX;
   }
   ret.setCompacted();
   return ret;
 }
Beispiel #4
0
  /** @param tok Ignore whether it is NRANGE or not. */
  protected void intersectRanges(Token token) {
    RangeToken tok = (RangeToken) token;
    if (tok.ranges == null || this.ranges == null) return;
    this.icaseCache = null;
    this.sortRanges();
    this.compactRanges();
    tok.sortRanges();
    tok.compactRanges();

    int[] result = new int[this.ranges.length + tok.ranges.length];
    int wp = 0, src1 = 0, src2 = 0;
    while (src1 < this.ranges.length && src2 < tok.ranges.length) {
      int src1begin = this.ranges[src1];
      int src1end = this.ranges[src1 + 1];
      int src2begin = tok.ranges[src2];
      int src2end = tok.ranges[src2 + 1];
      if (src1end < src2begin) { // Not overlapped
        // src1: o-----o
        // src2:         o-----o
        // res:  empty
        // Reuse src2
        src1 += 2;
      } else if (src1end >= src2begin && src1begin <= src2end) { // Overlapped
        // src1:    o--------o
        // src2:  o----o
        // src2:      o----o
        // src2:          o----o
        // src2:  o------------o
        if (src2begin <= src2begin && src1end <= src2end) {
          // src1:    o--------o
          // src2:  o------------o
          // res:     o--------o
          // Reuse src2
          result[wp++] = src1begin;
          result[wp++] = src1end;
          src1 += 2;
        } else if (src2begin <= src1begin) {
          // src1:    o--------o
          // src2:  o----o
          // res:     o--o
          // Reuse the rest of src1
          result[wp++] = src1begin;
          result[wp++] = src2end;
          this.ranges[src1] = src2end + 1;
          src2 += 2;
        } else if (src1end <= src2end) {
          // src1:    o--------o
          // src2:          o----o
          // res:           o--o
          // Reuse src2
          result[wp++] = src2begin;
          result[wp++] = src1end;
          src1 += 2;
        } else {
          // src1:    o--------o
          // src2:      o----o
          // res:       o----o
          // Reuse the rest of src1
          result[wp++] = src2begin;
          result[wp++] = src2end;
          this.ranges[src1] = src2end + 1;
        }
      } else if (src2end < src1begin) {
        // Not overlapped
        // src1:          o-----o
        // src2: o----o
        src2 += 2;
      } else {
        throw new RuntimeException(
            "Token#intersectRanges(): Internal Error: ["
                + this.ranges[src1]
                + ","
                + this.ranges[src1 + 1]
                + "] & ["
                + tok.ranges[src2]
                + ","
                + tok.ranges[src2 + 1]
                + "]");
      }
    }
    while (src1 < this.ranges.length) {
      result[wp++] = this.ranges[src1++];
      result[wp++] = this.ranges[src1++];
    }
    this.ranges = new int[wp];
    System.arraycopy(result, 0, this.ranges, 0, wp);
    // this.ranges is sorted and compacted.
  }
Beispiel #5
0
  protected void subtractRanges(Token token) {
    if (token.type == NRANGE) {
      this.intersectRanges(token);
      return;
    }
    RangeToken tok = (RangeToken) token;
    if (tok.ranges == null || this.ranges == null) return;
    this.icaseCache = null;
    this.sortRanges();
    this.compactRanges();
    tok.sortRanges();
    tok.compactRanges();

    // System.err.println("Token#substractRanges(): Entry: "+this.ranges.length+",
    // "+tok.ranges.length);

    int[] result = new int[this.ranges.length + tok.ranges.length];
    int wp = 0, src = 0, sub = 0;
    while (src < this.ranges.length && sub < tok.ranges.length) {
      int srcbegin = this.ranges[src];
      int srcend = this.ranges[src + 1];
      int subbegin = tok.ranges[sub];
      int subend = tok.ranges[sub + 1];
      if (srcend < subbegin) { // Not overlapped
        // src: o-----o
        // sub:         o-----o
        // res: o-----o
        // Reuse sub
        result[wp++] = this.ranges[src++];
        result[wp++] = this.ranges[src++];
      } else if (srcend >= subbegin && srcbegin <= subend) { // Overlapped
        // src:    o--------o
        // sub:  o----o
        // sub:      o----o
        // sub:          o----o
        // sub:  o------------o
        if (subbegin <= srcbegin && srcend <= subend) {
          // src:    o--------o
          // sub:  o------------o
          // res: empty
          // Reuse sub
          src += 2;
        } else if (subbegin <= srcbegin) {
          // src:    o--------o
          // sub:  o----o
          // res:       o-----o
          // Reuse src(=res)
          this.ranges[src] = subend + 1;
          sub += 2;
        } else if (srcend <= subend) {
          // src:    o--------o
          // sub:          o----o
          // res:    o-----o
          // Reuse sub
          result[wp++] = srcbegin;
          result[wp++] = subbegin - 1;
          src += 2;
        } else {
          // src:    o--------o
          // sub:      o----o
          // res:    o-o    o-o
          // Reuse src(=right res)
          result[wp++] = srcbegin;
          result[wp++] = subbegin - 1;
          this.ranges[src] = subend + 1;
          sub += 2;
        }
      } else if (subend < srcbegin) {
        // Not overlapped
        // src:          o-----o
        // sub: o----o
        sub += 2;
      } else {
        throw new RuntimeException(
            "Token#subtractRanges(): Internal Error: ["
                + this.ranges[src]
                + ","
                + this.ranges[src + 1]
                + "] - ["
                + tok.ranges[sub]
                + ","
                + tok.ranges[sub + 1]
                + "]");
      }
    }
    while (src < this.ranges.length) {
      result[wp++] = this.ranges[src++];
      result[wp++] = this.ranges[src++];
    }
    this.ranges = new int[wp];
    System.arraycopy(result, 0, this.ranges, 0, wp);
    // this.ranges is sorted and compacted.
  }