WALA/com.ibm.wala.cast/source/java/com/ibm/wala/cast/util/SourceBuffer.java

189 lines
5.3 KiB
Java

/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.cast.util;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
import com.ibm.wala.cast.tree.impl.AbstractSourcePosition;
public class SourceBuffer {
private String[] lines;
private final Position p;
public SourceBuffer(Position p) throws IOException {
this.p = p;
BufferedReader reader = new BufferedReader(p.getReader());
String currentLine = null;
List<String> lines = new ArrayList<String>();
int offset = 0, line = 0;
do {
currentLine = reader.readLine();
if (currentLine == null) {
this.lines = new String[0];
return;
}
offset += (currentLine.length() + 1);
line++;
} while (p.getLastOffset()>=0? p.getFirstOffset() > offset: p.getFirstLine() > line);
// partial first line
if (p.getLastOffset() >= 0) {
if (p.getFirstOffset() == offset) {
lines.add("\n");
} else {
int startOffset = p.getFirstOffset() - (offset-currentLine.length()-1);
if (offset > p.getLastOffset()) {
int endOffset = p.getLastOffset() - (offset-currentLine.length()-1);
lines.add(currentLine.substring(startOffset, endOffset));
} else {
lines.add(currentLine.substring(startOffset));
}
}
} else {
lines.add(currentLine.substring(p.getFirstCol()));
}
while (p.getLastOffset()>=0? p.getLastOffset() >= offset: p.getLastLine() >= line) {
currentLine = reader.readLine();
if (currentLine == null) {
offset = p.getLastOffset();
break;
} else {
offset += currentLine.length() + 1;
}
line++;
if (p.getLastOffset() >= 0) {
if (offset > p.getLastOffset()) {
lines.add(currentLine.substring(0, currentLine.length() - (offset - p.getLastOffset()) + 1));
} else {
lines.add(currentLine);
}
} else {
if (p.getLastLine() == line) {
lines.add(currentLine.substring(0, p.getLastCol()));
} else {
lines.add(currentLine);
}
}
}
this.lines = lines.toArray(new String[ lines.size() ]);
}
@Override
public String toString() {
StringBuffer result = new StringBuffer();
for(int i = 0; i < lines.length; i++) {
if (i == lines.length - 1) {
result.append(lines[i]);
} else {
result.append(lines[i]).append("\n");
}
}
return result.toString();
}
public void substitute(Position range, String newText) {
int startLine = range.getFirstLine() - p.getFirstLine();
int endLine = range.getLastLine() - p.getFirstLine();
if (startLine != endLine) {
String newLines[] = new String[ lines.length - (endLine-startLine) ];
int i = 0;
while (i < startLine) {
newLines[i] = lines[i];
i++;
}
newLines[i++] =
lines[startLine].substring(0, range.getFirstCol()) +
lines[endLine].substring(range.getLastCol());
while(i < newLines.length) {
newLines[i] = lines[i+ (endLine-startLine)];
i++;
}
lines = newLines;
endLine = startLine;
final Position hack = range;
range = new AbstractSourcePosition() {
@Override
public int getFirstLine() { return hack.getFirstLine(); }
@Override
public int getLastLine() { return hack.getFirstLine(); }
@Override
public int getFirstCol() { return hack.getFirstCol(); }
@Override
public int getLastCol() { return hack.getFirstCol(); }
@Override
public int getFirstOffset() { return hack.getFirstOffset(); }
@Override
public int getLastOffset() { return hack.getFirstOffset(); }
@Override
public URL getURL() { return hack.getURL(); }
@Override
public Reader getReader() throws IOException {
return hack.getReader();
}
};
}
String[] newTextLines = newText.split("\n");
if (newTextLines.length == 1) {
lines[startLine] =
lines[startLine].substring(0, range.getFirstCol()) +
newTextLines[0] +
lines[startLine].substring(range.getLastCol()+1);
} else {
String[] newLines =
new String[ lines.length + newTextLines.length - 1 ];
int i = 0;
while (i < startLine) {
newLines[i] = lines[i];
i++;
}
newLines[i++] =
lines[startLine].substring(0, range.getFirstCol()) +
newTextLines[0];
for(int j = 1; j < newTextLines.length - 1; j++) {
lines[i++] = newTextLines[j];
}
newLines[i++] =
newTextLines[newTextLines.length-1] +
lines[endLine].substring(range.getLastCol()+1);
while (i < newLines.length) {
newLines[i] = lines[i - newTextLines.length + 1];
i++;
}
lines = newLines;
}
}
}