Пример #1
0
        /// <inheritdoc/>
        public byte[] Decompress(byte[] data, long start = 0, long count = -1, object decompressorSettings = null)
        {
            if (count == 0)
            {
                return(Array.Empty <byte>());
            }
            #region Проверка аргументов
#if CHECK_ARGS
            if (data is null)
            {
                throw new ArgumentNullException(nameof(data));
            }
            if ((start < 0) || (start >= data.LongLength))
            {
                throw new ArgumentOutOfRangeException(nameof(start));
            }
            if ((start + count) > data.LongLength)
            {
                throw new ArgumentOutOfRangeException(nameof(count));
            }
#endif
            #endregion Проверка аргументов
            #region Инициализация
            var last     = (count < 0) ? (data.LongLength) : (start + count);
            var pos      = start;
            var settings = new SavegameCompressonSettings(data[start], data[start + 1]);
            int size     = data.LoadUInt16(start + 2, isLittleEndian: true);
            var res      = new MemoryStream();
            #endregion Инициализация
            #region  аспаковка
            for (var i = start; i < last; i++)
            {
                if (data[i] == settings.ControlCode)
                {
                    if ((i + 2) >= last)
                    {
                        throw new IncompleteDataException();
                    }
                    var cnt = data[++i];
                    var val = data[++i];
                    for (var j = 0; j < cnt; j++)
                    {
                        res.WriteByte(val);
                    }
                }
                else
                {
                    res.WriteByte(data[i]);
                }
            }
            #endregion  аспаковка
            return(res.ToArray());
        }
Пример #2
0
 /// <summary>
 /// <para>Записать упаковочную последовательность байт в поток</para>
 /// </summary>
 /// <param name="outStream">Целевой поток</param>
 /// <param name="val">Значение</param>
 /// <param name="count">Количество повторов</param>
 /// <param name="settings">Параметры упаковки</param>
 private static void WriteRLE(Stream outStream, byte val, int count, SavegameCompressonSettings settings)
 {
     if (count > 0)
     {
         if (val == settings.ControlCode)
         {
             WritePackedSequence(outStream, val, count, settings);
         }
         else if (count <= settings.MaxUnRLEValueCount)
         {
             for (var i = 0; i < count; i++)
             {
                 outStream.WriteByte(val);
             }
         }
         else
         {
             WritePackedSequence(outStream, val, count, settings);
         }
     }
 }
Пример #3
0
 /// <summary>
 /// <para>Записать кодовую последовательность в поток</para>
 /// </summary>
 /// <param name="outStream">Целевой поток</param>
 /// <param name="val">Значение</param>
 /// <param name="count">Количество повторов</param>
 /// <param name="settings">Параметры упаковки</param>
 private static void WritePackedSequence(Stream outStream, byte val, int count, SavegameCompressonSettings settings)
 {
     if (count > 0)
     {
         while (count > byte.MaxValue)
         {
             outStream.WriteByte(settings.ControlCode);
             outStream.WriteByte(byte.MaxValue);
             outStream.WriteByte(val);
             count -= byte.MaxValue;
         }
         outStream.WriteByte(settings.ControlCode);
         outStream.WriteByte((byte)count);
         outStream.WriteByte(val);
     }
 }