You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
619 lines
20 KiB
619 lines
20 KiB
using System;
|
|
using System.Text;
|
|
using System.Linq;
|
|
using System.Collections.Generic;
|
|
using LitJson;
|
|
using Newtonsoft.Json.Linq;
|
|
|
|
|
|
namespace Sog
|
|
{
|
|
public class TabBinFile
|
|
{
|
|
private string FileName;
|
|
private string[] Titles;
|
|
private string[] Types;
|
|
private Dictionary<string, int> m_titleIndex;
|
|
|
|
|
|
private int LineLength;
|
|
private int LineCount;
|
|
private int[] LinePosList;
|
|
private int[] ColPosList;
|
|
private int ColCount;
|
|
|
|
private byte[] m_bodyBlock; // 除去头部的两行的 content;
|
|
private List<byte> m_stringBlock;
|
|
|
|
private string m_splitFlag = "*$*";
|
|
private int headerLength;
|
|
|
|
private int CurrentColIndex = 0;
|
|
public int CurrentLine { get; private set; }
|
|
|
|
|
|
public TabBinFile(string strFileName, byte[] content)
|
|
{
|
|
FileName = strFileName;
|
|
|
|
GetHeader(content);
|
|
|
|
int bodyLen = LineCount * LineLength;
|
|
m_bodyBlock = content.Skip(4 + headerLength).Take(bodyLen).ToArray();
|
|
m_stringBlock = content.Skip(4 + headerLength + bodyLen).Take(content.Length - (4 + headerLength + bodyLen))
|
|
.ToArray().ToList();
|
|
|
|
ColCount = Titles.Length;
|
|
|
|
SetPos();
|
|
Begin();
|
|
}
|
|
|
|
public void Begin()
|
|
{
|
|
CurrentLine = -1;
|
|
}
|
|
|
|
public bool Next()
|
|
{
|
|
CurrentLine++;
|
|
if (CurrentLine >= LineCount)
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
public void SetCurrentLine(int currentLine)
|
|
{
|
|
CurrentLine = currentLine;
|
|
}
|
|
|
|
public void SetCurrentCol(int currentCol)
|
|
{
|
|
CurrentColIndex = currentCol;
|
|
}
|
|
|
|
private void SetPos()
|
|
{
|
|
int position = 0;
|
|
int flag = 0;
|
|
if (ColPosList == null)
|
|
{
|
|
ColPosList = new int[Titles.Length];
|
|
}
|
|
|
|
foreach (var item in Types)
|
|
{
|
|
ColPosList[flag] = position;
|
|
switch (item)
|
|
{
|
|
case "int":
|
|
case "uint":
|
|
case "uint_key":
|
|
case "int_group":
|
|
case "int_key":
|
|
position += 4;
|
|
flag++;
|
|
break;
|
|
case "long":
|
|
position += 8;
|
|
flag++;
|
|
break;
|
|
case "string":
|
|
case "json":
|
|
case "array":
|
|
case "string_lan":
|
|
case "string_key":
|
|
// 先长度后位置
|
|
position += 4;
|
|
position += 4;
|
|
flag++;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
if (LinePosList == null)
|
|
{
|
|
LinePosList = new int[LineCount];
|
|
}
|
|
|
|
for (int i = 0; i < LineCount; i++)
|
|
{
|
|
LinePosList[i] = i * LineLength;
|
|
}
|
|
}
|
|
|
|
|
|
private void GetHeader(byte[] content)
|
|
{
|
|
int titlesLen = (int)((content[0] & 0xFF)
|
|
| ((content[1] & 0xFF) << 8)
|
|
| ((content[2] & 0xFF) << 16)
|
|
| ((content[3] & 0xFF) << 24));
|
|
headerLength += 4;
|
|
|
|
byte[] titles = content.Skip(headerLength).Take(titlesLen).ToArray();
|
|
headerLength += titlesLen;
|
|
string strTitle = Encoding.UTF8.GetString(titles);
|
|
Titles = strTitle.Split(m_splitFlag.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
if (m_titleIndex == null)
|
|
{
|
|
m_titleIndex = new Dictionary<string, int>();
|
|
for (int i = 0; i < Titles.Count(); i++)
|
|
{
|
|
m_titleIndex.Add(Titles[i], i);
|
|
}
|
|
}
|
|
|
|
|
|
int typesLen = (int)((content[headerLength] & 0xFF)
|
|
| ((content[headerLength + 1] & 0xFF) << 8)
|
|
| ((content[headerLength + 2] & 0xFF) << 16)
|
|
| ((content[headerLength + 3] & 0xFF) << 24));
|
|
headerLength += 4;
|
|
byte[] types = content.Skip(headerLength).Take(typesLen).ToArray();
|
|
headerLength += typesLen;
|
|
|
|
string strTypes = Encoding.UTF8.GetString(types);
|
|
Types = strTypes.Split(m_splitFlag.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
|
|
LineLength = (int)((content[headerLength] & 0xFF)
|
|
| ((content[headerLength + 1] & 0xFF) << 8)
|
|
| ((content[headerLength + 2] & 0xFF) << 16)
|
|
| ((content[headerLength + 3] & 0xFF) << 24));
|
|
headerLength += 4;
|
|
|
|
LineCount = (int)((content[headerLength] & 0xFF)
|
|
| ((content[headerLength + 1] & 0xFF) << 8)
|
|
| ((content[headerLength + 2] & 0xFF) << 16)
|
|
| ((content[headerLength + 3] & 0xFF) << 24));
|
|
}
|
|
|
|
public uint GetuintByIndex(string key = null)
|
|
{
|
|
int colIndex = CurrentColIndex;
|
|
if (key != null)
|
|
{
|
|
if (!m_titleIndex.ContainsKey(key))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
colIndex = m_titleIndex[key];
|
|
}
|
|
|
|
int valuePos = ColPosList[colIndex] + LinePosList[CurrentLine];
|
|
if (CurrentColIndex >= ColCount - 1)
|
|
{
|
|
CurrentColIndex = 0;
|
|
}
|
|
else
|
|
{
|
|
CurrentColIndex++;
|
|
}
|
|
|
|
return (uint)((m_bodyBlock[valuePos] & 0xFF)
|
|
| ((m_bodyBlock[valuePos + 1] & 0xFF) << 8)
|
|
| ((m_bodyBlock[valuePos + 2] & 0xFF) << 16)
|
|
| ((m_bodyBlock[valuePos + 3] & 0xFF) << 24));
|
|
}
|
|
|
|
public int GetintByIndex(string key = null)
|
|
{
|
|
int colIndex = CurrentColIndex;
|
|
if (key != null)
|
|
{
|
|
if (!m_titleIndex.ContainsKey(key))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
colIndex = m_titleIndex[key];
|
|
}
|
|
|
|
int valuePos = ColPosList[colIndex] + LinePosList[CurrentLine];
|
|
if (CurrentColIndex >= ColCount - 1)
|
|
{
|
|
CurrentColIndex = 0;
|
|
}
|
|
else
|
|
{
|
|
CurrentColIndex++;
|
|
}
|
|
|
|
return (int)((m_bodyBlock[valuePos] & 0xFF)
|
|
| ((m_bodyBlock[valuePos + 1] & 0xFF) << 8)
|
|
| ((m_bodyBlock[valuePos + 2] & 0xFF) << 16)
|
|
| ((m_bodyBlock[valuePos + 3] & 0xFF) << 24));
|
|
}
|
|
|
|
public long GetlongByIndex(string key = null)
|
|
{
|
|
int colIndex = CurrentColIndex;
|
|
if (key != null)
|
|
{
|
|
if (!m_titleIndex.ContainsKey(key))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
colIndex = m_titleIndex[key];
|
|
}
|
|
|
|
int valuePos = ColPosList[colIndex] + LinePosList[CurrentLine];
|
|
|
|
if (CurrentColIndex >= ColCount - 1)
|
|
{
|
|
CurrentColIndex = 0;
|
|
}
|
|
else
|
|
{
|
|
CurrentColIndex++;
|
|
}
|
|
|
|
return (long)((m_bodyBlock[valuePos] & (long)0xFF)
|
|
| ((m_bodyBlock[valuePos + 1] & (long)0xFF) << 8)
|
|
| ((m_bodyBlock[valuePos + 2] & (long)0xFF) << 16)
|
|
| ((m_bodyBlock[valuePos + 3] & (long)0xFF) << 24)
|
|
| ((m_bodyBlock[valuePos + 4] & (long)0xFF) << 32)
|
|
| ((m_bodyBlock[valuePos + 5] & (long)0xFF) << 40)
|
|
| ((m_bodyBlock[valuePos + 6] & (long)0xFF) << 48)
|
|
| ((m_bodyBlock[valuePos + 7] & (long)0xFF) << 56));
|
|
}
|
|
|
|
public long[] GetlongArrayByIndex(string key = null)
|
|
{
|
|
int colIndex = CurrentColIndex;
|
|
if (key != null)
|
|
{
|
|
if (!m_titleIndex.ContainsKey(key))
|
|
{
|
|
return Array.Empty<long>();
|
|
}
|
|
|
|
colIndex = m_titleIndex[key];
|
|
}
|
|
|
|
int valuePos = ColPosList[colIndex] + LinePosList[CurrentLine];
|
|
int strlen = (int)((m_bodyBlock[valuePos] & 0xFF)
|
|
| ((m_bodyBlock[valuePos + 1] & 0xFF) << 8)
|
|
| ((m_bodyBlock[valuePos + 2] & 0xFF) << 16)
|
|
| ((m_bodyBlock[valuePos + 3] & 0xFF) << 24));
|
|
valuePos += 4;
|
|
int strpos = (int)((m_bodyBlock[valuePos] & 0xFF)
|
|
| ((m_bodyBlock[valuePos + 1] & 0xFF) << 8)
|
|
| ((m_bodyBlock[valuePos + 2] & 0xFF) << 16)
|
|
| ((m_bodyBlock[valuePos + 3] & 0xFF) << 24));
|
|
|
|
if (CurrentColIndex >= ColCount - 1)
|
|
{
|
|
CurrentColIndex = 0;
|
|
}
|
|
else
|
|
{
|
|
CurrentColIndex++;
|
|
}
|
|
|
|
var bytes = m_stringBlock.Skip(strpos).Take(strlen).ToArray();
|
|
var length = bytes.Length / 8;
|
|
var result = new long[length];
|
|
|
|
for (var i = 0; i < length; i++)
|
|
{
|
|
long value = 0;
|
|
|
|
value |= ((long)bytes[i * 8 + 0] & 0xFF);
|
|
value |= ((long)bytes[i * 8 + 1] & 0xFF) << 8;
|
|
value |= ((long)bytes[i * 8 + 2] & 0xFF) << 16;
|
|
value |= ((long)bytes[i * 8 + 3] & 0xFF) << 24;
|
|
value |= ((long)bytes[i * 8 + 4] & 0xFF) << 32;
|
|
value |= ((long)bytes[i * 8 + 5] & 0xFF) << 40;
|
|
value |= ((long)bytes[i * 8 + 6] & 0xFF) << 48;
|
|
value |= ((long)bytes[i * 8 + 7] & 0xFF) << 56;
|
|
result[i] = value;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public int[] GetintArrayByIndex(string key = null)
|
|
{
|
|
int colIndex = CurrentColIndex;
|
|
if (key != null)
|
|
{
|
|
if (!m_titleIndex.ContainsKey(key))
|
|
{
|
|
return Array.Empty<int>();
|
|
}
|
|
|
|
colIndex = m_titleIndex[key];
|
|
}
|
|
|
|
int valuePos = ColPosList[colIndex] + LinePosList[CurrentLine];
|
|
int strlen = (int)((m_bodyBlock[valuePos] & 0xFF)
|
|
| ((m_bodyBlock[valuePos + 1] & 0xFF) << 8)
|
|
| ((m_bodyBlock[valuePos + 2] & 0xFF) << 16)
|
|
| ((m_bodyBlock[valuePos + 3] & 0xFF) << 24));
|
|
valuePos += 4;
|
|
int strpos = (int)((m_bodyBlock[valuePos] & 0xFF)
|
|
| ((m_bodyBlock[valuePos + 1] & 0xFF) << 8)
|
|
| ((m_bodyBlock[valuePos + 2] & 0xFF) << 16)
|
|
| ((m_bodyBlock[valuePos + 3] & 0xFF) << 24));
|
|
|
|
if (CurrentColIndex >= ColCount - 1)
|
|
{
|
|
CurrentColIndex = 0;
|
|
}
|
|
else
|
|
{
|
|
CurrentColIndex++;
|
|
}
|
|
|
|
var bytes = m_stringBlock.Skip(strpos).Take(strlen).ToArray();
|
|
int length = bytes.Length / 4;
|
|
var result = new int[length];
|
|
|
|
for (int i = 0; i < length; i++)
|
|
{
|
|
int value = 0;
|
|
|
|
value |= (bytes[i * 4 + 0] & 0xFF);
|
|
value |= (bytes[i * 4 + 1] & 0xFF) << 8;
|
|
value |= (bytes[i * 4 + 2] & 0xFF) << 16;
|
|
value |= (bytes[i * 4 + 3] & 0xFF) << 24;
|
|
|
|
result[i] = value;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public uint[] GetuintArrayByIndex(string key = null)
|
|
{
|
|
int colIndex = CurrentColIndex;
|
|
if (key != null)
|
|
{
|
|
if (!m_titleIndex.ContainsKey(key))
|
|
{
|
|
return Array.Empty<uint>();
|
|
}
|
|
|
|
colIndex = m_titleIndex[key];
|
|
}
|
|
|
|
int valuePos = ColPosList[colIndex] + LinePosList[CurrentLine];
|
|
int strlen = (int)((m_bodyBlock[valuePos] & 0xFF)
|
|
| ((m_bodyBlock[valuePos + 1] & 0xFF) << 8)
|
|
| ((m_bodyBlock[valuePos + 2] & 0xFF) << 16)
|
|
| ((m_bodyBlock[valuePos + 3] & 0xFF) << 24));
|
|
valuePos += 4;
|
|
int strpos = (int)((m_bodyBlock[valuePos] & 0xFF)
|
|
| ((m_bodyBlock[valuePos + 1] & 0xFF) << 8)
|
|
| ((m_bodyBlock[valuePos + 2] & 0xFF) << 16)
|
|
| ((m_bodyBlock[valuePos + 3] & 0xFF) << 24));
|
|
|
|
if (CurrentColIndex >= ColCount - 1)
|
|
{
|
|
CurrentColIndex = 0;
|
|
}
|
|
else
|
|
{
|
|
CurrentColIndex++;
|
|
}
|
|
|
|
var bytes = m_stringBlock.Skip(strpos).Take(strlen).ToArray();
|
|
int length = bytes.Length / 4;
|
|
var result = new uint[length];
|
|
|
|
for (int i = 0; i < length; i++)
|
|
{
|
|
uint value = 0;
|
|
|
|
value |= ((uint)bytes[i * 4 + 0] & 0xFF);
|
|
value |= ((uint)bytes[i * 4 + 1] & 0xFF) << 8;
|
|
value |= ((uint)bytes[i * 4 + 2] & 0xFF) << 16;
|
|
value |= ((uint)bytes[i * 4 + 3] & 0xFF) << 24;
|
|
|
|
result[i] = value;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
public string GetstringByIndex(string key = null)
|
|
{
|
|
int colIndex = CurrentColIndex;
|
|
if (key != null)
|
|
{
|
|
if (!m_titleIndex.ContainsKey(key))
|
|
{
|
|
return "";
|
|
}
|
|
|
|
colIndex = m_titleIndex[key];
|
|
}
|
|
|
|
int valuePos = ColPosList[colIndex] + LinePosList[CurrentLine];
|
|
int strlen = (int)((m_bodyBlock[valuePos] & 0xFF)
|
|
| ((m_bodyBlock[valuePos + 1] & 0xFF) << 8)
|
|
| ((m_bodyBlock[valuePos + 2] & 0xFF) << 16)
|
|
| ((m_bodyBlock[valuePos + 3] & 0xFF) << 24));
|
|
valuePos += 4;
|
|
int strpos = (int)((m_bodyBlock[valuePos] & 0xFF)
|
|
| ((m_bodyBlock[valuePos + 1] & 0xFF) << 8)
|
|
| ((m_bodyBlock[valuePos + 2] & 0xFF) << 16)
|
|
| ((m_bodyBlock[valuePos + 3] & 0xFF) << 24));
|
|
|
|
if (CurrentColIndex >= ColCount - 1)
|
|
{
|
|
CurrentColIndex = 0;
|
|
}
|
|
else
|
|
{
|
|
CurrentColIndex++;
|
|
}
|
|
|
|
return GetParseStringPos(strlen, strpos);
|
|
}
|
|
|
|
|
|
public string[] GetstringArrayByIndex(string key = null)
|
|
{
|
|
var str = GetstringByIndex(key);
|
|
if (string.IsNullOrEmpty(str) || str.Equals("0"))
|
|
{
|
|
return Array.Empty<string>();
|
|
}
|
|
|
|
var arr = new string[str.Length / 2 + 1];
|
|
var validCount = 0;
|
|
var sb = new StringBuilder();
|
|
foreach (var c in str)
|
|
{
|
|
if (c == ';')
|
|
{
|
|
if (sb.Length > 0)
|
|
{
|
|
arr[validCount++] = sb.ToString();
|
|
sb.Clear();
|
|
}
|
|
else
|
|
{
|
|
arr[validCount++] = "";
|
|
sb.Clear();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sb.Append(c);
|
|
}
|
|
}
|
|
|
|
if (sb.Length > 0)
|
|
{
|
|
arr[validCount++] = sb.ToString();
|
|
}
|
|
|
|
var ret = new string[validCount];
|
|
for (var i = 0; i < validCount; i++)
|
|
{
|
|
ret[i] = arr[i];
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
public JObject GetJObjectByIndex(string key = null)
|
|
{
|
|
var str = GetstringByIndex(key);
|
|
if (string.IsNullOrEmpty(str)||string.IsNullOrEmpty(str.Trim()))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return JObject.Parse(str);
|
|
}
|
|
|
|
public JArray GetJArrayByIndex(string key = null)
|
|
{
|
|
var str = GetstringByIndex(key);
|
|
if (string.IsNullOrEmpty(str))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return JArray.Parse(str);
|
|
}
|
|
|
|
private string GetParseStringPos(int strLen, int postion)
|
|
{
|
|
return Encoding.UTF8.GetString(m_stringBlock.Skip(postion).Take(strLen).ToArray());
|
|
}
|
|
|
|
private int FromBinaryToInt(byte[] binaryBits, int offset = 0)
|
|
{
|
|
int value;
|
|
value = (int)((binaryBits[offset] & 0xFF)
|
|
| ((binaryBits[offset + 1] & 0xFF) << 8)
|
|
| ((binaryBits[offset + 2] & 0xFF) << 16)
|
|
| ((binaryBits[offset + 3] & 0xFF) << 24));
|
|
return value;
|
|
}
|
|
|
|
private long FromBinaryToLong(byte[] binaryBits, int offset = 0)
|
|
{
|
|
long value;
|
|
value = (long)((binaryBits[offset] & (long)0xFF)
|
|
| ((binaryBits[offset + 1] & (long)0xFF) << 8)
|
|
| ((binaryBits[offset + 2] & (long)0xFF) << 16)
|
|
| ((binaryBits[offset + 3] & (long)0xFF) << 24)
|
|
| ((binaryBits[offset + 4] & (long)0xFF) << 32)
|
|
| ((binaryBits[offset + 5] & (long)0xFF) << 40)
|
|
| ((binaryBits[offset + 6] & (long)0xFF) << 48)
|
|
| ((binaryBits[offset + 7] & (long)0xFF) << 56));
|
|
|
|
return value;
|
|
}
|
|
|
|
public uint Getuint(string strColName)
|
|
{
|
|
int nColIndex = Array.IndexOf(Titles, strColName);
|
|
if (nColIndex < 0)
|
|
{
|
|
TraceLog.Error("TabBinFile: read data error, file:{0}, colName:{1}", FileName, strColName);
|
|
return 0;
|
|
}
|
|
|
|
int valuePos = ColPosList[nColIndex] + LinePosList[CurrentLine];
|
|
|
|
return (uint)FromBinaryToInt(m_bodyBlock.Skip(valuePos).Take(4).ToArray());
|
|
}
|
|
|
|
public int Getint(string strColName)
|
|
{
|
|
int nColIndex = Array.IndexOf(Titles, strColName);
|
|
if (nColIndex < 0)
|
|
{
|
|
TraceLog.Error("TabBinFile: read data error, file:{0}, colName:{1}", FileName, strColName);
|
|
return 0;
|
|
}
|
|
|
|
int valuePos = ColPosList[nColIndex] + LinePosList[CurrentLine];
|
|
|
|
return FromBinaryToInt(m_bodyBlock.Skip(valuePos).Take(4).ToArray());
|
|
}
|
|
|
|
public long Getlong(string strColName)
|
|
{
|
|
int nColIndex = Array.IndexOf(Titles, strColName);
|
|
if (nColIndex < 0)
|
|
{
|
|
TraceLog.Error("TabBinFile: read data error, file:{0}, colName:{1}", FileName, strColName);
|
|
return 0;
|
|
}
|
|
|
|
int valuePos = ColPosList[nColIndex] + LinePosList[CurrentLine];
|
|
|
|
return FromBinaryToInt(m_bodyBlock.Skip(valuePos).Take(8).ToArray());
|
|
}
|
|
|
|
public string Getstring(string strColName)
|
|
{
|
|
int nColIndex = Array.IndexOf(Titles, strColName);
|
|
if (nColIndex < 0)
|
|
{
|
|
TraceLog.Error("TabBinFile: read data error, file:{0}, colName:{1}", FileName, strColName);
|
|
return "";
|
|
}
|
|
|
|
int valuePos = ColPosList[nColIndex] + LinePosList[CurrentLine];
|
|
|
|
int strlen = FromBinaryToInt(m_bodyBlock.Skip(valuePos).Take(4).ToArray());
|
|
valuePos += 4;
|
|
int strpos = FromBinaryToInt(m_bodyBlock.Skip(valuePos).Take(4).ToArray());
|
|
return GetParseStringPos(strlen, strpos);
|
|
}
|
|
}
|
|
}
|