static <T> Segment<T> newSegment(T source, int start, int length) {
   Segment segment = new Segment();
   segment.source = source;
   segment.start = start;
   segment.length = length;
   return segment;
 }
示例#2
0
 private int totalSize(List<Segment> unsortedSegments) {
   int totalSize = 0;
   for (Segment segment : unsortedSegments) {
     totalSize += segment.length();
   }
   return totalSize;
 }
  public void reset(int pos, char[] buffer) {
    if (pos < 0 && activeSegments.size() == 1) {
      return;
    }

    while (true) {
      Segment<T> lastActiveSegment = activeSegments.peekLast();
      if (pos < lastActiveSegment.start - 1) {
        // segment is removed if root, and last suspended segment is merged
        // with last active segment if it is the same source
        if (lastActiveSegment.root) {
          activeSegments.removeLast();
          activeLength -= lastActiveSegment.length;
          freeLength += lastActiveSegment.length;

          lastActiveSegment = activeSegments.peekLast();
          Segment<T> lastSuspendedSegment = suspendedSegments.peekLast();
          if (lastSuspendedSegment != null
              && lastSuspendedSegment.source.equals(lastActiveSegment.source)) {
            lastActiveSegment.length += lastSuspendedSegment.length;

            // move data in buffer : suspended space -> active space
            System.arraycopy(
                buffer,
                lastSuspendedSegment.start,
                buffer,
                activeLength,
                lastSuspendedSegment.length);

            suspendedSegments.removeLast();
            activeLength += lastSuspendedSegment.length;
            suspendedLength -= lastSuspendedSegment.length;
          }

          continue;
        }

        // segment is suspended if not root
        activeSegments.removeLast();
        suspendedSegments.addLast(lastActiveSegment);
        int startInSuspendedSpace = size - suspendedLength - lastActiveSegment.length;

        // move data in buffer : active space -> suspended space
        System.arraycopy(
            buffer,
            lastActiveSegment.start,
            buffer,
            startInSuspendedSpace,
            lastActiveSegment.length);
        lastActiveSegment.start = startInSuspendedSpace;

        activeLength -= lastActiveSegment.length;
        suspendedLength += lastActiveSegment.length;

      } else {
        break;
      }
    }
  }
  public void newDataAdded(int size) {
    this.activeLength += size;
    this.freeLength -= size;

    Segment<T> lastSource = activeSegments.peekLast();
    if (lastSource != null) {
      lastSource.length += size;
    }
  }
  private void validateRegions() {
    if (region_map == null) return;

    synchronized (region_map) {
      if (regions_valid) return;

      Segment s = new Segment();

      region_map.clear();

      for (BaleRegion br : fragment_regions) {
        RegionData rd = new RegionData(indent_size);
        region_map.put(br, rd);
        int soff = br.getStart();
        int eoff = br.getEnd();
        if (eoff < soff) continue;
        try {
          base_document.getText(soff, eoff - soff, s);
        } catch (BadLocationException e) {
          BoardLog.logE("BALE", "Problem getting region indentation", e);
          continue;
        }
        int ln = s.length();

        LineData ld;
        boolean sol = true;
        for (int i = 0; i < ln; ++i) {
          char c = s.charAt(i);
          if (sol) {
            ld = computeLineData(i, s);
            rd.add(ld);
            sol = false;
          }
          if (c == '\n') sol = true;
        }
        if (!sol) {
          ld = computeLineData(ln, s);
          rd.add(ld);
          ++ln;
        }
      }

      regions_valid = true;
    }
  }
  public void consume(int size) {
    this.activeLength -= size;
    this.freeLength += size;

    // remove from active segments
    int removed = 0;
    for (Iterator<Segment<T>> it = activeSegments.iterator(); it.hasNext(); ) {
      Segment<T> segment = it.next();

      int remaining = size - removed;
      int sizeToRemove = Math.min(remaining, segment.length);
      segment.length -= sizeToRemove;
      segment.start -= removed;
      removed += sizeToRemove;

      if (segment.length == 0 && activeSegments.size() > 1) {
        it.remove();
      }
    }
  }
  /** ***************************************************************************** */
  private LineData computeLineData(int offset, Segment s) {
    int delchar = 0;
    int addchar = 0;
    int indent = 0;
    int ln = s.length();
    boolean havetab = false;

    for (int i = offset; indent < indent_size; ++i) {
      char c = (i < ln ? s.charAt(i) : '\n');
      if (c == ' ') {
        ++indent;
        ++delchar;
      } else if (c == '\t') {
        havetab = true;
        indent = nextTabPosition(indent);
        if (indent > indent_size) {
          delchar = (i - offset + 1);
          addchar = indent - indent_size;
          break;
        } else {
          ++delchar;
        }
      } else if (c == '\n') {
        if (havetab) {
          delchar = (i - offset);
          addchar = indent_size;
        } else {
          addchar = indent_size - (i - offset);
        }
        break;
      } else {
        BoardLog.logE("BALE", "Minimum space compute incorrectly");
        break;
      }
    }

    return new LineData(offset, addchar, delchar);
  }
  // segment is divided into two segments :
  // the first one remains in active space, but its length is adjusted
  // to current position; the second one is added to suspended space
  private void suspendSegmentAtPosition(Segment<T> segment, int position, char[] buffer) {
    if (segment != null) {
      // length of two segments
      int len1 = position - segment.start + 1;
      int len2 = segment.length - len1;

      // don't create suspended segment if no data to suspend
      if (len2 == 0) return;

      // start of second segment (in suspended space)
      int start2 = size - suspendedLength - len2;

      segment.length = len1;
      suspendedSegments.add(segment.childSegment(start2, len2));

      activeLength -= len2;
      suspendedLength += len2;

      if (len2 > 0) {
        System.arraycopy(buffer, position + 1, buffer, start2, len2);
      }
    }
  }
 // Documentation inherited from CharStreamSource
 public long getEstimatedMaximumOutputLength() {
   return segment.length() * 2;
 }
    boolean getText(Segment brtext, int voff, int len, Segment s) {
      s.array = new char[len + 1];
      s.count = 0;
      s.offset = 0;

      if (len == 0) return false;

      int spos = 0;
      int line = 0;

      // first find the line where the data starts
      for (int i = 1; i < num_lines; ++i) {
        int npos =
            spos
                + line_data[i].getOffset()
                - line_data[i - 1].getOffset()
                + line_data[i - 1].getViewDelta();
        if (voff < npos) break;
        spos = npos;
        line = i;
      }

      // now add the data
      int pos = spos;
      for (int i = line + 1; i < num_lines; ++i) {
        int rpos = line_data[i - 1].getOffset();
        rpos += line_data[i - 1].getDelete();
        int npos =
            spos
                + line_data[i].getOffset()
                - line_data[i - 1].getOffset()
                + line_data[i - 1].getViewDelta();
        int addct = (line_data[i - 1].getDelete() > 0 ? line_data[i - 1].getAdd() : 0);
        while (pos < npos) {
          char c;
          if (pos - spos < addct) c = ' ';
          else c = brtext.charAt(rpos + pos - spos - addct);
          if (pos >= voff) s.array[s.count++] = c;
          if (s.count == len) break;
          ++pos;
        }
        spos = npos;
        if (s.count == len) break;
      }

      boolean lastbad = false;

      if (s.count < len && num_lines > 0) {
        if (pos < voff) pos = voff;
        int rpos = line_data[num_lines - 1].getOffset();
        rpos += line_data[num_lines - 1].getDelete();
        int addct = line_data[num_lines - 1].getAdd();
        while (s.count < len) {
          char c;
          int idx = rpos + pos - spos - addct;
          if (pos - spos < addct) c = ' ';
          else if (idx < brtext.length()) c = brtext.charAt(idx);
          else {
            lastbad = true;
            c = '\n';
          }
          s.array[s.count++] = c;
          ++pos;
        }
      } else if (s.count < len) {
        while (s.count < len) {
          s.array[s.count++] = '\n';
        }
        lastbad = true;
      }

      return lastbad;
    }
  /** ***************************************************************************** */
  private void setupSpacing() {
    // get the tab_size from appropriate property
    BoardProperties bp = BoardProperties.getProperties("Bale");
    String v = bp.getProperty("indent.tabulation.size");
    if (v == null)
      v = BumpClient.getBump().getOption("org.eclipse.jdt.core.formatter.tabulation.size");
    if (v == null) v = bp.getProperty("Bale.tabsize");
    tab_size = 8;
    try {
      if (v != null) tab_size = Integer.parseInt(v);
    } catch (NumberFormatException e) {
    }

    region_map = null;
    regions_valid = true;
    indent_size = 0;
    indent_string = null;

    // determine minimum indent
    Segment s = new Segment();
    int minsp = -1;
    for (BaleRegion br : fragment_regions) {
      int soff = br.getStart();
      int eoff = br.getEnd();
      try {
        base_document.getText(soff, eoff - soff, s);
      } catch (BadLocationException e) {
        BoardLog.logE(
            "BALE",
            "Problem getting region text "
                + soff
                + " "
                + eoff
                + " "
                + s.length()
                + " "
                + base_document.getLength(),
            e);
        // should this be "throw e;"
        continue;
      }

      int ln = s.length();

      boolean sol = true;
      int ind = 0;
      for (int i = 0; i < ln && (minsp < 0 || minsp >= MIN_INDENT); ++i) {
        char c = s.charAt(i);
        if (sol) {
          switch (c) {
            case ' ':
              ind += 1;
              break;
            case '\t':
              ind = nextTabPosition(ind);
              break;
            case '\n':
              ind = 0;
              break;
            default:
              if (minsp < 0 || minsp > ind) minsp = ind;
              sol = false;
              break;
          }
        } else if (c == '\n') {
          sol = true;
          ind = 0;
        }
      }

      if (minsp >= 0 && minsp < MIN_INDENT) break;
    }

    if (minsp <= 0 || minsp < MIN_INDENT) return;

    indent_size = minsp;
    indent_string = "";
    for (int i = 0; i < minsp; ++i) indent_string += " ";

    region_map = new HashMap<BaleRegion, RegionData>();
    regions_valid = false;
    for (BaleRegion br : fragment_regions) {
      for (int i = getRegionLength(br) - 1; i >= 0; --i) {
        fixupOffset(br, i, true);
      }
    }
  }