mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
convert SsiProcessor to kotlin
This commit is contained in:
+253
-263
@@ -13,429 +13,419 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.builtInWebServer.ssi;
|
||||
package org.jetbrains.builtInWebServer.ssi
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.util.SmartList;
|
||||
import gnu.trove.THashMap;
|
||||
import io.netty.buffer.ByteBufUtf8Writer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.util.SmartList
|
||||
import gnu.trove.THashMap
|
||||
import io.netty.buffer.ByteBufUtf8Writer
|
||||
import java.io.FileInputStream
|
||||
import java.io.IOException
|
||||
import java.util.*
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.*;
|
||||
internal val LOG = Logger.getInstance(SsiProcessor::class.java)
|
||||
|
||||
public class SsiProcessor {
|
||||
static final Logger LOG = Logger.getInstance(SsiProcessor.class);
|
||||
internal val COMMAND_START = "<!--#"
|
||||
internal val COMMAND_END = "-->"
|
||||
|
||||
protected static final String COMMAND_START = "<!--#";
|
||||
protected static final String COMMAND_END = "-->";
|
||||
interface SsiCommand {
|
||||
fun process(state: SsiProcessingState, commandName: String, paramNames: List<String>, paramValues: Array<String>, writer: ByteBufUtf8Writer): Long
|
||||
}
|
||||
|
||||
protected final Map<String, SsiCommand> commands = new THashMap<String, SsiCommand>();
|
||||
class SsiProcessor(allowExec: Boolean) {
|
||||
private val commands: MutableMap<String, SsiCommand> = THashMap()
|
||||
|
||||
@SuppressWarnings("SpellCheckingInspection")
|
||||
public SsiProcessor(boolean allowExec) {
|
||||
commands.put("config", new SsiCommand() {
|
||||
@Override
|
||||
public long process(@NotNull SsiProcessingState state, @NotNull String commandName, @NotNull List<String> paramNames, @NotNull String[] paramValues, @NotNull ByteBufUtf8Writer writer) {
|
||||
for (int i = 0; i < paramNames.size(); i++) {
|
||||
String paramName = paramNames.get(i);
|
||||
String paramValue = paramValues[i];
|
||||
String substitutedValue = state.substituteVariables(paramValue);
|
||||
if (paramName.equalsIgnoreCase("errmsg")) {
|
||||
state.configErrorMessage = substitutedValue;
|
||||
init {
|
||||
commands.put("config", object : SsiCommand {
|
||||
override fun process(state: SsiProcessingState, commandName: String, paramNames: List<String>, paramValues: Array<String>, writer: ByteBufUtf8Writer): Long {
|
||||
for (i in paramNames.indices) {
|
||||
val paramName = paramNames[i]
|
||||
val paramValue = paramValues[i]
|
||||
val substitutedValue = state.substituteVariables(paramValue)
|
||||
if (paramName.equals("errmsg", ignoreCase = true)) {
|
||||
state.configErrorMessage = substitutedValue
|
||||
}
|
||||
else if (paramName.equalsIgnoreCase("sizefmt")) {
|
||||
state.configSizeFmt = substitutedValue;
|
||||
else if (paramName.equals("sizefmt", ignoreCase = true)) {
|
||||
state.configSizeFmt = substitutedValue
|
||||
}
|
||||
else if (paramName.equalsIgnoreCase("timefmt")) {
|
||||
state.setConfigTimeFormat(substitutedValue, false);
|
||||
else if (paramName.equals("timefmt", ignoreCase = true)) {
|
||||
state.setConfigTimeFormat(substitutedValue, false)
|
||||
}
|
||||
else {
|
||||
LOG.info("#config--Invalid attribute: " + paramName);
|
||||
LOG.info("#config--Invalid attribute: " + paramName)
|
||||
// We need to fetch this value each time, since it may change during the loop
|
||||
writer.write(state.configErrorMessage);
|
||||
writer.write(state.configErrorMessage)
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return 0
|
||||
}
|
||||
});
|
||||
commands.put("echo", new SsiCommand() {
|
||||
@Override
|
||||
public long process(@NotNull SsiProcessingState state, @NotNull String commandName, @NotNull List<String> paramNames, @NotNull String[] paramValues, @NotNull ByteBufUtf8Writer writer) {
|
||||
String encoding = "entity";
|
||||
String originalValue = null;
|
||||
String errorMessage = state.configErrorMessage;
|
||||
for (int i = 0; i < paramNames.size(); i++) {
|
||||
String paramName = paramNames.get(i);
|
||||
String paramValue = paramValues[i];
|
||||
if (paramName.equalsIgnoreCase("var")) {
|
||||
originalValue = paramValue;
|
||||
})
|
||||
commands.put("echo", object : SsiCommand {
|
||||
override fun process(state: SsiProcessingState, commandName: String, paramNames: List<String>, paramValues: Array<String>, writer: ByteBufUtf8Writer): Long {
|
||||
var encoding = "entity"
|
||||
var originalValue: String? = null
|
||||
val errorMessage = state.configErrorMessage
|
||||
for (i in paramNames.indices) {
|
||||
val paramName = paramNames[i]
|
||||
val paramValue = paramValues[i]
|
||||
if (paramName.equals("var", ignoreCase = true)) {
|
||||
originalValue = paramValue
|
||||
}
|
||||
else if (paramName.equalsIgnoreCase("encoding")) {
|
||||
if (paramValue.equalsIgnoreCase("url") || paramValue.equalsIgnoreCase("entity") || paramValue.equalsIgnoreCase("none")) {
|
||||
encoding = paramValue;
|
||||
else if (paramName.equals("encoding", ignoreCase = true)) {
|
||||
if (paramValue.equals("url", ignoreCase = true) || paramValue.equals("entity", ignoreCase = true) || paramValue.equals("none", ignoreCase = true)) {
|
||||
encoding = paramValue
|
||||
}
|
||||
else {
|
||||
LOG.info("#echo--Invalid encoding: " + paramValue);
|
||||
writer.write(errorMessage);
|
||||
LOG.info("#echo--Invalid encoding: " + paramValue)
|
||||
writer.write(errorMessage)
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG.info("#echo--Invalid attribute: " + paramName);
|
||||
writer.write(errorMessage);
|
||||
LOG.info("#echo--Invalid attribute: " + paramName)
|
||||
writer.write(errorMessage)
|
||||
}
|
||||
}
|
||||
assert originalValue != null;
|
||||
String variableValue = state.getVariableValue(originalValue, encoding);
|
||||
writer.write(variableValue == null ? "(none)" : variableValue);
|
||||
return System.currentTimeMillis();
|
||||
val variableValue = state.getVariableValue(originalValue!!, encoding)
|
||||
writer.write(variableValue ?: "(none)")
|
||||
return System.currentTimeMillis()
|
||||
}
|
||||
});
|
||||
})
|
||||
//noinspection StatementWithEmptyBody
|
||||
if (allowExec) {
|
||||
// commands.put("exec", new SsiExec());
|
||||
}
|
||||
commands.put("include", new SsiCommand() {
|
||||
@Override
|
||||
public long process(@NotNull SsiProcessingState state, @NotNull String commandName, @NotNull List<String> paramNames, @NotNull String[] paramValues, @NotNull ByteBufUtf8Writer writer) {
|
||||
long lastModified = 0;
|
||||
String configErrorMessage = state.configErrorMessage;
|
||||
for (int i = 0; i < paramNames.size(); i++) {
|
||||
String paramName = paramNames.get(i);
|
||||
if (paramName.equalsIgnoreCase("file") || paramName.equalsIgnoreCase("virtual")) {
|
||||
String substitutedValue = state.substituteVariables(paramValues[i]);
|
||||
commands.put("include", object : SsiCommand {
|
||||
override fun process(state: SsiProcessingState, commandName: String, paramNames: List<String>, paramValues: Array<String>, writer: ByteBufUtf8Writer): Long {
|
||||
var lastModified: Long = 0
|
||||
val configErrorMessage = state.configErrorMessage
|
||||
for (i in paramNames.indices) {
|
||||
val paramName = paramNames[i]
|
||||
if (paramName.equals("file", ignoreCase = true) || paramName.equals("virtual", ignoreCase = true)) {
|
||||
val substitutedValue = state.substituteVariables(paramValues[i])
|
||||
try {
|
||||
boolean virtual = paramName.equalsIgnoreCase("virtual");
|
||||
lastModified = state.ssiExternalResolver.getFileLastModified(substitutedValue, virtual);
|
||||
File file = state.ssiExternalResolver.findFile(substitutedValue, virtual);
|
||||
val virtual = paramName.equals("virtual", ignoreCase = true)
|
||||
lastModified = state.ssiExternalResolver.getFileLastModified(substitutedValue, virtual)
|
||||
val file = state.ssiExternalResolver.findFile(substitutedValue, virtual)
|
||||
if (file == null) {
|
||||
LOG.warn("#include-- Couldn't find file: " + substitutedValue);
|
||||
return 0;
|
||||
LOG.warn("#include-- Couldn't find file: " + substitutedValue)
|
||||
return 0
|
||||
}
|
||||
|
||||
InputStream in = new FileInputStream(file);
|
||||
val `in` = FileInputStream(file)
|
||||
try {
|
||||
writer.write(in, (int)file.length());
|
||||
writer.write(`in`, file.length().toInt())
|
||||
}
|
||||
finally {
|
||||
in.close();
|
||||
`in`.close()
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.warn("#include--Couldn't include file: " + substitutedValue, e);
|
||||
writer.write(configErrorMessage);
|
||||
catch (e: IOException) {
|
||||
LOG.warn("#include--Couldn't include file: " + substitutedValue, e)
|
||||
writer.write(configErrorMessage)
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
LOG.info("#include--Invalid attribute: " + paramName);
|
||||
writer.write(configErrorMessage);
|
||||
LOG.info("#include--Invalid attribute: " + paramName)
|
||||
writer.write(configErrorMessage)
|
||||
}
|
||||
}
|
||||
return lastModified;
|
||||
return lastModified
|
||||
}
|
||||
});
|
||||
commands.put("flastmod", new SsiCommand() {
|
||||
@Override
|
||||
public long process(@NotNull SsiProcessingState state, @NotNull String commandName, @NotNull List<String> paramNames, @NotNull String[] paramValues, @NotNull ByteBufUtf8Writer writer) {
|
||||
long lastModified = 0;
|
||||
String configErrMsg = state.configErrorMessage;
|
||||
for (int i = 0; i < paramNames.size(); i++) {
|
||||
String paramName = paramNames.get(i);
|
||||
String paramValue = paramValues[i];
|
||||
String substitutedValue = state.substituteVariables(paramValue);
|
||||
if (paramName.equalsIgnoreCase("file") || paramName.equalsIgnoreCase("virtual")) {
|
||||
boolean virtual = paramName.equalsIgnoreCase("virtual");
|
||||
lastModified = state.ssiExternalResolver.getFileLastModified(substitutedValue, virtual);
|
||||
Strftime strftime = new Strftime(state.configTimeFmt, Locale.US);
|
||||
writer.write(strftime.format(new Date(lastModified)));
|
||||
})
|
||||
commands.put("flastmod", object : SsiCommand {
|
||||
override fun process(state: SsiProcessingState, commandName: String, paramNames: List<String>, paramValues: Array<String>, writer: ByteBufUtf8Writer): Long {
|
||||
var lastModified: Long = 0
|
||||
val configErrMsg = state.configErrorMessage
|
||||
for (i in paramNames.indices) {
|
||||
val paramName = paramNames[i]
|
||||
val paramValue = paramValues[i]
|
||||
val substitutedValue = state.substituteVariables(paramValue)
|
||||
if (paramName.equals("file", ignoreCase = true) || paramName.equals("virtual", ignoreCase = true)) {
|
||||
val virtual = paramName.equals("virtual", ignoreCase = true)
|
||||
lastModified = state.ssiExternalResolver.getFileLastModified(substitutedValue, virtual)
|
||||
val strftime = Strftime(state.configTimeFmt, Locale.US)
|
||||
writer.write(strftime.format(Date(lastModified)))
|
||||
}
|
||||
else {
|
||||
LOG.info("#flastmod--Invalid attribute: " + paramName);
|
||||
writer.write(configErrMsg);
|
||||
LOG.info("#flastmod--Invalid attribute: " + paramName)
|
||||
writer.write(configErrMsg)
|
||||
}
|
||||
}
|
||||
return lastModified;
|
||||
return lastModified
|
||||
}
|
||||
});
|
||||
commands.put("fsize", new SsiFsize());
|
||||
commands.put("printenv", new SsiCommand() {
|
||||
@Override
|
||||
public long process(@NotNull SsiProcessingState state, @NotNull String commandName, @NotNull List<String> paramNames, @NotNull String[] paramValues, @NotNull ByteBufUtf8Writer writer) {
|
||||
long lastModified = 0;
|
||||
})
|
||||
commands.put("fsize", SsiFsize())
|
||||
commands.put("printenv", object : SsiCommand {
|
||||
override fun process(state: SsiProcessingState, commandName: String, paramNames: List<String>, paramValues: Array<String>, writer: ByteBufUtf8Writer): Long {
|
||||
var lastModified: Long = 0
|
||||
// any arguments should produce an error
|
||||
if (paramNames.isEmpty()) {
|
||||
Set<String> variableNames = new LinkedHashSet<String>();
|
||||
val variableNames = LinkedHashSet<String>()
|
||||
//These built-in variables are supplied by the mediator ( if not over-written by the user ) and always exist
|
||||
variableNames.add("DATE_GMT");
|
||||
variableNames.add("DATE_LOCAL");
|
||||
variableNames.add("LAST_MODIFIED");
|
||||
state.ssiExternalResolver.addVariableNames(variableNames);
|
||||
for (String variableName : variableNames) {
|
||||
String variableValue = state.getVariableValue(variableName);
|
||||
variableNames.add("DATE_GMT")
|
||||
variableNames.add("DATE_LOCAL")
|
||||
variableNames.add("LAST_MODIFIED")
|
||||
state.ssiExternalResolver.addVariableNames(variableNames)
|
||||
for (variableName in variableNames) {
|
||||
var variableValue: String? = state.getVariableValue(variableName)
|
||||
// This shouldn't happen, since all the variable names must have values
|
||||
if (variableValue == null) {
|
||||
variableValue = "(none)";
|
||||
variableValue = "(none)"
|
||||
}
|
||||
writer.write(variableName);
|
||||
writer.write('=');
|
||||
writer.write(variableValue);
|
||||
writer.write('\n');
|
||||
lastModified = System.currentTimeMillis();
|
||||
writer.append(variableName).append('=').append(variableValue).append('\n')
|
||||
lastModified = System.currentTimeMillis()
|
||||
}
|
||||
}
|
||||
else {
|
||||
writer.write(state.configErrorMessage);
|
||||
writer.write(state.configErrorMessage)
|
||||
}
|
||||
return lastModified;
|
||||
return lastModified
|
||||
}
|
||||
});
|
||||
commands.put("set", new SsiCommand() {
|
||||
@Override
|
||||
public long process(@NotNull SsiProcessingState state, @NotNull String commandName, @NotNull List<String> paramNames, @NotNull String[] paramValues, @NotNull ByteBufUtf8Writer writer) {
|
||||
long lastModified = 0;
|
||||
String errorMessage = state.configErrorMessage;
|
||||
String variableName = null;
|
||||
for (int i = 0; i < paramNames.size(); i++) {
|
||||
String paramName = paramNames.get(i);
|
||||
String paramValue = paramValues[i];
|
||||
if (paramName.equalsIgnoreCase("var")) {
|
||||
variableName = paramValue;
|
||||
})
|
||||
commands.put("set", object : SsiCommand {
|
||||
override fun process(state: SsiProcessingState, commandName: String, paramNames: List<String>, paramValues: Array<String>, writer: ByteBufUtf8Writer): Long {
|
||||
var lastModified: Long = 0
|
||||
val errorMessage = state.configErrorMessage
|
||||
var variableName: String? = null
|
||||
for (i in paramNames.indices) {
|
||||
val paramName = paramNames[i]
|
||||
val paramValue = paramValues[i]
|
||||
if (paramName.equals("var", ignoreCase = true)) {
|
||||
variableName = paramValue
|
||||
}
|
||||
else if (paramName.equalsIgnoreCase("value")) {
|
||||
else if (paramName.equals("value", ignoreCase = true)) {
|
||||
if (variableName != null) {
|
||||
String substitutedValue = state.substituteVariables(paramValue);
|
||||
state.ssiExternalResolver.setVariableValue(variableName, substitutedValue);
|
||||
lastModified = System.currentTimeMillis();
|
||||
val substitutedValue = state.substituteVariables(paramValue)
|
||||
state.ssiExternalResolver.setVariableValue(variableName, substitutedValue)
|
||||
lastModified = System.currentTimeMillis()
|
||||
}
|
||||
else {
|
||||
LOG.info("#set--no variable specified");
|
||||
writer.write(errorMessage);
|
||||
throw new SsiStopProcessingException();
|
||||
LOG.info("#set--no variable specified")
|
||||
writer.write(errorMessage)
|
||||
throw SsiStopProcessingException()
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG.info("#set--Invalid attribute: " + paramName);
|
||||
writer.write(errorMessage);
|
||||
throw new SsiStopProcessingException();
|
||||
LOG.info("#set--Invalid attribute: " + paramName)
|
||||
writer.write(errorMessage)
|
||||
throw SsiStopProcessingException()
|
||||
}
|
||||
}
|
||||
return lastModified;
|
||||
return lastModified
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
SsiConditional ssiConditional = new SsiConditional();
|
||||
commands.put("if", ssiConditional);
|
||||
commands.put("elif", ssiConditional);
|
||||
commands.put("endif", ssiConditional);
|
||||
commands.put("else", ssiConditional);
|
||||
val ssiConditional = SsiConditional()
|
||||
commands.put("if", ssiConditional)
|
||||
commands.put("elif", ssiConditional)
|
||||
commands.put("endif", ssiConditional)
|
||||
commands.put("else", ssiConditional)
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the most current modified date resulting from any SSI commands
|
||||
*/
|
||||
public long process(@NotNull SsiExternalResolver ssiExternalResolver, @NotNull String fileContents, long lastModifiedDate, @NotNull ByteBufUtf8Writer writer) {
|
||||
SsiProcessingState ssiProcessingState = new SsiProcessingState(ssiExternalResolver, lastModifiedDate);
|
||||
int index = 0;
|
||||
boolean inside = false;
|
||||
StringBuilder command = new StringBuilder();
|
||||
fun process(ssiExternalResolver: SsiExternalResolver, fileContents: String, lastModifiedDate: Long, writer: ByteBufUtf8Writer): Long {
|
||||
var resultLastModifiedDate = lastModifiedDate
|
||||
val ssiProcessingState = SsiProcessingState(ssiExternalResolver, resultLastModifiedDate)
|
||||
var index = 0
|
||||
var inside = false
|
||||
val command = StringBuilder()
|
||||
try {
|
||||
while (index < fileContents.length()) {
|
||||
char c = fileContents.charAt(index);
|
||||
while (index < fileContents.length) {
|
||||
val c = fileContents[index]
|
||||
if (inside) {
|
||||
if (c == COMMAND_END.charAt(0) && charCmp(fileContents, index, COMMAND_END)) {
|
||||
inside = false;
|
||||
index += COMMAND_END.length();
|
||||
String commandName = parseCommand(command);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("SSIProcessor.process -- processing command: " + commandName);
|
||||
if (c == COMMAND_END[0] && charCmp(fileContents, index, COMMAND_END)) {
|
||||
inside = false
|
||||
index += COMMAND_END.length
|
||||
val commandName = parseCommand(command)
|
||||
if (LOG.isDebugEnabled) {
|
||||
LOG.debug("SSIProcessor.process -- processing command: " + commandName)
|
||||
}
|
||||
List<String> paramNames = parseParamNames(command, commandName.length());
|
||||
String[] paramValues = parseParamValues(command, commandName.length(), paramNames.size());
|
||||
val paramNames = parseParamNames(command, commandName.length)
|
||||
val paramValues = parseParamValues(command, commandName.length, paramNames.size)
|
||||
// We need to fetch this value each time, since it may change during the loop
|
||||
String configErrMsg = ssiProcessingState.configErrorMessage;
|
||||
SsiCommand ssiCommand = commands.get(commandName.toLowerCase(Locale.ENGLISH));
|
||||
String errorMessage = null;
|
||||
val configErrMsg = ssiProcessingState.configErrorMessage
|
||||
val ssiCommand = commands[commandName.toLowerCase(Locale.ENGLISH)]
|
||||
var errorMessage: String? = null
|
||||
if (ssiCommand == null) {
|
||||
errorMessage = "Unknown command: " + commandName;
|
||||
errorMessage = "Unknown command: " + commandName
|
||||
}
|
||||
else if (paramValues == null) {
|
||||
errorMessage = "Error parsing directive parameters.";
|
||||
errorMessage = "Error parsing directive parameters."
|
||||
}
|
||||
else if (paramNames.size() != paramValues.length) {
|
||||
errorMessage = "Parameter names count does not match parameter values count on command: " + commandName;
|
||||
else if (paramNames.size != paramValues.size) {
|
||||
errorMessage = "Parameter names count does not match parameter values count on command: " + commandName
|
||||
}
|
||||
else {
|
||||
// don't process the command if we are processing conditional commands only and the command is not conditional
|
||||
if (!ssiProcessingState.conditionalState.processConditionalCommandsOnly || ssiCommand instanceof SsiConditional) {
|
||||
long newLastModified = ssiCommand.process(ssiProcessingState, commandName, paramNames, paramValues, writer);
|
||||
if (newLastModified > lastModifiedDate) {
|
||||
lastModifiedDate = newLastModified;
|
||||
if (!ssiProcessingState.conditionalState.processConditionalCommandsOnly || ssiCommand is SsiConditional) {
|
||||
val newLastModified = ssiCommand.process(ssiProcessingState, commandName, paramNames, paramValues, writer)
|
||||
if (newLastModified > resultLastModifiedDate) {
|
||||
resultLastModifiedDate = newLastModified
|
||||
}
|
||||
}
|
||||
}
|
||||
if (errorMessage != null) {
|
||||
LOG.warn(errorMessage);
|
||||
writer.write(configErrMsg);
|
||||
LOG.warn(errorMessage)
|
||||
writer.write(configErrMsg)
|
||||
}
|
||||
}
|
||||
else {
|
||||
command.append(c);
|
||||
index++;
|
||||
command.append(c)
|
||||
index++
|
||||
}
|
||||
}
|
||||
else if (c == COMMAND_START.charAt(0) && charCmp(fileContents, index, COMMAND_START)) {
|
||||
inside = true;
|
||||
index += COMMAND_START.length();
|
||||
command.setLength(0);
|
||||
else if (c == COMMAND_START[0] && charCmp(fileContents, index, COMMAND_START)) {
|
||||
inside = true
|
||||
index += COMMAND_START.length
|
||||
command.setLength(0)
|
||||
}
|
||||
else {
|
||||
if (!ssiProcessingState.conditionalState.processConditionalCommandsOnly) {
|
||||
writer.write(c);
|
||||
writer.write(c.toInt())
|
||||
}
|
||||
index++;
|
||||
index++
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SsiStopProcessingException e) {
|
||||
catch (e: SsiStopProcessingException) {
|
||||
//If we are here, then we have already stopped processing, so all is good
|
||||
}
|
||||
return lastModifiedDate;
|
||||
|
||||
return resultLastModifiedDate
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected List<String> parseParamNames(@NotNull StringBuilder command, int start) {
|
||||
int bIdx = start;
|
||||
List<String> values = new SmartList<String>();
|
||||
boolean inside = false;
|
||||
StringBuilder builder = new StringBuilder();
|
||||
while (bIdx < command.length()) {
|
||||
protected fun parseParamNames(command: StringBuilder, start: Int): List<String> {
|
||||
var bIdx = start
|
||||
val values = SmartList<String>()
|
||||
var inside = false
|
||||
val builder = StringBuilder()
|
||||
while (bIdx < command.length) {
|
||||
if (inside) {
|
||||
while (bIdx < command.length() && command.charAt(bIdx) != '=') {
|
||||
builder.append(command.charAt(bIdx));
|
||||
bIdx++;
|
||||
while (bIdx < command.length && command[bIdx] != '=') {
|
||||
builder.append(command[bIdx])
|
||||
bIdx++
|
||||
}
|
||||
|
||||
values.add(builder.toString());
|
||||
builder.setLength(0);
|
||||
inside = false;
|
||||
int quotes = 0;
|
||||
boolean escaped = false;
|
||||
for (; bIdx < command.length() && quotes != 2; bIdx++) {
|
||||
char c = command.charAt(bIdx);
|
||||
values.add(builder.toString())
|
||||
builder.setLength(0)
|
||||
inside = false
|
||||
var quotes = 0
|
||||
var escaped = false
|
||||
while (bIdx < command.length && quotes != 2) {
|
||||
val c = command[bIdx]
|
||||
// Need to skip escaped characters
|
||||
if (c == '\\' && !escaped) {
|
||||
escaped = true;
|
||||
continue;
|
||||
escaped = true
|
||||
bIdx++
|
||||
continue
|
||||
}
|
||||
if (c == '"' && !escaped) {
|
||||
quotes++;
|
||||
quotes++
|
||||
}
|
||||
escaped = false;
|
||||
escaped = false
|
||||
bIdx++
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (bIdx < command.length() && isSpace(command.charAt(bIdx))) {
|
||||
bIdx++;
|
||||
while (bIdx < command.length && isSpace(command[bIdx])) {
|
||||
bIdx++
|
||||
}
|
||||
if (bIdx >= command.length()) {
|
||||
break;
|
||||
if (bIdx >= command.length) {
|
||||
break
|
||||
}
|
||||
inside = true;
|
||||
inside = true
|
||||
}
|
||||
}
|
||||
return values;
|
||||
return values
|
||||
}
|
||||
|
||||
@SuppressWarnings("AssignmentToForLoopParameter")
|
||||
protected String[] parseParamValues(@NotNull StringBuilder command, int start, int count) {
|
||||
int valueIndex = 0;
|
||||
boolean inside = false;
|
||||
String[] values = new String[count];
|
||||
StringBuilder builder = new StringBuilder();
|
||||
char endQuote = 0;
|
||||
for (int bIdx = start; bIdx < command.length(); bIdx++) {
|
||||
protected fun parseParamValues(command: StringBuilder, start: Int, count: Int): Array<String>? {
|
||||
var valueIndex = 0
|
||||
var inside = false
|
||||
val values = arrayOfNulls<String>(count)
|
||||
val builder = StringBuilder()
|
||||
var endQuote: Char = 0.toChar()
|
||||
var bIdx = start
|
||||
while (bIdx < command.length) {
|
||||
if (!inside) {
|
||||
while (bIdx < command.length() && !isQuote(command.charAt(bIdx))) {
|
||||
bIdx++;
|
||||
while (bIdx < command.length && !isQuote(command[bIdx])) {
|
||||
bIdx++
|
||||
}
|
||||
if (bIdx >= command.length()) {
|
||||
break;
|
||||
if (bIdx >= command.length) {
|
||||
break
|
||||
}
|
||||
inside = true;
|
||||
endQuote = command.charAt(bIdx);
|
||||
inside = true
|
||||
endQuote = command[bIdx]
|
||||
}
|
||||
else {
|
||||
boolean escaped = false;
|
||||
for (; bIdx < command.length(); bIdx++) {
|
||||
char c = command.charAt(bIdx);
|
||||
var escaped = false
|
||||
while (bIdx < command.length) {
|
||||
val c = command[bIdx]
|
||||
// Check for escapes
|
||||
if (c == '\\' && !escaped) {
|
||||
escaped = true;
|
||||
continue;
|
||||
escaped = true
|
||||
bIdx++
|
||||
continue
|
||||
}
|
||||
// If we reach the other " then stop
|
||||
if (c == endQuote && !escaped) {
|
||||
break;
|
||||
break
|
||||
}
|
||||
// Since parsing of attributes and var
|
||||
// substitution is done in separate places,
|
||||
// we need to leave escape in the string
|
||||
if (c == '$' && escaped) {
|
||||
builder.append('\\');
|
||||
builder.append('\\')
|
||||
}
|
||||
escaped = false;
|
||||
builder.append(c);
|
||||
escaped = false
|
||||
builder.append(c)
|
||||
bIdx++
|
||||
}
|
||||
// If we hit the end without seeing a quote
|
||||
// the signal an error
|
||||
if (bIdx == command.length()) {
|
||||
return null;
|
||||
if (bIdx == command.length) {
|
||||
return null
|
||||
}
|
||||
values[valueIndex++] = builder.toString();
|
||||
builder.setLength(0);
|
||||
inside = false;
|
||||
values[valueIndex++] = builder.toString()
|
||||
builder.setLength(0)
|
||||
inside = false
|
||||
}
|
||||
bIdx++
|
||||
}
|
||||
return values;
|
||||
@Suppress("CAST_NEVER_SUCCEEDS")
|
||||
return values as Array<String>
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private String parseCommand(@NotNull StringBuilder instruction) {
|
||||
int firstLetter = -1;
|
||||
int lastLetter = -1;
|
||||
for (int i = 0; i < instruction.length(); i++) {
|
||||
char c = instruction.charAt(i);
|
||||
private fun parseCommand(instruction: StringBuilder): String {
|
||||
var firstLetter = -1
|
||||
var lastLetter = -1
|
||||
for (i in 0..instruction.length - 1) {
|
||||
val c = instruction[i]
|
||||
if (Character.isLetter(c)) {
|
||||
if (firstLetter == -1) {
|
||||
firstLetter = i;
|
||||
firstLetter = i
|
||||
}
|
||||
lastLetter = i;
|
||||
lastLetter = i
|
||||
}
|
||||
else if (isSpace(c)) {
|
||||
if (lastLetter > -1) {
|
||||
break;
|
||||
break
|
||||
}
|
||||
}
|
||||
else {
|
||||
break;
|
||||
break
|
||||
}
|
||||
}
|
||||
return firstLetter == -1 ? "" : instruction.substring(firstLetter, lastLetter + 1);
|
||||
return if (firstLetter == -1) "" else instruction.substring(firstLetter, lastLetter + 1)
|
||||
}
|
||||
|
||||
protected boolean charCmp(String buf, int index, String command) {
|
||||
return buf.regionMatches(index, command, 0, command.length());
|
||||
}
|
||||
protected fun charCmp(buf: String, index: Int, command: String) = buf.regionMatches(index, command, 0, command.length)
|
||||
|
||||
protected fun isSpace(c: Char) = c == ' ' || c == '\n' || c == '\t' || c == '\r'
|
||||
|
||||
protected boolean isSpace(char c) {
|
||||
return c == ' ' || c == '\n' || c == '\t' || c == '\r';
|
||||
}
|
||||
|
||||
protected boolean isQuote(char c) {
|
||||
return c == '\'' || c == '\"' || c == '`';
|
||||
}
|
||||
protected fun isQuote(c: Char) = c == '\'' || c == '\"' || c == '`'
|
||||
}
|
||||
Reference in New Issue
Block a user