using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; namespace PkmnFoundations.Support { public class EncodedString5 : EncodedStringBase { /// /// Instances an EncodedString5 from its binary representation. /// /// This buffer is copied. public EncodedString5(byte[] data) : base(data) { } /// /// Instances an EncodedString5 from its binary representation. /// /// Buffer to copy from /// Offset in buffer /// Number of bytes (not chars) to copy public EncodedString5(byte[] data, int start, int length) : base(data, start, length) { } /// /// Instances an EncodedString5 from a Unicode string. /// /// text /// Length of encoded buffer in bytes (not chars) public EncodedString5(string text, int length) : base(text, length) { } // todo: Use pointers for both of these public static string DecodeString_impl(byte[] data, int start, int count) { if (data.Length < start + count) throw new ArgumentOutOfRangeException("count"); if (count < 0) throw new ArgumentOutOfRangeException("count"); StringBuilder sb = new StringBuilder(); for (int i = start; i < start + count * 2; i += 2) { ushort gamecode = BitConverter.ToUInt16(data, i); if (gamecode == 0xffff) { break; } char ch = Generation5TextLookupTable.ContainsKey(gamecode) ? Generation5TextLookupTable[gamecode] : (char)gamecode; sb.Append(ch); } return sb.ToString(); } public static string DecodeString_impl(byte[] data) { return DecodeString_impl(data, 0, data.Length >> 1); } public static byte[] EncodeString_impl(string str, int size) { int actualLength = (size >> 1) - 1; if (str.Length > actualLength) throw new ArgumentOutOfRangeException("size"); byte[] result = new byte[size]; MemoryStream m = new MemoryStream(result); foreach (char c in str.ToCharArray()) { m.Write(BitConverter.GetBytes(LookupReverse.ContainsKey(c) ? LookupReverse[c] : c), 0, 2); } m.WriteByte(0xff); m.WriteByte(0xff); return result; } protected override string DecodeString(byte[] data, int start, int count) { return DecodeString_impl(data, start, count); } protected override byte[] EncodeString(string str, int size) { return EncodeString_impl(str, size); } public override string ToString() { return Text; } public EncodedString5 Clone() { return new EncodedString5(RawData); } private static Dictionary m_lookup_reverse = null; private static Dictionary LookupReverse { get { if (m_lookup_reverse == null) { Dictionary reverse = new Dictionary(Generation5TextLookupTable.Count); foreach (KeyValuePair pair in Generation5TextLookupTable) { //if (!reverse.ContainsKey(pair.Value)) reverse.Add(pair.Value, pair.Key); } m_lookup_reverse = reverse; } return m_lookup_reverse; } } private static Dictionary Generation5TextLookupTable = new Dictionary { {0x2467, '\u00d7'}, {0x2468, '\u00f7'}, {0x246c, '\u2026'}, {0x246d, '\u2642'}, {0x246e, '\u2640'}, {0x246f, '\u2660'}, {0x2470, '\u2663'}, {0x2471, '\u2665'}, {0x2472, '\u2666'}, {0x2473, '\u2605'}, {0x2474, '\u25ce'}, {0x2475, '\u25cb'}, {0x2476, '\u25a1'}, {0x2477, '\u25b3'}, {0x2478, '\u25c7'}, {0x2479, '\u266a'}, {0x247a, '\u2600'}, {0x247b, '\u2601'}, {0x247d, '\u2602'}, }; } }