package com.google.jstestdriver.idea.rt.util;
import com.google.common.collect.Lists;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.List;
/**
* @author Sergey Simonchik
*/
public class EscapeUtils {
private static final char ESCAPE_CHAR = '\\';
private EscapeUtils() {}
@NotNull
public static List<String> split(@NotNull String str, char delimiterChar) {
Splitter splitter = new Splitter(str, delimiterChar);
List<String> out = Lists.newArrayList();
while (splitter.hasNext()) {
out.add(splitter.next());
}
return out;
}
@NotNull
public static String join(@NotNull Collection<String> list, char delimiterChar) {
if (list.isEmpty()) {
return "";
}
int expectedSize = calcExpectedJoinedSize(list);
StringBuilder out = new StringBuilder(expectedSize);
boolean addDelimiter = false;
for (String str : list) {
if (addDelimiter) {
out.append(delimiterChar);
}
addDelimiter = true;
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if (ch == delimiterChar) {
out.append(ESCAPE_CHAR).append(delimiterChar);
} else if (ch == ESCAPE_CHAR) {
out.append(ESCAPE_CHAR).append(ESCAPE_CHAR);
} else {
out.append(ch);
}
}
}
return out.toString();
}
private static int calcExpectedJoinedSize(@NotNull Collection<String> list) {
int size = list.size() - 1;
for (String s : list) {
size += s.length();
}
return size;
}
private static class Splitter {
private final String myStr;
private final char myDelimiterChar;
private int myInd;
private final StringBuilder myBuffer = new StringBuilder();
private boolean myExtraEmptyString = false;
public Splitter(@NotNull String str, char delimiterChar) {
myStr = str;
myDelimiterChar = delimiterChar;
myInd = 0;
}
public boolean hasNext() {
return myExtraEmptyString || myInd < myStr.length();
}
public String next() {
if (myExtraEmptyString) {
myExtraEmptyString = false;
return "";
}
myBuffer.setLength(0);
while (myInd < myStr.length()) {
char ch = myStr.charAt(myInd);
if (ch == myDelimiterChar) {
myInd++;
myExtraEmptyString = myInd == myStr.length();
return myBuffer.toString();
}
if (ch == ESCAPE_CHAR) {
if (myInd + 1 >= myStr.length()) {
throw new RuntimeException("String ends with escape char: " + myStr);
}
char nextChar = myStr.charAt(myInd + 1);
if (nextChar == ESCAPE_CHAR || nextChar == myDelimiterChar) {
myBuffer.append(nextChar);
myInd += 2;
} else {
throw new RuntimeException("Unexpected char is escaped '" + nextChar + "' in " + myStr);
}
} else {
myBuffer.append(ch);
myInd++;
}
}
return myBuffer.toString();
}
}
}