1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-14 19:55:45 +02:00

Optimization from Chris Songer in manipulating strings.

This commit is contained in:
Alain Magloire 2003-06-25 19:08:29 +00:00
parent effbc07d12
commit ad7625bc1c

View file

@ -121,7 +121,7 @@ public class MIParser {
if (token.charAt(0) == '^') { if (token.charAt(0) == '^') {
token.deleteCharAt(0); token.deleteCharAt(0);
rr = processMIResultRecord(token, id); rr = processMIResultRecord(token, id);
} else if(token.toString().startsWith(MIOutput.terminator)) { } else if (token.toString().startsWith(MIOutput.terminator)) {
//break; // Do nothing. //break; // Do nothing.
} else { } else {
MIOOBRecord band = processMIOOBRecord(token, id); MIOOBRecord band = processMIOOBRecord(token, id);
@ -166,7 +166,7 @@ public class MIParser {
// Results are separated by commas. // Results are separated by commas.
if (buffer.length() > 0 && buffer.charAt(0) == ',') { if (buffer.length() > 0 && buffer.charAt(0) == ',') {
buffer.deleteCharAt(0); buffer.deleteCharAt(0);
MIResult[] res = processMIResults(buffer); MIResult[] res = processMIResults(new FSB(buffer));
rr.setMIResults(res); rr.setMIResults(res);
} }
return rr; return rr;
@ -207,7 +207,7 @@ public class MIParser {
async.setAsyncClass(buffer.toString().trim()); async.setAsyncClass(buffer.toString().trim());
buffer.setLength(0); buffer.setLength(0);
} }
MIResult[] res = processMIResults(buffer); MIResult[] res = processMIResults(new FSB(buffer));
async.setMIResults(res); async.setMIResults(res);
oob = async; oob = async;
} else if (c == '~' || c == '@' || c == '&') { } else if (c == '~' || c == '@' || c == '&') {
@ -231,7 +231,7 @@ public class MIParser {
if (buffer.length() > 0 && buffer.charAt(0) == '"') { if (buffer.length() > 0 && buffer.charAt(0) == '"') {
buffer.deleteCharAt(0); buffer.deleteCharAt(0);
} }
stream.setCString(translateCString(buffer)); stream.setCString(translateCString(new FSB(buffer)));
oob = stream; oob = stream;
} }
return oob; return oob;
@ -241,7 +241,7 @@ public class MIParser {
* Assuming that the usual leading comma was consumed. * Assuming that the usual leading comma was consumed.
* Extract the MI Result comma seperated responses. * Extract the MI Result comma seperated responses.
*/ */
private MIResult[] processMIResults(StringBuffer buffer) { private MIResult[] processMIResults(FSB buffer) {
List aList = new ArrayList(); List aList = new ArrayList();
MIResult result = processMIResult(buffer); MIResult result = processMIResult(buffer);
if (result != null) { if (result != null) {
@ -261,11 +261,10 @@ public class MIParser {
* Construct the MIResult. Characters will be consume/delete * Construct the MIResult. Characters will be consume/delete
* moving forward constructing the AST. * moving forward constructing the AST.
*/ */
private MIResult processMIResult(StringBuffer buffer) { private MIResult processMIResult(FSB buffer) {
MIResult result = new MIResult(); MIResult result = new MIResult();
int equal; int equal;
if (buffer.length() > 0 && Character.isLetter(buffer.charAt(0)) if (buffer.length() > 0 && Character.isLetter(buffer.charAt(0)) && (equal = buffer.indexOf('=')) != -1) {
&& (equal = buffer.toString().indexOf('=')) != -1) {
String variable = buffer.substring(0, equal); String variable = buffer.substring(0, equal);
result.setVariable(variable); result.setVariable(variable);
buffer.delete(0, equal + 1); buffer.delete(0, equal + 1);
@ -282,7 +281,7 @@ public class MIParser {
/** /**
* Find a MIValue implementation or return null. * Find a MIValue implementation or return null.
*/ */
private MIValue processMIValue(StringBuffer buffer) { private MIValue processMIValue(FSB buffer) {
MIValue value = null; MIValue value = null;
if (buffer.length() > 0) { if (buffer.length() > 0) {
if (buffer.charAt(0) == '{') { if (buffer.charAt(0) == '{') {
@ -306,7 +305,7 @@ public class MIParser {
* go to the closing '}' consuming/deleting all the characters. * go to the closing '}' consuming/deleting all the characters.
* This is usually call by processMIvalue(); * This is usually call by processMIvalue();
*/ */
private MIValue processMITuple(StringBuffer buffer) { private MIValue processMITuple(FSB buffer) {
MITuple tuple = new MITuple(); MITuple tuple = new MITuple();
MIResult[] results = null; MIResult[] results = null;
// Catch closing '}' // Catch closing '}'
@ -327,7 +326,7 @@ public class MIParser {
* Assuming the leading '[' was deleted, find the closing * Assuming the leading '[' was deleted, find the closing
* ']' consuming/delete chars from the StringBuffer. * ']' consuming/delete chars from the StringBuffer.
*/ */
private MIValue processMIList(StringBuffer buffer) { private MIValue processMIList(FSB buffer) {
MIList list = new MIList(); MIList list = new MIList();
List valueList = new ArrayList(); List valueList = new ArrayList();
List resultList = new ArrayList(); List resultList = new ArrayList();
@ -337,7 +336,7 @@ public class MIParser {
MIValue value = processMIValue(buffer); MIValue value = processMIValue(buffer);
if (value != null) { if (value != null) {
valueList.add(value); valueList.add(value);
} else { } else {
MIResult result = processMIResult(buffer); MIResult result = processMIResult(buffer);
if (result != null) { if (result != null) {
resultList.add(result); resultList.add(result);
@ -350,8 +349,8 @@ public class MIParser {
if (buffer.length() > 0 && buffer.charAt(0) == ']') { if (buffer.length() > 0 && buffer.charAt(0) == ']') {
buffer.deleteCharAt(0); buffer.deleteCharAt(0);
} }
MIValue[] values = (MIValue[])valueList.toArray(new MIValue[valueList.size()]); MIValue[] values = (MIValue[]) valueList.toArray(new MIValue[valueList.size()]);
MIResult[] res = (MIResult[])resultList.toArray(new MIResult[resultList.size()]); MIResult[] res = (MIResult[]) resultList.toArray(new MIResult[resultList.size()]);
list.setMIValues(values); list.setMIValues(values);
list.setMIResults(res); list.setMIResults(res);
return list; return list;
@ -365,7 +364,7 @@ public class MIParser {
* backslach escaping and return the string __without__ the enclosing double quotes * backslach escaping and return the string __without__ the enclosing double quotes
* The orignal StringBuffer will move forward. * The orignal StringBuffer will move forward.
*/ */
private String translateCString(StringBuffer buffer) { private String translateCString(FSB buffer) {
boolean escape = false; boolean escape = false;
boolean closingQuotes = false; boolean closingQuotes = false;
@ -383,7 +382,7 @@ public class MIParser {
} }
} else if (c == '"') { } else if (c == '"') {
if (escape) { if (escape) {
sb.append(c);; sb.append(c);
escape = false; escape = false;
} else { } else {
// Bail out. // Bail out.
@ -400,4 +399,111 @@ public class MIParser {
buffer.delete(0, index); buffer.delete(0, index);
return sb.toString(); return sb.toString();
} }
/**
* Fast String Buffer class. MIParser does a lot
* of deleting off the front of a string, that's clearly
* an order N operation for StringBuffer which makes
* the MIParser an order N^2 operation. There are "issues"
* with this for large arrays. Use of FSB rather than String
* Buffer makes MIParser N rather than N^2 because FSB can
* delete from the front in constant time.
*/
public class FSB {
StringBuffer buf;
int pos;
boolean shared;
public FSB(StringBuffer buf) {
this.buf = buf;
pos = 0;
shared = false;
}
public FSB(FSB fbuf) {
pos = fbuf.pos;
buf = fbuf.buf;
shared = true;
}
public int length() {
int res = buf.length() - pos;
if (res < 0)
return 0;
return res;
}
public char charAt(int index) {
return buf.charAt(index + pos);
}
private void resolveCopy() {
if (shared) {
buf = new StringBuffer(buf.toString());
shared = false;
}
}
public FSB deleteCharAt(int index) {
if (index == 0) {
pos++;
} else {
resolveCopy();
buf = buf.deleteCharAt(pos + index);
}
return this;
}
public FSB delete(int start, int end) {
if (start == 0) {
pos = pos + end - start;
} else {
resolveCopy();
buf.delete(start + pos, end + pos);
}
return this;
}
public void setLength(int a) {
if (a == 0)
pos = buf.length();
else {
// panic! fortunately we don't do this.
}
}
public String substring(int start, int end) {
return buf.substring(start + pos, end + pos);
}
public String toString() {
return buf.substring(pos, buf.length());
}
int indexOf(char c) {
int len = buf.length();
for (int i = pos; i < len; i++) {
if (buf.charAt(i) == c)
return i - pos;
}
return -1;
}
boolean startsWith(String s) {
int len = Math.min(s.length(), length());
if (len < s.length())
return false;
for (int i = 0; i < len; i++) {
if (s.charAt(i) != buf.charAt(pos + i))
return false;
}
return true;
}
}
} }