package loon.utils;
import java.util.StringTokenizer;
import loon.BaseIO;
import loon.Bundle;
import loon.action.avg.drama.Expression;
import loon.action.map.Field2D;
/**
* 一个简单的多文本数据存储及读取用类,作用类似于ini文件
*
* 存储格式为:
* begin name = "key1"
* value1
* end
* begin name = "key2"
* value2
* end
*/
public class ConfigReader implements Expression, Bundle<String> {
private String FLAG_L_TAG = "//";
private String FLAG_C_TAG = "#";
private String FLAG_I_TAG = "'";
private final static ObjectMap<String, ConfigReader> pConfigReaders = new ObjectMap<String, ConfigReader>();
public static ConfigReader getInstance(final String path) {
synchronized (pConfigReaders) {
ConfigReader reader = pConfigReaders.get(path);
if (reader == null || reader.isClose) {
reader = new ConfigReader(path);
pConfigReaders.put(path, reader);
}
return reader;
}
}
private final ObjectMap<String, String> pConfigItems = new ObjectMap<String, String>();
private StringBuffer values = new StringBuffer();
private boolean isClose;
public ObjectMap<String, String> getContent() {
return new ObjectMap<String, String>(pConfigItems);
}
public ConfigReader(final String resName) {
parse(BaseIO.loadText(resName));
}
public void parse(final String text) {
StringTokenizer reader = new StringTokenizer(text, "\r\n");
String record = null;
StringBuffer mapBuffer = new StringBuffer();
boolean mapFlag = false;
String mapName = null;
for (; reader.hasMoreTokens();) {
record = reader.nextToken().trim();
if (record.length() > 0 && !record.startsWith(FLAG_L_TAG) && !record.startsWith(FLAG_C_TAG)
&& !record.startsWith(FLAG_I_TAG)) {
if (record.startsWith("begin")) {
mapBuffer.delete(0, mapBuffer.length());
String mes = record.substring(5, record.length()).trim();
if (mes.startsWith("name")) {
mapName = loadItem(mes, false);
}
mapFlag = true;
} else if (record.startsWith("end")) {
mapFlag = false;
if (mapName != null) {
pConfigItems.put(mapName, mapBuffer.toString());
}
} else if (mapFlag) {
mapBuffer.append(record);
} else {
loadItem(record, true);
}
}
}
}
private final String loadItem(final String mes, final boolean save) {
char[] chars = mes.toCharArray();
int size = chars.length;
StringBuffer sbr = values.delete(0, values.length());
String key = null;
String value = null;
int idx = 0;
int equals = 0;
for (int i = 0; i < size; i++) {
char flag = chars[i];
switch (flag) {
case '=':
if (equals < 3) {
equals++;
if (idx == 0) {
key = sbr.toString();
sbr.delete(0, sbr.length());
}
idx++;
}
break;
case '\'':
if (equals > 1) {
sbr.append(flag);
}
break;
case '\"':
equals++;
break;
default:
sbr.append(flag);
break;
}
}
if (key != null) {
value = sbr.toString();
if (save) {
pConfigItems.put(key.trim(), value.trim());
}
}
return value.trim();
}
public void putItem(String key, String value) {
synchronized (pConfigItems) {
pConfigItems.put(key, value);
}
}
public void removeItem(String key) {
synchronized (pConfigItems) {
pConfigItems.remove(key);
}
}
public boolean getBoolValue(String name) {
return getBoolValue(name, false);
}
public boolean getBoolValue(String name, boolean fallback) {
String v = null;
synchronized (pConfigItems) {
v = pConfigItems.get(name);
}
if (v == null) {
return fallback;
}
return StringUtils.toBoolean(v);
}
public int getIntValue(String name) {
return getIntValue(name, 0);
}
public int getIntValue(String name, int fallback) {
String v = null;
synchronized (pConfigItems) {
v = pConfigItems.get(name);
}
if (v == null) {
return fallback;
}
return Integer.parseInt(v);
}
public float getFloatValue(String name) {
return getFloatValue(name, 0f);
}
public float getFloatValue(String name, float fallback) {
String v = null;
synchronized (pConfigItems) {
v = pConfigItems.get(name);
}
if (v == null) {
return fallback;
}
return Float.parseFloat(v);
}
public String getValue(String name) {
return getValue(name, null);
}
public String getValue(String name, String fallback) {
String v = null;
synchronized (pConfigItems) {
v = pConfigItems.get(name);
}
if (v == null) {
return fallback;
}
return v;
}
public String get(String name) {
return getValue(name, null);
}
@Override
public void put(String key, String value) {
putItem(key, value);
}
@Override
public String get(String key, String defaultValue) {
return getValue(key, defaultValue);
}
@Override
public String remove(String key) {
String result = getValue(key);
removeItem(key);
return result;
}
@Override
public String remove(String key, String defaultValue) {
String result = getValue(key, defaultValue);
removeItem(key);
return result;
}
public Field2D getField2D(String name, int width, int height) {
return getField2D(name, width, height, null);
}
public Field2D getField2D(String name, int width, int height, Field2D fallback) {
int[][] arrays = getArray2D(name, fallback == null ? null : fallback.getMap());
if (arrays != null) {
return new Field2D(arrays, width, height);
}
return null;
}
public int[][] getArray2D(String name) {
return getArray2D(name, null);
}
public int[][] getArray2D(String name, int[][] fallback) {
String v = null;
synchronized (pConfigItems) {
v = pConfigItems.get(name);
}
if (v != null) {
boolean pFlag = false;
char[] chars = v.toCharArray();
int size = chars.length;
StringBuffer sbr = new StringBuffer(128);
TArray<int[]> records = new TArray<int[]>(CollectionUtils.INITIAL_CAPACITY);
for (int i = 0; i < size; i++) {
char pValue = chars[i];
switch (pValue) {
case '{':
pFlag = true;
break;
case '}':
pFlag = false;
String row = sbr.toString();
String[] strings = row.split(",");
int length = strings.length;
int[] arrays = new int[length];
for (int j = 0; j < length; j++) {
arrays[j] = Integer.parseInt(strings[j]);
}
records.add(arrays);
sbr.delete(0, sbr.length());
break;
case ' ':
break;
default:
if (pFlag) {
sbr.append(pValue);
}
break;
}
}
int col = records.size;
int[][] result = new int[col][];
for (int i = 0; i < col; i++) {
result[i] = records.get(i);
}
return result;
}
return fallback;
}
public boolean isClose() {
return isClose;
}
public void dispose() {
isClose = true;
if (pConfigItems != null) {
pConfigItems.clear();
}
}
}