123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 |
- //----------------------------------------------
- // NGUI: Next-Gen UI kit
- // Copyright © 2011-2014 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)
- 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;
- ++wordStart;
- }
- 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;
- }
- }
|