You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
678 lines
25 KiB
678 lines
25 KiB
#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 |
|
|
|
// ReSharper disable CheckNamespace |
|
// ReSharper disable InconsistentNaming |
|
// ReSharper disable TooWideLocalVariableScope |
|
// ReSharper disable JoinDeclarationAndInitializer |
|
// ReSharper disable RedundantIfElseBlock |
|
|
|
namespace MessagePack.LZ4 |
|
{ |
|
public static 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 |
|
} |
|
} |
|
|
|
// ReSharper restore RedundantIfElseBlock |
|
// ReSharper restore JoinDeclarationAndInitializer |
|
// ReSharper restore TooWideLocalVariableScope |
|
// ReSharper restore InconsistentNaming |
|
// ReSharper restore CheckNamespace |