Initial Client/Server Communication
#1 Followed the MagicOnion quickstart guide, borrowing code from the chat sample app to get something working
This commit is contained in:
parent
52b0d4d8ff
commit
a0c8dbee72
493 changed files with 57790 additions and 3 deletions
94
Assets/Scripts/MessagePack/LZ4/LZ4Codec.Helper.cs
Normal file
94
Assets/Scripts/MessagePack/LZ4/LZ4Codec.Helper.cs
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
// Copyright (c) All contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System;
|
||||
|
||||
namespace MessagePack.LZ4
|
||||
{
|
||||
internal partial class LZ4Codec
|
||||
{
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
|
||||
// use 'Safe' code for Unity because in IL2CPP gots strange behaviour.
|
||||
|
||||
public static int Encode(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset, int outputLength)
|
||||
{
|
||||
if (IntPtr.Size == 4)
|
||||
{
|
||||
return LZ4Codec.Encode32Safe(input, inputOffset, inputLength, output, outputOffset, outputLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
return LZ4Codec.Encode64Safe(input, inputOffset, inputLength, output, outputOffset, outputLength);
|
||||
}
|
||||
}
|
||||
|
||||
public static int Decode(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset, int outputLength)
|
||||
{
|
||||
if (IntPtr.Size == 4)
|
||||
{
|
||||
return LZ4Codec.Decode32Safe(input, inputOffset, inputLength, output, outputOffset, outputLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
return LZ4Codec.Decode64Safe(input, inputOffset, inputLength, output, outputOffset, outputLength);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
internal static class HashTablePool
|
||||
{
|
||||
[ThreadStatic]
|
||||
private static ushort[] ushortPool;
|
||||
|
||||
[ThreadStatic]
|
||||
private static uint[] uintPool;
|
||||
|
||||
[ThreadStatic]
|
||||
private static int[] intPool;
|
||||
|
||||
public static ushort[] GetUShortHashTablePool()
|
||||
{
|
||||
if (ushortPool == null)
|
||||
{
|
||||
ushortPool = new ushort[HASH64K_TABLESIZE];
|
||||
}
|
||||
else
|
||||
{
|
||||
Array.Clear(ushortPool, 0, ushortPool.Length);
|
||||
}
|
||||
|
||||
return ushortPool;
|
||||
}
|
||||
|
||||
public static uint[] GetUIntHashTablePool()
|
||||
{
|
||||
if (uintPool == null)
|
||||
{
|
||||
uintPool = new uint[HASH_TABLESIZE];
|
||||
}
|
||||
else
|
||||
{
|
||||
Array.Clear(uintPool, 0, uintPool.Length);
|
||||
}
|
||||
|
||||
return uintPool;
|
||||
}
|
||||
|
||||
public static int[] GetIntHashTablePool()
|
||||
{
|
||||
if (intPool == null)
|
||||
{
|
||||
intPool = new int[HASH_TABLESIZE];
|
||||
}
|
||||
else
|
||||
{
|
||||
Array.Clear(intPool, 0, intPool.Length);
|
||||
}
|
||||
|
||||
return intPool;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/MessagePack/LZ4/LZ4Codec.Helper.cs.meta
Normal file
11
Assets/Scripts/MessagePack/LZ4/LZ4Codec.Helper.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f33bc878911a8855d8df41dd514c5a42
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
467
Assets/Scripts/MessagePack/LZ4/LZ4Codec.Safe.cs
Normal file
467
Assets/Scripts/MessagePack/LZ4/LZ4Codec.Safe.cs
Normal file
|
|
@ -0,0 +1,467 @@
|
|||
// Copyright (c) All contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
|
||||
#region license
|
||||
|
||||
/*
|
||||
Copyright (c) 2013, Milosz Krajewski
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions
|
||||
and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace MessagePack.LZ4
|
||||
{
|
||||
/// <summary>Safe LZ4 codec.</summary>
|
||||
internal partial class LZ4Codec
|
||||
{
|
||||
#region Helper
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
private static void Assert(bool condition, string errorMessage)
|
||||
{
|
||||
if (!condition)
|
||||
{
|
||||
throw new ArgumentException(errorMessage);
|
||||
}
|
||||
|
||||
Debug.Assert(condition, errorMessage);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Byte manipulation
|
||||
|
||||
internal static void Poke2(byte[] buffer, int offset, ushort value)
|
||||
{
|
||||
buffer[offset] = (byte)value;
|
||||
buffer[offset + 1] = (byte)(value >> 8);
|
||||
}
|
||||
|
||||
internal static ushort Peek2(byte[] buffer, int offset)
|
||||
{
|
||||
// NOTE: It's faster than BitConverter.ToUInt16 (suprised? me too)
|
||||
return (ushort)(((uint)buffer[offset]) | ((uint)buffer[offset + 1] << 8));
|
||||
}
|
||||
|
||||
internal static uint Peek4(byte[] buffer, int offset)
|
||||
{
|
||||
// NOTE: It's faster than BitConverter.ToUInt32 (suprised? me too)
|
||||
return
|
||||
((uint)buffer[offset]) |
|
||||
((uint)buffer[offset + 1] << 8) |
|
||||
((uint)buffer[offset + 2] << 16) |
|
||||
((uint)buffer[offset + 3] << 24);
|
||||
}
|
||||
|
||||
private static uint Xor4(byte[] buffer, int offset1, int offset2)
|
||||
{
|
||||
// return Peek4(buffer, offset1) ^ Peek4(buffer, offset2);
|
||||
var value1 =
|
||||
((uint)buffer[offset1]) |
|
||||
((uint)buffer[offset1 + 1] << 8) |
|
||||
((uint)buffer[offset1 + 2] << 16) |
|
||||
((uint)buffer[offset1 + 3] << 24);
|
||||
var value2 =
|
||||
((uint)buffer[offset2]) |
|
||||
((uint)buffer[offset2 + 1] << 8) |
|
||||
((uint)buffer[offset2 + 2] << 16) |
|
||||
((uint)buffer[offset2 + 3] << 24);
|
||||
return value1 ^ value2;
|
||||
}
|
||||
|
||||
private static ulong Xor8(byte[] buffer, int offset1, int offset2)
|
||||
{
|
||||
// return Peek8(buffer, offset1) ^ Peek8(buffer, offset2);
|
||||
var value1 =
|
||||
((ulong)buffer[offset1]) |
|
||||
((ulong)buffer[offset1 + 1] << 8) |
|
||||
((ulong)buffer[offset1 + 2] << 16) |
|
||||
((ulong)buffer[offset1 + 3] << 24) |
|
||||
((ulong)buffer[offset1 + 4] << 32) |
|
||||
((ulong)buffer[offset1 + 5] << 40) |
|
||||
((ulong)buffer[offset1 + 6] << 48) |
|
||||
((ulong)buffer[offset1 + 7] << 56);
|
||||
var value2 =
|
||||
((ulong)buffer[offset2]) |
|
||||
((ulong)buffer[offset2 + 1] << 8) |
|
||||
((ulong)buffer[offset2 + 2] << 16) |
|
||||
((ulong)buffer[offset2 + 3] << 24) |
|
||||
((ulong)buffer[offset2 + 4] << 32) |
|
||||
((ulong)buffer[offset2 + 5] << 40) |
|
||||
((ulong)buffer[offset2 + 6] << 48) |
|
||||
((ulong)buffer[offset2 + 7] << 56);
|
||||
return value1 ^ value2;
|
||||
}
|
||||
|
||||
private static bool Equal2(byte[] buffer, int offset1, int offset2)
|
||||
{
|
||||
// return Peek2(buffer, offset1) == Peek2(buffer, offset2);
|
||||
if (buffer[offset1] != buffer[offset2])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return buffer[offset1 + 1] == buffer[offset2 + 1];
|
||||
}
|
||||
|
||||
private static bool Equal4(byte[] buffer, int offset1, int offset2)
|
||||
{
|
||||
// return Peek4(buffer, offset1) == Peek4(buffer, offset2);
|
||||
if (buffer[offset1] != buffer[offset2])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (buffer[offset1 + 1] != buffer[offset2 + 1])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (buffer[offset1 + 2] != buffer[offset2 + 2])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return buffer[offset1 + 3] == buffer[offset2 + 3];
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Byte block copy
|
||||
|
||||
private static void Copy4(byte[] buf, int src, int dst)
|
||||
{
|
||||
Assert(dst > src, "Copying backwards is not implemented");
|
||||
buf[dst + 3] = buf[src + 3];
|
||||
buf[dst + 2] = buf[src + 2];
|
||||
buf[dst + 1] = buf[src + 1];
|
||||
buf[dst] = buf[src];
|
||||
}
|
||||
|
||||
private static void Copy8(byte[] buf, int src, int dst)
|
||||
{
|
||||
Assert(dst > src, "Copying backwards is not implemented");
|
||||
buf[dst + 7] = buf[src + 7];
|
||||
buf[dst + 6] = buf[src + 6];
|
||||
buf[dst + 5] = buf[src + 5];
|
||||
buf[dst + 4] = buf[src + 4];
|
||||
buf[dst + 3] = buf[src + 3];
|
||||
buf[dst + 2] = buf[src + 2];
|
||||
buf[dst + 1] = buf[src + 1];
|
||||
buf[dst] = buf[src];
|
||||
}
|
||||
|
||||
private static void BlockCopy(byte[] src, int src_0, byte[] dst, int dst_0, int len)
|
||||
{
|
||||
Assert(src != dst, "BlockCopy does not handle copying to the same buffer");
|
||||
|
||||
if (len >= BLOCK_COPY_LIMIT)
|
||||
{
|
||||
Buffer.BlockCopy(src, src_0, dst, dst_0, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (len >= 8)
|
||||
{
|
||||
dst[dst_0] = src[src_0];
|
||||
dst[dst_0 + 1] = src[src_0 + 1];
|
||||
dst[dst_0 + 2] = src[src_0 + 2];
|
||||
dst[dst_0 + 3] = src[src_0 + 3];
|
||||
dst[dst_0 + 4] = src[src_0 + 4];
|
||||
dst[dst_0 + 5] = src[src_0 + 5];
|
||||
dst[dst_0 + 6] = src[src_0 + 6];
|
||||
dst[dst_0 + 7] = src[src_0 + 7];
|
||||
len -= 8;
|
||||
src_0 += 8;
|
||||
dst_0 += 8;
|
||||
}
|
||||
|
||||
while (len >= 4)
|
||||
{
|
||||
dst[dst_0] = src[src_0];
|
||||
dst[dst_0 + 1] = src[src_0 + 1];
|
||||
dst[dst_0 + 2] = src[src_0 + 2];
|
||||
dst[dst_0 + 3] = src[src_0 + 3];
|
||||
len -= 4;
|
||||
src_0 += 4;
|
||||
dst_0 += 4;
|
||||
}
|
||||
|
||||
while (len-- > 0)
|
||||
{
|
||||
dst[dst_0++] = src[src_0++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static int WildCopy(byte[] src, int src_0, byte[] dst, int dst_0, int dst_end)
|
||||
{
|
||||
var len = dst_end - dst_0;
|
||||
|
||||
Assert(src != dst, "BlockCopy does not handle copying to the same buffer");
|
||||
Assert(len > 0, "Length have to be greater than 0");
|
||||
|
||||
if (len >= BLOCK_COPY_LIMIT)
|
||||
{
|
||||
Buffer.BlockCopy(src, src_0, dst, dst_0, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
// apparently (tested) this is an overkill
|
||||
// it seems to be faster without this 8-byte loop
|
||||
////while (len >= 8)
|
||||
////{
|
||||
//// dst[dst_0] = src[src_0];
|
||||
//// dst[dst_0 + 1] = src[src_0 + 1];
|
||||
//// dst[dst_0 + 2] = src[src_0 + 2];
|
||||
//// dst[dst_0 + 3] = src[src_0 + 3];
|
||||
//// dst[dst_0 + 4] = src[src_0 + 4];
|
||||
//// dst[dst_0 + 5] = src[src_0 + 5];
|
||||
//// dst[dst_0 + 6] = src[src_0 + 6];
|
||||
//// dst[dst_0 + 7] = src[src_0 + 7];
|
||||
//// len -= 8; src_0 += 8; dst_0 += 8;
|
||||
////}
|
||||
|
||||
while (len >= 4)
|
||||
{
|
||||
dst[dst_0] = src[src_0];
|
||||
dst[dst_0 + 1] = src[src_0 + 1];
|
||||
dst[dst_0 + 2] = src[src_0 + 2];
|
||||
dst[dst_0 + 3] = src[src_0 + 3];
|
||||
len -= 4;
|
||||
src_0 += 4;
|
||||
dst_0 += 4;
|
||||
}
|
||||
|
||||
while (len-- > 0)
|
||||
{
|
||||
dst[dst_0++] = src[src_0++];
|
||||
}
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
private static int SecureCopy(byte[] buffer, int src, int dst, int dst_end)
|
||||
{
|
||||
var diff = dst - src;
|
||||
var length = dst_end - dst;
|
||||
var len = length;
|
||||
|
||||
Assert(diff >= 4, "Target must be at least 4 bytes further than source");
|
||||
Assert(BLOCK_COPY_LIMIT > 4, "This method requires BLOCK_COPY_LIMIT > 4");
|
||||
Assert(len > 0, "Length have to be greater than 0");
|
||||
|
||||
if (diff >= BLOCK_COPY_LIMIT)
|
||||
{
|
||||
if (diff >= length)
|
||||
{
|
||||
Buffer.BlockCopy(buffer, src, buffer, dst, length);
|
||||
return length; // done
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
Buffer.BlockCopy(buffer, src, buffer, dst, diff);
|
||||
src += diff;
|
||||
dst += diff;
|
||||
len -= diff;
|
||||
}
|
||||
while (len >= diff);
|
||||
}
|
||||
|
||||
// apparently (tested) this is an overkill
|
||||
// it seems to be faster without this 8-byte loop
|
||||
////while (len >= 8)
|
||||
////{
|
||||
//// buffer[dst] = buffer[src];
|
||||
//// buffer[dst + 1] = buffer[src + 1];
|
||||
//// buffer[dst + 2] = buffer[src + 2];
|
||||
//// buffer[dst + 3] = buffer[src + 3];
|
||||
//// buffer[dst + 4] = buffer[src + 4];
|
||||
//// buffer[dst + 5] = buffer[src + 5];
|
||||
//// buffer[dst + 6] = buffer[src + 6];
|
||||
//// buffer[dst + 7] = buffer[src + 7];
|
||||
//// dst += 8; src += 8; len -= 8;
|
||||
////}
|
||||
|
||||
while (len >= 4)
|
||||
{
|
||||
buffer[dst] = buffer[src];
|
||||
buffer[dst + 1] = buffer[src + 1];
|
||||
buffer[dst + 2] = buffer[src + 2];
|
||||
buffer[dst + 3] = buffer[src + 3];
|
||||
dst += 4;
|
||||
src += 4;
|
||||
len -= 4;
|
||||
}
|
||||
|
||||
while (len-- > 0)
|
||||
{
|
||||
buffer[dst++] = buffer[src++];
|
||||
}
|
||||
|
||||
return length; // done
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>Encodes the specified input.</summary>
|
||||
/// <param name="input">The input.</param>
|
||||
/// <param name="inputOffset">The input offset.</param>
|
||||
/// <param name="inputLength">Length of the input.</param>
|
||||
/// <param name="output">The output.</param>
|
||||
/// <param name="outputOffset">The output offset.</param>
|
||||
/// <param name="outputLength">Length of the output.</param>
|
||||
/// <returns>Number of bytes written.</returns>
|
||||
public static int Encode32Safe(
|
||||
byte[] input,
|
||||
int inputOffset,
|
||||
int inputLength,
|
||||
byte[] output,
|
||||
int outputOffset,
|
||||
int outputLength)
|
||||
{
|
||||
CheckArguments(input, inputOffset, inputLength, output, outputOffset, outputLength);
|
||||
if (outputLength == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (inputLength < LZ4_64KLIMIT)
|
||||
{
|
||||
var hashTable = HashTablePool.GetUShortHashTablePool();
|
||||
return LZ4_compress64kCtx_safe32(hashTable, input, output, inputOffset, outputOffset, inputLength, outputLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
var hashTable = HashTablePool.GetIntHashTablePool();
|
||||
return LZ4_compressCtx_safe32(hashTable, input, output, inputOffset, outputOffset, inputLength, outputLength);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Encodes the specified input.</summary>
|
||||
/// <param name="input">The input.</param>
|
||||
/// <param name="inputOffset">The input offset.</param>
|
||||
/// <param name="inputLength">Length of the input.</param>
|
||||
/// <param name="output">The output.</param>
|
||||
/// <param name="outputOffset">The output offset.</param>
|
||||
/// <param name="outputLength">Length of the output.</param>
|
||||
/// <returns>Number of bytes written.</returns>
|
||||
public static int Encode64Safe(
|
||||
byte[] input,
|
||||
int inputOffset,
|
||||
int inputLength,
|
||||
byte[] output,
|
||||
int outputOffset,
|
||||
int outputLength)
|
||||
{
|
||||
CheckArguments(input, inputOffset, inputLength, output, outputOffset, outputLength);
|
||||
if (outputLength == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (inputLength < LZ4_64KLIMIT)
|
||||
{
|
||||
var hashTable = HashTablePool.GetUShortHashTablePool();
|
||||
return LZ4_compress64kCtx_safe64(hashTable, input, output, inputOffset, outputOffset, inputLength, outputLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
var hashTable = HashTablePool.GetIntHashTablePool();
|
||||
return LZ4_compressCtx_safe64(hashTable, input, output, inputOffset, outputOffset, inputLength, outputLength);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Decodes the specified input.</summary>
|
||||
/// <param name="input">The input.</param>
|
||||
/// <param name="inputOffset">The input offset.</param>
|
||||
/// <param name="inputLength">Length of the input.</param>
|
||||
/// <param name="output">The output.</param>
|
||||
/// <param name="outputOffset">The output offset.</param>
|
||||
/// <param name="outputLength">Length of the output.</param>
|
||||
/// <returns>Number of bytes written.</returns>
|
||||
public static int Decode32Safe(
|
||||
byte[] input,
|
||||
int inputOffset,
|
||||
int inputLength,
|
||||
byte[] output,
|
||||
int outputOffset,
|
||||
int outputLength)
|
||||
{
|
||||
CheckArguments(input, inputOffset, inputLength, output, outputOffset, outputLength);
|
||||
|
||||
if (outputLength == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
var length = LZ4_uncompress_safe32(input, output, inputOffset, outputOffset, outputLength);
|
||||
if (length != inputLength)
|
||||
{
|
||||
throw new MessagePackSerializationException("LZ4 block is corrupted, or invalid length has been given.");
|
||||
}
|
||||
|
||||
return outputLength;
|
||||
}
|
||||
|
||||
/// <summary>Decodes the specified input.</summary>
|
||||
/// <param name="input">The input.</param>
|
||||
/// <param name="inputOffset">The input offset.</param>
|
||||
/// <param name="inputLength">Length of the input.</param>
|
||||
/// <param name="output">The output.</param>
|
||||
/// <param name="outputOffset">The output offset.</param>
|
||||
/// <param name="outputLength">Length of the output.</param>
|
||||
/// <returns>Number of bytes written.</returns>
|
||||
public static int Decode64Safe(
|
||||
byte[] input,
|
||||
int inputOffset,
|
||||
int inputLength,
|
||||
byte[] output,
|
||||
int outputOffset,
|
||||
int outputLength)
|
||||
{
|
||||
CheckArguments(input, inputOffset, inputLength, output, outputOffset, outputLength);
|
||||
|
||||
if (outputLength == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
var length = LZ4_uncompress_safe64(input, output, inputOffset, outputOffset, outputLength);
|
||||
if (length != inputLength)
|
||||
{
|
||||
throw new MessagePackSerializationException("LZ4 block is corrupted, or invalid length has been given.");
|
||||
}
|
||||
|
||||
return outputLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
11
Assets/Scripts/MessagePack/LZ4/LZ4Codec.Safe.cs.meta
Normal file
11
Assets/Scripts/MessagePack/LZ4/LZ4Codec.Safe.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5fe9256cf4f62c6df8c144caef0ebc6a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
753
Assets/Scripts/MessagePack/LZ4/LZ4Codec.Safe32.Dirty.cs
Normal file
753
Assets/Scripts/MessagePack/LZ4/LZ4Codec.Safe32.Dirty.cs
Normal file
|
|
@ -0,0 +1,753 @@
|
|||
// Copyright (c) All contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
|
||||
#region LZ4 original
|
||||
|
||||
/*
|
||||
LZ4 - Fast LZ compression algorithm
|
||||
Copyright (C) 2011-2012, Yann Collet.
|
||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
You can contact the author at :
|
||||
- LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
|
||||
- LZ4 source repository : http://code.google.com/p/lz4/
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region LZ4 port
|
||||
|
||||
/*
|
||||
Copyright (c) 2013, Milosz Krajewski
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions
|
||||
and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#pragma warning disable SA1312 // Variable names should begin with lower-case letter
|
||||
|
||||
namespace MessagePack.LZ4
|
||||
{
|
||||
internal partial class LZ4Codec
|
||||
{
|
||||
#region LZ4_compressCtx
|
||||
|
||||
private static int LZ4_compressCtx_safe32(
|
||||
int[] hash_table,
|
||||
byte[] src,
|
||||
byte[] dst,
|
||||
int src_0,
|
||||
int dst_0,
|
||||
int src_len,
|
||||
int dst_maxlen)
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var debruijn32 = DEBRUIJN_TABLE_32;
|
||||
int _i;
|
||||
|
||||
// ---- preprocessed source start here ----
|
||||
// r93
|
||||
var src_p = src_0;
|
||||
var src_base = src_0;
|
||||
var src_anchor = src_p;
|
||||
var src_end = src_p + src_len;
|
||||
var src_mflimit = src_end - MFLIMIT;
|
||||
|
||||
var dst_p = dst_0;
|
||||
var dst_end = dst_p + dst_maxlen;
|
||||
|
||||
var src_LASTLITERALS = src_end - LASTLITERALS;
|
||||
var src_LASTLITERALS_1 = src_LASTLITERALS - 1;
|
||||
|
||||
var src_LASTLITERALS_STEPSIZE_1 = src_LASTLITERALS - (STEPSIZE_32 - 1);
|
||||
var dst_LASTLITERALS_1 = dst_end - (1 + LASTLITERALS);
|
||||
var dst_LASTLITERALS_3 = dst_end - (2 + 1 + LASTLITERALS);
|
||||
|
||||
int length;
|
||||
|
||||
uint h, h_fwd;
|
||||
|
||||
// Init
|
||||
if (src_len < MINLENGTH)
|
||||
{
|
||||
goto _last_literals;
|
||||
}
|
||||
|
||||
// First Byte
|
||||
hash_table[(Peek4(src, src_p) * 2654435761u) >> HASH_ADJUST] = src_p - src_base;
|
||||
src_p++;
|
||||
h_fwd = (Peek4(src, src_p) * 2654435761u) >> HASH_ADJUST;
|
||||
|
||||
// Main Loop
|
||||
while (true)
|
||||
{
|
||||
var findMatchAttempts = (1 << SKIPSTRENGTH) + 3;
|
||||
var src_p_fwd = src_p;
|
||||
int src_ref;
|
||||
int dst_token;
|
||||
|
||||
// Find a match
|
||||
do
|
||||
{
|
||||
h = h_fwd;
|
||||
var step = findMatchAttempts++ >> SKIPSTRENGTH;
|
||||
src_p = src_p_fwd;
|
||||
src_p_fwd = src_p + step;
|
||||
|
||||
if (src_p_fwd > src_mflimit)
|
||||
{
|
||||
goto _last_literals;
|
||||
}
|
||||
|
||||
h_fwd = (Peek4(src, src_p_fwd) * 2654435761u) >> HASH_ADJUST;
|
||||
src_ref = src_base + hash_table[h];
|
||||
hash_table[h] = src_p - src_base;
|
||||
}
|
||||
while ((src_ref < src_p - MAX_DISTANCE) || (!Equal4(src, src_ref, src_p)));
|
||||
|
||||
// Catch up
|
||||
while ((src_p > src_anchor) && (src_ref > src_0) && (src[src_p - 1] == src[src_ref - 1]))
|
||||
{
|
||||
src_p--;
|
||||
src_ref--;
|
||||
}
|
||||
|
||||
// Encode Literal length
|
||||
length = src_p - src_anchor;
|
||||
dst_token = dst_p++;
|
||||
|
||||
if (dst_p + length + (length >> 8) > dst_LASTLITERALS_3)
|
||||
{
|
||||
return 0; // Check output limit
|
||||
}
|
||||
|
||||
if (length >= RUN_MASK)
|
||||
{
|
||||
var len = length - RUN_MASK;
|
||||
dst[dst_token] = RUN_MASK << ML_BITS;
|
||||
if (len > 254)
|
||||
{
|
||||
do
|
||||
{
|
||||
dst[dst_p++] = 255;
|
||||
len -= 255;
|
||||
}
|
||||
while (len > 254);
|
||||
dst[dst_p++] = (byte)len;
|
||||
BlockCopy(src, src_anchor, dst, dst_p, length);
|
||||
dst_p += length;
|
||||
goto _next_match;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[dst_p++] = (byte)len;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[dst_token] = (byte)(length << ML_BITS);
|
||||
}
|
||||
|
||||
// Copy Literals
|
||||
if (length > 0)
|
||||
{
|
||||
_i = dst_p + length;
|
||||
WildCopy(src, src_anchor, dst, dst_p, _i);
|
||||
dst_p = _i;
|
||||
}
|
||||
|
||||
_next_match:
|
||||
|
||||
// Encode Offset
|
||||
Poke2(dst, dst_p, (ushort)(src_p - src_ref));
|
||||
dst_p += 2;
|
||||
|
||||
// Start Counting
|
||||
src_p += MINMATCH;
|
||||
src_ref += MINMATCH; // MinMatch already verified
|
||||
src_anchor = src_p;
|
||||
|
||||
while (src_p < src_LASTLITERALS_STEPSIZE_1)
|
||||
{
|
||||
var diff = (int)Xor4(src, src_ref, src_p);
|
||||
if (diff == 0)
|
||||
{
|
||||
src_p += STEPSIZE_32;
|
||||
src_ref += STEPSIZE_32;
|
||||
continue;
|
||||
}
|
||||
|
||||
src_p += debruijn32[((uint)(diff & -diff) * 0x077CB531u) >> 27];
|
||||
goto _endCount;
|
||||
}
|
||||
|
||||
if ((src_p < src_LASTLITERALS_1) && Equal2(src, src_ref, src_p))
|
||||
{
|
||||
src_p += 2;
|
||||
src_ref += 2;
|
||||
}
|
||||
|
||||
if ((src_p < src_LASTLITERALS) && (src[src_ref] == src[src_p]))
|
||||
{
|
||||
src_p++;
|
||||
}
|
||||
|
||||
_endCount:
|
||||
|
||||
// Encode MatchLength
|
||||
length = src_p - src_anchor;
|
||||
|
||||
if (dst_p + (length >> 8) > dst_LASTLITERALS_1)
|
||||
{
|
||||
return 0; // Check output limit
|
||||
}
|
||||
|
||||
if (length >= ML_MASK)
|
||||
{
|
||||
dst[dst_token] += ML_MASK;
|
||||
length -= ML_MASK;
|
||||
for (; length > 509; length -= 510)
|
||||
{
|
||||
dst[dst_p++] = 255;
|
||||
dst[dst_p++] = 255;
|
||||
}
|
||||
|
||||
if (length > 254)
|
||||
{
|
||||
length -= 255;
|
||||
dst[dst_p++] = 255;
|
||||
}
|
||||
|
||||
dst[dst_p++] = (byte)length;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[dst_token] += (byte)length;
|
||||
}
|
||||
|
||||
// Test end of chunk
|
||||
if (src_p > src_mflimit)
|
||||
{
|
||||
src_anchor = src_p;
|
||||
break;
|
||||
}
|
||||
|
||||
// Fill table
|
||||
hash_table[(Peek4(src, src_p - 2) * 2654435761u) >> HASH_ADJUST] = src_p - 2 - src_base;
|
||||
|
||||
// Test next position
|
||||
h = (Peek4(src, src_p) * 2654435761u) >> HASH_ADJUST;
|
||||
src_ref = src_base + hash_table[h];
|
||||
hash_table[h] = src_p - src_base;
|
||||
|
||||
if ((src_ref > src_p - (MAX_DISTANCE + 1)) && Equal4(src, src_ref, src_p))
|
||||
{
|
||||
dst_token = dst_p++;
|
||||
dst[dst_token] = 0;
|
||||
goto _next_match;
|
||||
}
|
||||
|
||||
// Prepare next loop
|
||||
src_anchor = src_p++;
|
||||
h_fwd = (Peek4(src, src_p) * 2654435761u) >> HASH_ADJUST;
|
||||
}
|
||||
|
||||
_last_literals:
|
||||
|
||||
// Encode Last Literals
|
||||
{
|
||||
var lastRun = src_end - src_anchor;
|
||||
|
||||
if (dst_p + lastRun + 1 + ((lastRun + 255 - RUN_MASK) / 255) > dst_end)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lastRun >= RUN_MASK)
|
||||
{
|
||||
dst[dst_p++] = RUN_MASK << ML_BITS;
|
||||
lastRun -= RUN_MASK;
|
||||
for (; lastRun > 254; lastRun -= 255)
|
||||
{
|
||||
dst[dst_p++] = 255;
|
||||
}
|
||||
|
||||
dst[dst_p++] = (byte)lastRun;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[dst_p++] = (byte)(lastRun << ML_BITS);
|
||||
}
|
||||
|
||||
BlockCopy(src, src_anchor, dst, dst_p, src_end - src_anchor);
|
||||
dst_p += src_end - src_anchor;
|
||||
}
|
||||
|
||||
// End
|
||||
return dst_p - dst_0;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region LZ4_compress64kCtx
|
||||
|
||||
private static int LZ4_compress64kCtx_safe32(
|
||||
ushort[] hash_table,
|
||||
byte[] src,
|
||||
byte[] dst,
|
||||
int src_0,
|
||||
int dst_0,
|
||||
int src_len,
|
||||
int dst_maxlen)
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var debruijn32 = DEBRUIJN_TABLE_32;
|
||||
int _i;
|
||||
|
||||
// ---- preprocessed source start here ----
|
||||
// r93
|
||||
var src_p = src_0;
|
||||
var src_anchor = src_p;
|
||||
var src_base = src_p;
|
||||
var src_end = src_p + src_len;
|
||||
var src_mflimit = src_end - MFLIMIT;
|
||||
|
||||
var dst_p = dst_0;
|
||||
var dst_end = dst_p + dst_maxlen;
|
||||
|
||||
var src_LASTLITERALS = src_end - LASTLITERALS;
|
||||
var src_LASTLITERALS_1 = src_LASTLITERALS - 1;
|
||||
|
||||
var src_LASTLITERALS_STEPSIZE_1 = src_LASTLITERALS - (STEPSIZE_32 - 1);
|
||||
var dst_LASTLITERALS_1 = dst_end - (1 + LASTLITERALS);
|
||||
var dst_LASTLITERALS_3 = dst_end - (2 + 1 + LASTLITERALS);
|
||||
|
||||
int len, length;
|
||||
|
||||
uint h, h_fwd;
|
||||
|
||||
// Init
|
||||
if (src_len < MINLENGTH)
|
||||
{
|
||||
goto _last_literals;
|
||||
}
|
||||
|
||||
// First Byte
|
||||
src_p++;
|
||||
h_fwd = (Peek4(src, src_p) * 2654435761u) >> HASH64K_ADJUST;
|
||||
|
||||
// Main Loop
|
||||
while (true)
|
||||
{
|
||||
var findMatchAttempts = (1 << SKIPSTRENGTH) + 3;
|
||||
var src_p_fwd = src_p;
|
||||
int src_ref;
|
||||
int dst_token;
|
||||
|
||||
// Find a match
|
||||
do
|
||||
{
|
||||
h = h_fwd;
|
||||
var step = findMatchAttempts++ >> SKIPSTRENGTH;
|
||||
src_p = src_p_fwd;
|
||||
src_p_fwd = src_p + step;
|
||||
|
||||
if (src_p_fwd > src_mflimit)
|
||||
{
|
||||
goto _last_literals;
|
||||
}
|
||||
|
||||
h_fwd = (Peek4(src, src_p_fwd) * 2654435761u) >> HASH64K_ADJUST;
|
||||
src_ref = src_base + hash_table[h];
|
||||
hash_table[h] = (ushort)(src_p - src_base);
|
||||
}
|
||||
while (!Equal4(src, src_ref, src_p));
|
||||
|
||||
// Catch up
|
||||
while ((src_p > src_anchor) && (src_ref > src_0) && (src[src_p - 1] == src[src_ref - 1]))
|
||||
{
|
||||
src_p--;
|
||||
src_ref--;
|
||||
}
|
||||
|
||||
// Encode Literal length
|
||||
length = src_p - src_anchor;
|
||||
dst_token = dst_p++;
|
||||
|
||||
if (dst_p + length + (length >> 8) > dst_LASTLITERALS_3)
|
||||
{
|
||||
return 0; // Check output limit
|
||||
}
|
||||
|
||||
if (length >= RUN_MASK)
|
||||
{
|
||||
len = length - RUN_MASK;
|
||||
dst[dst_token] = RUN_MASK << ML_BITS;
|
||||
if (len > 254)
|
||||
{
|
||||
do
|
||||
{
|
||||
dst[dst_p++] = 255;
|
||||
len -= 255;
|
||||
}
|
||||
while (len > 254);
|
||||
dst[dst_p++] = (byte)len;
|
||||
BlockCopy(src, src_anchor, dst, dst_p, length);
|
||||
dst_p += length;
|
||||
goto _next_match;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[dst_p++] = (byte)len;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[dst_token] = (byte)(length << ML_BITS);
|
||||
}
|
||||
|
||||
// Copy Literals
|
||||
if (length > 0)
|
||||
{
|
||||
_i = dst_p + length;
|
||||
WildCopy(src, src_anchor, dst, dst_p, _i);
|
||||
dst_p = _i;
|
||||
}
|
||||
|
||||
_next_match:
|
||||
|
||||
// Encode Offset
|
||||
Poke2(dst, dst_p, (ushort)(src_p - src_ref));
|
||||
dst_p += 2;
|
||||
|
||||
// Start Counting
|
||||
src_p += MINMATCH;
|
||||
src_ref += MINMATCH; // MinMatch verified
|
||||
src_anchor = src_p;
|
||||
|
||||
while (src_p < src_LASTLITERALS_STEPSIZE_1)
|
||||
{
|
||||
var diff = (int)Xor4(src, src_ref, src_p);
|
||||
if (diff == 0)
|
||||
{
|
||||
src_p += STEPSIZE_32;
|
||||
src_ref += STEPSIZE_32;
|
||||
continue;
|
||||
}
|
||||
|
||||
src_p += debruijn32[((uint)(diff & -diff) * 0x077CB531u) >> 27];
|
||||
goto _endCount;
|
||||
}
|
||||
|
||||
if ((src_p < src_LASTLITERALS_1) && Equal2(src, src_ref, src_p))
|
||||
{
|
||||
src_p += 2;
|
||||
src_ref += 2;
|
||||
}
|
||||
|
||||
if ((src_p < src_LASTLITERALS) && (src[src_ref] == src[src_p]))
|
||||
{
|
||||
src_p++;
|
||||
}
|
||||
|
||||
_endCount:
|
||||
|
||||
// Encode MatchLength
|
||||
len = src_p - src_anchor;
|
||||
|
||||
if (dst_p + (len >> 8) > dst_LASTLITERALS_1)
|
||||
{
|
||||
return 0; // Check output limit
|
||||
}
|
||||
|
||||
if (len >= ML_MASK)
|
||||
{
|
||||
dst[dst_token] += ML_MASK;
|
||||
len -= ML_MASK;
|
||||
for (; len > 509; len -= 510)
|
||||
{
|
||||
dst[dst_p++] = 255;
|
||||
dst[dst_p++] = 255;
|
||||
}
|
||||
|
||||
if (len > 254)
|
||||
{
|
||||
len -= 255;
|
||||
dst[dst_p++] = 255;
|
||||
}
|
||||
|
||||
dst[dst_p++] = (byte)len;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[dst_token] += (byte)len;
|
||||
}
|
||||
|
||||
// Test end of chunk
|
||||
if (src_p > src_mflimit)
|
||||
{
|
||||
src_anchor = src_p;
|
||||
break;
|
||||
}
|
||||
|
||||
// Fill table
|
||||
hash_table[(Peek4(src, src_p - 2) * 2654435761u) >> HASH64K_ADJUST] = (ushort)(src_p - 2 - src_base);
|
||||
|
||||
// Test next position
|
||||
h = (Peek4(src, src_p) * 2654435761u) >> HASH64K_ADJUST;
|
||||
src_ref = src_base + hash_table[h];
|
||||
hash_table[h] = (ushort)(src_p - src_base);
|
||||
|
||||
if (Equal4(src, src_ref, src_p))
|
||||
{
|
||||
dst_token = dst_p++;
|
||||
dst[dst_token] = 0;
|
||||
goto _next_match;
|
||||
}
|
||||
|
||||
// Prepare next loop
|
||||
src_anchor = src_p++;
|
||||
h_fwd = (Peek4(src, src_p) * 2654435761u) >> HASH64K_ADJUST;
|
||||
}
|
||||
|
||||
_last_literals:
|
||||
|
||||
// Encode Last Literals
|
||||
var lastRun = src_end - src_anchor;
|
||||
if (dst_p + lastRun + 1 + ((lastRun - RUN_MASK + 255) / 255) > dst_end)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lastRun >= RUN_MASK)
|
||||
{
|
||||
dst[dst_p++] = RUN_MASK << ML_BITS;
|
||||
lastRun -= RUN_MASK;
|
||||
for (; lastRun > 254; lastRun -= 255)
|
||||
{
|
||||
dst[dst_p++] = 255;
|
||||
}
|
||||
|
||||
dst[dst_p++] = (byte)lastRun;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[dst_p++] = (byte)(lastRun << ML_BITS);
|
||||
}
|
||||
|
||||
BlockCopy(src, src_anchor, dst, dst_p, src_end - src_anchor);
|
||||
dst_p += src_end - src_anchor;
|
||||
|
||||
// End
|
||||
return dst_p - dst_0;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region LZ4_uncompress
|
||||
|
||||
private static int LZ4_uncompress_safe32(
|
||||
byte[] src,
|
||||
byte[] dst,
|
||||
int src_0,
|
||||
int dst_0,
|
||||
int dst_len)
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var dec32table = DECODER_TABLE_32;
|
||||
int _i;
|
||||
|
||||
// ---- preprocessed source start here ----
|
||||
// r93
|
||||
var src_p = src_0;
|
||||
int dst_ref;
|
||||
|
||||
var dst_p = dst_0;
|
||||
var dst_end = dst_p + dst_len;
|
||||
int dst_cpy;
|
||||
|
||||
var dst_LASTLITERALS = dst_end - LASTLITERALS;
|
||||
var dst_COPYLENGTH = dst_end - COPYLENGTH;
|
||||
var dst_COPYLENGTH_STEPSIZE_4 = dst_end - COPYLENGTH - (STEPSIZE_32 - 4);
|
||||
|
||||
byte token;
|
||||
|
||||
// Main Loop
|
||||
while (true)
|
||||
{
|
||||
int length;
|
||||
|
||||
// get runlength
|
||||
token = src[src_p++];
|
||||
if ((length = token >> ML_BITS) == RUN_MASK)
|
||||
{
|
||||
int len;
|
||||
for (; (len = src[src_p++]) == 255; length += 255)
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
length += len;
|
||||
}
|
||||
|
||||
// copy literals
|
||||
dst_cpy = dst_p + length;
|
||||
|
||||
if (dst_cpy > dst_COPYLENGTH)
|
||||
{
|
||||
if (dst_cpy != dst_end)
|
||||
{
|
||||
goto _output_error; // Error : not enough place for another match (min 4) + 5 literals
|
||||
}
|
||||
|
||||
BlockCopy(src, src_p, dst, dst_p, length);
|
||||
src_p += length;
|
||||
break; // EOF
|
||||
}
|
||||
|
||||
if (dst_p < dst_cpy)
|
||||
{
|
||||
_i = WildCopy(src, src_p, dst, dst_p, dst_cpy);
|
||||
src_p += _i;
|
||||
dst_p += _i;
|
||||
}
|
||||
|
||||
src_p -= dst_p - dst_cpy;
|
||||
dst_p = dst_cpy;
|
||||
|
||||
// get offset
|
||||
dst_ref = dst_cpy - Peek2(src, src_p);
|
||||
src_p += 2;
|
||||
if (dst_ref < dst_0)
|
||||
{
|
||||
goto _output_error; // Error : offset outside destination buffer
|
||||
}
|
||||
|
||||
// get matchlength
|
||||
if ((length = token & ML_MASK) == ML_MASK)
|
||||
{
|
||||
for (; src[src_p] == 255; length += 255)
|
||||
{
|
||||
src_p++;
|
||||
}
|
||||
|
||||
length += src[src_p++];
|
||||
}
|
||||
|
||||
// copy repeated sequence
|
||||
if ((dst_p - dst_ref) < STEPSIZE_32)
|
||||
{
|
||||
const int dec64 = 0;
|
||||
dst[dst_p + 0] = dst[dst_ref + 0];
|
||||
dst[dst_p + 1] = dst[dst_ref + 1];
|
||||
dst[dst_p + 2] = dst[dst_ref + 2];
|
||||
dst[dst_p + 3] = dst[dst_ref + 3];
|
||||
dst_p += 4;
|
||||
dst_ref += 4;
|
||||
dst_ref -= dec32table[dst_p - dst_ref];
|
||||
Copy4(dst, dst_ref, dst_p);
|
||||
dst_p += STEPSIZE_32 - 4;
|
||||
dst_ref -= dec64;
|
||||
}
|
||||
else
|
||||
{
|
||||
Copy4(dst, dst_ref, dst_p);
|
||||
dst_p += 4;
|
||||
dst_ref += 4;
|
||||
}
|
||||
|
||||
dst_cpy = dst_p + length - (STEPSIZE_32 - 4);
|
||||
|
||||
if (dst_cpy > dst_COPYLENGTH_STEPSIZE_4)
|
||||
{
|
||||
if (dst_cpy > dst_LASTLITERALS)
|
||||
{
|
||||
goto _output_error; // Error : last 5 bytes must be literals
|
||||
}
|
||||
|
||||
if (dst_p < dst_COPYLENGTH)
|
||||
{
|
||||
_i = SecureCopy(dst, dst_ref, dst_p, dst_COPYLENGTH);
|
||||
dst_ref += _i;
|
||||
dst_p += _i;
|
||||
}
|
||||
|
||||
while (dst_p < dst_cpy)
|
||||
{
|
||||
dst[dst_p++] = dst[dst_ref++];
|
||||
}
|
||||
|
||||
dst_p = dst_cpy;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dst_p < dst_cpy)
|
||||
{
|
||||
SecureCopy(dst, dst_ref, dst_p, dst_cpy);
|
||||
}
|
||||
|
||||
dst_p = dst_cpy; // correction
|
||||
}
|
||||
|
||||
// end of decoding
|
||||
return src_p - src_0;
|
||||
|
||||
// write overflow error detected
|
||||
_output_error:
|
||||
return -(src_p - src_0);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
11
Assets/Scripts/MessagePack/LZ4/LZ4Codec.Safe32.Dirty.cs.meta
Normal file
11
Assets/Scripts/MessagePack/LZ4/LZ4Codec.Safe32.Dirty.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4e76c34fb36d14138b0196dbb3bdc544
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
774
Assets/Scripts/MessagePack/LZ4/LZ4Codec.Safe64.Dirty.cs
Normal file
774
Assets/Scripts/MessagePack/LZ4/LZ4Codec.Safe64.Dirty.cs
Normal file
|
|
@ -0,0 +1,774 @@
|
|||
// Copyright (c) All contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
|
||||
#region LZ4 original
|
||||
|
||||
/*
|
||||
LZ4 - Fast LZ compression algorithm
|
||||
Copyright (C) 2011-2012, Yann Collet.
|
||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
You can contact the author at :
|
||||
- LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
|
||||
- LZ4 source repository : http://code.google.com/p/lz4/
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region LZ4 port
|
||||
|
||||
/*
|
||||
Copyright (c) 2013, Milosz Krajewski
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions
|
||||
and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#pragma warning disable SA1312 // Variable names should begin with lower-case letter
|
||||
|
||||
namespace MessagePack.LZ4
|
||||
{
|
||||
internal partial class LZ4Codec
|
||||
{
|
||||
#region LZ4_compressCtx
|
||||
|
||||
private static int LZ4_compressCtx_safe64(
|
||||
int[] hash_table,
|
||||
byte[] src,
|
||||
byte[] dst,
|
||||
int src_0,
|
||||
int dst_0,
|
||||
int src_len,
|
||||
int dst_maxlen)
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var debruijn64 = DEBRUIJN_TABLE_64;
|
||||
int _i;
|
||||
|
||||
// ---- preprocessed source start here ----
|
||||
// r93
|
||||
var src_p = src_0;
|
||||
var src_base = src_0;
|
||||
var src_anchor = src_p;
|
||||
var src_end = src_p + src_len;
|
||||
var src_mflimit = src_end - MFLIMIT;
|
||||
|
||||
var dst_p = dst_0;
|
||||
var dst_end = dst_p + dst_maxlen;
|
||||
|
||||
var src_LASTLITERALS = src_end - LASTLITERALS;
|
||||
var src_LASTLITERALS_1 = src_LASTLITERALS - 1;
|
||||
|
||||
var src_LASTLITERALS_3 = src_LASTLITERALS - 3;
|
||||
|
||||
var src_LASTLITERALS_STEPSIZE_1 = src_LASTLITERALS - (STEPSIZE_64 - 1);
|
||||
var dst_LASTLITERALS_1 = dst_end - (1 + LASTLITERALS);
|
||||
var dst_LASTLITERALS_3 = dst_end - (2 + 1 + LASTLITERALS);
|
||||
|
||||
int length;
|
||||
|
||||
uint h, h_fwd;
|
||||
|
||||
// Init
|
||||
if (src_len < MINLENGTH)
|
||||
{
|
||||
goto _last_literals;
|
||||
}
|
||||
|
||||
// First Byte
|
||||
hash_table[(Peek4(src, src_p) * 2654435761u) >> HASH_ADJUST] = src_p - src_base;
|
||||
src_p++;
|
||||
h_fwd = (Peek4(src, src_p) * 2654435761u) >> HASH_ADJUST;
|
||||
|
||||
// Main Loop
|
||||
while (true)
|
||||
{
|
||||
var findMatchAttempts = (1 << SKIPSTRENGTH) + 3;
|
||||
var src_p_fwd = src_p;
|
||||
int src_ref;
|
||||
int dst_token;
|
||||
|
||||
// Find a match
|
||||
do
|
||||
{
|
||||
h = h_fwd;
|
||||
var step = findMatchAttempts++ >> SKIPSTRENGTH;
|
||||
src_p = src_p_fwd;
|
||||
src_p_fwd = src_p + step;
|
||||
|
||||
if (src_p_fwd > src_mflimit)
|
||||
{
|
||||
goto _last_literals;
|
||||
}
|
||||
|
||||
h_fwd = (Peek4(src, src_p_fwd) * 2654435761u) >> HASH_ADJUST;
|
||||
src_ref = src_base + hash_table[h];
|
||||
hash_table[h] = src_p - src_base;
|
||||
}
|
||||
while ((src_ref < src_p - MAX_DISTANCE) || (!Equal4(src, src_ref, src_p)));
|
||||
|
||||
// Catch up
|
||||
while ((src_p > src_anchor) && (src_ref > src_0) && (src[src_p - 1] == src[src_ref - 1]))
|
||||
{
|
||||
src_p--;
|
||||
src_ref--;
|
||||
}
|
||||
|
||||
// Encode Literal length
|
||||
length = src_p - src_anchor;
|
||||
dst_token = dst_p++;
|
||||
|
||||
if (dst_p + length + (length >> 8) > dst_LASTLITERALS_3)
|
||||
{
|
||||
return 0; // Check output limit
|
||||
}
|
||||
|
||||
if (length >= RUN_MASK)
|
||||
{
|
||||
var len = length - RUN_MASK;
|
||||
dst[dst_token] = RUN_MASK << ML_BITS;
|
||||
if (len > 254)
|
||||
{
|
||||
do
|
||||
{
|
||||
dst[dst_p++] = 255;
|
||||
len -= 255;
|
||||
}
|
||||
while (len > 254);
|
||||
dst[dst_p++] = (byte)len;
|
||||
BlockCopy(src, src_anchor, dst, dst_p, length);
|
||||
dst_p += length;
|
||||
goto _next_match;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[dst_p++] = (byte)len;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[dst_token] = (byte)(length << ML_BITS);
|
||||
}
|
||||
|
||||
// Copy Literals
|
||||
if (length > 0)
|
||||
{
|
||||
_i = dst_p + length;
|
||||
WildCopy(src, src_anchor, dst, dst_p, _i);
|
||||
dst_p = _i;
|
||||
}
|
||||
|
||||
_next_match:
|
||||
|
||||
// Encode Offset
|
||||
Poke2(dst, dst_p, (ushort)(src_p - src_ref));
|
||||
dst_p += 2;
|
||||
|
||||
// Start Counting
|
||||
src_p += MINMATCH;
|
||||
src_ref += MINMATCH; // MinMatch already verified
|
||||
src_anchor = src_p;
|
||||
|
||||
while (src_p < src_LASTLITERALS_STEPSIZE_1)
|
||||
{
|
||||
var diff = (long)Xor8(src, src_ref, src_p);
|
||||
if (diff == 0)
|
||||
{
|
||||
src_p += STEPSIZE_64;
|
||||
src_ref += STEPSIZE_64;
|
||||
continue;
|
||||
}
|
||||
|
||||
src_p += debruijn64[((ulong)(diff & -diff) * 0x0218A392CDABBD3FL) >> 58];
|
||||
goto _endCount;
|
||||
}
|
||||
|
||||
if ((src_p < src_LASTLITERALS_3) && Equal4(src, src_ref, src_p))
|
||||
{
|
||||
src_p += 4;
|
||||
src_ref += 4;
|
||||
}
|
||||
|
||||
if ((src_p < src_LASTLITERALS_1) && Equal2(src, src_ref, src_p))
|
||||
{
|
||||
src_p += 2;
|
||||
src_ref += 2;
|
||||
}
|
||||
|
||||
if ((src_p < src_LASTLITERALS) && (src[src_ref] == src[src_p]))
|
||||
{
|
||||
src_p++;
|
||||
}
|
||||
|
||||
_endCount:
|
||||
|
||||
// Encode MatchLength
|
||||
length = src_p - src_anchor;
|
||||
|
||||
if (dst_p + (length >> 8) > dst_LASTLITERALS_1)
|
||||
{
|
||||
return 0; // Check output limit
|
||||
}
|
||||
|
||||
if (length >= ML_MASK)
|
||||
{
|
||||
dst[dst_token] += ML_MASK;
|
||||
length -= ML_MASK;
|
||||
for (; length > 509; length -= 510)
|
||||
{
|
||||
dst[dst_p++] = 255;
|
||||
dst[dst_p++] = 255;
|
||||
}
|
||||
|
||||
if (length > 254)
|
||||
{
|
||||
length -= 255;
|
||||
dst[dst_p++] = 255;
|
||||
}
|
||||
|
||||
dst[dst_p++] = (byte)length;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[dst_token] += (byte)length;
|
||||
}
|
||||
|
||||
// Test end of chunk
|
||||
if (src_p > src_mflimit)
|
||||
{
|
||||
src_anchor = src_p;
|
||||
break;
|
||||
}
|
||||
|
||||
// Fill table
|
||||
hash_table[(Peek4(src, src_p - 2) * 2654435761u) >> HASH_ADJUST] = src_p - 2 - src_base;
|
||||
|
||||
// Test next position
|
||||
h = (Peek4(src, src_p) * 2654435761u) >> HASH_ADJUST;
|
||||
src_ref = src_base + hash_table[h];
|
||||
hash_table[h] = src_p - src_base;
|
||||
|
||||
if ((src_ref > src_p - (MAX_DISTANCE + 1)) && Equal4(src, src_ref, src_p))
|
||||
{
|
||||
dst_token = dst_p++;
|
||||
dst[dst_token] = 0;
|
||||
goto _next_match;
|
||||
}
|
||||
|
||||
// Prepare next loop
|
||||
src_anchor = src_p++;
|
||||
h_fwd = (Peek4(src, src_p) * 2654435761u) >> HASH_ADJUST;
|
||||
}
|
||||
|
||||
_last_literals:
|
||||
|
||||
// Encode Last Literals
|
||||
{
|
||||
var lastRun = src_end - src_anchor;
|
||||
|
||||
if (dst_p + lastRun + 1 + ((lastRun + 255 - RUN_MASK) / 255) > dst_end)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lastRun >= RUN_MASK)
|
||||
{
|
||||
dst[dst_p++] = RUN_MASK << ML_BITS;
|
||||
lastRun -= RUN_MASK;
|
||||
for (; lastRun > 254; lastRun -= 255)
|
||||
{
|
||||
dst[dst_p++] = 255;
|
||||
}
|
||||
|
||||
dst[dst_p++] = (byte)lastRun;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[dst_p++] = (byte)(lastRun << ML_BITS);
|
||||
}
|
||||
|
||||
BlockCopy(src, src_anchor, dst, dst_p, src_end - src_anchor);
|
||||
dst_p += src_end - src_anchor;
|
||||
}
|
||||
|
||||
// End
|
||||
return dst_p - dst_0;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region LZ4_compress64kCtx
|
||||
|
||||
private static int LZ4_compress64kCtx_safe64(
|
||||
ushort[] hash_table,
|
||||
byte[] src,
|
||||
byte[] dst,
|
||||
int src_0,
|
||||
int dst_0,
|
||||
int src_len,
|
||||
int dst_maxlen)
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var debruijn64 = DEBRUIJN_TABLE_64;
|
||||
int _i;
|
||||
|
||||
// ---- preprocessed source start here ----
|
||||
// r93
|
||||
var src_p = src_0;
|
||||
var src_anchor = src_p;
|
||||
var src_base = src_p;
|
||||
var src_end = src_p + src_len;
|
||||
var src_mflimit = src_end - MFLIMIT;
|
||||
|
||||
var dst_p = dst_0;
|
||||
var dst_end = dst_p + dst_maxlen;
|
||||
|
||||
var src_LASTLITERALS = src_end - LASTLITERALS;
|
||||
var src_LASTLITERALS_1 = src_LASTLITERALS - 1;
|
||||
|
||||
var src_LASTLITERALS_3 = src_LASTLITERALS - 3;
|
||||
|
||||
var src_LASTLITERALS_STEPSIZE_1 = src_LASTLITERALS - (STEPSIZE_64 - 1);
|
||||
var dst_LASTLITERALS_1 = dst_end - (1 + LASTLITERALS);
|
||||
var dst_LASTLITERALS_3 = dst_end - (2 + 1 + LASTLITERALS);
|
||||
|
||||
int len, length;
|
||||
|
||||
uint h, h_fwd;
|
||||
|
||||
// Init
|
||||
if (src_len < MINLENGTH)
|
||||
{
|
||||
goto _last_literals;
|
||||
}
|
||||
|
||||
// First Byte
|
||||
src_p++;
|
||||
h_fwd = (Peek4(src, src_p) * 2654435761u) >> HASH64K_ADJUST;
|
||||
|
||||
// Main Loop
|
||||
while (true)
|
||||
{
|
||||
var findMatchAttempts = (1 << SKIPSTRENGTH) + 3;
|
||||
var src_p_fwd = src_p;
|
||||
int src_ref;
|
||||
int dst_token;
|
||||
|
||||
// Find a match
|
||||
do
|
||||
{
|
||||
h = h_fwd;
|
||||
var step = findMatchAttempts++ >> SKIPSTRENGTH;
|
||||
src_p = src_p_fwd;
|
||||
src_p_fwd = src_p + step;
|
||||
|
||||
if (src_p_fwd > src_mflimit)
|
||||
{
|
||||
goto _last_literals;
|
||||
}
|
||||
|
||||
h_fwd = (Peek4(src, src_p_fwd) * 2654435761u) >> HASH64K_ADJUST;
|
||||
src_ref = src_base + hash_table[h];
|
||||
hash_table[h] = (ushort)(src_p - src_base);
|
||||
}
|
||||
while (!Equal4(src, src_ref, src_p));
|
||||
|
||||
// Catch up
|
||||
while ((src_p > src_anchor) && (src_ref > src_0) && (src[src_p - 1] == src[src_ref - 1]))
|
||||
{
|
||||
src_p--;
|
||||
src_ref--;
|
||||
}
|
||||
|
||||
// Encode Literal length
|
||||
length = src_p - src_anchor;
|
||||
dst_token = dst_p++;
|
||||
|
||||
if (dst_p + length + (length >> 8) > dst_LASTLITERALS_3)
|
||||
{
|
||||
return 0; // Check output limit
|
||||
}
|
||||
|
||||
if (length >= RUN_MASK)
|
||||
{
|
||||
len = length - RUN_MASK;
|
||||
dst[dst_token] = RUN_MASK << ML_BITS;
|
||||
if (len > 254)
|
||||
{
|
||||
do
|
||||
{
|
||||
dst[dst_p++] = 255;
|
||||
len -= 255;
|
||||
}
|
||||
while (len > 254);
|
||||
dst[dst_p++] = (byte)len;
|
||||
BlockCopy(src, src_anchor, dst, dst_p, length);
|
||||
dst_p += length;
|
||||
goto _next_match;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[dst_p++] = (byte)len;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[dst_token] = (byte)(length << ML_BITS);
|
||||
}
|
||||
|
||||
// Copy Literals
|
||||
if (length > 0)
|
||||
{
|
||||
_i = dst_p + length;
|
||||
WildCopy(src, src_anchor, dst, dst_p, _i);
|
||||
dst_p = _i;
|
||||
}
|
||||
|
||||
_next_match:
|
||||
|
||||
// Encode Offset
|
||||
Poke2(dst, dst_p, (ushort)(src_p - src_ref));
|
||||
dst_p += 2;
|
||||
|
||||
// Start Counting
|
||||
src_p += MINMATCH;
|
||||
src_ref += MINMATCH; // MinMatch verified
|
||||
src_anchor = src_p;
|
||||
|
||||
while (src_p < src_LASTLITERALS_STEPSIZE_1)
|
||||
{
|
||||
var diff = (long)Xor8(src, src_ref, src_p);
|
||||
if (diff == 0)
|
||||
{
|
||||
src_p += STEPSIZE_64;
|
||||
src_ref += STEPSIZE_64;
|
||||
continue;
|
||||
}
|
||||
|
||||
src_p += debruijn64[((ulong)(diff & -diff) * 0x0218A392CDABBD3FL) >> 58];
|
||||
goto _endCount;
|
||||
}
|
||||
|
||||
if ((src_p < src_LASTLITERALS_3) && Equal4(src, src_ref, src_p))
|
||||
{
|
||||
src_p += 4;
|
||||
src_ref += 4;
|
||||
}
|
||||
|
||||
if ((src_p < src_LASTLITERALS_1) && Equal2(src, src_ref, src_p))
|
||||
{
|
||||
src_p += 2;
|
||||
src_ref += 2;
|
||||
}
|
||||
|
||||
if ((src_p < src_LASTLITERALS) && (src[src_ref] == src[src_p]))
|
||||
{
|
||||
src_p++;
|
||||
}
|
||||
|
||||
_endCount:
|
||||
|
||||
// Encode MatchLength
|
||||
len = src_p - src_anchor;
|
||||
|
||||
if (dst_p + (len >> 8) > dst_LASTLITERALS_1)
|
||||
{
|
||||
return 0; // Check output limit
|
||||
}
|
||||
|
||||
if (len >= ML_MASK)
|
||||
{
|
||||
dst[dst_token] += ML_MASK;
|
||||
len -= ML_MASK;
|
||||
for (; len > 509; len -= 510)
|
||||
{
|
||||
dst[dst_p++] = 255;
|
||||
dst[dst_p++] = 255;
|
||||
}
|
||||
|
||||
if (len > 254)
|
||||
{
|
||||
len -= 255;
|
||||
dst[dst_p++] = 255;
|
||||
}
|
||||
|
||||
dst[dst_p++] = (byte)len;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[dst_token] += (byte)len;
|
||||
}
|
||||
|
||||
// Test end of chunk
|
||||
if (src_p > src_mflimit)
|
||||
{
|
||||
src_anchor = src_p;
|
||||
break;
|
||||
}
|
||||
|
||||
// Fill table
|
||||
hash_table[(Peek4(src, src_p - 2) * 2654435761u) >> HASH64K_ADJUST] = (ushort)(src_p - 2 - src_base);
|
||||
|
||||
// Test next position
|
||||
h = (Peek4(src, src_p) * 2654435761u) >> HASH64K_ADJUST;
|
||||
src_ref = src_base + hash_table[h];
|
||||
hash_table[h] = (ushort)(src_p - src_base);
|
||||
|
||||
if (Equal4(src, src_ref, src_p))
|
||||
{
|
||||
dst_token = dst_p++;
|
||||
dst[dst_token] = 0;
|
||||
goto _next_match;
|
||||
}
|
||||
|
||||
// Prepare next loop
|
||||
src_anchor = src_p++;
|
||||
h_fwd = (Peek4(src, src_p) * 2654435761u) >> HASH64K_ADJUST;
|
||||
}
|
||||
|
||||
_last_literals:
|
||||
|
||||
// Encode Last Literals
|
||||
{
|
||||
var lastRun = src_end - src_anchor;
|
||||
if (dst_p + lastRun + 1 + ((lastRun - RUN_MASK + 255) / 255) > dst_end)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lastRun >= RUN_MASK)
|
||||
{
|
||||
dst[dst_p++] = RUN_MASK << ML_BITS;
|
||||
lastRun -= RUN_MASK;
|
||||
for (; lastRun > 254; lastRun -= 255)
|
||||
{
|
||||
dst[dst_p++] = 255;
|
||||
}
|
||||
|
||||
dst[dst_p++] = (byte)lastRun;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[dst_p++] = (byte)(lastRun << ML_BITS);
|
||||
}
|
||||
|
||||
BlockCopy(src, src_anchor, dst, dst_p, src_end - src_anchor);
|
||||
dst_p += src_end - src_anchor;
|
||||
}
|
||||
|
||||
// End
|
||||
return dst_p - dst_0;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region LZ4_uncompress
|
||||
|
||||
private static int LZ4_uncompress_safe64(
|
||||
byte[] src,
|
||||
byte[] dst,
|
||||
int src_0,
|
||||
int dst_0,
|
||||
int dst_len)
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var dec32table = DECODER_TABLE_32;
|
||||
var dec64table = DECODER_TABLE_64;
|
||||
int _i;
|
||||
|
||||
// ---- preprocessed source start here ----
|
||||
// r93
|
||||
var src_p = src_0;
|
||||
int dst_ref;
|
||||
|
||||
var dst_p = dst_0;
|
||||
var dst_end = dst_p + dst_len;
|
||||
int dst_cpy;
|
||||
|
||||
var dst_LASTLITERALS = dst_end - LASTLITERALS;
|
||||
var dst_COPYLENGTH = dst_end - COPYLENGTH;
|
||||
var dst_COPYLENGTH_STEPSIZE_4 = dst_end - COPYLENGTH - (STEPSIZE_64 - 4);
|
||||
|
||||
uint token;
|
||||
|
||||
// Main Loop
|
||||
while (true)
|
||||
{
|
||||
int length;
|
||||
|
||||
// get runlength
|
||||
token = src[src_p++];
|
||||
if ((length = (byte)(token >> ML_BITS)) == RUN_MASK)
|
||||
{
|
||||
int len;
|
||||
for (; (len = src[src_p++]) == 255; length += 255)
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
length += len;
|
||||
}
|
||||
|
||||
// copy literals
|
||||
dst_cpy = dst_p + length;
|
||||
|
||||
if (dst_cpy > dst_COPYLENGTH)
|
||||
{
|
||||
if (dst_cpy != dst_end)
|
||||
{
|
||||
goto _output_error; // Error : not enough place for another match (min 4) + 5 literals
|
||||
}
|
||||
|
||||
BlockCopy(src, src_p, dst, dst_p, length);
|
||||
src_p += length;
|
||||
break; // EOF
|
||||
}
|
||||
|
||||
if (dst_p < dst_cpy)
|
||||
{
|
||||
_i = WildCopy(src, src_p, dst, dst_p, dst_cpy);
|
||||
src_p += _i;
|
||||
dst_p += _i;
|
||||
}
|
||||
|
||||
src_p -= dst_p - dst_cpy;
|
||||
dst_p = dst_cpy;
|
||||
|
||||
// get offset
|
||||
dst_ref = dst_cpy - Peek2(src, src_p);
|
||||
src_p += 2;
|
||||
if (dst_ref < dst_0)
|
||||
{
|
||||
goto _output_error; // Error : offset outside destination buffer
|
||||
}
|
||||
|
||||
// get matchlength
|
||||
if ((length = (byte)(token & ML_MASK)) == ML_MASK)
|
||||
{
|
||||
for (; src[src_p] == 255; length += 255)
|
||||
{
|
||||
src_p++;
|
||||
}
|
||||
|
||||
length += src[src_p++];
|
||||
}
|
||||
|
||||
// copy repeated sequence
|
||||
if ((dst_p - dst_ref) < STEPSIZE_64)
|
||||
{
|
||||
var dec64 = dec64table[dst_p - dst_ref];
|
||||
|
||||
dst[dst_p + 0] = dst[dst_ref + 0];
|
||||
dst[dst_p + 1] = dst[dst_ref + 1];
|
||||
dst[dst_p + 2] = dst[dst_ref + 2];
|
||||
dst[dst_p + 3] = dst[dst_ref + 3];
|
||||
dst_p += 4;
|
||||
dst_ref += 4;
|
||||
dst_ref -= dec32table[dst_p - dst_ref];
|
||||
Copy4(dst, dst_ref, dst_p);
|
||||
dst_p += STEPSIZE_64 - 4;
|
||||
dst_ref -= dec64;
|
||||
}
|
||||
else
|
||||
{
|
||||
Copy8(dst, dst_ref, dst_p);
|
||||
dst_p += 8;
|
||||
dst_ref += 8;
|
||||
}
|
||||
|
||||
dst_cpy = dst_p + length - (STEPSIZE_64 - 4);
|
||||
|
||||
if (dst_cpy > dst_COPYLENGTH_STEPSIZE_4)
|
||||
{
|
||||
if (dst_cpy > dst_LASTLITERALS)
|
||||
{
|
||||
goto _output_error; // Error : last 5 bytes must be literals
|
||||
}
|
||||
|
||||
if (dst_p < dst_COPYLENGTH)
|
||||
{
|
||||
_i = SecureCopy(dst, dst_ref, dst_p, dst_COPYLENGTH);
|
||||
dst_ref += _i;
|
||||
dst_p += _i;
|
||||
}
|
||||
|
||||
while (dst_p < dst_cpy)
|
||||
{
|
||||
dst[dst_p++] = dst[dst_ref++];
|
||||
}
|
||||
|
||||
dst_p = dst_cpy;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dst_p < dst_cpy)
|
||||
{
|
||||
SecureCopy(dst, dst_ref, dst_p, dst_cpy);
|
||||
}
|
||||
|
||||
dst_p = dst_cpy; // correction
|
||||
}
|
||||
|
||||
// end of decoding
|
||||
return src_p - src_0;
|
||||
|
||||
_output_error:
|
||||
|
||||
// write overflow error detected
|
||||
return -(src_p - src_0);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
11
Assets/Scripts/MessagePack/LZ4/LZ4Codec.Safe64.Dirty.cs.meta
Normal file
11
Assets/Scripts/MessagePack/LZ4/LZ4Codec.Safe64.Dirty.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 31798435f43678c67b458999c71cfbb3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
118
Assets/Scripts/MessagePack/LZ4/LZ4Codec.Unsafe.cs
Normal file
118
Assets/Scripts/MessagePack/LZ4/LZ4Codec.Unsafe.cs
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
// Copyright (c) All contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#region license
|
||||
|
||||
/*
|
||||
Copyright (c) 2013, Milosz Krajewski
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions
|
||||
and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
|
||||
namespace MessagePack.LZ4
|
||||
{
|
||||
/// <summary>Unsafe LZ4 codec.</summary>
|
||||
internal partial class LZ4Codec
|
||||
{
|
||||
/// <summary>Encodes the specified input.</summary>
|
||||
/// <param name="input">The input.</param>
|
||||
/// <param name="output">The output.</param>
|
||||
/// <returns>Number of bytes written.</returns>
|
||||
public static unsafe int Encode(ReadOnlySpan<byte> input, Span<byte> output)
|
||||
{
|
||||
if (output.Length == 0)
|
||||
{
|
||||
throw new MessagePackSerializationException("Output is empty.");
|
||||
}
|
||||
|
||||
fixed (byte* inputPtr = input)
|
||||
fixed (byte* outputPtr = output)
|
||||
{
|
||||
if (input.Length < LZ4_64KLIMIT)
|
||||
{
|
||||
var uHashTable = HashTablePool.GetUShortHashTablePool();
|
||||
fixed (ushort* hash1 = &uHashTable[0])
|
||||
{
|
||||
if (IntPtr.Size == 4)
|
||||
{
|
||||
return LZ4_compress64kCtx_32(hash1, inputPtr, outputPtr, input.Length, output.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
return LZ4_compress64kCtx_64(hash1, inputPtr, outputPtr, input.Length, output.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var bHashTable = HashTablePool.GetUIntHashTablePool();
|
||||
fixed (uint* hash2 = &bHashTable[0])
|
||||
{
|
||||
if (IntPtr.Size == 4)
|
||||
{
|
||||
return LZ4_compressCtx_32(hash2, inputPtr, outputPtr, input.Length, output.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
return LZ4_compressCtx_64(hash2, inputPtr, outputPtr, input.Length, output.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Decodes the specified input.</summary>
|
||||
/// <param name="input">The input.</param>
|
||||
/// <param name="output">The output.</param>
|
||||
/// <returns>Number of bytes written.</returns>
|
||||
public static unsafe int Decode(ReadOnlySpan<byte> input, Span<byte> output)
|
||||
{
|
||||
if (output.Length == 0)
|
||||
{
|
||||
throw new MessagePackSerializationException("Output is empty.");
|
||||
}
|
||||
|
||||
fixed (byte* inputPtr = input)
|
||||
fixed (byte* outputPtr = output)
|
||||
{
|
||||
int length;
|
||||
if (IntPtr.Size == 4)
|
||||
{
|
||||
length = LZ4_uncompress_32(inputPtr, outputPtr, output.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
length = LZ4_uncompress_64(inputPtr, outputPtr, output.Length);
|
||||
}
|
||||
|
||||
if (length != input.Length)
|
||||
{
|
||||
throw new MessagePackSerializationException("LZ4 block is corrupted, or invalid length has been given.");
|
||||
}
|
||||
|
||||
return output.Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/MessagePack/LZ4/LZ4Codec.Unsafe.cs.meta
Normal file
11
Assets/Scripts/MessagePack/LZ4/LZ4Codec.Unsafe.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 719385c28cab29b71a262f02263f385e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
796
Assets/Scripts/MessagePack/LZ4/LZ4Codec.Unsafe32.Dirty.cs
Normal file
796
Assets/Scripts/MessagePack/LZ4/LZ4Codec.Unsafe32.Dirty.cs
Normal file
|
|
@ -0,0 +1,796 @@
|
|||
// Copyright (c) All contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#region LZ4 original
|
||||
|
||||
/*
|
||||
LZ4 - Fast LZ compression algorithm
|
||||
Copyright (C) 2011-2012, Yann Collet.
|
||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
You can contact the author at :
|
||||
- LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
|
||||
- LZ4 source repository : http://code.google.com/p/lz4/
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region LZ4 port
|
||||
|
||||
/*
|
||||
Copyright (c) 2013, Milosz Krajewski
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions
|
||||
and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#pragma warning disable SA1312 // Variable names should begin with lower-case letter
|
||||
|
||||
namespace MessagePack.LZ4
|
||||
{
|
||||
internal partial class LZ4Codec
|
||||
{
|
||||
#region LZ4_compressCtx_32
|
||||
|
||||
private static unsafe int LZ4_compressCtx_32(
|
||||
uint* hash_table,
|
||||
byte* src,
|
||||
byte* dst,
|
||||
int src_len,
|
||||
int dst_maxlen)
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
byte* _p;
|
||||
|
||||
fixed (int* debruijn32 = &DEBRUIJN_TABLE_32[0])
|
||||
{
|
||||
// r93
|
||||
var src_p = src;
|
||||
var src_base = src_p;
|
||||
var src_anchor = src_p;
|
||||
var src_end = src_p + src_len;
|
||||
var src_mflimit = src_end - MFLIMIT;
|
||||
|
||||
var dst_p = dst;
|
||||
var dst_end = dst_p + dst_maxlen;
|
||||
|
||||
var src_LASTLITERALS = src_end - LASTLITERALS;
|
||||
var src_LASTLITERALS_1 = src_LASTLITERALS - 1;
|
||||
|
||||
var src_LASTLITERALS_STEPSIZE_1 = src_LASTLITERALS - (STEPSIZE_32 - 1);
|
||||
var dst_LASTLITERALS_1 = dst_end - (1 + LASTLITERALS);
|
||||
var dst_LASTLITERALS_3 = dst_end - (2 + 1 + LASTLITERALS);
|
||||
|
||||
int length;
|
||||
|
||||
uint h, h_fwd;
|
||||
|
||||
// Init
|
||||
if (src_len < MINLENGTH)
|
||||
{
|
||||
goto _last_literals;
|
||||
}
|
||||
|
||||
// First Byte
|
||||
hash_table[(*(uint*)src_p * 2654435761u) >> HASH_ADJUST] = (uint)(src_p - src_base);
|
||||
src_p++;
|
||||
h_fwd = (*(uint*)src_p * 2654435761u) >> HASH_ADJUST;
|
||||
|
||||
// Main Loop
|
||||
while (true)
|
||||
{
|
||||
var findMatchAttempts = (1 << SKIPSTRENGTH) + 3;
|
||||
var src_p_fwd = src_p;
|
||||
byte* xxx_ref;
|
||||
byte* xxx_token;
|
||||
|
||||
// Find a match
|
||||
do
|
||||
{
|
||||
h = h_fwd;
|
||||
var step = findMatchAttempts++ >> SKIPSTRENGTH;
|
||||
src_p = src_p_fwd;
|
||||
src_p_fwd = src_p + step;
|
||||
|
||||
if (src_p_fwd > src_mflimit)
|
||||
{
|
||||
goto _last_literals;
|
||||
}
|
||||
|
||||
h_fwd = (*(uint*)src_p_fwd * 2654435761u) >> HASH_ADJUST;
|
||||
xxx_ref = src_base + hash_table[h];
|
||||
hash_table[h] = (uint)(src_p - src_base);
|
||||
}
|
||||
while ((xxx_ref < src_p - MAX_DISTANCE) || ((*(uint*)xxx_ref) != (*(uint*)src_p)));
|
||||
|
||||
// Catch up
|
||||
while ((src_p > src_anchor) && (xxx_ref > src) && (src_p[-1] == xxx_ref[-1]))
|
||||
{
|
||||
src_p--;
|
||||
xxx_ref--;
|
||||
}
|
||||
|
||||
// Encode Literal length
|
||||
length = (int)(src_p - src_anchor);
|
||||
xxx_token = dst_p++;
|
||||
|
||||
if (dst_p + length + (length >> 8) > dst_LASTLITERALS_3)
|
||||
{
|
||||
return 0; // Check output limit
|
||||
}
|
||||
|
||||
if (length >= RUN_MASK)
|
||||
{
|
||||
var len = length - RUN_MASK;
|
||||
*xxx_token = RUN_MASK << ML_BITS;
|
||||
if (len > 254)
|
||||
{
|
||||
do
|
||||
{
|
||||
*dst_p++ = 255;
|
||||
len -= 255;
|
||||
}
|
||||
while (len > 254);
|
||||
*dst_p++ = (byte)len;
|
||||
BlockCopy32(src_anchor, dst_p, length);
|
||||
dst_p += length;
|
||||
goto _next_match;
|
||||
}
|
||||
|
||||
*dst_p++ = (byte)len;
|
||||
}
|
||||
else
|
||||
{
|
||||
*xxx_token = (byte)(length << ML_BITS);
|
||||
}
|
||||
|
||||
// Copy Literals
|
||||
_p = dst_p + length;
|
||||
do
|
||||
{
|
||||
*(uint*)dst_p = *(uint*)src_anchor;
|
||||
dst_p += 4;
|
||||
src_anchor += 4;
|
||||
*(uint*)dst_p = *(uint*)src_anchor;
|
||||
dst_p += 4;
|
||||
src_anchor += 4;
|
||||
}
|
||||
while (dst_p < _p);
|
||||
dst_p = _p;
|
||||
|
||||
_next_match:
|
||||
|
||||
// Encode Offset
|
||||
*(ushort*)dst_p = (ushort)(src_p - xxx_ref);
|
||||
dst_p += 2;
|
||||
|
||||
// Start Counting
|
||||
src_p += MINMATCH;
|
||||
xxx_ref += MINMATCH; // MinMatch already verified
|
||||
src_anchor = src_p;
|
||||
|
||||
while (src_p < src_LASTLITERALS_STEPSIZE_1)
|
||||
{
|
||||
var diff = (*(int*)xxx_ref) ^ (*(int*)src_p);
|
||||
if (diff == 0)
|
||||
{
|
||||
src_p += STEPSIZE_32;
|
||||
xxx_ref += STEPSIZE_32;
|
||||
continue;
|
||||
}
|
||||
|
||||
src_p += debruijn32[((uint)(diff & -diff) * 0x077CB531u) >> 27];
|
||||
goto _endCount;
|
||||
}
|
||||
|
||||
if ((src_p < src_LASTLITERALS_1) && ((*(ushort*)xxx_ref) == (*(ushort*)src_p)))
|
||||
{
|
||||
src_p += 2;
|
||||
xxx_ref += 2;
|
||||
}
|
||||
|
||||
if ((src_p < src_LASTLITERALS) && (*xxx_ref == *src_p))
|
||||
{
|
||||
src_p++;
|
||||
}
|
||||
|
||||
_endCount:
|
||||
|
||||
// Encode MatchLength
|
||||
length = (int)(src_p - src_anchor);
|
||||
|
||||
if (dst_p + (length >> 8) > dst_LASTLITERALS_1)
|
||||
{
|
||||
return 0; // Check output limit
|
||||
}
|
||||
|
||||
if (length >= ML_MASK)
|
||||
{
|
||||
*xxx_token += ML_MASK;
|
||||
length -= ML_MASK;
|
||||
for (; length > 509; length -= 510)
|
||||
{
|
||||
*dst_p++ = 255;
|
||||
*dst_p++ = 255;
|
||||
}
|
||||
|
||||
if (length > 254)
|
||||
{
|
||||
length -= 255;
|
||||
*dst_p++ = 255;
|
||||
}
|
||||
|
||||
*dst_p++ = (byte)length;
|
||||
}
|
||||
else
|
||||
{
|
||||
*xxx_token += (byte)length;
|
||||
}
|
||||
|
||||
// Test end of chunk
|
||||
if (src_p > src_mflimit)
|
||||
{
|
||||
src_anchor = src_p;
|
||||
break;
|
||||
}
|
||||
|
||||
// Fill table
|
||||
hash_table[(*(uint*)(src_p - 2) * 2654435761u) >> HASH_ADJUST] = (uint)(src_p - 2 - src_base);
|
||||
|
||||
// Test next position
|
||||
h = (*(uint*)src_p * 2654435761u) >> HASH_ADJUST;
|
||||
xxx_ref = src_base + hash_table[h];
|
||||
hash_table[h] = (uint)(src_p - src_base);
|
||||
|
||||
if ((xxx_ref > src_p - (MAX_DISTANCE + 1)) && ((*(uint*)xxx_ref) == (*(uint*)src_p)))
|
||||
{
|
||||
xxx_token = dst_p++;
|
||||
*xxx_token = 0;
|
||||
goto _next_match;
|
||||
}
|
||||
|
||||
// Prepare next loop
|
||||
src_anchor = src_p++;
|
||||
h_fwd = (*(uint*)src_p * 2654435761u) >> HASH_ADJUST;
|
||||
}
|
||||
|
||||
_last_literals:
|
||||
|
||||
// Encode Last Literals
|
||||
{
|
||||
var lastRun = (int)(src_end - src_anchor);
|
||||
|
||||
if (dst_p + lastRun + 1 + ((lastRun + 255 - RUN_MASK) / 255) > dst_end)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lastRun >= RUN_MASK)
|
||||
{
|
||||
*dst_p++ = RUN_MASK << ML_BITS;
|
||||
lastRun -= RUN_MASK;
|
||||
for (; lastRun > 254; lastRun -= 255)
|
||||
{
|
||||
*dst_p++ = 255;
|
||||
}
|
||||
|
||||
*dst_p++ = (byte)lastRun;
|
||||
}
|
||||
else
|
||||
{
|
||||
*dst_p++ = (byte)(lastRun << ML_BITS);
|
||||
}
|
||||
|
||||
BlockCopy32(src_anchor, dst_p, (int)(src_end - src_anchor));
|
||||
dst_p += src_end - src_anchor;
|
||||
}
|
||||
|
||||
// End
|
||||
return (int)(dst_p - dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region LZ4_compress64kCtx_32
|
||||
|
||||
private static unsafe int LZ4_compress64kCtx_32(
|
||||
ushort* hash_table,
|
||||
byte* src,
|
||||
byte* dst,
|
||||
int src_len,
|
||||
int dst_maxlen)
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
byte* _p;
|
||||
fixed (int* debruijn32 = &DEBRUIJN_TABLE_32[0])
|
||||
{
|
||||
// r93
|
||||
var src_p = src;
|
||||
var src_anchor = src_p;
|
||||
var src_base = src_p;
|
||||
var src_end = src_p + src_len;
|
||||
var src_mflimit = src_end - MFLIMIT;
|
||||
|
||||
var dst_p = dst;
|
||||
var dst_end = dst_p + dst_maxlen;
|
||||
|
||||
var src_LASTLITERALS = src_end - LASTLITERALS;
|
||||
var src_LASTLITERALS_1 = src_LASTLITERALS - 1;
|
||||
|
||||
var src_LASTLITERALS_STEPSIZE_1 = src_LASTLITERALS - (STEPSIZE_32 - 1);
|
||||
var dst_LASTLITERALS_1 = dst_end - (1 + LASTLITERALS);
|
||||
var dst_LASTLITERALS_3 = dst_end - (2 + 1 + LASTLITERALS);
|
||||
|
||||
int len, length;
|
||||
|
||||
uint h, h_fwd;
|
||||
|
||||
// Init
|
||||
if (src_len < MINLENGTH)
|
||||
{
|
||||
goto _last_literals;
|
||||
}
|
||||
|
||||
// First Byte
|
||||
src_p++;
|
||||
h_fwd = (*(uint*)src_p * 2654435761u) >> HASH64K_ADJUST;
|
||||
|
||||
// Main Loop
|
||||
while (true)
|
||||
{
|
||||
var findMatchAttempts = (1 << SKIPSTRENGTH) + 3;
|
||||
var src_p_fwd = src_p;
|
||||
byte* xxx_ref;
|
||||
byte* xxx_token;
|
||||
|
||||
// Find a match
|
||||
do
|
||||
{
|
||||
h = h_fwd;
|
||||
var step = findMatchAttempts++ >> SKIPSTRENGTH;
|
||||
src_p = src_p_fwd;
|
||||
src_p_fwd = src_p + step;
|
||||
|
||||
if (src_p_fwd > src_mflimit)
|
||||
{
|
||||
goto _last_literals;
|
||||
}
|
||||
|
||||
h_fwd = (*(uint*)src_p_fwd * 2654435761u) >> HASH64K_ADJUST;
|
||||
xxx_ref = src_base + hash_table[h];
|
||||
hash_table[h] = (ushort)(src_p - src_base);
|
||||
}
|
||||
while ((*(uint*)xxx_ref) != (*(uint*)src_p));
|
||||
|
||||
// Catch up
|
||||
while ((src_p > src_anchor) && (xxx_ref > src) && (src_p[-1] == xxx_ref[-1]))
|
||||
{
|
||||
src_p--;
|
||||
xxx_ref--;
|
||||
}
|
||||
|
||||
// Encode Literal length
|
||||
length = (int)(src_p - src_anchor);
|
||||
xxx_token = dst_p++;
|
||||
|
||||
if (dst_p + length + (length >> 8) > dst_LASTLITERALS_3)
|
||||
{
|
||||
return 0; // Check output limit
|
||||
}
|
||||
|
||||
if (length >= RUN_MASK)
|
||||
{
|
||||
len = length - RUN_MASK;
|
||||
*xxx_token = RUN_MASK << ML_BITS;
|
||||
if (len > 254)
|
||||
{
|
||||
do
|
||||
{
|
||||
*dst_p++ = 255;
|
||||
len -= 255;
|
||||
}
|
||||
while (len > 254);
|
||||
*dst_p++ = (byte)len;
|
||||
BlockCopy32(src_anchor, dst_p, length);
|
||||
dst_p += length;
|
||||
goto _next_match;
|
||||
}
|
||||
|
||||
*dst_p++ = (byte)len;
|
||||
}
|
||||
else
|
||||
{
|
||||
*xxx_token = (byte)(length << ML_BITS);
|
||||
}
|
||||
|
||||
// Copy Literals
|
||||
_p = dst_p + length;
|
||||
do
|
||||
{
|
||||
*(uint*)dst_p = *(uint*)src_anchor;
|
||||
dst_p += 4;
|
||||
src_anchor += 4;
|
||||
*(uint*)dst_p = *(uint*)src_anchor;
|
||||
dst_p += 4;
|
||||
src_anchor += 4;
|
||||
}
|
||||
while (dst_p < _p);
|
||||
dst_p = _p;
|
||||
|
||||
_next_match:
|
||||
|
||||
// Encode Offset
|
||||
*(ushort*)dst_p = (ushort)(src_p - xxx_ref);
|
||||
dst_p += 2;
|
||||
|
||||
// Start Counting
|
||||
src_p += MINMATCH;
|
||||
xxx_ref += MINMATCH; // MinMatch verified
|
||||
src_anchor = src_p;
|
||||
|
||||
while (src_p < src_LASTLITERALS_STEPSIZE_1)
|
||||
{
|
||||
var diff = (*(int*)xxx_ref) ^ (*(int*)src_p);
|
||||
if (diff == 0)
|
||||
{
|
||||
src_p += STEPSIZE_32;
|
||||
xxx_ref += STEPSIZE_32;
|
||||
continue;
|
||||
}
|
||||
|
||||
src_p += debruijn32[((uint)(diff & -diff) * 0x077CB531u) >> 27];
|
||||
goto _endCount;
|
||||
}
|
||||
|
||||
if ((src_p < src_LASTLITERALS_1) && ((*(ushort*)xxx_ref) == (*(ushort*)src_p)))
|
||||
{
|
||||
src_p += 2;
|
||||
xxx_ref += 2;
|
||||
}
|
||||
|
||||
if ((src_p < src_LASTLITERALS) && (*xxx_ref == *src_p))
|
||||
{
|
||||
src_p++;
|
||||
}
|
||||
|
||||
_endCount:
|
||||
|
||||
// Encode MatchLength
|
||||
len = (int)(src_p - src_anchor);
|
||||
|
||||
if (dst_p + (len >> 8) > dst_LASTLITERALS_1)
|
||||
{
|
||||
return 0; // Check output limit
|
||||
}
|
||||
|
||||
if (len >= ML_MASK)
|
||||
{
|
||||
*xxx_token += ML_MASK;
|
||||
len -= ML_MASK;
|
||||
for (; len > 509; len -= 510)
|
||||
{
|
||||
*dst_p++ = 255;
|
||||
*dst_p++ = 255;
|
||||
}
|
||||
|
||||
if (len > 254)
|
||||
{
|
||||
len -= 255;
|
||||
*dst_p++ = 255;
|
||||
}
|
||||
|
||||
*dst_p++ = (byte)len;
|
||||
}
|
||||
else
|
||||
{
|
||||
*xxx_token += (byte)len;
|
||||
}
|
||||
|
||||
// Test end of chunk
|
||||
if (src_p > src_mflimit)
|
||||
{
|
||||
src_anchor = src_p;
|
||||
break;
|
||||
}
|
||||
|
||||
// Fill table
|
||||
hash_table[(*(uint*)(src_p - 2) * 2654435761u) >> HASH64K_ADJUST] = (ushort)(src_p - 2 - src_base);
|
||||
|
||||
// Test next position
|
||||
h = (*(uint*)src_p * 2654435761u) >> HASH64K_ADJUST;
|
||||
xxx_ref = src_base + hash_table[h];
|
||||
hash_table[h] = (ushort)(src_p - src_base);
|
||||
|
||||
if ((*(uint*)xxx_ref) == (*(uint*)src_p))
|
||||
{
|
||||
xxx_token = dst_p++;
|
||||
*xxx_token = 0;
|
||||
goto _next_match;
|
||||
}
|
||||
|
||||
// Prepare next loop
|
||||
src_anchor = src_p++;
|
||||
h_fwd = (*(uint*)src_p * 2654435761u) >> HASH64K_ADJUST;
|
||||
}
|
||||
|
||||
_last_literals:
|
||||
|
||||
// Encode Last Literals
|
||||
{
|
||||
var lastRun = (int)(src_end - src_anchor);
|
||||
if (dst_p + lastRun + 1 + ((lastRun - RUN_MASK + 255) / 255) > dst_end)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lastRun >= RUN_MASK)
|
||||
{
|
||||
*dst_p++ = RUN_MASK << ML_BITS;
|
||||
lastRun -= RUN_MASK;
|
||||
for (; lastRun > 254; lastRun -= 255)
|
||||
{
|
||||
*dst_p++ = 255;
|
||||
}
|
||||
|
||||
*dst_p++ = (byte)lastRun;
|
||||
}
|
||||
else
|
||||
{
|
||||
*dst_p++ = (byte)(lastRun << ML_BITS);
|
||||
}
|
||||
|
||||
BlockCopy32(src_anchor, dst_p, (int)(src_end - src_anchor));
|
||||
dst_p += src_end - src_anchor;
|
||||
}
|
||||
|
||||
// End
|
||||
return (int)(dst_p - dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region LZ4_uncompress_32
|
||||
|
||||
private static unsafe int LZ4_uncompress_32(
|
||||
byte* src,
|
||||
byte* dst,
|
||||
int dst_len)
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
fixed (int* dec32table = &DECODER_TABLE_32[0])
|
||||
{
|
||||
// r93
|
||||
var src_p = src;
|
||||
byte* xxx_ref;
|
||||
|
||||
var dst_p = dst;
|
||||
var dst_end = dst_p + dst_len;
|
||||
byte* dst_cpy;
|
||||
|
||||
var dst_LASTLITERALS = dst_end - LASTLITERALS;
|
||||
var dst_COPYLENGTH = dst_end - COPYLENGTH;
|
||||
var dst_COPYLENGTH_STEPSIZE_4 = dst_end - COPYLENGTH - (STEPSIZE_32 - 4);
|
||||
|
||||
uint xxx_token;
|
||||
|
||||
// Main Loop
|
||||
while (true)
|
||||
{
|
||||
int length;
|
||||
|
||||
// get runlength
|
||||
xxx_token = *src_p++;
|
||||
if ((length = (int)(xxx_token >> ML_BITS)) == RUN_MASK)
|
||||
{
|
||||
int len;
|
||||
for (; (len = *src_p++) == 255; length += 255)
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
length += len;
|
||||
}
|
||||
|
||||
// copy literals
|
||||
dst_cpy = dst_p + length;
|
||||
|
||||
if (dst_cpy > dst_COPYLENGTH)
|
||||
{
|
||||
if (dst_cpy != dst_end)
|
||||
{
|
||||
goto _output_error; // Error : not enough place for another match (min 4) + 5 literals
|
||||
}
|
||||
|
||||
BlockCopy32(src_p, dst_p, length);
|
||||
src_p += length;
|
||||
break; // EOF
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
*(uint*)dst_p = *(uint*)src_p;
|
||||
dst_p += 4;
|
||||
src_p += 4;
|
||||
*(uint*)dst_p = *(uint*)src_p;
|
||||
dst_p += 4;
|
||||
src_p += 4;
|
||||
}
|
||||
while (dst_p < dst_cpy);
|
||||
src_p -= dst_p - dst_cpy;
|
||||
dst_p = dst_cpy;
|
||||
|
||||
// get offset
|
||||
xxx_ref = dst_cpy - (*(ushort*)src_p);
|
||||
src_p += 2;
|
||||
if (xxx_ref < dst)
|
||||
{
|
||||
goto _output_error; // Error : offset outside destination buffer
|
||||
}
|
||||
|
||||
// get matchlength
|
||||
if ((length = (int)(xxx_token & ML_MASK)) == ML_MASK)
|
||||
{
|
||||
for (; *src_p == 255; length += 255)
|
||||
{
|
||||
src_p++;
|
||||
}
|
||||
|
||||
length += *src_p++;
|
||||
}
|
||||
|
||||
// copy repeated sequence
|
||||
if ((dst_p - xxx_ref) < STEPSIZE_32)
|
||||
{
|
||||
const int dec64 = 0;
|
||||
|
||||
dst_p[0] = xxx_ref[0];
|
||||
dst_p[1] = xxx_ref[1];
|
||||
dst_p[2] = xxx_ref[2];
|
||||
dst_p[3] = xxx_ref[3];
|
||||
dst_p += 4;
|
||||
xxx_ref += 4;
|
||||
xxx_ref -= dec32table[dst_p - xxx_ref];
|
||||
*(uint*)dst_p = *(uint*)xxx_ref;
|
||||
dst_p += STEPSIZE_32 - 4;
|
||||
xxx_ref -= dec64;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(uint*)dst_p = *(uint*)xxx_ref;
|
||||
dst_p += 4;
|
||||
xxx_ref += 4;
|
||||
}
|
||||
|
||||
dst_cpy = dst_p + length - (STEPSIZE_32 - 4);
|
||||
|
||||
if (dst_cpy > dst_COPYLENGTH_STEPSIZE_4)
|
||||
{
|
||||
if (dst_cpy > dst_LASTLITERALS)
|
||||
{
|
||||
goto _output_error; // Error : last 5 bytes must be literals
|
||||
}
|
||||
|
||||
{
|
||||
do
|
||||
{
|
||||
*(uint*)dst_p = *(uint*)xxx_ref;
|
||||
dst_p += 4;
|
||||
xxx_ref += 4;
|
||||
*(uint*)dst_p = *(uint*)xxx_ref;
|
||||
dst_p += 4;
|
||||
xxx_ref += 4;
|
||||
}
|
||||
while (dst_p < dst_COPYLENGTH);
|
||||
}
|
||||
|
||||
while (dst_p < dst_cpy)
|
||||
{
|
||||
*dst_p++ = *xxx_ref++;
|
||||
}
|
||||
|
||||
dst_p = dst_cpy;
|
||||
continue;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
*(uint*)dst_p = *(uint*)xxx_ref;
|
||||
dst_p += 4;
|
||||
xxx_ref += 4;
|
||||
*(uint*)dst_p = *(uint*)xxx_ref;
|
||||
dst_p += 4;
|
||||
xxx_ref += 4;
|
||||
}
|
||||
while (dst_p < dst_cpy);
|
||||
dst_p = dst_cpy; // correction
|
||||
}
|
||||
|
||||
// end of decoding
|
||||
return (int)(src_p - src);
|
||||
|
||||
// write overflow error detected
|
||||
_output_error:
|
||||
return (int)-(src_p - src);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>Copies block of memory.</summary>
|
||||
/// <param name="src">The source.</param>
|
||||
/// <param name="dst">The destination.</param>
|
||||
/// <param name="len">The length (in bytes).</param>
|
||||
private static unsafe void BlockCopy32(byte* src, byte* dst, int len)
|
||||
{
|
||||
while (len >= 4)
|
||||
{
|
||||
*(uint*)dst = *(uint*)src;
|
||||
dst += 4;
|
||||
src += 4;
|
||||
len -= 4;
|
||||
}
|
||||
|
||||
if (len >= 2)
|
||||
{
|
||||
*(ushort*)dst = *(ushort*)src;
|
||||
dst += 2;
|
||||
src += 2;
|
||||
len -= 2;
|
||||
}
|
||||
|
||||
if (len >= 1)
|
||||
{
|
||||
*dst = *src; /* d++; s++; l--; */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 44efef809614456e8a4d40559c526efa
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
808
Assets/Scripts/MessagePack/LZ4/LZ4Codec.Unsafe64.Dirty.cs
Normal file
808
Assets/Scripts/MessagePack/LZ4/LZ4Codec.Unsafe64.Dirty.cs
Normal file
|
|
@ -0,0 +1,808 @@
|
|||
// Copyright (c) All contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#region LZ4 original
|
||||
|
||||
/*
|
||||
LZ4 - Fast LZ compression algorithm
|
||||
Copyright (C) 2011-2012, Yann Collet.
|
||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
You can contact the author at :
|
||||
- LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
|
||||
- LZ4 source repository : http://code.google.com/p/lz4/
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region LZ4 port
|
||||
|
||||
/*
|
||||
Copyright (c) 2013, Milosz Krajewski
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions
|
||||
and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#pragma warning disable SA1312 // Variable names should begin with lower-case letter
|
||||
|
||||
namespace MessagePack.LZ4
|
||||
{
|
||||
internal partial class LZ4Codec
|
||||
{
|
||||
#region LZ4_compressCtx_64
|
||||
|
||||
private static unsafe int LZ4_compressCtx_64(
|
||||
uint* hash_table,
|
||||
byte* src,
|
||||
byte* dst,
|
||||
int src_len,
|
||||
int dst_maxlen)
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
byte* _p;
|
||||
|
||||
fixed (int* debruijn64 = &DEBRUIJN_TABLE_64[0])
|
||||
{
|
||||
// r93
|
||||
var src_p = src;
|
||||
var src_base = src_p;
|
||||
var src_anchor = src_p;
|
||||
var src_end = src_p + src_len;
|
||||
var src_mflimit = src_end - MFLIMIT;
|
||||
|
||||
var dst_p = dst;
|
||||
var dst_end = dst_p + dst_maxlen;
|
||||
|
||||
var src_LASTLITERALS = src_end - LASTLITERALS;
|
||||
var src_LASTLITERALS_1 = src_LASTLITERALS - 1;
|
||||
|
||||
var src_LASTLITERALS_3 = src_LASTLITERALS - 3;
|
||||
var src_LASTLITERALS_STEPSIZE_1 = src_LASTLITERALS - (STEPSIZE_64 - 1);
|
||||
var dst_LASTLITERALS_1 = dst_end - (1 + LASTLITERALS);
|
||||
var dst_LASTLITERALS_3 = dst_end - (2 + 1 + LASTLITERALS);
|
||||
|
||||
int length;
|
||||
uint h, h_fwd;
|
||||
|
||||
// Init
|
||||
if (src_len < MINLENGTH)
|
||||
{
|
||||
goto _last_literals;
|
||||
}
|
||||
|
||||
// First Byte
|
||||
hash_table[(*(uint*)src_p * 2654435761u) >> HASH_ADJUST] = (uint)(src_p - src_base);
|
||||
src_p++;
|
||||
h_fwd = (*(uint*)src_p * 2654435761u) >> HASH_ADJUST;
|
||||
|
||||
// Main Loop
|
||||
while (true)
|
||||
{
|
||||
var findMatchAttempts = (1 << SKIPSTRENGTH) + 3;
|
||||
var src_p_fwd = src_p;
|
||||
byte* src_ref;
|
||||
byte* dst_token;
|
||||
|
||||
// Find a match
|
||||
do
|
||||
{
|
||||
h = h_fwd;
|
||||
var step = findMatchAttempts++ >> SKIPSTRENGTH;
|
||||
src_p = src_p_fwd;
|
||||
src_p_fwd = src_p + step;
|
||||
|
||||
if (src_p_fwd > src_mflimit)
|
||||
{
|
||||
goto _last_literals;
|
||||
}
|
||||
|
||||
h_fwd = (*(uint*)src_p_fwd * 2654435761u) >> HASH_ADJUST;
|
||||
src_ref = src_base + hash_table[h];
|
||||
hash_table[h] = (uint)(src_p - src_base);
|
||||
}
|
||||
while ((src_ref < src_p - MAX_DISTANCE) || ((*(uint*)src_ref) != (*(uint*)src_p)));
|
||||
|
||||
// Catch up
|
||||
while ((src_p > src_anchor) && (src_ref > src) && (src_p[-1] == src_ref[-1]))
|
||||
{
|
||||
src_p--;
|
||||
src_ref--;
|
||||
}
|
||||
|
||||
// Encode Literal length
|
||||
length = (int)(src_p - src_anchor);
|
||||
dst_token = dst_p++;
|
||||
|
||||
if (dst_p + length + (length >> 8) > dst_LASTLITERALS_3)
|
||||
{
|
||||
return 0; // Check output limit
|
||||
}
|
||||
|
||||
if (length >= RUN_MASK)
|
||||
{
|
||||
var len = length - RUN_MASK;
|
||||
*dst_token = RUN_MASK << ML_BITS;
|
||||
if (len > 254)
|
||||
{
|
||||
do
|
||||
{
|
||||
*dst_p++ = 255;
|
||||
len -= 255;
|
||||
}
|
||||
while (len > 254);
|
||||
*dst_p++ = (byte)len;
|
||||
BlockCopy64(src_anchor, dst_p, length);
|
||||
dst_p += length;
|
||||
goto _next_match;
|
||||
}
|
||||
|
||||
*dst_p++ = (byte)len;
|
||||
}
|
||||
else
|
||||
{
|
||||
*dst_token = (byte)(length << ML_BITS);
|
||||
}
|
||||
|
||||
// Copy Literals
|
||||
_p = dst_p + length;
|
||||
{
|
||||
do
|
||||
{
|
||||
*(ulong*)dst_p = *(ulong*)src_anchor;
|
||||
dst_p += 8;
|
||||
src_anchor += 8;
|
||||
}
|
||||
while (dst_p < _p);
|
||||
}
|
||||
|
||||
dst_p = _p;
|
||||
|
||||
_next_match:
|
||||
|
||||
// Encode Offset
|
||||
*(ushort*)dst_p = (ushort)(src_p - src_ref);
|
||||
dst_p += 2;
|
||||
|
||||
// Start Counting
|
||||
src_p += MINMATCH;
|
||||
src_ref += MINMATCH; // MinMatch already verified
|
||||
src_anchor = src_p;
|
||||
|
||||
while (src_p < src_LASTLITERALS_STEPSIZE_1)
|
||||
{
|
||||
var diff = (*(long*)src_ref) ^ (*(long*)src_p);
|
||||
if (diff == 0)
|
||||
{
|
||||
src_p += STEPSIZE_64;
|
||||
src_ref += STEPSIZE_64;
|
||||
continue;
|
||||
}
|
||||
|
||||
src_p += debruijn64[((ulong)(diff & -diff) * 0x0218A392CDABBD3FL) >> 58];
|
||||
goto _endCount;
|
||||
}
|
||||
|
||||
if ((src_p < src_LASTLITERALS_3) && ((*(uint*)src_ref) == (*(uint*)src_p)))
|
||||
{
|
||||
src_p += 4;
|
||||
src_ref += 4;
|
||||
}
|
||||
|
||||
if ((src_p < src_LASTLITERALS_1) && ((*(ushort*)src_ref) == (*(ushort*)src_p)))
|
||||
{
|
||||
src_p += 2;
|
||||
src_ref += 2;
|
||||
}
|
||||
|
||||
if ((src_p < src_LASTLITERALS) && (*src_ref == *src_p))
|
||||
{
|
||||
src_p++;
|
||||
}
|
||||
|
||||
_endCount:
|
||||
|
||||
// Encode MatchLength
|
||||
length = (int)(src_p - src_anchor);
|
||||
|
||||
if (dst_p + (length >> 8) > dst_LASTLITERALS_1)
|
||||
{
|
||||
return 0; // Check output limit
|
||||
}
|
||||
|
||||
if (length >= ML_MASK)
|
||||
{
|
||||
*dst_token += ML_MASK;
|
||||
length -= ML_MASK;
|
||||
for (; length > 509; length -= 510)
|
||||
{
|
||||
*dst_p++ = 255;
|
||||
*dst_p++ = 255;
|
||||
}
|
||||
|
||||
if (length > 254)
|
||||
{
|
||||
length -= 255;
|
||||
*dst_p++ = 255;
|
||||
}
|
||||
|
||||
*dst_p++ = (byte)length;
|
||||
}
|
||||
else
|
||||
{
|
||||
*dst_token += (byte)length;
|
||||
}
|
||||
|
||||
// Test end of chunk
|
||||
if (src_p > src_mflimit)
|
||||
{
|
||||
src_anchor = src_p;
|
||||
break;
|
||||
}
|
||||
|
||||
// Fill table
|
||||
hash_table[(*(uint*)(src_p - 2) * 2654435761u) >> HASH_ADJUST] = (uint)(src_p - 2 - src_base);
|
||||
|
||||
// Test next position
|
||||
h = (*(uint*)src_p * 2654435761u) >> HASH_ADJUST;
|
||||
src_ref = src_base + hash_table[h];
|
||||
hash_table[h] = (uint)(src_p - src_base);
|
||||
|
||||
if ((src_ref > src_p - (MAX_DISTANCE + 1)) && ((*(uint*)src_ref) == (*(uint*)src_p)))
|
||||
{
|
||||
dst_token = dst_p++;
|
||||
*dst_token = 0;
|
||||
goto _next_match;
|
||||
}
|
||||
|
||||
// Prepare next loop
|
||||
src_anchor = src_p++;
|
||||
h_fwd = (*(uint*)src_p * 2654435761u) >> HASH_ADJUST;
|
||||
}
|
||||
|
||||
_last_literals:
|
||||
|
||||
// Encode Last Literals
|
||||
var lastRun = (int)(src_end - src_anchor);
|
||||
if (dst_p + lastRun + 1 + ((lastRun + 255 - RUN_MASK) / 255) > dst_end)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lastRun >= RUN_MASK)
|
||||
{
|
||||
*dst_p++ = RUN_MASK << ML_BITS;
|
||||
lastRun -= RUN_MASK;
|
||||
for (; lastRun > 254; lastRun -= 255)
|
||||
{
|
||||
*dst_p++ = 255;
|
||||
}
|
||||
|
||||
*dst_p++ = (byte)lastRun;
|
||||
}
|
||||
else
|
||||
{
|
||||
*dst_p++ = (byte)(lastRun << ML_BITS);
|
||||
}
|
||||
|
||||
BlockCopy64(src_anchor, dst_p, (int)(src_end - src_anchor));
|
||||
dst_p += src_end - src_anchor;
|
||||
|
||||
// End
|
||||
return (int)(dst_p - dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region LZ4_compress64kCtx_64
|
||||
|
||||
private static unsafe int LZ4_compress64kCtx_64(
|
||||
ushort* hash_table,
|
||||
byte* src,
|
||||
byte* dst,
|
||||
int src_len,
|
||||
int dst_maxlen)
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
byte* _p;
|
||||
|
||||
fixed (int* debruijn64 = &DEBRUIJN_TABLE_64[0])
|
||||
{
|
||||
// r93
|
||||
var src_p = src;
|
||||
var src_anchor = src_p;
|
||||
var src_base = src_p;
|
||||
var src_end = src_p + src_len;
|
||||
var src_mflimit = src_end - MFLIMIT;
|
||||
|
||||
var dst_p = dst;
|
||||
var dst_end = dst_p + dst_maxlen;
|
||||
|
||||
var src_LASTLITERALS = src_end - LASTLITERALS;
|
||||
var src_LASTLITERALS_1 = src_LASTLITERALS - 1;
|
||||
|
||||
var src_LASTLITERALS_3 = src_LASTLITERALS - 3;
|
||||
|
||||
var src_LASTLITERALS_STEPSIZE_1 = src_LASTLITERALS - (STEPSIZE_64 - 1);
|
||||
var dst_LASTLITERALS_1 = dst_end - (1 + LASTLITERALS);
|
||||
var dst_LASTLITERALS_3 = dst_end - (2 + 1 + LASTLITERALS);
|
||||
|
||||
int len, length;
|
||||
|
||||
uint h, h_fwd;
|
||||
|
||||
// Init
|
||||
if (src_len < MINLENGTH)
|
||||
{
|
||||
goto _last_literals;
|
||||
}
|
||||
|
||||
// First Byte
|
||||
src_p++;
|
||||
h_fwd = (*(uint*)src_p * 2654435761u) >> HASH64K_ADJUST;
|
||||
|
||||
// Main Loop
|
||||
while (true)
|
||||
{
|
||||
var findMatchAttempts = (1 << SKIPSTRENGTH) + 3;
|
||||
var src_p_fwd = src_p;
|
||||
byte* src_ref;
|
||||
byte* dst_token;
|
||||
|
||||
// Find a match
|
||||
do
|
||||
{
|
||||
h = h_fwd;
|
||||
var step = findMatchAttempts++ >> SKIPSTRENGTH;
|
||||
src_p = src_p_fwd;
|
||||
src_p_fwd = src_p + step;
|
||||
|
||||
if (src_p_fwd > src_mflimit)
|
||||
{
|
||||
goto _last_literals;
|
||||
}
|
||||
|
||||
h_fwd = (*(uint*)src_p_fwd * 2654435761u) >> HASH64K_ADJUST;
|
||||
src_ref = src_base + hash_table[h];
|
||||
hash_table[h] = (ushort)(src_p - src_base);
|
||||
}
|
||||
while ((*(uint*)src_ref) != (*(uint*)src_p));
|
||||
|
||||
// Catch up
|
||||
while ((src_p > src_anchor) && (src_ref > src) && (src_p[-1] == src_ref[-1]))
|
||||
{
|
||||
src_p--;
|
||||
src_ref--;
|
||||
}
|
||||
|
||||
// Encode Literal length
|
||||
length = (int)(src_p - src_anchor);
|
||||
dst_token = dst_p++;
|
||||
|
||||
if (dst_p + length + (length >> 8) > dst_LASTLITERALS_3)
|
||||
{
|
||||
return 0; // Check output limit
|
||||
}
|
||||
|
||||
if (length >= RUN_MASK)
|
||||
{
|
||||
len = length - RUN_MASK;
|
||||
*dst_token = RUN_MASK << ML_BITS;
|
||||
if (len > 254)
|
||||
{
|
||||
do
|
||||
{
|
||||
*dst_p++ = 255;
|
||||
len -= 255;
|
||||
}
|
||||
while (len > 254);
|
||||
*dst_p++ = (byte)len;
|
||||
BlockCopy64(src_anchor, dst_p, length);
|
||||
dst_p += length;
|
||||
goto _next_match;
|
||||
}
|
||||
|
||||
*dst_p++ = (byte)len;
|
||||
}
|
||||
else
|
||||
{
|
||||
*dst_token = (byte)(length << ML_BITS);
|
||||
}
|
||||
|
||||
// Copy Literals
|
||||
{
|
||||
_p = dst_p + length;
|
||||
{
|
||||
do
|
||||
{
|
||||
*(ulong*)dst_p = *(ulong*)src_anchor;
|
||||
dst_p += 8;
|
||||
src_anchor += 8;
|
||||
}
|
||||
while (dst_p < _p);
|
||||
}
|
||||
|
||||
dst_p = _p;
|
||||
}
|
||||
|
||||
_next_match:
|
||||
|
||||
// Encode Offset
|
||||
*(ushort*)dst_p = (ushort)(src_p - src_ref);
|
||||
dst_p += 2;
|
||||
|
||||
// Start Counting
|
||||
src_p += MINMATCH;
|
||||
src_ref += MINMATCH; // MinMatch verified
|
||||
src_anchor = src_p;
|
||||
|
||||
while (src_p < src_LASTLITERALS_STEPSIZE_1)
|
||||
{
|
||||
var diff = (*(long*)src_ref) ^ (*(long*)src_p);
|
||||
if (diff == 0)
|
||||
{
|
||||
src_p += STEPSIZE_64;
|
||||
src_ref += STEPSIZE_64;
|
||||
continue;
|
||||
}
|
||||
|
||||
src_p += debruijn64[((ulong)(diff & -diff) * 0x0218A392CDABBD3FL) >> 58];
|
||||
goto _endCount;
|
||||
}
|
||||
|
||||
if ((src_p < src_LASTLITERALS_3) && ((*(uint*)src_ref) == (*(uint*)src_p)))
|
||||
{
|
||||
src_p += 4;
|
||||
src_ref += 4;
|
||||
}
|
||||
|
||||
if ((src_p < src_LASTLITERALS_1) && ((*(ushort*)src_ref) == (*(ushort*)src_p)))
|
||||
{
|
||||
src_p += 2;
|
||||
src_ref += 2;
|
||||
}
|
||||
|
||||
if ((src_p < src_LASTLITERALS) && (*src_ref == *src_p))
|
||||
{
|
||||
src_p++;
|
||||
}
|
||||
|
||||
_endCount:
|
||||
|
||||
// Encode MatchLength
|
||||
len = (int)(src_p - src_anchor);
|
||||
|
||||
if (dst_p + (len >> 8) > dst_LASTLITERALS_1)
|
||||
{
|
||||
return 0; // Check output limit
|
||||
}
|
||||
|
||||
if (len >= ML_MASK)
|
||||
{
|
||||
*dst_token += ML_MASK;
|
||||
len -= ML_MASK;
|
||||
for (; len > 509; len -= 510)
|
||||
{
|
||||
*dst_p++ = 255;
|
||||
*dst_p++ = 255;
|
||||
}
|
||||
|
||||
if (len > 254)
|
||||
{
|
||||
len -= 255;
|
||||
*dst_p++ = 255;
|
||||
}
|
||||
|
||||
*dst_p++ = (byte)len;
|
||||
}
|
||||
else
|
||||
{
|
||||
*dst_token += (byte)len;
|
||||
}
|
||||
|
||||
// Test end of chunk
|
||||
if (src_p > src_mflimit)
|
||||
{
|
||||
src_anchor = src_p;
|
||||
break;
|
||||
}
|
||||
|
||||
// Fill table
|
||||
hash_table[(*(uint*)(src_p - 2) * 2654435761u) >> HASH64K_ADJUST] = (ushort)(src_p - 2 - src_base);
|
||||
|
||||
// Test next position
|
||||
h = (*(uint*)src_p * 2654435761u) >> HASH64K_ADJUST;
|
||||
src_ref = src_base + hash_table[h];
|
||||
hash_table[h] = (ushort)(src_p - src_base);
|
||||
|
||||
if ((*(uint*)src_ref) == (*(uint*)src_p))
|
||||
{
|
||||
dst_token = dst_p++;
|
||||
*dst_token = 0;
|
||||
goto _next_match;
|
||||
}
|
||||
|
||||
// Prepare next loop
|
||||
src_anchor = src_p++;
|
||||
h_fwd = (*(uint*)src_p * 2654435761u) >> HASH64K_ADJUST;
|
||||
}
|
||||
|
||||
_last_literals:
|
||||
|
||||
// Encode Last Literals
|
||||
var lastRun = (int)(src_end - src_anchor);
|
||||
if (dst_p + lastRun + 1 + ((lastRun - RUN_MASK + 255) / 255) > dst_end)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lastRun >= RUN_MASK)
|
||||
{
|
||||
*dst_p++ = RUN_MASK << ML_BITS;
|
||||
lastRun -= RUN_MASK;
|
||||
for (; lastRun > 254; lastRun -= 255)
|
||||
{
|
||||
*dst_p++ = 255;
|
||||
}
|
||||
|
||||
*dst_p++ = (byte)lastRun;
|
||||
}
|
||||
else
|
||||
{
|
||||
*dst_p++ = (byte)(lastRun << ML_BITS);
|
||||
}
|
||||
|
||||
BlockCopy64(src_anchor, dst_p, (int)(src_end - src_anchor));
|
||||
dst_p += src_end - src_anchor;
|
||||
|
||||
// End
|
||||
return (int)(dst_p - dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region LZ4_uncompress_64
|
||||
|
||||
private static unsafe int LZ4_uncompress_64(
|
||||
byte* src,
|
||||
byte* dst,
|
||||
int dst_len)
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
fixed (int* dec32table = &DECODER_TABLE_32[0])
|
||||
fixed (int* dec64table = &DECODER_TABLE_64[0])
|
||||
{
|
||||
// r93
|
||||
var src_p = src;
|
||||
byte* dst_ref;
|
||||
|
||||
var dst_p = dst;
|
||||
var dst_end = dst_p + dst_len;
|
||||
byte* dst_cpy;
|
||||
|
||||
var dst_LASTLITERALS = dst_end - LASTLITERALS;
|
||||
var dst_COPYLENGTH = dst_end - COPYLENGTH;
|
||||
var dst_COPYLENGTH_STEPSIZE_4 = dst_end - COPYLENGTH - (STEPSIZE_64 - 4);
|
||||
|
||||
byte token;
|
||||
|
||||
// Main Loop
|
||||
while (true)
|
||||
{
|
||||
int length;
|
||||
|
||||
// get runlength
|
||||
token = *src_p++;
|
||||
if ((length = token >> ML_BITS) == RUN_MASK)
|
||||
{
|
||||
int len;
|
||||
for (; (len = *src_p++) == 255; length += 255)
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
length += len;
|
||||
}
|
||||
|
||||
// copy literals
|
||||
dst_cpy = dst_p + length;
|
||||
|
||||
if (dst_cpy > dst_COPYLENGTH)
|
||||
{
|
||||
if (dst_cpy != dst_end)
|
||||
{
|
||||
goto _output_error; // Error : not enough place for another match (min 4) + 5 literals
|
||||
}
|
||||
|
||||
BlockCopy64(src_p, dst_p, length);
|
||||
src_p += length;
|
||||
break; // EOF
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
*(ulong*)dst_p = *(ulong*)src_p;
|
||||
dst_p += 8;
|
||||
src_p += 8;
|
||||
}
|
||||
while (dst_p < dst_cpy);
|
||||
src_p -= dst_p - dst_cpy;
|
||||
dst_p = dst_cpy;
|
||||
|
||||
// get offset
|
||||
dst_ref = dst_cpy - (*(ushort*)src_p);
|
||||
src_p += 2;
|
||||
if (dst_ref < dst)
|
||||
{
|
||||
goto _output_error; // Error : offset outside destination buffer
|
||||
}
|
||||
|
||||
// get matchlength
|
||||
if ((length = token & ML_MASK) == ML_MASK)
|
||||
{
|
||||
for (; *src_p == 255; length += 255)
|
||||
{
|
||||
src_p++;
|
||||
}
|
||||
|
||||
length += *src_p++;
|
||||
}
|
||||
|
||||
// copy repeated sequence
|
||||
if ((dst_p - dst_ref) < STEPSIZE_64)
|
||||
{
|
||||
var dec64 = dec64table[dst_p - dst_ref];
|
||||
|
||||
dst_p[0] = dst_ref[0];
|
||||
dst_p[1] = dst_ref[1];
|
||||
dst_p[2] = dst_ref[2];
|
||||
dst_p[3] = dst_ref[3];
|
||||
dst_p += 4;
|
||||
dst_ref += 4;
|
||||
dst_ref -= dec32table[dst_p - dst_ref];
|
||||
*(uint*)dst_p = *(uint*)dst_ref;
|
||||
dst_p += STEPSIZE_64 - 4;
|
||||
dst_ref -= dec64;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(ulong*)dst_p = *(ulong*)dst_ref;
|
||||
dst_p += 8;
|
||||
dst_ref += 8;
|
||||
}
|
||||
|
||||
dst_cpy = dst_p + length - (STEPSIZE_64 - 4);
|
||||
|
||||
if (dst_cpy > dst_COPYLENGTH_STEPSIZE_4)
|
||||
{
|
||||
if (dst_cpy > dst_LASTLITERALS)
|
||||
{
|
||||
goto _output_error; // Error : last 5 bytes must be literals
|
||||
}
|
||||
|
||||
while (dst_p < dst_COPYLENGTH)
|
||||
{
|
||||
*(ulong*)dst_p = *(ulong*)dst_ref;
|
||||
dst_p += 8;
|
||||
dst_ref += 8;
|
||||
}
|
||||
|
||||
while (dst_p < dst_cpy)
|
||||
{
|
||||
*dst_p++ = *dst_ref++;
|
||||
}
|
||||
|
||||
dst_p = dst_cpy;
|
||||
continue;
|
||||
}
|
||||
|
||||
{
|
||||
do
|
||||
{
|
||||
*(ulong*)dst_p = *(ulong*)dst_ref;
|
||||
dst_p += 8;
|
||||
dst_ref += 8;
|
||||
}
|
||||
while (dst_p < dst_cpy);
|
||||
}
|
||||
|
||||
dst_p = dst_cpy; // correction
|
||||
}
|
||||
|
||||
// end of decoding
|
||||
return (int)(src_p - src);
|
||||
|
||||
// write overflow error detected
|
||||
_output_error:
|
||||
return (int)-(src_p - src);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>Copies block of memory.</summary>
|
||||
/// <param name="src">The source.</param>
|
||||
/// <param name="dst">The destination.</param>
|
||||
/// <param name="len">The length (in bytes).</param>
|
||||
private static unsafe void BlockCopy64(byte* src, byte* dst, int len)
|
||||
{
|
||||
while (len >= 8)
|
||||
{
|
||||
*(ulong*)dst = *(ulong*)src;
|
||||
dst += 8;
|
||||
src += 8;
|
||||
len -= 8;
|
||||
}
|
||||
|
||||
if (len >= 4)
|
||||
{
|
||||
*(uint*)dst = *(uint*)src;
|
||||
dst += 4;
|
||||
src += 4;
|
||||
len -= 4;
|
||||
}
|
||||
|
||||
if (len >= 2)
|
||||
{
|
||||
*(ushort*)dst = *(ushort*)src;
|
||||
dst += 2;
|
||||
src += 2;
|
||||
len -= 2;
|
||||
}
|
||||
|
||||
if (len >= 1)
|
||||
{
|
||||
*dst = *src; /* d++; s++; l--; */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: fa2e5105dcebe0410bb8ed76f622889f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
178
Assets/Scripts/MessagePack/LZ4/LZ4Codec.cs
Normal file
178
Assets/Scripts/MessagePack/LZ4/LZ4Codec.cs
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
// Copyright (c) All contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#region license
|
||||
|
||||
/*
|
||||
Copyright (c) 2013, Milosz Krajewski
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions
|
||||
and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
|
||||
#pragma warning disable SA1310 // Field names should not contain underscore
|
||||
|
||||
namespace MessagePack.LZ4
|
||||
{
|
||||
internal static partial class LZ4Codec
|
||||
{
|
||||
#region configuration
|
||||
|
||||
/// <summary>
|
||||
/// Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.)
|
||||
/// Increasing memory usage improves compression ratio
|
||||
/// Reduced memory usage can improve speed, due to cache effect
|
||||
/// Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache.
|
||||
/// </summary>
|
||||
private const int MEMORY_USAGE = 12; // modified use 12.
|
||||
|
||||
/// <summary>
|
||||
/// Decreasing this value will make the algorithm skip faster data segments considered "incompressible"
|
||||
/// This may decrease compression ratio dramatically, but will be faster on incompressible data
|
||||
/// Increasing this value will make the algorithm search more before declaring a segment "incompressible"
|
||||
/// This could improve compression a bit, but will be slower on incompressible data
|
||||
/// The default value (6) is recommended.
|
||||
/// </summary>
|
||||
private const int NOTCOMPRESSIBLE_DETECTIONLEVEL = 6;
|
||||
|
||||
#endregion
|
||||
|
||||
#region consts
|
||||
|
||||
private const int MINMATCH = 4;
|
||||
|
||||
#pragma warning disable 162, 429
|
||||
|
||||
private const int SKIPSTRENGTH = NOTCOMPRESSIBLE_DETECTIONLEVEL > 2 ? NOTCOMPRESSIBLE_DETECTIONLEVEL : 2;
|
||||
#pragma warning restore 162, 429
|
||||
|
||||
private const int COPYLENGTH = 8;
|
||||
private const int LASTLITERALS = 5;
|
||||
private const int MFLIMIT = COPYLENGTH + MINMATCH;
|
||||
private const int MINLENGTH = MFLIMIT + 1;
|
||||
private const int MAXD_LOG = 16;
|
||||
private const int MAXD = 1 << MAXD_LOG;
|
||||
private const int MAXD_MASK = MAXD - 1;
|
||||
private const int MAX_DISTANCE = (1 << MAXD_LOG) - 1;
|
||||
private const int ML_BITS = 4;
|
||||
private const int ML_MASK = (1 << ML_BITS) - 1;
|
||||
private const int RUN_BITS = 8 - ML_BITS;
|
||||
private const int RUN_MASK = (1 << RUN_BITS) - 1;
|
||||
private const int STEPSIZE_64 = 8;
|
||||
private const int STEPSIZE_32 = 4;
|
||||
|
||||
private const int LZ4_64KLIMIT = (1 << 16) + (MFLIMIT - 1);
|
||||
|
||||
private const int HASH_LOG = MEMORY_USAGE - 2;
|
||||
private const int HASH_TABLESIZE = 1 << HASH_LOG;
|
||||
private const int HASH_ADJUST = (MINMATCH * 8) - HASH_LOG;
|
||||
|
||||
private const int HASH64K_LOG = HASH_LOG + 1;
|
||||
private const int HASH64K_TABLESIZE = 1 << HASH64K_LOG;
|
||||
private const int HASH64K_ADJUST = (MINMATCH * 8) - HASH64K_LOG;
|
||||
|
||||
private const int HASHHC_LOG = MAXD_LOG - 1;
|
||||
private const int HASHHC_TABLESIZE = 1 << HASHHC_LOG;
|
||||
private const int HASHHC_ADJUST = (MINMATCH * 8) - HASHHC_LOG;
|
||||
////private const int HASHHC_MASK = HASHHC_TABLESIZE - 1;
|
||||
|
||||
private const int MAX_NB_ATTEMPTS = 256;
|
||||
private const int OPTIMAL_ML = ML_MASK - 1 + MINMATCH;
|
||||
|
||||
private const int BLOCK_COPY_LIMIT = 16;
|
||||
|
||||
private static readonly int[] DECODER_TABLE_32 = { 0, 3, 2, 3, 0, 0, 0, 0 };
|
||||
private static readonly int[] DECODER_TABLE_64 = { 0, 0, 0, -1, 0, 1, 2, 3 };
|
||||
|
||||
private static readonly int[] DEBRUIJN_TABLE_32 =
|
||||
{
|
||||
0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1,
|
||||
3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1,
|
||||
};
|
||||
|
||||
private static readonly int[] DEBRUIJN_TABLE_64 =
|
||||
{
|
||||
0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7,
|
||||
0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7,
|
||||
7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6,
|
||||
7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7,
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
#region public interface (common)
|
||||
|
||||
/// <summary>Gets maximum the length of the output.</summary>
|
||||
/// <param name="inputLength">Length of the input.</param>
|
||||
/// <returns>Maximum number of bytes needed for compressed buffer.</returns>
|
||||
public static int MaximumOutputLength(int inputLength)
|
||||
{
|
||||
return inputLength + (inputLength / 255) + 16;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region internal interface (common)
|
||||
|
||||
internal static void CheckArguments(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset, int outputLength)
|
||||
{
|
||||
if (inputLength == 0)
|
||||
{
|
||||
outputLength = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (input == null)
|
||||
{
|
||||
throw new ArgumentNullException("input");
|
||||
}
|
||||
|
||||
if ((uint)inputOffset > (uint)input.Length)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("inputOffset");
|
||||
}
|
||||
|
||||
if ((uint)inputLength > (uint)input.Length - (uint)inputOffset)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("inputLength");
|
||||
}
|
||||
|
||||
if (output == null)
|
||||
{
|
||||
throw new ArgumentNullException("output");
|
||||
}
|
||||
|
||||
if ((uint)outputOffset > (uint)output.Length)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("outputOffset");
|
||||
}
|
||||
|
||||
if ((uint)outputLength > (uint)output.Length - (uint)outputOffset)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("outputLength");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/MessagePack/LZ4/LZ4Codec.cs.meta
Normal file
11
Assets/Scripts/MessagePack/LZ4/LZ4Codec.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b67a7760eb98ee768b90af4f2d6d9dc4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Loading…
Reference in a new issue