示例#1
0
		internal static Buffer Compress(byte[] inputBytes, int offset, int length, Buffer buffer, bool useFirstHit)
		{
			if (buffer == null)
			{
				buffer = new Buffer(32 + length * 6 / 5);
			}
			else
			{
				buffer.EnsureCapacity(32 + length * 6 / 5);
			}

			byte[] target = buffer.Data;
			int targetIndex = 0;
			int lasthit = offset;

			int l = length;
			while (l > 0)
			{
				if (l >= 128)
				{
					target[targetIndex++] = (byte) (0x80 | (l & 0x7f));
				}
				else
				{
					target[targetIndex++] = (byte) l;
				}
				l >>= 7;
			}

			var ilhm = new IntListHashMap(length/13 + 1);

			for (int i = offset; i + 4 < length && i < offset + 4; i++)
			{
				ilhm.Put(ToInt(inputBytes, i), i);
			}

			for (int i = offset + 4; i < offset + length; i++)
			{
				Hit h = Search(inputBytes, i, length, ilhm, useFirstHit);
				if (i + 4 < offset + length)
				{
					ilhm.Put(ToInt(inputBytes, i), i);
				}
				if (h != null)
				{
					if (lasthit < i)
					{
						int len = i - lasthit - 1;
						if (len < 60)
						{
							target[targetIndex++] = (byte) (len << 2);
						}
						else if (len < 0x100)
						{
							target[targetIndex++] = 60 << 2;
							target[targetIndex++] = (byte) len;
						}
						else if (len < 0x10000)
						{
							target[targetIndex++] = 61 << 2;
							target[targetIndex++] = (byte) len;
							target[targetIndex++] = (byte) (len >> 8);
						}
						else if (len < 0x1000000)
						{
							target[targetIndex++] = 62 << 2;
							target[targetIndex++] = (byte) len;
							target[targetIndex++] = (byte) (len >> 8);
							target[targetIndex++] = (byte) (len >> 16);
						}
						else
						{
							target[targetIndex++] = 63 << 2;
							target[targetIndex++] = (byte) len;
							target[targetIndex++] = (byte) (len >> 8);
							target[targetIndex++] = (byte) (len >> 16);
							target[targetIndex++] = (byte) (len >> 24);
						}
						Array.Copy(inputBytes, lasthit, target, targetIndex, i + offset - lasthit);
						targetIndex += i - lasthit;
						lasthit = i;
					}
					if (h.Length <= 11 && h.Offset < 2048)
					{
						target[targetIndex] = 1;
						target[targetIndex] |= (byte) ((h.Length - 4) << 2);
						target[targetIndex++] |= (byte) ((h.Offset >> 3) & 0xe0);
						target[targetIndex++] = (byte) (h.Offset & 0xff);
					}
					else if (h.Offset < 65536)
					{
						target[targetIndex] = 2;
						target[targetIndex++] |= (byte) ((h.Length - 1) << 2);
						target[targetIndex++] = (byte) (h.Offset);
						target[targetIndex++] = (byte) (h.Offset >> 8);
					}
					else
					{
						target[targetIndex] = 3;
						target[targetIndex++] |= (byte) ((h.Length - 1) << 2);
						target[targetIndex++] = (byte) (h.Offset);
						target[targetIndex++] = (byte) (h.Offset >> 8);
						target[targetIndex++] = (byte) (h.Offset >> 16);
						target[targetIndex++] = (byte) (h.Offset >> 24);
					}
					for (; i < lasthit; i++)
					{
						if (i + 4 < inputBytes.Length)
						{
							ilhm.Put(ToInt(inputBytes, i), i);
						}
					}
					lasthit = i + h.Length;
					while (i < lasthit - 1)
					{
						if (i + 4 < inputBytes.Length)
						{
							ilhm.Put(ToInt(inputBytes, i), i);
						}
						i++;
					}
				}
				else
				{
					if (i + 4 < length)
					{
						ilhm.Put(ToInt(inputBytes, i), i);
					}
				}
			}

			if (lasthit < offset + length)
			{
				int len = (offset + length) - lasthit - 1;
				if (len < 60)
				{
					target[targetIndex++] = (byte) (len << 2);
				}
				else if (len < 0x100)
				{
					target[targetIndex++] = 60 << 2;
					target[targetIndex++] = (byte) len;
				}
				else if (len < 0x10000)
				{
					target[targetIndex++] = 61 << 2;
					target[targetIndex++] = (byte) len;
					target[targetIndex++] = (byte) (len >> 8);
				}
				else if (len < 0x1000000)
				{
					target[targetIndex++] = 62 << 2;
					target[targetIndex++] = (byte) len;
					target[targetIndex++] = (byte) (len >> 8);
					target[targetIndex++] = (byte) (len >> 16);
				}
				else
				{
					target[targetIndex++] = 63 << 2;
					target[targetIndex++] = (byte) len;
					target[targetIndex++] = (byte) (len >> 8);
					target[targetIndex++] = (byte) (len >> 16);
					target[targetIndex++] = (byte) (len >> 24);
				}
				Array.ConstrainedCopy(inputBytes, lasthit, target, targetIndex, length + offset - lasthit);
				targetIndex += length - lasthit;
			}
			buffer.Length = targetIndex + offset;
			return buffer;
		}
