/*******************************************************************************
* Copyright (c) 2011 Subgraph.
* 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:
* Subgraph - initial API and implementation
******************************************************************************/
package com.subgraph.vega.ui.httpviewer.partitioning;
import org.eclipse.jface.text.rules.ICharacterScanner;
import org.eclipse.jface.text.rules.IPredicateRule;
import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.text.rules.Token;
abstract class AbstractStartLinePartitionRule implements IPredicateRule {
protected final int FLAG_UNTIL_SPACE = 1;
protected final int FLAG_UNTIL_EOL = 2;
protected final int FLAG_UNTIL_EOF = 4;
private final IToken token;
private ICharacterScanner scanner;
AbstractStartLinePartitionRule(IToken token) {
this.token = token;
}
protected int nextChar() {
return scanner.read();
}
protected void unread() {
scanner.unread();
}
protected boolean isFirstColumn() {
return scanner.getColumn() == 0;
}
protected void unread(int n) {
for(int i = 0; i < n; i++)
scanner.unread();
}
protected boolean detectSingleSpace() {
if(nextChar() == ' ')
return true;
unread();
return false;
}
protected String parseWord() {
return parseText(FLAG_UNTIL_SPACE);
}
protected String parseText(int flags) {
final StringBuilder sb = new StringBuilder();
int c;
boolean lastCharCR = false;
while((c = nextChar()) != ICharacterScanner.EOF) {
switch(c) {
case '\n':
if((flags & (FLAG_UNTIL_EOL | FLAG_UNTIL_SPACE)) != 0) {
if(lastCharCR)
unread();
unread();
return sb.toString();
}
break;
case '\r':
if((flags & FLAG_UNTIL_SPACE) != 0) {
unread();
return sb.toString();
}
lastCharCR = true;
break;
case ' ':
if((flags & FLAG_UNTIL_SPACE) != 0) {
unread();
return sb.toString();
}
break;
}
sb.append((char) c);
}
if((flags & FLAG_UNTIL_EOF) == 0) {
unread(sb.length());
return "";
}
return sb.toString();
}
/*
* Matches "\n" or "\r\n"
*/
protected boolean detectEOL() {
final int c = nextChar();
if(c == '\n')
return true;
if(c == '\r') {
if(nextChar() == '\n')
return true;
else
unread();
}
unread();
return false;
}
protected abstract boolean doEvaluate();
@Override
public IToken evaluate(ICharacterScanner scanner) {
if(scanner.getColumn() != 0)
return Token.UNDEFINED;
this.scanner = scanner;
if(doEvaluate()) {
return token;
} else {
return Token.UNDEFINED;
}
}
@Override
public IToken getSuccessToken() {
return token;
}
@Override
public IToken evaluate(ICharacterScanner scanner, boolean resume) {
return evaluate(scanner);
}
protected boolean isHttpVersion(String s) {
if(s == null || !s.toUpperCase().startsWith("HTTP/"))
return false;
return isVersionDigits(s.substring(5));
}
private boolean isVersionDigits(String s) {
final String[] digits = s.split("\\.");
if(digits.length != 2)
return false;
return isInteger(digits[0]) && isInteger(digits[1]);
}
protected boolean isInteger(String s) {
if(s == null || s.isEmpty())
return false;
try {
Integer.parseInt(s);
return true;
} catch (NumberFormatException e) {
return false;
}
}
}