/**
* Copyright (c) 2010-2017 by the respective copyright holders.
*
* 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
*/
package org.openhab.binding.modbus.internal;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.StringEscapeUtils;
/**
* String tokenizer for splitting strings. Understands quoting and escaped quotes.
*
* See tests for details
*
* @author Sami Salonen
* @since 1.10.0
*
*/
public class SimpleTokenizer {
private final char delimiter;
public SimpleTokenizer(char delimiter) {
this.delimiter = delimiter;
}
public List<String> parse(String itemConfig) {
boolean insideQuotes = false;
boolean escaping = false;
List<String> tokens = new ArrayList<>();
StringBuilder currentToken = new StringBuilder(itemConfig.length());
for (int i = 0; i <= itemConfig.length(); i++) {
if (i == itemConfig.length()) {
// We have the read the full string, store the final token
tokens.add(getToken(currentToken));
break;
}
char currentChar = itemConfig.charAt(i);
boolean currentIsQuote = currentChar == '\"';
if (currentChar == delimiter) {
if (insideQuotes) {
currentToken.append(currentChar);
} else if (!insideQuotes) {
tokens.add(getToken(currentToken));
currentToken.delete(0, currentToken.length());
escaping = false;
}
} else if (currentChar == '\\') {
escaping = true;
currentToken.append(currentChar);
} else if (currentIsQuote) {
if (!escaping) {
insideQuotes = !insideQuotes;
} else {
escaping = false;
}
currentToken.append(currentChar);
} else {
escaping = false;
currentToken.append(currentChar);
}
}
return tokens;
}
private String getToken(StringBuilder currentToken) {
String token;
if (currentToken.length() > 0 && currentToken.charAt(0) == '\"') {
if (currentToken.charAt(currentToken.length() - 1) == '\"') {
token = StringEscapeUtils.unescapeJava(currentToken.toString().substring(1, currentToken.length() - 1));
} else {
// String started with a quote but did not end with one
// basically we have invalid quoting. Let's just pass string as is then
token = StringEscapeUtils.unescapeJava(currentToken.toString());
}
} else {
// token is empty or does not start with a quote
token = currentToken.toString();
}
return token;
}
}