示例#2
0
        internal static Buffer Compress(byte[] inputBytes, int offset, int length, Buffer buffer, bool useFirstHit)
        {
            if (buffer == null)
            {
                buffer = new Buffer(32 + length * 6 / 5);
            }
            else
            {
                buffer.EnsureCapacity(32 + length * 6 / 5);
            }

            byte[] target      = buffer.Data;
            int    targetIndex = 0;
            int    lasthit     = offset;

            int l = length;

            while (l > 0)
            {
                if (l >= 128)
                {
                    target[targetIndex++] = (byte)(0x80 | (l & 0x7f));
                }
                else
                {
                    target[targetIndex++] = (byte)l;
                }
                l >>= 7;
            }

            var ilhm = new IntListHashMap(length / 13 + 1);

            for (int i = offset; i + 4 < length && i < offset + 4; i++)
            {
                ilhm.Put(ToInt(inputBytes, i), i);
            }

            for (int i = offset + 4; i < offset + length; i++)
            {
                Hit h = Search(inputBytes, i, length, ilhm, useFirstHit);
                if (i + 4 < offset + length)
                {
                    ilhm.Put(ToInt(inputBytes, i), i);
                }
                if (h != null)
                {
                    if (lasthit < i)
                    {
                        int len = i - lasthit - 1;
                        if (len < 60)
                        {
                            target[targetIndex++] = (byte)(len << 2);
                        }
                        else if (len < 0x100)
                        {
                            target[targetIndex++] = 60 << 2;
                            target[targetIndex++] = (byte)len;
                        }
                        else if (len < 0x10000)
                        {
                            target[targetIndex++] = 61 << 2;
                            target[targetIndex++] = (byte)len;
                            target[targetIndex++] = (byte)(len >> 8);
                        }
                        else if (len < 0x1000000)
                        {
                            target[targetIndex++] = 62 << 2;
                            target[targetIndex++] = (byte)len;
                            target[targetIndex++] = (byte)(len >> 8);
                            target[targetIndex++] = (byte)(len >> 16);
                        }
                        else
                        {
                            target[targetIndex++] = 63 << 2;
                            target[targetIndex++] = (byte)len;
                            target[targetIndex++] = (byte)(len >> 8);
                            target[targetIndex++] = (byte)(len >> 16);
                            target[targetIndex++] = (byte)(len >> 24);
                        }
                        Array.Copy(inputBytes, lasthit, target, targetIndex, i + offset - lasthit);
                        targetIndex += i - lasthit;
                        lasthit      = i;
                    }
                    if (h.Length <= 11 && h.Offset < 2048)
                    {
                        target[targetIndex]    = 1;
                        target[targetIndex]   |= (byte)((h.Length - 4) << 2);
                        target[targetIndex++] |= (byte)((h.Offset >> 3) & 0xe0);
                        target[targetIndex++]  = (byte)(h.Offset & 0xff);
                    }
                    else if (h.Offset < 65536)
                    {
                        target[targetIndex]    = 2;
                        target[targetIndex++] |= (byte)((h.Length - 1) << 2);
                        target[targetIndex++]  = (byte)(h.Offset);
                        target[targetIndex++]  = (byte)(h.Offset >> 8);
                    }
                    else
                    {
                        target[targetIndex]    = 3;
                        target[targetIndex++] |= (byte)((h.Length - 1) << 2);
                        target[targetIndex++]  = (byte)(h.Offset);
                        target[targetIndex++]  = (byte)(h.Offset >> 8);
                        target[targetIndex++]  = (byte)(h.Offset >> 16);
                        target[targetIndex++]  = (byte)(h.Offset >> 24);
                    }
                    for (; i < lasthit; i++)
                    {
                        if (i + 4 < inputBytes.Length)
                        {
                            ilhm.Put(ToInt(inputBytes, i), i);
                        }
                    }
                    lasthit = i + h.Length;
                    while (i < lasthit - 1)
                    {
                        if (i + 4 < inputBytes.Length)
                        {
                            ilhm.Put(ToInt(inputBytes, i), i);
                        }
                        i++;
                    }
                }
                else
                {
                    if (i + 4 < length)
                    {
                        ilhm.Put(ToInt(inputBytes, i), i);
                    }
                }
            }

            if (lasthit < offset + length)
            {
                int len = (offset + length) - lasthit - 1;
                if (len < 60)
                {
                    target[targetIndex++] = (byte)(len << 2);
                }
                else if (len < 0x100)
                {
                    target[targetIndex++] = 60 << 2;
                    target[targetIndex++] = (byte)len;
                }
                else if (len < 0x10000)
                {
                    target[targetIndex++] = 61 << 2;
                    target[targetIndex++] = (byte)len;
                    target[targetIndex++] = (byte)(len >> 8);
                }
                else if (len < 0x1000000)
                {
                    target[targetIndex++] = 62 << 2;
                    target[targetIndex++] = (byte)len;
                    target[targetIndex++] = (byte)(len >> 8);
                    target[targetIndex++] = (byte)(len >> 16);
                }
                else
                {
                    target[targetIndex++] = 63 << 2;
                    target[targetIndex++] = (byte)len;
                    target[targetIndex++] = (byte)(len >> 8);
                    target[targetIndex++] = (byte)(len >> 16);
                    target[targetIndex++] = (byte)(len >> 24);
                }
                Array.ConstrainedCopy(inputBytes, lasthit, target, targetIndex, length + offset - lasthit);
                targetIndex += length - lasthit;
            }
            buffer.Length = targetIndex + offset;
            return(buffer);
        }
