001: //This is free software; for terms and warranty disclaimer see ./COPYING.
002:
003: package gnu.jemacs.swt;
004:
005: import gnu.lists.FString;
006: import gnu.lists.GapVector;
007:
008: /**
009: * TODO Explain that this is all about.
010: * @author Christian Surlykke
011: * 18-07-2004
012: */
013: public class SwtCharBuffer extends GapVector implements CharSequence {
014: protected FString chars;
015: protected LineOffsets lineOffsets;
016:
017: public SwtCharBuffer(int initialSize) {
018: super (new FString(new char[initialSize]));
019: chars = (FString) base;
020: this .lineOffsets = new LineOffsets(initialSize / 50);
021: }
022:
023: /* #ifdef use:java.lang.CharSequence */
024: public CharSequence subSequence(int start, int end) {
025: return new SubSequence(start, end);
026: }
027:
028: class SubSequence implements CharSequence {
029: private int start;
030: private int end;
031:
032: public SubSequence(int start, int end) {
033: this .start = start;
034: this .end = end;
035: }
036:
037: /**
038: * @see java.lang.CharSequence#length()
039: */
040: public int length() {
041: return end - start;
042: }
043:
044: /**
045: * @see java.lang.CharSequence#charAt(int)
046: */
047: public char charAt(int index) {
048: return SwtCharBuffer.this .charAt(index + start);
049: }
050:
051: /**
052: * @see java.lang.CharSequence#subSequence(int, int)
053: */
054: public CharSequence subSequence(int start, int end) {
055: return SwtCharBuffer.this .subSequence(this .start + start,
056: this .start + end);
057: }
058: }
059:
060: /* #endif */
061:
062: public int pos2offset(int pos) {
063: return pos < gapStart ? pos : pos + gapEnd - gapStart;
064: }
065:
066: public int offset2pos(int offset) {
067: return offset <= gapStart ? offset : offset - gapEnd + gapStart;
068: }
069:
070: /**
071: * @see gnu.lists.GapVector#gapReserve(int)
072: */
073: protected void gapReserve(int size) {
074: int oldGapSize = gapEnd - gapStart;
075: super .gapReserve(size);
076: int newGapSize = gapEnd - gapStart;
077: if (newGapSize > oldGapSize) // It never shrinks
078: {
079: lineOffsets.textRegionMoved(gapStart + oldGapSize, size(),
080: newGapSize - oldGapSize);
081: }
082: }
083:
084: /**
085: * @see gnu.lists.GapVector#shiftGap(int)
086: */
087: protected void shiftGap(int newGapStart) {
088: int oldGapStart = gapStart;
089: super .shiftGap(newGapStart);
090: if (oldGapStart != gapStart) {
091: int regionStart = oldGapStart < newGapStart ? oldGapStart
092: + gapEnd - gapStart : gapStart;
093: int regionEnd = oldGapStart < newGapStart ? gapEnd
094: : oldGapStart;
095: int displacement = oldGapStart < newGapStart ? gapStart
096: - gapEnd : gapEnd - gapStart;
097: lineOffsets.textRegionMoved(regionStart, regionEnd,
098: displacement);
099:
100: }
101: }
102:
103: /**
104: * @see java.lang.CharSequence#length()
105: */
106: public int length() {
107: return size();
108: }
109:
110: /**
111: * @see java.lang.CharSequence#charAt(int)
112: */
113: public char charAt(int index) {
114: char c = chars.charAt(index < gapStart ? index : index + gapEnd
115: - gapStart);
116: return c;
117: }
118:
119: /**
120: * @param where
121: * @param str
122: */
123: public void insert(int where, String str) {
124: gapReserve(where, str.length());
125: str.getChars(0, str.length(), chars.data, where);
126: gapStart += str.length();
127: lineOffsets.textInserted(where, str);
128: }
129:
130: /**
131: * @param where
132: * @param count
133: */
134: public void delete(int where, int count) {
135: shiftGap(where + count);
136: gapStart -= count;
137: lineOffsets.textDeleted(where, where + count);
138: }
139:
140: public void getChars(int start, int end, char[] dest, int destStart) {
141: int startOffset = pos2offset(start);
142: int endOffset = pos2offset(end);
143: // First we get the part of the string before the gap
144: int startOffset1 = Math.min(startOffset, gapStart);
145: int len1 = Math.min(endOffset, gapStart) - startOffset1;
146: System.arraycopy(chars.data, startOffset1, dest, destStart,
147: len1);
148:
149: // Then the part after the gap
150: int startOffset2 = Math.max(startOffset, gapEnd);
151: int len2 = Math.max(endOffset, gapEnd) - startOffset2;
152: System.arraycopy(chars.data, startOffset2, dest, destStart
153: + len1, len2);
154: }
155:
156: public String toString() {
157: StringBuffer sbuf = new StringBuffer();
158: sbuf.append("Text: {" + size() + ", " + gapStart + ", "
159: + gapEnd);
160: sbuf.append(" [");
161: for (int i = 0; i < size(); i++) {
162: if (i == gapStart) {
163: sbuf.append("|");
164: }
165: char c = chars.charAt(i < gapStart ? i : i + gapEnd
166: - gapStart);
167: if (c == '\r')
168: c = 'R';
169: if (c == '\n')
170: c = 'N';
171: sbuf.append(c);
172: }
173: sbuf.append("]}\n");
174: sbuf.append(lineOffsets.toString());
175:
176: return sbuf.toString();
177:
178: }
179:
180: /**
181: *
182: */
183: protected void show() {
184: System.out.println(this );
185: }
186:
187: protected static String printable(String s) {
188: return ">>" + s.replaceAll("\r", "R").replaceAll("\n", "N")
189: + "<<";
190: }
191:
192: }
|