add
This commit is contained in:
@@ -0,0 +1,281 @@
|
||||
//----------------------------------------------
|
||||
// NGUI: Next-Gen UI kit
|
||||
// Copyright © 2011-2015 Tasharen Entertainment
|
||||
//----------------------------------------------
|
||||
|
||||
using UnityEngine;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
/// <summary>
|
||||
/// MemoryStream.ReadLine has an interesting oddity: it doesn't always advance the stream's position by the correct amount:
|
||||
/// http://social.msdn.microsoft.com/Forums/en-AU/Vsexpressvcs/thread/b8f7837b-e396-494e-88e1-30547fcf385f
|
||||
/// Solution? Custom line reader with the added benefit of not having to use streams at all.
|
||||
/// </summary>
|
||||
|
||||
public class ByteReader
|
||||
{
|
||||
byte[] mBuffer;
|
||||
int mOffset = 0;
|
||||
|
||||
public ByteReader (byte[] bytes) { mBuffer = bytes; }
|
||||
public ByteReader (TextAsset asset) { mBuffer = asset.bytes; }
|
||||
|
||||
/// <summary>
|
||||
/// Read the contents of the specified file and return a Byte Reader to work with.
|
||||
/// </summary>
|
||||
|
||||
static public ByteReader Open (string path)
|
||||
{
|
||||
#if UNITY_EDITOR || (!UNITY_FLASH && !NETFX_CORE && !UNITY_WP8 && !UNITY_WP_8_1)
|
||||
FileStream fs = File.OpenRead(path);
|
||||
|
||||
if (fs != null)
|
||||
{
|
||||
fs.Seek(0, SeekOrigin.End);
|
||||
byte[] buffer = new byte[fs.Position];
|
||||
fs.Seek(0, SeekOrigin.Begin);
|
||||
fs.Read(buffer, 0, buffer.Length);
|
||||
fs.Close();
|
||||
return new ByteReader(buffer);
|
||||
}
|
||||
#endif
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether the buffer is readable.
|
||||
/// </summary>
|
||||
|
||||
public bool canRead { get { return (mBuffer != null && mOffset < mBuffer.Length); } }
|
||||
|
||||
/// <summary>
|
||||
/// Read a single line from the buffer.
|
||||
/// </summary>
|
||||
|
||||
static string ReadLine (byte[] buffer, int start, int count)
|
||||
{
|
||||
#if UNITY_FLASH
|
||||
// Encoding.UTF8 is not supported in Flash :(
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
int max = start + count;
|
||||
|
||||
for (int i = start; i < max; ++i)
|
||||
{
|
||||
byte byte0 = buffer[i];
|
||||
|
||||
if ((byte0 & 128) == 0)
|
||||
{
|
||||
// If an UCS fits 7 bits, its coded as 0xxxxxxx. This makes ASCII character represented by themselves
|
||||
sb.Append((char)byte0);
|
||||
}
|
||||
else if ((byte0 & 224) == 192)
|
||||
{
|
||||
// If an UCS fits 11 bits, it is coded as 110xxxxx 10xxxxxx
|
||||
if (++i == count) break;
|
||||
byte byte1 = buffer[i];
|
||||
int ch = (byte0 & 31) << 6;
|
||||
ch |= (byte1 & 63);
|
||||
sb.Append((char)ch);
|
||||
}
|
||||
else if ((byte0 & 240) == 224)
|
||||
{
|
||||
// If an UCS fits 16 bits, it is coded as 1110xxxx 10xxxxxx 10xxxxxx
|
||||
if (++i == count) break;
|
||||
byte byte1 = buffer[i];
|
||||
if (++i == count) break;
|
||||
byte byte2 = buffer[i];
|
||||
|
||||
if (byte0 == 0xEF && byte1 == 0xBB && byte2 == 0xBF)
|
||||
{
|
||||
// Byte Order Mark -- generally the first 3 bytes in a Windows-saved UTF-8 file. Skip it.
|
||||
}
|
||||
else
|
||||
{
|
||||
int ch = (byte0 & 15) << 12;
|
||||
ch |= (byte1 & 63) << 6;
|
||||
ch |= (byte2 & 63);
|
||||
sb.Append((char)ch);
|
||||
}
|
||||
}
|
||||
else if ((byte0 & 248) == 240)
|
||||
{
|
||||
// If an UCS fits 21 bits, it is coded as 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
||||
if (++i == count) break;
|
||||
byte byte1 = buffer[i];
|
||||
if (++i == count) break;
|
||||
byte byte2 = buffer[i];
|
||||
if (++i == count) break;
|
||||
byte byte3 = buffer[i];
|
||||
|
||||
int ch = (byte0 & 7) << 18;
|
||||
ch |= (byte1 & 63) << 12;
|
||||
ch |= (byte2 & 63) << 6;
|
||||
ch |= (byte3 & 63);
|
||||
sb.Append((char)ch);
|
||||
}
|
||||
}
|
||||
return sb.ToString();
|
||||
#else
|
||||
return Encoding.UTF8.GetString(buffer, start, count);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a single line from the buffer.
|
||||
/// </summary>
|
||||
|
||||
public string ReadLine () { return ReadLine(true); }
|
||||
|
||||
/// <summary>
|
||||
/// Read a single line from the buffer.
|
||||
/// </summary>
|
||||
|
||||
public string ReadLine (bool skipEmptyLines)
|
||||
{
|
||||
int max = mBuffer.Length;
|
||||
|
||||
// Skip empty characters
|
||||
if (skipEmptyLines)
|
||||
{
|
||||
while (mOffset < max && mBuffer[mOffset] < 32) ++mOffset;
|
||||
}
|
||||
|
||||
int end = mOffset;
|
||||
|
||||
if (end < max)
|
||||
{
|
||||
for (; ; )
|
||||
{
|
||||
if (end < max)
|
||||
{
|
||||
int ch = mBuffer[end++];
|
||||
if (ch != '\n' && ch != '\r') continue;
|
||||
}
|
||||
else ++end;
|
||||
|
||||
string line = ReadLine(mBuffer, mOffset, end - mOffset - 1);
|
||||
mOffset = end;
|
||||
return line;
|
||||
}
|
||||
}
|
||||
mOffset = max;
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assume that the entire file is a collection of key/value pairs.
|
||||
/// </summary>
|
||||
|
||||
public Dictionary<string, string> ReadDictionary ()
|
||||
{
|
||||
Dictionary<string, string> dict = new Dictionary<string, string>();
|
||||
char[] separator = new char[] { '=' };
|
||||
|
||||
while (canRead)
|
||||
{
|
||||
string line = ReadLine();
|
||||
if (line == null) break;
|
||||
if (line.StartsWith("//")) continue;
|
||||
|
||||
#if UNITY_FLASH
|
||||
string[] split = line.Split(separator, System.StringSplitOptions.RemoveEmptyEntries);
|
||||
#else
|
||||
string[] split = line.Split(separator, 2, System.StringSplitOptions.RemoveEmptyEntries);
|
||||
#endif
|
||||
|
||||
if (split.Length == 2)
|
||||
{
|
||||
string key = split[0].Trim();
|
||||
string val = split[1].Trim().Replace("\\n", "\n");
|
||||
dict[key] = val;
|
||||
}
|
||||
}
|
||||
return dict;
|
||||
}
|
||||
|
||||
static BetterList<string> mTemp = new BetterList<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Read a single line of Comma-Separated Values from the file.
|
||||
/// </summary>
|
||||
|
||||
public BetterList<string> ReadCSV ()
|
||||
{
|
||||
mTemp.Clear();
|
||||
string line = "";
|
||||
bool insideQuotes = false;
|
||||
int wordStart = 0;
|
||||
|
||||
while (canRead)
|
||||
{
|
||||
if (insideQuotes)
|
||||
{
|
||||
string s = ReadLine(false);
|
||||
if (s == null) return null;
|
||||
s = s.Replace("\\n", "\n");
|
||||
line += "\n" + s;
|
||||
}
|
||||
else
|
||||
{
|
||||
line = ReadLine(true);
|
||||
if (line == null) return null;
|
||||
line = line.Replace("\\n", "\n");
|
||||
wordStart = 0;
|
||||
}
|
||||
|
||||
for (int i = wordStart, imax = line.Length; i < imax; ++i)
|
||||
{
|
||||
char ch = line[i];
|
||||
|
||||
if (ch == ',')
|
||||
{
|
||||
if (!insideQuotes)
|
||||
{
|
||||
mTemp.Add(line.Substring(wordStart, i - wordStart));
|
||||
wordStart = i + 1;
|
||||
}
|
||||
}
|
||||
else if (ch == '"')
|
||||
{
|
||||
if (insideQuotes)
|
||||
{
|
||||
if (i + 1 >= imax)
|
||||
{
|
||||
mTemp.Add(line.Substring(wordStart, i - wordStart).Replace("\"\"", "\""));
|
||||
return mTemp;
|
||||
}
|
||||
|
||||
if (line[i + 1] != '"')
|
||||
{
|
||||
mTemp.Add(line.Substring(wordStart, i - wordStart).Replace("\"\"", "\""));
|
||||
insideQuotes = false;
|
||||
|
||||
if (line[i + 1] == ',')
|
||||
{
|
||||
++i;
|
||||
wordStart = i + 1;
|
||||
}
|
||||
}
|
||||
else ++i;
|
||||
}
|
||||
else
|
||||
{
|
||||
wordStart = i + 1;
|
||||
insideQuotes = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (wordStart < line.Length)
|
||||
{
|
||||
if (insideQuotes) continue;
|
||||
mTemp.Add(line.Substring(wordStart, line.Length - wordStart));
|
||||
}
|
||||
return mTemp;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user