示例#3
0
		private static Hit Search(byte[] source, int index, int length, IntListHashMap map, bool useFirstHit)
		{
			if (index + 4 >= length)
			{
				return null;
			}

			if (index > 0 && 
				source[index] == source[index - 1] &&
				source[index] == source[index + 1] &&
				source[index] == source[index + 2] &&
				source[index] == source[index + 3])
			{
				int len = 0;
				for (int i = index; len < 64 && i < length && source[index] == source[i]; i++, len++)
				{
				}
				return new Hit(1, len);
			}

			if (useFirstHit)
			{
				int fp = map.GetFirstHit(ToInt(source, index), index - 4);
				if (fp < 0)
				{
					return null;
				}
				int offset = index - fp;
				int l = 0;
				for (int o = fp, io = index; io < length && source[o] == source[io] && o < index && l < 64; o++, io++)
				{
					l++;
				}
				return new Hit(offset, l);
			}
			IEnumerable<int> ii = map.GetReverse(ToInt(source, index));
			Hit res = null;
			foreach (int fp in ii)
			{
				int offset = index - fp;
				if (offset > DefaultMaxOffset)
				{
					break;
				}
				if (offset >= 4)
				{
					int l = 0;
					for (int o = index - offset, io = index; io < length && source[o] == source[io] && o < index && l < 64; o++, io++)
					{
						l++;
					}
					if (res == null)
					{
						res = new Hit(offset, l);
					}
					else if (l > res.Length)
					{
						res.Offset = offset;
						res.Length = l;
					}
				}
			}
			return res;
		}
示例#4
0
        private static Hit Search(byte[] source, int index, int length, IntListHashMap map, bool useFirstHit)
        {
            if (index + 4 >= length)
            {
                return(null);
            }

            if (index > 0 &&
                source[index] == source[index - 1] &&
                source[index] == source[index + 1] &&
                source[index] == source[index + 2] &&
                source[index] == source[index + 3])
            {
                int len = 0;
                for (int i = index; len < 64 && i < length && source[index] == source[i]; i++, len++)
                {
                }
                return(new Hit(1, len));
            }

            if (useFirstHit)
            {
                int fp = map.GetFirstHit(ToInt(source, index), index - 4);
                if (fp < 0)
                {
                    return(null);
                }
                int offset = index - fp;
                int l      = 0;
                for (int o = fp, io = index; io < length && source[o] == source[io] && o < index && l < 64; o++, io++)
                {
                    l++;
                }
                return(new Hit(offset, l));
            }
            IEnumerable <int> ii = map.GetReverse(ToInt(source, index));
            Hit res = null;

            foreach (int fp in ii)
            {
                int offset = index - fp;
                if (offset > DefaultMaxOffset)
                {
                    break;
                }
                if (offset >= 4)
                {
                    int l = 0;
                    for (int o = index - offset, io = index; io < length && source[o] == source[io] && o < index && l < 64; o++, io++)
                    {
                        l++;
                    }
                    if (res == null)
                    {
                        res = new Hit(offset, l);
                    }
                    else if (l > res.Length)
                    {
                        res.Offset = offset;
                        res.Length = l;
                    }
                }
            }
            return(res);
        }