squidpony.Converters Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of squidlib-util Show documentation
Show all versions of squidlib-util Show documentation
SquidLib platform-independent logic and utility code. Please refer to
https://github.com/SquidPony/SquidLib .
package squidpony;
import squidpony.squidmath.*;
import java.util.*;
/**
* Ways to produce concrete implementations of StringConvert for various data structures.
* Keeping the StringConvert producers separate from the data structures allows us to convert
* JDK types as well as to keep the parts that need ObText, and thus RegExodus, separate from
* the more general-use data structures.
* Created by Tommy Ettinger on 3/9/2017.
*/
@SuppressWarnings("unchecked")
public class Converters {
public static void appendQuoted(StringBuilder sb, String text)
{
ObText.appendQuoted(sb, text);
}
public static ObText.ContentMatcher makeMatcher(CharSequence text)
{
return ObText.makeMatcherNoComments(text);
}
public static StringConvert> convertOrderedSet(final StringConvert convert) {
CharSequence[] types = StringConvert.asArray("OrderedSet", convert.name);
StringConvert found = StringConvert.lookup(types);
if (found != null)
return found; // in this case we've already created a StringConvert for this type combination
return new StringConvert>(types) {
@Override
public String stringify(OrderedSet item) {
StringBuilder sb = new StringBuilder(100);
K k;
for (int i = 0; i < item.size(); ) {
k = item.getAt(i);
if (item == k)
return "";
ObText.appendQuoted(sb, convert.stringify(k));
if (++i < item.size())
sb.append(' ');
}
return sb.toString();
}
@Override
public OrderedSet restore(String text) {
ObText.ContentMatcher m = makeMatcher(text);
OrderedSet d;
if(convert.isArray)
d = new OrderedSet<>(CrossHash.generalHasher);
else
d = new OrderedSet<>();
while (m.find()) {
if (m.hasMatch()) {
d.add(convert.restore(m.getMatch()));
}
}
return d;
}
};
}
public static StringConvert> convertOrderedSet(final CharSequence type) {
return convertOrderedSet((StringConvert) StringConvert.get(type));
}
public static StringConvert> convertOrderedSet(final Class type) {
return convertOrderedSet((StringConvert) StringConvert.get(type.getSimpleName()));
}
public static StringConvert> convertUnorderedSet(final StringConvert convert) {
CharSequence[] types = StringConvert.asArray("UnorderedSet", convert.name);
StringConvert found = StringConvert.lookup(types);
if (found != null)
return found; // in this case we've already created a StringConvert for this type combination
return new StringConvert>(types) {
@Override
public String stringify(UnorderedSet item) {
StringBuilder sb = new StringBuilder(100);
int i = 0;
for (K k : item) {
if (item == k)
return "";
ObText.appendQuoted(sb, convert.stringify(k));
if (++i < item.size())
sb.append(' ');
}
return sb.toString();
}
@Override
public UnorderedSet restore(String text) {
ObText.ContentMatcher m = makeMatcher(text);
UnorderedSet d;
if(convert.isArray)
d = new UnorderedSet<>(CrossHash.generalHasher);
else
d = new UnorderedSet<>();
while (m.find()) {
if (m.hasMatch()) {
d.add(convert.restore(m.getMatch()));
}
}
return d;
}
};
}
public static StringConvert> convertUnorderedSet(final CharSequence type) {
return convertUnorderedSet((StringConvert) StringConvert.get(type));
}
public static StringConvert> convertUnorderedSet(final Class type) {
return convertUnorderedSet((StringConvert) StringConvert.get(type.getSimpleName()));
}
public static StringConvert> convertOrderedMap(final StringConvert convertK, final StringConvert convertV) {
CharSequence[] types = StringConvert.asArray("OrderedMap", convertK.name, convertV.name);
StringConvert found = StringConvert.lookup(types);
if (found != null)
return found; // in this case we've already created a StringConvert for this type combination
return new StringConvert>(types) {
@Override
public String stringify(OrderedMap item) {
StringBuilder sb = new StringBuilder(100);
K k;
V v;
for (int i = 0; i < item.size(); ) {
k = item.keyAt(i);
if (k == item)
return "";
appendQuoted(sb, convertK.stringify(k));
sb.append(' ');
v = item.getAt(i);
if (v == item)
return "";
appendQuoted(sb, convertV.stringify(v));
if (++i < item.size())
sb.append(' ');
}
return sb.toString();
}
@Override
public OrderedMap restore(String text) {
ObText.ContentMatcher m = makeMatcher(text);
OrderedMap d;
if(convertK.isArray)
d = new OrderedMap<>(CrossHash.generalHasher);
else
d = new OrderedMap<>();
String t;
while (m.find()) {
if (m.hasMatch()) {
t = m.getMatch();
if (m.find() && m.hasMatch()) {
d.put(convertK.restore(t), convertV.restore(m.getMatch()));
}
}
}
return d;
}
};
}
public static StringConvert> convertOrderedMap(final CharSequence typeK, final CharSequence typeV) {
return convertOrderedMap((StringConvert) StringConvert.get(typeK), (StringConvert) StringConvert.get(typeV));
}
public static StringConvert> convertOrderedMap(final Class typeK, final Class typeV) {
return convertOrderedMap((StringConvert) StringConvert.get(typeK.getSimpleName()),
(StringConvert) StringConvert.get(typeV.getSimpleName()));
}
public static StringConvert> convertUnorderedMap(final StringConvert convertK, final StringConvert convertV) {
CharSequence[] types = StringConvert.asArray("UnorderedMap", convertK.name, convertV.name);
StringConvert found = StringConvert.lookup(types);
if (found != null)
return found; // in this case we've already created a StringConvert for this type combination
return new StringConvert>(types) {
@Override
public String stringify(UnorderedMap item) {
StringBuilder sb = new StringBuilder(100);
K k;
V v;
Iterator> it = item.entrySet().iterator();
Map.Entry ent;
while (it.hasNext())
{
ent = it.next();
k = ent.getKey();
if (k == item)
return "";
appendQuoted(sb, convertK.stringify(k));
sb.append(' ');
v = ent.getValue();
if (v == item)
return "";
appendQuoted(sb, convertV.stringify(v));
if (it.hasNext())
sb.append(' ');
}
return sb.toString();
}
@Override
public UnorderedMap restore(String text) {
ObText.ContentMatcher m = makeMatcher(text);
UnorderedMap d;
if(convertK.isArray)
d = new UnorderedMap<>(CrossHash.generalHasher);
else
d = new UnorderedMap<>();
String t;
while (m.find()) {
if (m.hasMatch()) {
t = m.getMatch();
if (m.find() && m.hasMatch()) {
d.put(convertK.restore(t), convertV.restore(m.getMatch()));
}
}
}
return d;
}
};
}
public static StringConvert> convertUnorderedMap(final CharSequence typeK, final CharSequence typeV) {
return convertUnorderedMap((StringConvert) StringConvert.get(typeK), (StringConvert) StringConvert.get(typeV));
}
public static StringConvert> convertUnorderedMap(final Class typeK, final Class typeV) {
return convertUnorderedMap((StringConvert) StringConvert.get(typeK.getSimpleName()),
(StringConvert) StringConvert.get(typeV.getSimpleName()));
}
public static StringConvert> convertHashSet(final StringConvert convert) {
CharSequence[] types = StringConvert.asArray("HashSet", convert.name);
StringConvert found = StringConvert.lookup(types);
if (found != null)
return found; // in this case we've already created a StringConvert for this type combination
return new StringConvert>(types) {
@Override
public String stringify(HashSet item) {
StringBuilder sb = new StringBuilder(100);
Iterator it = item.iterator();
K k;
while (it.hasNext()){
k = it.next();
if (item == k)
return "";
ObText.appendQuoted(sb, convert.stringify(k));
if (it.hasNext())
sb.append(' ');
}
return sb.toString();
}
@Override
public HashSet restore(String text) {
ObText.ContentMatcher m = makeMatcher(text);
HashSet d = new HashSet<>();
while (m.find()) {
if (m.hasMatch()) {
d.add(convert.restore(m.getMatch()));
}
}
return d;
}
};
}
public static StringConvert> convertHashSet(final CharSequence type) {
return convertHashSet((StringConvert) StringConvert.get(type));
}
public static StringConvert> convertHashSet(final Class type) {
return convertHashSet((StringConvert) StringConvert.get(type.getSimpleName()));
}
public static StringConvert> convertHashMap(final StringConvert convertK, final StringConvert convertV) {
CharSequence[] types = StringConvert.asArray("HashMap", convertK.name, convertV.name);
StringConvert found = StringConvert.lookup(types);
if (found != null)
return found; // in this case we've already created a StringConvert for this type combination
return new StringConvert>(types) {
@Override
public String stringify(HashMap item) {
StringBuilder sb = new StringBuilder(100);
K k;
V v;
Iterator kit = item.keySet().iterator();
Iterator vit = item.values().iterator();
while (kit.hasNext()) {
k = kit.next();
if (k == item)
return "";
appendQuoted(sb, convertK.stringify(k));
sb.append(' ');
v = vit.next();
if (v == item)
return "";
appendQuoted(sb, convertV.stringify(v));
if (kit.hasNext())
sb.append(' ');
}
return sb.toString();
}
@Override
public HashMap restore(String text) {
ObText.ContentMatcher m = makeMatcher(text);
HashMap d = new HashMap<>();
String t;
while (m.find()) {
if (m.hasMatch()) {
t = m.getMatch();
if (m.find() && m.hasMatch()) {
d.put(convertK.restore(t), convertV.restore(m.getMatch()));
}
}
}
return d;
}
};
}
public static StringConvert> convertHashMap(final CharSequence typeK, final CharSequence typeV) {
return convertHashMap((StringConvert) StringConvert.get(typeK), (StringConvert) StringConvert.get(typeV));
}
public static StringConvert> convertHashMap(final Class typeK, final Class typeV) {
return convertHashMap((StringConvert) StringConvert.get(typeK.getSimpleName()),
(StringConvert) StringConvert.get(typeV.getSimpleName()));
}
public static StringConvert> convertArrangement(final StringConvert convert) {
CharSequence[] types = StringConvert.asArray("Arrangement", convert.name);
StringConvert found = StringConvert.lookup(types);
if (found != null)
return found; // in this case we've already created a StringConvert for this type combination
return new StringConvert>(types) {
@Override
public String stringify(Arrangement item) {
StringBuilder sb = new StringBuilder(100);
K k;
for (int i = 0; i < item.size(); ) {
k = item.keyAt(i);
if (item == k)
return "";
ObText.appendQuoted(sb, convert.stringify(k));
if (++i < item.size())
sb.append(' ');
}
return sb.toString();
}
@Override
public Arrangement restore(String text) {
ObText.ContentMatcher m = makeMatcher(text);
Arrangement d;
if(convert.isArray)
d = new Arrangement<>(CrossHash.generalHasher);
else
d = new Arrangement<>();
while (m.find()) {
if (m.hasMatch()) {
d.add(convert.restore(m.getMatch()));
}
}
return d;
}
};
}
public static StringConvert> convertArrangement(final CharSequence type) {
return convertArrangement((StringConvert) StringConvert.get(type));
}
public static StringConvert> convertArrangement(final Class type) {
return convertArrangement((StringConvert) StringConvert.get(type.getSimpleName()));
}
public static StringConvert> convertArrayList(final StringConvert convert) {
CharSequence[] types = StringConvert.asArray("ArrayList", convert.name);
StringConvert found = StringConvert.lookup(types);
if (found != null)
return found; // in this case we've already created a StringConvert for this type combination
return new StringConvert>(types) {
@Override
public String stringify(ArrayList item) {
StringBuilder sb = new StringBuilder(100);
K k;
for (int i = 0; i < item.size(); ) {
k = item.get(i);
if (item == k)
return "";
appendQuoted(sb, convert.stringify(k));
if (++i < item.size())
sb.append(' ');
}
return sb.toString();
}
@Override
public ArrayList restore(String text) {
ObText.ContentMatcher m = makeMatcher(text);
ArrayList d = new ArrayList<>();
while (m.find()) {
if (m.hasMatch()) {
d.add(convert.restore(m.getMatch()));
}
}
return d;
}
};
}
public static StringConvert> convertArrayList(final CharSequence type) {
return convertArrayList((StringConvert) StringConvert.get(type));
}
public static StringConvert> convertArrayList(final Class type) {
return convertArrayList((StringConvert) StringConvert.get(type.getSimpleName()));
}
public static StringConvert> convertList(final StringConvert convert) {
CharSequence[] types = StringConvert.asArray("List", convert.name);
StringConvert found = StringConvert.lookup(types);
if (found != null)
return found; // in this case we've already created a StringConvert for this type combination
return new StringConvert>(types) {
@Override
public String stringify(List item) {
StringBuilder sb = new StringBuilder(100);
K k;
for (int i = 0; i < item.size(); ) {
k = item.get(i);
if (item == k)
return "";
appendQuoted(sb, convert.stringify(k));
if (++i < item.size())
sb.append(' ');
}
return sb.toString();
}
@Override
public ArrayList restore(String text) {
ObText.ContentMatcher m = makeMatcher(text);
ArrayList d = new ArrayList<>();
while (m.find()) {
if (m.hasMatch()) {
d.add(convert.restore(m.getMatch()));
}
}
return d;
}
};
}
public static StringConvert> convertList(final CharSequence type) {
return convertList((StringConvert) StringConvert.get(type));
}
public static StringConvert> convertList(final Class type) {
return convertList((StringConvert) StringConvert.get(type.getSimpleName()));
}
public static final StringConvert convertCoord = new StringConvert("Coord") {
@Override
public String stringify(Coord item) {
if(item == null) return "n";
return item.x + "," + item.y;
}
@Override
public Coord restore(String text) {
if(text == null || text.equals("n")) return null;
return Coord.get(StringKit.intFromDec(text), StringKit.intFromDec(text, text.indexOf(',') + 1, text.length()));
}
};
public static final StringConvert convertArrayCoord = new StringConvert(true,"Coord[]") {
@Override
public String stringify(Coord[] item) {
if(item == null)
return "N";
int len = item.length;
StringBuilder sb = new StringBuilder(len * 5);
for (int i = 0; i < len; ) {
if(item[i] == null)
sb.append('n');
else
sb.append(item[i].x).append(',').append(item[i].y);
if (++i < len)
sb.append(';');
}
return sb.toString();
}
@Override
public Coord[] restore(String text) {
if(text == null || text.equals("N"))
return null;
Coord[] coords = new Coord[StringKit.count(text, ';') + 1];
int start = -1, end = text.indexOf(',');
for (int i = 0; i < coords.length; i++) {
if(text.charAt(start+1) == 'n') {
coords[i] = null;
start = text.indexOf(';', end + 1);
}
else
coords[i] = Coord.get(StringKit.intFromDec(text, start + 1, end),
StringKit.intFromDec(text, end + 1, (start = text.indexOf(';', end + 1))));
end = text.indexOf(',', start + 1);
}
return coords;
}
};
public static final StringConvert convertGreasedRegion = new StringConvert("GreasedRegion") {
@Override
public String stringify(GreasedRegion item) {
return item.serializeToString();
}
@Override
public GreasedRegion restore(String text) {
return GreasedRegion.deserializeFromString(text);
}
};
public static final StringConvert convertIntVLA = new StringConvert("IntVLA") {
@Override
public String stringify(IntVLA item) {
return item.toString(",");
}
@Override
public IntVLA restore(String text) {
return IntVLA.deserializeFromString(text);
}
};
public static final StringConvert convertFakeLanguageGen = new StringConvert("FakeLanguageGen")
{
@Override
public String stringify(FakeLanguageGen item) {
return item.serializeToString();
}
@Override
public FakeLanguageGen restore(String text) {
return FakeLanguageGen.deserializeFromString(text);
}
};
public static final StringConvert convertSentenceForm = new StringConvert("FakeLanguageGen$SentenceForm")
{
@Override
public String stringify(FakeLanguageGen.SentenceForm item) {
return item.serializeToString();
}
@Override
public FakeLanguageGen.SentenceForm restore(String text) {
return FakeLanguageGen.SentenceForm.deserializeFromString(text);
}
};
public static final StringConvert convertMarkovText = new StringConvert("MarkovTextLimited")
{
@Override
public String stringify(MarkovTextLimited item) {
return item.serializeToString();
}
@Override
public MarkovTextLimited restore(String text) {
return MarkovTextLimited.deserializeFromString(text);
}
};
public static final StringConvert convertObText = new StringConvert("ObText") {
@Override
public String stringify(ObText item) {
return item.serializeToString();
}
@Override
public ObText restore(String text) {
return ObText.deserializeFromString(text);
}
};
public static final StringConvert convertWeightedTable = new StringConvert("WeightedTable") {
@Override
public String stringify(WeightedTable item) {
return item.serializeToString();
}
@Override
public WeightedTable restore(String text) {
return WeightedTable.deserializeFromString(text);
}
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////// CORE JDK TYPES, PRIMITIVES, AND PRIMITIVE ARRAYS ARE THE ONLY TYPES AFTER THIS POINT
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Simple implementation to help when passing StringConverts around with data that is already a String.
*/
public static final StringConvert convertString = new StringConvert("String") {
@Override
public String stringify(String item) {
return item;
}
@Override
public String restore(String text) {
return text;
}
};
public static final StringConvert convertBoolean = new StringConvert("Boolean") {
@Override
public String stringify(Boolean item) {
return item == null ? "n" : item ? "1" : "0";
}
@Override
public Boolean restore(String text) {
char c;
return (text == null || text.isEmpty() || (c = text.charAt(0)) == 'n') ? null : c == '1';
}
};
public static final StringConvert convertByte = new StringConvert("Byte") {
@Override
public String stringify(Byte item) {
return item.toString();
}
@Override
public Byte restore(String text) {
return Byte.decode(text);
}
};
public static final StringConvert convertShort = new StringConvert("Short") {
@Override
public String stringify(Short item) {
return item.toString();
}
@Override
public Short restore(String text) {
return Short.decode(text);
}
};
public static final StringConvert convertInt = new StringConvert("Integer") {
@Override
public String stringify(Integer item) {
return item.toString();
}
@Override
public Integer restore(String text) {
return Integer.decode(text);
}
};
public static final StringConvert convertLong = new StringConvert("Long") {
@Override
public String stringify(Long item) {
return item.toString();
}
@Override
public Long restore(String text) {
return Long.decode(text);
}
};
public static final StringConvert convertFloat = new StringConvert("Float") {
@Override
public String stringify(Float item) {
return item.toString();
}
@Override
public Float restore(String text) {
return Float.parseFloat(text);
}
};
public static final StringConvert convertDouble = new StringConvert("Double") {
@Override
public String stringify(Double item) {
return item.toString();
}
@Override
public Double restore(String text) {
return Double.parseDouble(text);
}
};
public static final StringConvert convertChar = new StringConvert("Character") {
@Override
public String stringify(Character item) {
return item.toString();
}
@Override
public Character restore(String text) {
return text.charAt(0);
}
};
public static final StringConvert convertArrayBoolean = new StringConvert(true,"boolean[]") {
@Override
public String stringify(boolean[] item) {
return StringKit.joinAlt(item);
}
@Override
public boolean[] restore(String text) {
if(text == null || text.equals("N")) return null;
int amount = text.length();
if (amount <= 0) return new boolean[0];
boolean[] splat = new boolean[amount];
for (int i = 0; i < amount; i++) {
splat[amount] = text.charAt(i) == '1';
}
return splat;
}
};
public static final StringConvert convertArrayByte = new StringConvert(true,"byte[]") {
@Override
public String stringify(byte[] item) {
if(item == null) return "N";
return StringKit.join(",", item);
}
@Override
public byte[] restore(String text) {
if(text == null || text.equals("N")) return null;
int amount = StringKit.count(text, ",");
if (amount <= 0) return new byte[]{Byte.decode(text)};
byte[] splat = new byte[amount + 1];
int dl = 1, idx = -dl, idx2;
for (int i = 0; i < amount; i++) {
splat[i] = Byte.decode(StringKit.safeSubstring(text, idx + dl, idx = text.indexOf(',', idx + dl)));
}
if ((idx2 = text.indexOf(',', idx + dl)) < 0) {
splat[amount] = Byte.decode(StringKit.safeSubstring(text, idx + dl, text.length()));
} else {
splat[amount] = Byte.decode(StringKit.safeSubstring(text, idx + dl, idx2));
}
return splat;
}
};
public static final StringConvert convertArrayShort = new StringConvert(true,"short[]") {
@Override
public String stringify(short[] item) {
if(item == null) return "N";
return StringKit.join(",", item);
}
@Override
public short[] restore(String text) {
if(text == null || text.equals("N")) return null;
int amount = StringKit.count(text, ",");
if (amount <= 0) return new short[]{Short.decode(text)};
short[] splat = new short[amount + 1];
int dl = 1, idx = -dl, idx2;
for (int i = 0; i < amount; i++) {
splat[i] = Short.decode(StringKit.safeSubstring(text, idx + dl, idx = text.indexOf(',', idx + dl)));
}
if ((idx2 = text.indexOf(',', idx + dl)) < 0) {
splat[amount] = Short.decode(StringKit.safeSubstring(text, idx + dl, text.length()));
} else {
splat[amount] = Short.decode(StringKit.safeSubstring(text, idx + dl, idx2));
}
return splat;
}
};
public static final StringConvert convertArrayInt = new StringConvert(true,"int[]") {
@Override
public String stringify(int[] item) {
if(item == null) return "N";
return StringKit.join(",", item);
}
@Override
public int[] restore(String text) {
if(text == null || text.equals("N")) return null;
int amount = StringKit.count(text, ",");
if (amount <= 0) return new int[]{Integer.decode(text)};
int[] splat = new int[amount + 1];
int dl = 1, idx = -dl, idx2;
for (int i = 0; i < amount; i++) {
splat[i] = Integer.decode(StringKit.safeSubstring(text, idx + dl, idx = text.indexOf(',', idx + dl)));
}
if ((idx2 = text.indexOf(',', idx + dl)) < 0) {
splat[amount] = Integer.decode(StringKit.safeSubstring(text, idx + dl, text.length()));
} else {
splat[amount] = Integer.decode(StringKit.safeSubstring(text, idx + dl, idx2));
}
return splat;
}
};
public static final StringConvert convertArrayLong = new StringConvert(true,"long[]") {
@Override
public String stringify(long[] item) {
if(item == null) return "N";
return StringKit.join(",", item);
}
@Override
public long[] restore(String text) {
if(text == null || text.equals("N")) return null;
int amount = StringKit.count(text, ",");
if (amount <= 0) return new long[]{Long.decode(text)};
long[] splat = new long[amount + 1];
int dl = 1, idx = -dl, idx2;
for (int i = 0; i < amount; i++) {
splat[i] = Long.decode(StringKit.safeSubstring(text, idx + dl, idx = text.indexOf(',', idx + dl)));
}
if ((idx2 = text.indexOf(',', idx + dl)) < 0) {
splat[amount] = Long.decode(StringKit.safeSubstring(text, idx + dl, text.length()));
} else {
splat[amount] = Long.decode(StringKit.safeSubstring(text, idx + dl, idx2));
}
return splat;
}
};
public static final StringConvert convertArrayFloat = new StringConvert(true,"float[]") {
@Override
public String stringify(float[] item) {
if(item == null) return "N";
return StringKit.join(",", item);
}
@Override
public float[] restore(String text) {
if(text == null || text.equals("N")) return null;
int amount = StringKit.count(text, ",");
if (amount <= 0) return new float[]{Float.parseFloat(text)};
float[] splat = new float[amount + 1];
int dl = 1, idx = -dl, idx2;
for (int i = 0; i < amount; i++) {
splat[i] = Float.parseFloat(StringKit.safeSubstring(text, idx + dl, idx = text.indexOf(',', idx + dl)));
}
if ((idx2 = text.indexOf(',', idx + dl)) < 0) {
splat[amount] = Float.parseFloat(StringKit.safeSubstring(text, idx + dl, text.length()));
} else {
splat[amount] = Float.parseFloat(StringKit.safeSubstring(text, idx + dl, idx2));
}
return splat;
}
};
public static final StringConvert convertArrayDouble = new StringConvert(true,"double[]") {
@Override
public String stringify(double[] item) {
if(item == null) return "N";
return StringKit.join(",", item);
}
@Override
public double[] restore(String text) {
if(text == null || text.equals("N")) return null;
int amount = StringKit.count(text, ",");
if (amount <= 0) return new double[]{Double.parseDouble(text)};
double[] splat = new double[amount + 1];
int dl = 1, idx = -dl, idx2;
for (int i = 0; i < amount; i++) {
splat[i] = Double.parseDouble(StringKit.safeSubstring(text, idx + dl, idx = text.indexOf(',', idx + dl)));
}
if ((idx2 = text.indexOf(',', idx + dl)) < 0) {
splat[amount] = Double.parseDouble(StringKit.safeSubstring(text, idx + dl, text.length()));
} else {
splat[amount] = Double.parseDouble(StringKit.safeSubstring(text, idx + dl, idx2));
}
return splat;
}
};
public static final StringConvert convertArrayChar = new StringConvert(true,"char[]") {
@Override
public String stringify(char[] item) {
if(item == null) return "";
return String.valueOf(item);
}
@Override
public char[] restore(String text) {
return text.toCharArray();
}
};
public static final StringConvert convertArrayBoolean2D = new StringConvert(true, "boolean[][]") {
@Override
public String stringify(boolean[][] item) {
if(item == null)
return "N";
int len;
if((len = item.length) <= 0)
return "";
StringBuilder sb = new StringBuilder(len * 128);
if(item[0] == null)
sb.append('n');
else
sb.append(StringKit.joinAlt(item[0]));
for (int i = 1; i < len; i++) {
if(item[i] == null)
sb.append(";n");
else
sb.append(';').append(StringKit.joinAlt(item[i]));
}
return sb.toString();
}
@Override
public boolean[][] restore(String text) {
if(text == null) return null;
int len;
if((len = text.length()) <= 0) return new boolean[0][0];
if(text.charAt(0) == 'N') return null;
int width = StringKit.count(text, ';')+1;
boolean[][] val = new boolean[width][];
int start = 0, end = text.indexOf(';');
for (int i = 0; i < width; i++) {
if(start == end || start >= len) val[i] = new boolean[0];
else if(text.charAt(start) == 'n') val[i] = null;
else {
int amount = end - start;
val[i] = new boolean[amount];
for (int j = 0; j < amount; j++) {
val[i][j] = text.charAt(start + j) == '1';
}
}
start = end+1;
end = text.indexOf(';', start);
}
return val;
}
};
public static final StringConvert convertArrayByte2D = new StringConvert(true, "byte[][]") {
@Override
public String stringify(byte[][] item) {
if(item == null)
return "N";
int len;
if((len = item.length) <= 0)
return "";
StringBuilder sb = new StringBuilder(len * 128);
if(item[0] == null)
sb.append('n');
else
sb.append(StringKit.join(",", item[0]));
for (int i = 1; i < len; i++) {
if(item[i] == null)
sb.append(";n");
else
sb.append(';').append(StringKit.join(",", item[i]));
}
return sb.toString();
}
@Override
public byte[][] restore(String text) {
if(text == null) return null;
int len;
if((len = text.length()) <= 0) return new byte[0][0];
if(text.charAt(0) == 'N') return null;
int width = StringKit.count(text, ';')+1;
byte[][] val = new byte[width][];
int start = 0, end = text.indexOf(';');
for (int i = 0; i < width; i++) {
if(start == end || start >= len) val[i] = new byte[0];
else if(text.charAt(start) == 'n') val[i] = null;
else {
int amount = StringKit.count(text, ",", start, end);
if (amount <= 0){
val[i] = new byte[]{Byte.decode(text)};
continue;
}
val[i] = new byte[amount + 1];
int dl = 1, idx = start - dl, idx2;
for (int j = 0; j < amount; j++) {
val[i][j] = Byte.decode(StringKit.safeSubstring(text, idx + dl, idx = text.indexOf(',', idx + dl)));
}
if ((idx2 = text.indexOf(',', idx + dl)) < 0) {
val[i][amount] = Byte.decode(StringKit.safeSubstring(text, idx + dl, text.length()));
} else if(idx2 < end){
val[i][amount] = Byte.decode(StringKit.safeSubstring(text, idx + dl, idx2));
} else {
val[i][amount] = Byte.decode(StringKit.safeSubstring(text, idx + dl, end));
}
}
start = end+1;
end = text.indexOf(';', start);
}
return val;
}
};
public static final StringConvert convertArrayShort2D = new StringConvert(true, "short[][]") {
@Override
public String stringify(short[][] item) {
if(item == null)
return "N";
int len;
if((len = item.length) <= 0)
return "";
StringBuilder sb = new StringBuilder(len * 128);
if(item[0] == null)
sb.append('n');
else
sb.append(StringKit.join(",", item[0]));
for (int i = 1; i < len; i++) {
if(item[i] == null)
sb.append(";n");
else
sb.append(';').append(StringKit.join(",", item[i]));
}
return sb.toString();
}
@Override
public short[][] restore(String text) {
if(text == null) return null;
int len;
if((len = text.length()) <= 0) return new short[0][0];
if(text.charAt(0) == 'N') return null;
int width = StringKit.count(text, ';')+1;
short[][] val = new short[width][];
int start = 0, end = text.indexOf(';');
for (int i = 0; i < width; i++) {
if(start == end || start >= len) val[i] = new short[0];
else if(text.charAt(start) == 'n') val[i] = null;
else {
int amount = StringKit.count(text, ",", start, end);
if (amount <= 0){
val[i] = new short[]{Short.decode(text)};
continue;
}
val[i] = new short[amount + 1];
int dl = 1, idx = start - dl, idx2;
for (int j = 0; j < amount; j++) {
val[i][j] = Short.decode(StringKit.safeSubstring(text, idx + dl, idx = text.indexOf(',', idx + dl)));
}
if ((idx2 = text.indexOf(',', idx + dl)) < 0) {
val[i][amount] = Short.decode(StringKit.safeSubstring(text, idx + dl, text.length()));
} else if(idx2 < end){
val[i][amount] = Short.decode(StringKit.safeSubstring(text, idx + dl, idx2));
} else {
val[i][amount] = Short.decode(StringKit.safeSubstring(text, idx + dl, end));
}
}
start = end+1;
end = text.indexOf(';', start);
}
return val;
}
};
public static final StringConvert convertArrayInt2D = new StringConvert(true, "int[][]") {
@Override
public String stringify(int[][] item) {
if(item == null)
return "N";
int len;
if((len = item.length) <= 0)
return "";
StringBuilder sb = new StringBuilder(len * 128);
if(item[0] == null)
sb.append('n');
else
sb.append(StringKit.join(",", item[0]));
for (int i = 1; i < len; i++) {
if(item[i] == null)
sb.append(";n");
else
sb.append(';').append(StringKit.join(",", item[i]));
}
return sb.toString();
}
@Override
public int[][] restore(String text) {
if(text == null) return null;
int len;
if((len = text.length()) <= 0) return new int[0][0];
if(text.charAt(0) == 'N') return null;
int width = StringKit.count(text, ';')+1;
int[][] val = new int[width][];
int start = 0, end = text.indexOf(';');
for (int i = 0; i < width; i++) {
if(start == end || start >= len) val[i] = new int[0];
else if(text.charAt(start) == 'n') val[i] = null;
else {
int amount = StringKit.count(text, ",", start, end);
if (amount <= 0){
val[i] = new int[]{Integer.decode(text)};
continue;
}
val[i] = new int[amount + 1];
int dl = 1, idx = start - dl, idx2;
for (int j = 0; j < amount; j++) {
val[i][j] = Integer.decode(StringKit.safeSubstring(text, idx + dl, idx = text.indexOf(',', idx + dl)));
}
if ((idx2 = text.indexOf(',', idx + dl)) < 0) {
val[i][amount] = Integer.decode(StringKit.safeSubstring(text, idx + dl, text.length()));
} else if(idx2 < end){
val[i][amount] = Integer.decode(StringKit.safeSubstring(text, idx + dl, idx2));
} else {
val[i][amount] = Integer.decode(StringKit.safeSubstring(text, idx + dl, end));
}
}
start = end+1;
end = text.indexOf(';', start);
}
return val;
}
};
public static final StringConvert convertArrayLong2D = new StringConvert(true, "long[][]") {
@Override
public String stringify(long[][] item) {
if(item == null)
return "N";
int len;
if((len = item.length) <= 0)
return "";
StringBuilder sb = new StringBuilder(len * 128);
if(item[0] == null)
sb.append('n');
else
sb.append(StringKit.join(",", item[0]));
for (int i = 1; i < len; i++) {
if(item[i] == null)
sb.append(";n");
else
sb.append(';').append(StringKit.join(",", item[i]));
}
return sb.toString();
}
@Override
public long[][] restore(String text) {
if(text == null) return null;
int len;
if((len = text.length()) <= 0) return new long[0][0];
if(text.charAt(0) == 'N') return null;
int width = StringKit.count(text, ';')+1;
long[][] val = new long[width][];
int start = 0, end = text.indexOf(';');
for (int i = 0; i < width; i++) {
if(start == end || start >= len) val[i] = new long[0];
else if(text.charAt(start) == 'n') val[i] = null;
else {
int amount = StringKit.count(text, ",", start, end);
if (amount <= 0){
val[i] = new long[]{Long.decode(text)};
continue;
}
val[i] = new long[amount + 1];
int dl = 1, idx = start - dl, idx2;
for (int j = 0; j < amount; j++) {
val[i][j] = Long.decode(StringKit.safeSubstring(text, idx + dl, idx = text.indexOf(',', idx + dl)));
}
if ((idx2 = text.indexOf(',', idx + dl)) < 0) {
val[i][amount] = Long.decode(StringKit.safeSubstring(text, idx + dl, text.length()));
} else if(idx2 < end){
val[i][amount] = Long.decode(StringKit.safeSubstring(text, idx + dl, idx2));
} else {
val[i][amount] = Long.decode(StringKit.safeSubstring(text, idx + dl, end));
}
}
start = end+1;
end = text.indexOf(';', start);
}
return val;
}
};
public static final StringConvert convertArrayFloat2D = new StringConvert(true, "float[][]") {
@Override
public String stringify(float[][] item) {
if(item == null)
return "N";
int len;
if((len = item.length) <= 0)
return "";
StringBuilder sb = new StringBuilder(len * 128);
if(item[0] == null)
sb.append('n');
else
sb.append(StringKit.join(",", item[0]));
for (int i = 1; i < len; i++) {
if(item[i] == null)
sb.append(";n");
else
sb.append(';').append(StringKit.join(",", item[i]));
}
return sb.toString();
}
@Override
public float[][] restore(String text) {
if(text == null) return null;
int len;
if((len = text.length()) <= 0) return new float[0][0];
if(text.charAt(0) == 'N') return null;
int width = StringKit.count(text, ';')+1;
float[][] val = new float[width][];
int start = 0, end = text.indexOf(';');
for (int i = 0; i < width; i++) {
if(start == end || start >= len) val[i] = new float[0];
else if(text.charAt(start) == 'n') val[i] = null;
else {
int amount = StringKit.count(text, ",", start, end);
if (amount <= 0){
val[i] = new float[]{Float.parseFloat(text)};
continue;
}
val[i] = new float[amount + 1];
int dl = 1, idx = start - dl, idx2;
for (int j = 0; j < amount; j++) {
val[i][j] = Float.parseFloat(StringKit.safeSubstring(text, idx + dl, idx = text.indexOf(',', idx + dl)));
}
if ((idx2 = text.indexOf(',', idx + dl)) < 0) {
val[i][amount] = Float.parseFloat(StringKit.safeSubstring(text, idx + dl, text.length()));
} else if(idx2 < end){
val[i][amount] = Float.parseFloat(StringKit.safeSubstring(text, idx + dl, idx2));
} else {
val[i][amount] = Float.parseFloat(StringKit.safeSubstring(text, idx + dl, end));
}
}
start = end+1;
end = text.indexOf(';', start);
}
return val;
}
};
public static final StringConvert convertArrayDouble2D = new StringConvert(true, "double[][]") {
@Override
public String stringify(double[][] item) {
if(item == null)
return "N";
int len;
if((len = item.length) <= 0)
return "";
StringBuilder sb = new StringBuilder(len * 128);
if(item[0] == null)
sb.append('n');
else
sb.append(StringKit.join(",", item[0]));
for (int i = 1; i < len; i++) {
if(item[i] == null)
sb.append(";n");
else
sb.append(';').append(StringKit.join(",", item[i]));
}
return sb.toString();
}
@Override
public double[][] restore(String text) {
if(text == null) return null;
int len;
if((len = text.length()) <= 0) return new double[0][0];
if(text.charAt(0) == 'N') return null;
int width = StringKit.count(text, ';')+1;
double[][] val = new double[width][];
int start = 0, end = text.indexOf(';');
for (int i = 0; i < width; i++) {
if(start == end || start >= len) val[i] = new double[0];
else if(text.charAt(start) == 'n') val[i] = null;
else {
int amount = StringKit.count(text, ",", start, end);
if (amount <= 0){
val[i] = new double[]{Double.parseDouble(text)};
continue;
}
val[i] = new double[amount + 1];
int dl = 1, idx = start - dl, idx2;
for (int j = 0; j < amount; j++) {
val[i][j] = Double.parseDouble(StringKit.safeSubstring(text, idx + dl, idx = text.indexOf(',', idx + dl)));
}
if ((idx2 = text.indexOf(',', idx + dl)) < 0) {
val[i][amount] = Double.parseDouble(StringKit.safeSubstring(text, idx + dl, text.length()));
} else if(idx2 < end){
val[i][amount] = Double.parseDouble(StringKit.safeSubstring(text, idx + dl, idx2));
} else {
val[i][amount] = Double.parseDouble(StringKit.safeSubstring(text, idx + dl, end));
}
}
start = end+1;
end = text.indexOf(';', start);
}
return val;
}
};
public static final StringConvert convertArrayChar2D = new StringConvert(true, "char[][]") {
@Override
public String stringify(char[][] item) {
int len, l2, sum;
if (item == null) return "N"; // N for null
if((len = item.length) <= 0) return "R0|0|";
sum = l2 = item[0].length;
char regular = 'R'; // R for rectangular
for (int i = 1; i < len; i++) {
if(item[i] == null)
{
regular = 'J'; // J for jagged
}
else if(l2 != (l2 = item[i].length))
{
regular = 'J'; // J for jagged
sum += l2;
}
}
StringBuilder sb;
if(regular == 'R')
{
sb = new StringBuilder(len * l2 + 15);
sb.append('R').append(len).append('|').append(l2).append('|');
for (int i = 0; i < len; i++) {
sb.append(item[i]);
}
}
else
{
sb = new StringBuilder(len * 7 + sum + 8);
sb.append('J').append(len).append('|');
for (int i = 0; i < len; i++) {
if(item[i] == null)
sb.append("-|");
else
sb.append(item[i].length).append('|').append(item[i]);
}
}
return sb.toString();
}
@Override
public char[][] restore(String text) {
if(text == null || text.length() <= 1) return null;
if(text.charAt(0) == 'R')
{
int width, height, start = 1, end = text.indexOf('|');
width = StringKit.intFromDec(text, start, end);
start = end+1;
end = text.indexOf('|', start);
height = StringKit.intFromDec(text, start, end);
start = end+1;
char[][] val = new char[width][height];
for (int i = 0; i < width; i++) {
text.getChars(start, start += height, val[i], 0);
}
return val;
}
else
{
int width, current, start = 1, end = text.indexOf('|');
width = StringKit.intFromDec(text, start, end);
start = end + 1;
char[][] val = new char[width][];
for (int i = 0; i < width; i++) {
end = text.indexOf('|', start);
if (text.charAt(start) == '-') {
val[i] = null;
start = end + 1;
} else {
current = StringKit.intFromDec(text, start, end);
start = end + 1;
val[i] = new char[current];
text.getChars(start, start += current, val[i], 0);
}
}
return val;
}
}
};
}