예제 #1
0
        /// <summary>
        /// Serializes the specified code page to the specified stream.
        /// </summary>
        /// <param name="codePage">The code page to serialize.</param>
        /// <param name="stream">The stream to serialize the code page to.</param>
        public static void Serialize(CodePageEncoding codePage, Stream stream)
        {
            if (codePage == null)
            {
                throw new ArgumentNullException(nameof(codePage));
            }
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            var buffer = new byte[1024];

            buffer[0] = codePage._hasDoubleByteChars ? (byte)1 : (byte)0;

            var length      = codePage._cpToUni.Count;
            var lengthBytes = BitConverter.GetBytes(length);

            Array.Copy(lengthBytes, 0, buffer, 1, 4);

            var head = 5;

            void Flush()
            {
                if (head == 0)
                {
                    return;
                }

                stream.Write(buffer, 0, head);
                head = 0;
            }

            foreach (var kv in codePage._cpToUni)
            {
                if (head + 4 > buffer.Length)
                {
                    Flush();
                }

                var val = (ushort)kv.Value;

                var keyL = (byte)(kv.Key & 0xff);
                var keyH = (byte)(kv.Key >> 8);

                var valL = (byte)(val & 0xff);
                var valH = (byte)(val >> 8);

                buffer[head++] = keyL;
                buffer[head++] = keyH;
                buffer[head++] = valL;
                buffer[head++] = valH;
            }

            Flush();
        }
예제 #2
0
        /// <summary>
        /// Deserializes a code page.
        /// </summary>
        /// <param name="stream">The stream.</param>
        /// <returns>The deserialized code page.</returns>
        public static CodePageEncoding Deserialize(Stream stream)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            var result = new CodePageEncoding();

            result._hasDoubleByteChars = stream.ReadByte() != 0;

            var buffer = new byte[4 * 256];

            stream.Read(buffer, 0, 4);

            var length = BitConverter.ToInt32(buffer, 0);

            var i    = 0;
            var head = 0;

            void Read()
            {
                var max = (length - i) * 4;
                var rd  = Math.Min(max, buffer.Length);

                if (rd != 0)
                {
                    stream.Read(buffer, 0, rd);
                }

                head = 0;
            }

            Read();

            for (; i < length; i++)
            {
                if (head == buffer.Length)
                {
                    Read();
                }

                var keyL = buffer[head++];
                var keyH = buffer[head++];
                var valL = buffer[head++];
                var valH = buffer[head++];

                var key = (ushort)(keyL | (keyH << 8));
                var val = (char)(ushort)(valL | (valH << 8));
                result._cpToUni[key] = val;
                result._uniToCp[val] = key;
            }

            return(result);
        }
예제 #3
0
        /// <summary>
        ///     Creates a new <see cref="CodePageEncoding" /> instance based on the data provided by the specified stream.
        /// </summary>
        /// <param name="stream">The steam to load the code page encoding from.</param>
        /// <returns>The newly created encoding instance.</returns>
        public static CodePageEncoding Load(Stream stream)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            var result = new CodePageEncoding();

            using (var reader = new StreamReader(stream))
            {
                while (!reader.EndOfStream)
                {
                    var line = reader.ReadLine();

                    var ln = line.Trim();

                    if (ln.StartsWith("#"))
                    {
                        continue;
                    }

                    var spl = ln.Split(' ', '\t');

                    string from = null, to = null;
                    foreach (var p in spl)
                    {
                        if (p.StartsWith("#"))
                        {
                            break;
                        }

                        if (from == null)
                        {
                            from = p;
                        }
                        else
                        {
                            to = p;
                            break;
                        }
                    }

                    if (string.IsNullOrWhiteSpace(from) || string.IsNullOrWhiteSpace(to))
                    {
                        continue;
                    }

                    try
                    {
                        var fromNum = System.Convert.ToUInt16(from, 16);
                        var toNum   = System.Convert.ToUInt16(to, 16);

                        if (fromNum > 0xff)
                        {
                            result._hasDoubleByteChars = true;
                        }
                        result._cpToUni[fromNum]     = (char)toNum;
                        result._uniToCp[(char)toNum] = fromNum;
                    }
                    catch (ArgumentOutOfRangeException)
                    {
                    }
                }
            }

            return(result);
        }