Compare commits

..

No commits in common. "main" and "v3.2.0" have entirely different histories.
main ... v3.2.0

205 changed files with 2599 additions and 10502 deletions

Binary file not shown.

Binary file not shown.

View File

@ -1,12 +0,0 @@
#include "../Il2CppCompatibleDef.h"
namespace hybridclr
{
const char* g_placeHolderAssemblies[] =
{
//!!!{{PLACE_HOLDER
//!!!}}PLACE_HOLDER
nullptr,
};
}

View File

@ -1,32 +0,0 @@
#include <codegen/il2cpp-codegen-metadata.h>
#if HYBRIDCLR_UNITY_2023_OR_NEW
#include <codegen/il2cpp-codegen.h>
#elif HYBRIDCLR_UNITY_2022
#include <codegen/il2cpp-codegen-il2cpp.h>
#elif HYBRIDCLR_UNITY_2020 || HYBRIDCLR_UNITY_2021
#include <codegen/il2cpp-codegen-common-big.h>
#else
#include <codegen/il2cpp-codegen-common.h>
#endif
#include "vm/ClassInlines.h"
#include "vm/Object.h"
#include "vm/Class.h"
#include "vm/ScopedThreadAttacher.h"
#include "../metadata/MetadataUtil.h"
#include "../interpreter/InterpreterModule.h"
#include "../interpreter/MethodBridge.h"
#include "../interpreter/Interpreter.h"
#include "../interpreter/MemoryUtil.h"
#include "../interpreter/InstrinctDef.h"
using namespace hybridclr::interpreter;
using namespace hybridclr::metadata;
//!!!{{CODE
//!!!}}CODE

View File

@ -0,0 +1,20 @@
#include <codegen/il2cpp-codegen-metadata.h>
#include "vm/ClassInlines.h"
#include "vm/Object.h"
#include "vm/Class.h"
#include "../metadata/MetadataModule.h"
#include "../metadata/MetadataUtil.h"
#include "../interpreter/MethodBridge.h"
#include "../interpreter/Interpreter.h"
#include "../interpreter/MemoryUtil.h"
#include "../interpreter/InstrinctDef.h"
using namespace hybridclr::interpreter;
#if {PLATFORM_ABI}
//!!!{{CODE
//!!!}}CODE
#endif

View File

@ -0,0 +1,32 @@
#include "../metadata/ReversePInvokeMethodStub.h"
#include "../metadata/MetadataModule.h"
namespace hybridclr
{
namespace metadata
{
#if {PLATFORM_ABI}
//!!!{{CODE
void __ReversePInvokeMethod_0(void* xState)
{
CallLuaFunction(xState, 0);
}
void __ReversePInvokeMethod_1(void* xState)
{
CallLuaFunction(xState, 1);
}
Il2CppMethodPointer s_ReversePInvokeMethodStub[]
{
(Il2CppMethodPointer)__ReversePInvokeMethod_0,
(Il2CppMethodPointer)__ReversePInvokeMethod_1,
nullptr,
};
//!!!}}CODE
#endif
}
}

View File

@ -1,6 +0,0 @@
#pragma once
//!!!{{UNITY_VERSION
//!!!}}UNITY_VERSION

View File

@ -1,39 +1,19 @@
{ {
"versions": [ "versions": [
{
"unity_version":"2019",
"hybridclr" : { "branch":"v8.6.0"},
"il2cpp_plus": { "branch":"v2019-8.1.0"}
},
{ {
"unity_version":"2020", "unity_version":"2020",
"hybridclr" : { "branch":"v8.6.0"}, "hybridclr" : { "branch":"v3.1.2"},
"il2cpp_plus": { "branch":"v2020-8.1.0"} "il2cpp_plus": { "branch":"v2020-3.0.0"}
}, },
{ {
"unity_version":"2021", "unity_version":"2021",
"hybridclr" : { "branch":"v8.6.0"}, "hybridclr" : { "branch":"v3.1.2"},
"il2cpp_plus": { "branch":"v2021-8.1.0"} "il2cpp_plus": { "branch":"v2021-3.0.2"}
}, },
{ {
"unity_version":"2022", "unity_version":"2022",
"hybridclr" : { "branch":"v8.6.0"}, "hybridclr" : { "branch":"v3.1.2"},
"il2cpp_plus": { "branch":"v2022-8.2.0"} "il2cpp_plus": { "branch":"v2022-3.0.2"}
},
{
"unity_version":"2022-tuanjie",
"hybridclr" : { "branch":"v8.6.0"},
"il2cpp_plus": { "branch":"v2022-tuanjie-8.6.0"}
},
{
"unity_version":"2023",
"hybridclr" : { "branch":"v8.6.0"},
"il2cpp_plus": { "branch":"v2023-8.1.0"}
},
{
"unity_version":"6000",
"hybridclr" : { "branch":"v8.6.0"},
"il2cpp_plus": { "branch":"v6000-8.1.0"}
} }
] ]
} }

View File

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 08f44f6e8bfbc2c45afae7bdd2d7f21f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 5cedddbfa873eb94496b496e2a3ce8aa
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,55 +0,0 @@
// Common/CRC.cs
namespace SevenZip
{
public class CRC
{
public static readonly uint[] Table;
static CRC()
{
Table = new uint[256];
const uint kPoly = 0xEDB88320;
for (uint i = 0; i < 256; i++)
{
uint r = i;
for (int j = 0; j < 8; j++)
if ((r & 1) != 0)
r = (r >> 1) ^ kPoly;
else
r >>= 1;
Table[i] = r;
}
}
uint _value = 0xFFFFFFFF;
public void Init() { _value = 0xFFFFFFFF; }
public void UpdateByte(byte b)
{
_value = Table[(((byte)(_value)) ^ b)] ^ (_value >> 8);
}
public void Update(byte[] data, uint offset, uint size)
{
for (uint i = 0; i < size; i++)
_value = Table[(((byte)(_value)) ^ data[offset + i])] ^ (_value >> 8);
}
public uint GetDigest() { return _value ^ 0xFFFFFFFF; }
static uint CalculateDigest(byte[] data, uint offset, uint size)
{
CRC crc = new CRC();
// crc.Init();
crc.Update(data, offset, size);
return crc.GetDigest();
}
static bool VerifyDigest(uint digest, byte[] data, uint offset, uint size)
{
return (CalculateDigest(data, offset, size) == digest);
}
}
}

View File

@ -1,274 +0,0 @@
// CommandLineParser.cs
using System;
using System.Collections;
namespace SevenZip.CommandLineParser
{
public enum SwitchType
{
Simple,
PostMinus,
LimitedPostString,
UnLimitedPostString,
PostChar
}
public class SwitchForm
{
public string IDString;
public SwitchType Type;
public bool Multi;
public int MinLen;
public int MaxLen;
public string PostCharSet;
public SwitchForm(string idString, SwitchType type, bool multi,
int minLen, int maxLen, string postCharSet)
{
IDString = idString;
Type = type;
Multi = multi;
MinLen = minLen;
MaxLen = maxLen;
PostCharSet = postCharSet;
}
public SwitchForm(string idString, SwitchType type, bool multi, int minLen):
this(idString, type, multi, minLen, 0, "")
{
}
public SwitchForm(string idString, SwitchType type, bool multi):
this(idString, type, multi, 0)
{
}
}
public class SwitchResult
{
public bool ThereIs;
public bool WithMinus;
public ArrayList PostStrings = new ArrayList();
public int PostCharIndex;
public SwitchResult()
{
ThereIs = false;
}
}
public class Parser
{
public ArrayList NonSwitchStrings = new ArrayList();
SwitchResult[] _switches;
public Parser(int numSwitches)
{
_switches = new SwitchResult[numSwitches];
for (int i = 0; i < numSwitches; i++)
_switches[i] = new SwitchResult();
}
bool ParseString(string srcString, SwitchForm[] switchForms)
{
int len = srcString.Length;
if (len == 0)
return false;
int pos = 0;
if (!IsItSwitchChar(srcString[pos]))
return false;
while (pos < len)
{
if (IsItSwitchChar(srcString[pos]))
pos++;
const int kNoLen = -1;
int matchedSwitchIndex = 0;
int maxLen = kNoLen;
for (int switchIndex = 0; switchIndex < _switches.Length; switchIndex++)
{
int switchLen = switchForms[switchIndex].IDString.Length;
if (switchLen <= maxLen || pos + switchLen > len)
continue;
if (String.Compare(switchForms[switchIndex].IDString, 0,
srcString, pos, switchLen, true) == 0)
{
matchedSwitchIndex = switchIndex;
maxLen = switchLen;
}
}
if (maxLen == kNoLen)
throw new Exception("maxLen == kNoLen");
SwitchResult matchedSwitch = _switches[matchedSwitchIndex];
SwitchForm switchForm = switchForms[matchedSwitchIndex];
if ((!switchForm.Multi) && matchedSwitch.ThereIs)
throw new Exception("switch must be single");
matchedSwitch.ThereIs = true;
pos += maxLen;
int tailSize = len - pos;
SwitchType type = switchForm.Type;
switch (type)
{
case SwitchType.PostMinus:
{
if (tailSize == 0)
matchedSwitch.WithMinus = false;
else
{
matchedSwitch.WithMinus = (srcString[pos] == kSwitchMinus);
if (matchedSwitch.WithMinus)
pos++;
}
break;
}
case SwitchType.PostChar:
{
if (tailSize < switchForm.MinLen)
throw new Exception("switch is not full");
string charSet = switchForm.PostCharSet;
const int kEmptyCharValue = -1;
if (tailSize == 0)
matchedSwitch.PostCharIndex = kEmptyCharValue;
else
{
int index = charSet.IndexOf(srcString[pos]);
if (index < 0)
matchedSwitch.PostCharIndex = kEmptyCharValue;
else
{
matchedSwitch.PostCharIndex = index;
pos++;
}
}
break;
}
case SwitchType.LimitedPostString:
case SwitchType.UnLimitedPostString:
{
int minLen = switchForm.MinLen;
if (tailSize < minLen)
throw new Exception("switch is not full");
if (type == SwitchType.UnLimitedPostString)
{
matchedSwitch.PostStrings.Add(srcString.Substring(pos));
return true;
}
String stringSwitch = srcString.Substring(pos, minLen);
pos += minLen;
for (int i = minLen; i < switchForm.MaxLen && pos < len; i++, pos++)
{
char c = srcString[pos];
if (IsItSwitchChar(c))
break;
stringSwitch += c;
}
matchedSwitch.PostStrings.Add(stringSwitch);
break;
}
}
}
return true;
}
public void ParseStrings(SwitchForm[] switchForms, string[] commandStrings)
{
int numCommandStrings = commandStrings.Length;
bool stopSwitch = false;
for (int i = 0; i < numCommandStrings; i++)
{
string s = commandStrings[i];
if (stopSwitch)
NonSwitchStrings.Add(s);
else
if (s == kStopSwitchParsing)
stopSwitch = true;
else
if (!ParseString(s, switchForms))
NonSwitchStrings.Add(s);
}
}
public SwitchResult this[int index] { get { return _switches[index]; } }
public static int ParseCommand(CommandForm[] commandForms, string commandString,
out string postString)
{
for (int i = 0; i < commandForms.Length; i++)
{
string id = commandForms[i].IDString;
if (commandForms[i].PostStringMode)
{
if (commandString.IndexOf(id) == 0)
{
postString = commandString.Substring(id.Length);
return i;
}
}
else
if (commandString == id)
{
postString = "";
return i;
}
}
postString = "";
return -1;
}
static bool ParseSubCharsCommand(int numForms, CommandSubCharsSet[] forms,
string commandString, ArrayList indices)
{
indices.Clear();
int numUsedChars = 0;
for (int i = 0; i < numForms; i++)
{
CommandSubCharsSet charsSet = forms[i];
int currentIndex = -1;
int len = charsSet.Chars.Length;
for (int j = 0; j < len; j++)
{
char c = charsSet.Chars[j];
int newIndex = commandString.IndexOf(c);
if (newIndex >= 0)
{
if (currentIndex >= 0)
return false;
if (commandString.IndexOf(c, newIndex + 1) >= 0)
return false;
currentIndex = j;
numUsedChars++;
}
}
if (currentIndex == -1 && !charsSet.EmptyAllowed)
return false;
indices.Add(currentIndex);
}
return (numUsedChars == commandString.Length);
}
const char kSwitchID1 = '-';
const char kSwitchID2 = '/';
const char kSwitchMinus = '-';
const string kStopSwitchParsing = "--";
static bool IsItSwitchChar(char c)
{
return (c == kSwitchID1 || c == kSwitchID2);
}
}
public class CommandForm
{
public string IDString = "";
public bool PostStringMode = false;
public CommandForm(string idString, bool postStringMode)
{
IDString = idString;
PostStringMode = postStringMode;
}
}
class CommandSubCharsSet
{
public string Chars = "";
public bool EmptyAllowed = false;
}
}

View File

@ -1,72 +0,0 @@
// InBuffer.cs
namespace SevenZip.Buffer
{
public class InBuffer
{
byte[] m_Buffer;
uint m_Pos;
uint m_Limit;
uint m_BufferSize;
System.IO.Stream m_Stream;
bool m_StreamWasExhausted;
ulong m_ProcessedSize;
public InBuffer(uint bufferSize)
{
m_Buffer = new byte[bufferSize];
m_BufferSize = bufferSize;
}
public void Init(System.IO.Stream stream)
{
m_Stream = stream;
m_ProcessedSize = 0;
m_Limit = 0;
m_Pos = 0;
m_StreamWasExhausted = false;
}
public bool ReadBlock()
{
if (m_StreamWasExhausted)
return false;
m_ProcessedSize += m_Pos;
int aNumProcessedBytes = m_Stream.Read(m_Buffer, 0, (int)m_BufferSize);
m_Pos = 0;
m_Limit = (uint)aNumProcessedBytes;
m_StreamWasExhausted = (aNumProcessedBytes == 0);
return (!m_StreamWasExhausted);
}
public void ReleaseStream()
{
// m_Stream.Close();
m_Stream = null;
}
public bool ReadByte(byte b) // check it
{
if (m_Pos >= m_Limit)
if (!ReadBlock())
return false;
b = m_Buffer[m_Pos++];
return true;
}
public byte ReadByte()
{
// return (byte)m_Stream.ReadByte();
if (m_Pos >= m_Limit)
if (!ReadBlock())
return 0xFF;
return m_Buffer[m_Pos++];
}
public ulong GetProcessedSize()
{
return m_ProcessedSize + m_Pos;
}
}
}

View File

@ -1,47 +0,0 @@
// OutBuffer.cs
namespace SevenZip.Buffer
{
public class OutBuffer
{
byte[] m_Buffer;
uint m_Pos;
uint m_BufferSize;
System.IO.Stream m_Stream;
ulong m_ProcessedSize;
public OutBuffer(uint bufferSize)
{
m_Buffer = new byte[bufferSize];
m_BufferSize = bufferSize;
}
public void SetStream(System.IO.Stream stream) { m_Stream = stream; }
public void FlushStream() { m_Stream.Flush(); }
public void CloseStream() { m_Stream.Close(); }
public void ReleaseStream() { m_Stream = null; }
public void Init()
{
m_ProcessedSize = 0;
m_Pos = 0;
}
public void WriteByte(byte b)
{
m_Buffer[m_Pos++] = b;
if (m_Pos >= m_BufferSize)
FlushData();
}
public void FlushData()
{
if (m_Pos == 0)
return;
m_Stream.Write(m_Buffer, 0, (int)m_Pos);
m_Pos = 0;
}
public ulong GetProcessedSize() { return m_ProcessedSize + m_Pos; }
}
}

View File

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 4b6765bf0d03fd243b47d74c9b73c38b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: a83572c42056f474db56e761a4f35e38
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,24 +0,0 @@
// IMatchFinder.cs
using System;
namespace SevenZip.Compression.LZ
{
interface IInWindowStream
{
void SetStream(System.IO.Stream inStream);
void Init();
void ReleaseStream();
Byte GetIndexByte(Int32 index);
UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit);
UInt32 GetNumAvailableBytes();
}
interface IMatchFinder : IInWindowStream
{
void Create(UInt32 historySize, UInt32 keepAddBufferBefore,
UInt32 matchMaxLen, UInt32 keepAddBufferAfter);
UInt32 GetMatches(UInt32[] distances);
void Skip(UInt32 num);
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: bfd1ee430d8108042a2607d92d7f58ad
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,367 +0,0 @@
// LzBinTree.cs
using System;
namespace SevenZip.Compression.LZ
{
public class BinTree : InWindow, IMatchFinder
{
UInt32 _cyclicBufferPos;
UInt32 _cyclicBufferSize = 0;
UInt32 _matchMaxLen;
UInt32[] _son;
UInt32[] _hash;
UInt32 _cutValue = 0xFF;
UInt32 _hashMask;
UInt32 _hashSizeSum = 0;
bool HASH_ARRAY = true;
const UInt32 kHash2Size = 1 << 10;
const UInt32 kHash3Size = 1 << 16;
const UInt32 kBT2HashSize = 1 << 16;
const UInt32 kStartMaxLen = 1;
const UInt32 kHash3Offset = kHash2Size;
const UInt32 kEmptyHashValue = 0;
const UInt32 kMaxValForNormalize = ((UInt32)1 << 31) - 1;
UInt32 kNumHashDirectBytes = 0;
UInt32 kMinMatchCheck = 4;
UInt32 kFixHashSize = kHash2Size + kHash3Size;
public void SetType(int numHashBytes)
{
HASH_ARRAY = (numHashBytes > 2);
if (HASH_ARRAY)
{
kNumHashDirectBytes = 0;
kMinMatchCheck = 4;
kFixHashSize = kHash2Size + kHash3Size;
}
else
{
kNumHashDirectBytes = 2;
kMinMatchCheck = 2 + 1;
kFixHashSize = 0;
}
}
public new void SetStream(System.IO.Stream stream) { base.SetStream(stream); }
public new void ReleaseStream() { base.ReleaseStream(); }
public new void Init()
{
base.Init();
for (UInt32 i = 0; i < _hashSizeSum; i++)
_hash[i] = kEmptyHashValue;
_cyclicBufferPos = 0;
ReduceOffsets(-1);
}
public new void MovePos()
{
if (++_cyclicBufferPos >= _cyclicBufferSize)
_cyclicBufferPos = 0;
base.MovePos();
if (_pos == kMaxValForNormalize)
Normalize();
}
public new Byte GetIndexByte(Int32 index) { return base.GetIndexByte(index); }
public new UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit)
{ return base.GetMatchLen(index, distance, limit); }
public new UInt32 GetNumAvailableBytes() { return base.GetNumAvailableBytes(); }
public void Create(UInt32 historySize, UInt32 keepAddBufferBefore,
UInt32 matchMaxLen, UInt32 keepAddBufferAfter)
{
if (historySize > kMaxValForNormalize - 256)
throw new Exception();
_cutValue = 16 + (matchMaxLen >> 1);
UInt32 windowReservSize = (historySize + keepAddBufferBefore +
matchMaxLen + keepAddBufferAfter) / 2 + 256;
base.Create(historySize + keepAddBufferBefore, matchMaxLen + keepAddBufferAfter, windowReservSize);
_matchMaxLen = matchMaxLen;
UInt32 cyclicBufferSize = historySize + 1;
if (_cyclicBufferSize != cyclicBufferSize)
_son = new UInt32[(_cyclicBufferSize = cyclicBufferSize) * 2];
UInt32 hs = kBT2HashSize;
if (HASH_ARRAY)
{
hs = historySize - 1;
hs |= (hs >> 1);
hs |= (hs >> 2);
hs |= (hs >> 4);
hs |= (hs >> 8);
hs >>= 1;
hs |= 0xFFFF;
if (hs > (1 << 24))
hs >>= 1;
_hashMask = hs;
hs++;
hs += kFixHashSize;
}
if (hs != _hashSizeSum)
_hash = new UInt32[_hashSizeSum = hs];
}
public UInt32 GetMatches(UInt32[] distances)
{
UInt32 lenLimit;
if (_pos + _matchMaxLen <= _streamPos)
lenLimit = _matchMaxLen;
else
{
lenLimit = _streamPos - _pos;
if (lenLimit < kMinMatchCheck)
{
MovePos();
return 0;
}
}
UInt32 offset = 0;
UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0;
UInt32 cur = _bufferOffset + _pos;
UInt32 maxLen = kStartMaxLen; // to avoid items for len < hashSize;
UInt32 hashValue, hash2Value = 0, hash3Value = 0;
if (HASH_ARRAY)
{
UInt32 temp = CRC.Table[_bufferBase[cur]] ^ _bufferBase[cur + 1];
hash2Value = temp & (kHash2Size - 1);
temp ^= ((UInt32)(_bufferBase[cur + 2]) << 8);
hash3Value = temp & (kHash3Size - 1);
hashValue = (temp ^ (CRC.Table[_bufferBase[cur + 3]] << 5)) & _hashMask;
}
else
hashValue = _bufferBase[cur] ^ ((UInt32)(_bufferBase[cur + 1]) << 8);
UInt32 curMatch = _hash[kFixHashSize + hashValue];
if (HASH_ARRAY)
{
UInt32 curMatch2 = _hash[hash2Value];
UInt32 curMatch3 = _hash[kHash3Offset + hash3Value];
_hash[hash2Value] = _pos;
_hash[kHash3Offset + hash3Value] = _pos;
if (curMatch2 > matchMinPos)
if (_bufferBase[_bufferOffset + curMatch2] == _bufferBase[cur])
{
distances[offset++] = maxLen = 2;
distances[offset++] = _pos - curMatch2 - 1;
}
if (curMatch3 > matchMinPos)
if (_bufferBase[_bufferOffset + curMatch3] == _bufferBase[cur])
{
if (curMatch3 == curMatch2)
offset -= 2;
distances[offset++] = maxLen = 3;
distances[offset++] = _pos - curMatch3 - 1;
curMatch2 = curMatch3;
}
if (offset != 0 && curMatch2 == curMatch)
{
offset -= 2;
maxLen = kStartMaxLen;
}
}
_hash[kFixHashSize + hashValue] = _pos;
UInt32 ptr0 = (_cyclicBufferPos << 1) + 1;
UInt32 ptr1 = (_cyclicBufferPos << 1);
UInt32 len0, len1;
len0 = len1 = kNumHashDirectBytes;
if (kNumHashDirectBytes != 0)
{
if (curMatch > matchMinPos)
{
if (_bufferBase[_bufferOffset + curMatch + kNumHashDirectBytes] !=
_bufferBase[cur + kNumHashDirectBytes])
{
distances[offset++] = maxLen = kNumHashDirectBytes;
distances[offset++] = _pos - curMatch - 1;
}
}
}
UInt32 count = _cutValue;
while(true)
{
if(curMatch <= matchMinPos || count-- == 0)
{
_son[ptr0] = _son[ptr1] = kEmptyHashValue;
break;
}
UInt32 delta = _pos - curMatch;
UInt32 cyclicPos = ((delta <= _cyclicBufferPos) ?
(_cyclicBufferPos - delta) :
(_cyclicBufferPos - delta + _cyclicBufferSize)) << 1;
UInt32 pby1 = _bufferOffset + curMatch;
UInt32 len = Math.Min(len0, len1);
if (_bufferBase[pby1 + len] == _bufferBase[cur + len])
{
while(++len != lenLimit)
if (_bufferBase[pby1 + len] != _bufferBase[cur + len])
break;
if (maxLen < len)
{
distances[offset++] = maxLen = len;
distances[offset++] = delta - 1;
if (len == lenLimit)
{
_son[ptr1] = _son[cyclicPos];
_son[ptr0] = _son[cyclicPos + 1];
break;
}
}
}
if (_bufferBase[pby1 + len] < _bufferBase[cur + len])
{
_son[ptr1] = curMatch;
ptr1 = cyclicPos + 1;
curMatch = _son[ptr1];
len1 = len;
}
else
{
_son[ptr0] = curMatch;
ptr0 = cyclicPos;
curMatch = _son[ptr0];
len0 = len;
}
}
MovePos();
return offset;
}
public void Skip(UInt32 num)
{
do
{
UInt32 lenLimit;
if (_pos + _matchMaxLen <= _streamPos)
lenLimit = _matchMaxLen;
else
{
lenLimit = _streamPos - _pos;
if (lenLimit < kMinMatchCheck)
{
MovePos();
continue;
}
}
UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0;
UInt32 cur = _bufferOffset + _pos;
UInt32 hashValue;
if (HASH_ARRAY)
{
UInt32 temp = CRC.Table[_bufferBase[cur]] ^ _bufferBase[cur + 1];
UInt32 hash2Value = temp & (kHash2Size - 1);
_hash[hash2Value] = _pos;
temp ^= ((UInt32)(_bufferBase[cur + 2]) << 8);
UInt32 hash3Value = temp & (kHash3Size - 1);
_hash[kHash3Offset + hash3Value] = _pos;
hashValue = (temp ^ (CRC.Table[_bufferBase[cur + 3]] << 5)) & _hashMask;
}
else
hashValue = _bufferBase[cur] ^ ((UInt32)(_bufferBase[cur + 1]) << 8);
UInt32 curMatch = _hash[kFixHashSize + hashValue];
_hash[kFixHashSize + hashValue] = _pos;
UInt32 ptr0 = (_cyclicBufferPos << 1) + 1;
UInt32 ptr1 = (_cyclicBufferPos << 1);
UInt32 len0, len1;
len0 = len1 = kNumHashDirectBytes;
UInt32 count = _cutValue;
while (true)
{
if (curMatch <= matchMinPos || count-- == 0)
{
_son[ptr0] = _son[ptr1] = kEmptyHashValue;
break;
}
UInt32 delta = _pos - curMatch;
UInt32 cyclicPos = ((delta <= _cyclicBufferPos) ?
(_cyclicBufferPos - delta) :
(_cyclicBufferPos - delta + _cyclicBufferSize)) << 1;
UInt32 pby1 = _bufferOffset + curMatch;
UInt32 len = Math.Min(len0, len1);
if (_bufferBase[pby1 + len] == _bufferBase[cur + len])
{
while (++len != lenLimit)
if (_bufferBase[pby1 + len] != _bufferBase[cur + len])
break;
if (len == lenLimit)
{
_son[ptr1] = _son[cyclicPos];
_son[ptr0] = _son[cyclicPos + 1];
break;
}
}
if (_bufferBase[pby1 + len] < _bufferBase[cur + len])
{
_son[ptr1] = curMatch;
ptr1 = cyclicPos + 1;
curMatch = _son[ptr1];
len1 = len;
}
else
{
_son[ptr0] = curMatch;
ptr0 = cyclicPos;
curMatch = _son[ptr0];
len0 = len;
}
}
MovePos();
}
while (--num != 0);
}
void NormalizeLinks(UInt32[] items, UInt32 numItems, UInt32 subValue)
{
for (UInt32 i = 0; i < numItems; i++)
{
UInt32 value = items[i];
if (value <= subValue)
value = kEmptyHashValue;
else
value -= subValue;
items[i] = value;
}
}
void Normalize()
{
UInt32 subValue = _pos - _cyclicBufferSize;
NormalizeLinks(_son, _cyclicBufferSize * 2, subValue);
NormalizeLinks(_hash, _hashSizeSum, subValue);
ReduceOffsets((Int32)subValue);
}
public void SetCutValue(UInt32 cutValue) { _cutValue = cutValue; }
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 3ba8015d2d5df3a459615ffc06635e6d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,132 +0,0 @@
// LzInWindow.cs
using System;
namespace SevenZip.Compression.LZ
{
public class InWindow
{
public Byte[] _bufferBase = null; // pointer to buffer with data
System.IO.Stream _stream;
UInt32 _posLimit; // offset (from _buffer) of first byte when new block reading must be done
bool _streamEndWasReached; // if (true) then _streamPos shows real end of stream
UInt32 _pointerToLastSafePosition;
public UInt32 _bufferOffset;
public UInt32 _blockSize; // Size of Allocated memory block
public UInt32 _pos; // offset (from _buffer) of curent byte
UInt32 _keepSizeBefore; // how many BYTEs must be kept in buffer before _pos
UInt32 _keepSizeAfter; // how many BYTEs must be kept buffer after _pos
public UInt32 _streamPos; // offset (from _buffer) of first not read byte from Stream
public void MoveBlock()
{
UInt32 offset = (UInt32)(_bufferOffset) + _pos - _keepSizeBefore;
// we need one additional byte, since MovePos moves on 1 byte.
if (offset > 0)
offset--;
UInt32 numBytes = (UInt32)(_bufferOffset) + _streamPos - offset;
// check negative offset ????
for (UInt32 i = 0; i < numBytes; i++)
_bufferBase[i] = _bufferBase[offset + i];
_bufferOffset -= offset;
}
public virtual void ReadBlock()
{
if (_streamEndWasReached)
return;
while (true)
{
int size = (int)((0 - _bufferOffset) + _blockSize - _streamPos);
if (size == 0)
return;
int numReadBytes = _stream.Read(_bufferBase, (int)(_bufferOffset + _streamPos), size);
if (numReadBytes == 0)
{
_posLimit = _streamPos;
UInt32 pointerToPostion = _bufferOffset + _posLimit;
if (pointerToPostion > _pointerToLastSafePosition)
_posLimit = (UInt32)(_pointerToLastSafePosition - _bufferOffset);
_streamEndWasReached = true;
return;
}
_streamPos += (UInt32)numReadBytes;
if (_streamPos >= _pos + _keepSizeAfter)
_posLimit = _streamPos - _keepSizeAfter;
}
}
void Free() { _bufferBase = null; }
public void Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, UInt32 keepSizeReserv)
{
_keepSizeBefore = keepSizeBefore;
_keepSizeAfter = keepSizeAfter;
UInt32 blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv;
if (_bufferBase == null || _blockSize != blockSize)
{
Free();
_blockSize = blockSize;
_bufferBase = new Byte[_blockSize];
}
_pointerToLastSafePosition = _blockSize - keepSizeAfter;
}
public void SetStream(System.IO.Stream stream) { _stream = stream; }
public void ReleaseStream() { _stream = null; }
public void Init()
{
_bufferOffset = 0;
_pos = 0;
_streamPos = 0;
_streamEndWasReached = false;
ReadBlock();
}
public void MovePos()
{
_pos++;
if (_pos > _posLimit)
{
UInt32 pointerToPostion = _bufferOffset + _pos;
if (pointerToPostion > _pointerToLastSafePosition)
MoveBlock();
ReadBlock();
}
}
public Byte GetIndexByte(Int32 index) { return _bufferBase[_bufferOffset + _pos + index]; }
// index + limit have not to exceed _keepSizeAfter;
public UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit)
{
if (_streamEndWasReached)
if ((_pos + index) + limit > _streamPos)
limit = _streamPos - (UInt32)(_pos + index);
distance++;
// Byte *pby = _buffer + (size_t)_pos + index;
UInt32 pby = _bufferOffset + _pos + (UInt32)index;
UInt32 i;
for (i = 0; i < limit && _bufferBase[pby + i] == _bufferBase[pby + i - distance]; i++);
return i;
}
public UInt32 GetNumAvailableBytes() { return _streamPos - _pos; }
public void ReduceOffsets(Int32 subValue)
{
_bufferOffset += (UInt32)subValue;
_posLimit -= (UInt32)subValue;
_pos -= (UInt32)subValue;
_streamPos -= (UInt32)subValue;
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 333112c3785a6ec4cbbfec8515081cac
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,110 +0,0 @@
// LzOutWindow.cs
namespace SevenZip.Compression.LZ
{
public class OutWindow
{
byte[] _buffer = null;
uint _pos;
uint _windowSize = 0;
uint _streamPos;
System.IO.Stream _stream;
public uint TrainSize = 0;
public void Create(uint windowSize)
{
if (_windowSize != windowSize)
{
// System.GC.Collect();
_buffer = new byte[windowSize];
}
_windowSize = windowSize;
_pos = 0;
_streamPos = 0;
}
public void Init(System.IO.Stream stream, bool solid)
{
ReleaseStream();
_stream = stream;
if (!solid)
{
_streamPos = 0;
_pos = 0;
TrainSize = 0;
}
}
public bool Train(System.IO.Stream stream)
{
long len = stream.Length;
uint size = (len < _windowSize) ? (uint)len : _windowSize;
TrainSize = size;
stream.Position = len - size;
_streamPos = _pos = 0;
while (size > 0)
{
uint curSize = _windowSize - _pos;
if (size < curSize)
curSize = size;
int numReadBytes = stream.Read(_buffer, (int)_pos, (int)curSize);
if (numReadBytes == 0)
return false;
size -= (uint)numReadBytes;
_pos += (uint)numReadBytes;
_streamPos += (uint)numReadBytes;
if (_pos == _windowSize)
_streamPos = _pos = 0;
}
return true;
}
public void ReleaseStream()
{
Flush();
_stream = null;
}
public void Flush()
{
uint size = _pos - _streamPos;
if (size == 0)
return;
_stream.Write(_buffer, (int)_streamPos, (int)size);
if (_pos >= _windowSize)
_pos = 0;
_streamPos = _pos;
}
public void CopyBlock(uint distance, uint len)
{
uint pos = _pos - distance - 1;
if (pos >= _windowSize)
pos += _windowSize;
for (; len > 0; len--)
{
if (pos >= _windowSize)
pos = 0;
_buffer[_pos++] = _buffer[pos++];
if (_pos >= _windowSize)
Flush();
}
}
public void PutByte(byte b)
{
_buffer[_pos++] = b;
if (_pos >= _windowSize)
Flush();
}
public byte GetByte(uint distance)
{
uint pos = _pos - distance - 1;
if (pos >= _windowSize)
pos += _windowSize;
return _buffer[pos];
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: bb296a6e14ab7c44cb6388693d581a62
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 5fcd2f5c8b724164a8a01cee73896d1a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,76 +0,0 @@
// LzmaBase.cs
namespace SevenZip.Compression.LZMA
{
internal abstract class Base
{
public const uint kNumRepDistances = 4;
public const uint kNumStates = 12;
// static byte []kLiteralNextStates = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5};
// static byte []kMatchNextStates = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
// static byte []kRepNextStates = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
// static byte []kShortRepNextStates = {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
public struct State
{
public uint Index;
public void Init() { Index = 0; }
public void UpdateChar()
{
if (Index < 4) Index = 0;
else if (Index < 10) Index -= 3;
else Index -= 6;
}
public void UpdateMatch() { Index = (uint)(Index < 7 ? 7 : 10); }
public void UpdateRep() { Index = (uint)(Index < 7 ? 8 : 11); }
public void UpdateShortRep() { Index = (uint)(Index < 7 ? 9 : 11); }
public bool IsCharState() { return Index < 7; }
}
public const int kNumPosSlotBits = 6;
public const int kDicLogSizeMin = 0;
// public const int kDicLogSizeMax = 30;
// public const uint kDistTableSizeMax = kDicLogSizeMax * 2;
public const int kNumLenToPosStatesBits = 2; // it's for speed optimization
public const uint kNumLenToPosStates = 1 << kNumLenToPosStatesBits;
public const uint kMatchMinLen = 2;
public static uint GetLenToPosState(uint len)
{
len -= kMatchMinLen;
if (len < kNumLenToPosStates)
return len;
return (uint)(kNumLenToPosStates - 1);
}
public const int kNumAlignBits = 4;
public const uint kAlignTableSize = 1 << kNumAlignBits;
public const uint kAlignMask = (kAlignTableSize - 1);
public const uint kStartPosModelIndex = 4;
public const uint kEndPosModelIndex = 14;
public const uint kNumPosModels = kEndPosModelIndex - kStartPosModelIndex;
public const uint kNumFullDistances = 1 << ((int)kEndPosModelIndex / 2);
public const uint kNumLitPosStatesBitsEncodingMax = 4;
public const uint kNumLitContextBitsMax = 8;
public const int kNumPosStatesBitsMax = 4;
public const uint kNumPosStatesMax = (1 << kNumPosStatesBitsMax);
public const int kNumPosStatesBitsEncodingMax = 4;
public const uint kNumPosStatesEncodingMax = (1 << kNumPosStatesBitsEncodingMax);
public const int kNumLowLenBits = 3;
public const int kNumMidLenBits = 3;
public const int kNumHighLenBits = 8;
public const uint kNumLowLenSymbols = 1 << kNumLowLenBits;
public const uint kNumMidLenSymbols = 1 << kNumMidLenBits;
public const uint kNumLenSymbols = kNumLowLenSymbols + kNumMidLenSymbols +
(1 << kNumHighLenBits);
public const uint kMatchMaxLen = kMatchMinLen + kNumLenSymbols - 1;
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 62f365191077342479f8227edadf57e3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,398 +0,0 @@
// LzmaDecoder.cs
using System;
namespace SevenZip.Compression.LZMA
{
using RangeCoder;
public class Decoder : ICoder, ISetDecoderProperties // ,System.IO.Stream
{
class LenDecoder
{
BitDecoder m_Choice = new BitDecoder();
BitDecoder m_Choice2 = new BitDecoder();
BitTreeDecoder[] m_LowCoder = new BitTreeDecoder[Base.kNumPosStatesMax];
BitTreeDecoder[] m_MidCoder = new BitTreeDecoder[Base.kNumPosStatesMax];
BitTreeDecoder m_HighCoder = new BitTreeDecoder(Base.kNumHighLenBits);
uint m_NumPosStates = 0;
public void Create(uint numPosStates)
{
for (uint posState = m_NumPosStates; posState < numPosStates; posState++)
{
m_LowCoder[posState] = new BitTreeDecoder(Base.kNumLowLenBits);
m_MidCoder[posState] = new BitTreeDecoder(Base.kNumMidLenBits);
}
m_NumPosStates = numPosStates;
}
public void Init()
{
m_Choice.Init();
for (uint posState = 0; posState < m_NumPosStates; posState++)
{
m_LowCoder[posState].Init();
m_MidCoder[posState].Init();
}
m_Choice2.Init();
m_HighCoder.Init();
}
public uint Decode(RangeCoder.Decoder rangeDecoder, uint posState)
{
if (m_Choice.Decode(rangeDecoder) == 0)
return m_LowCoder[posState].Decode(rangeDecoder);
else
{
uint symbol = Base.kNumLowLenSymbols;
if (m_Choice2.Decode(rangeDecoder) == 0)
symbol += m_MidCoder[posState].Decode(rangeDecoder);
else
{
symbol += Base.kNumMidLenSymbols;
symbol += m_HighCoder.Decode(rangeDecoder);
}
return symbol;
}
}
}
class LiteralDecoder
{
struct Decoder2
{
BitDecoder[] m_Decoders;
public void Create() { m_Decoders = new BitDecoder[0x300]; }
public void Init() { for (int i = 0; i < 0x300; i++) m_Decoders[i].Init(); }
public byte DecodeNormal(RangeCoder.Decoder rangeDecoder)
{
uint symbol = 1;
do
symbol = (symbol << 1) | m_Decoders[symbol].Decode(rangeDecoder);
while (symbol < 0x100);
return (byte)symbol;
}
public byte DecodeWithMatchByte(RangeCoder.Decoder rangeDecoder, byte matchByte)
{
uint symbol = 1;
do
{
uint matchBit = (uint)(matchByte >> 7) & 1;
matchByte <<= 1;
uint bit = m_Decoders[((1 + matchBit) << 8) + symbol].Decode(rangeDecoder);
symbol = (symbol << 1) | bit;
if (matchBit != bit)
{
while (symbol < 0x100)
symbol = (symbol << 1) | m_Decoders[symbol].Decode(rangeDecoder);
break;
}
}
while (symbol < 0x100);
return (byte)symbol;
}
}
Decoder2[] m_Coders;
int m_NumPrevBits;
int m_NumPosBits;
uint m_PosMask;
public void Create(int numPosBits, int numPrevBits)
{
if (m_Coders != null && m_NumPrevBits == numPrevBits &&
m_NumPosBits == numPosBits)
return;
m_NumPosBits = numPosBits;
m_PosMask = ((uint)1 << numPosBits) - 1;
m_NumPrevBits = numPrevBits;
uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits);
m_Coders = new Decoder2[numStates];
for (uint i = 0; i < numStates; i++)
m_Coders[i].Create();
}
public void Init()
{
uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits);
for (uint i = 0; i < numStates; i++)
m_Coders[i].Init();
}
uint GetState(uint pos, byte prevByte)
{ return ((pos & m_PosMask) << m_NumPrevBits) + (uint)(prevByte >> (8 - m_NumPrevBits)); }
public byte DecodeNormal(RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte)
{ return m_Coders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder); }
public byte DecodeWithMatchByte(RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte, byte matchByte)
{ return m_Coders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte); }
};
LZ.OutWindow m_OutWindow = new LZ.OutWindow();
RangeCoder.Decoder m_RangeDecoder = new RangeCoder.Decoder();
BitDecoder[] m_IsMatchDecoders = new BitDecoder[Base.kNumStates << Base.kNumPosStatesBitsMax];
BitDecoder[] m_IsRepDecoders = new BitDecoder[Base.kNumStates];
BitDecoder[] m_IsRepG0Decoders = new BitDecoder[Base.kNumStates];
BitDecoder[] m_IsRepG1Decoders = new BitDecoder[Base.kNumStates];
BitDecoder[] m_IsRepG2Decoders = new BitDecoder[Base.kNumStates];
BitDecoder[] m_IsRep0LongDecoders = new BitDecoder[Base.kNumStates << Base.kNumPosStatesBitsMax];
BitTreeDecoder[] m_PosSlotDecoder = new BitTreeDecoder[Base.kNumLenToPosStates];
BitDecoder[] m_PosDecoders = new BitDecoder[Base.kNumFullDistances - Base.kEndPosModelIndex];
BitTreeDecoder m_PosAlignDecoder = new BitTreeDecoder(Base.kNumAlignBits);
LenDecoder m_LenDecoder = new LenDecoder();
LenDecoder m_RepLenDecoder = new LenDecoder();
LiteralDecoder m_LiteralDecoder = new LiteralDecoder();
uint m_DictionarySize;
uint m_DictionarySizeCheck;
uint m_PosStateMask;
public Decoder()
{
m_DictionarySize = 0xFFFFFFFF;
for (int i = 0; i < Base.kNumLenToPosStates; i++)
m_PosSlotDecoder[i] = new BitTreeDecoder(Base.kNumPosSlotBits);
}
void SetDictionarySize(uint dictionarySize)
{
if (m_DictionarySize != dictionarySize)
{
m_DictionarySize = dictionarySize;
m_DictionarySizeCheck = Math.Max(m_DictionarySize, 1);
uint blockSize = Math.Max(m_DictionarySizeCheck, (1 << 12));
m_OutWindow.Create(blockSize);
}
}
void SetLiteralProperties(int lp, int lc)
{
if (lp > 8)
throw new InvalidParamException();
if (lc > 8)
throw new InvalidParamException();
m_LiteralDecoder.Create(lp, lc);
}
void SetPosBitsProperties(int pb)
{
if (pb > Base.kNumPosStatesBitsMax)
throw new InvalidParamException();
uint numPosStates = (uint)1 << pb;
m_LenDecoder.Create(numPosStates);
m_RepLenDecoder.Create(numPosStates);
m_PosStateMask = numPosStates - 1;
}
bool _solid = false;
void Init(System.IO.Stream inStream, System.IO.Stream outStream)
{
m_RangeDecoder.Init(inStream);
m_OutWindow.Init(outStream, _solid);
uint i;
for (i = 0; i < Base.kNumStates; i++)
{
for (uint j = 0; j <= m_PosStateMask; j++)
{
uint index = (i << Base.kNumPosStatesBitsMax) + j;
m_IsMatchDecoders[index].Init();
m_IsRep0LongDecoders[index].Init();
}
m_IsRepDecoders[i].Init();
m_IsRepG0Decoders[i].Init();
m_IsRepG1Decoders[i].Init();
m_IsRepG2Decoders[i].Init();
}
m_LiteralDecoder.Init();
for (i = 0; i < Base.kNumLenToPosStates; i++)
m_PosSlotDecoder[i].Init();
// m_PosSpecDecoder.Init();
for (i = 0; i < Base.kNumFullDistances - Base.kEndPosModelIndex; i++)
m_PosDecoders[i].Init();
m_LenDecoder.Init();
m_RepLenDecoder.Init();
m_PosAlignDecoder.Init();
}
public void Code(System.IO.Stream inStream, System.IO.Stream outStream,
Int64 inSize, Int64 outSize, ICodeProgress progress)
{
Init(inStream, outStream);
Base.State state = new Base.State();
state.Init();
uint rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0;
UInt64 nowPos64 = 0;
UInt64 outSize64 = (UInt64)outSize;
if (nowPos64 < outSize64)
{
if (m_IsMatchDecoders[state.Index << Base.kNumPosStatesBitsMax].Decode(m_RangeDecoder) != 0)
throw new DataErrorException();
state.UpdateChar();
byte b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, 0, 0);
m_OutWindow.PutByte(b);
nowPos64++;
}
while (nowPos64 < outSize64)
{
// UInt64 next = Math.Min(nowPos64 + (1 << 18), outSize64);
// while(nowPos64 < next)
{
uint posState = (uint)nowPos64 & m_PosStateMask;
if (m_IsMatchDecoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode(m_RangeDecoder) == 0)
{
byte b;
byte prevByte = m_OutWindow.GetByte(0);
if (!state.IsCharState())
b = m_LiteralDecoder.DecodeWithMatchByte(m_RangeDecoder,
(uint)nowPos64, prevByte, m_OutWindow.GetByte(rep0));
else
b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, (uint)nowPos64, prevByte);
m_OutWindow.PutByte(b);
state.UpdateChar();
nowPos64++;
}
else
{
uint len;
if (m_IsRepDecoders[state.Index].Decode(m_RangeDecoder) == 1)
{
if (m_IsRepG0Decoders[state.Index].Decode(m_RangeDecoder) == 0)
{
if (m_IsRep0LongDecoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode(m_RangeDecoder) == 0)
{
state.UpdateShortRep();
m_OutWindow.PutByte(m_OutWindow.GetByte(rep0));
nowPos64++;
continue;
}
}
else
{
UInt32 distance;
if (m_IsRepG1Decoders[state.Index].Decode(m_RangeDecoder) == 0)
{
distance = rep1;
}
else
{
if (m_IsRepG2Decoders[state.Index].Decode(m_RangeDecoder) == 0)
distance = rep2;
else
{
distance = rep3;
rep3 = rep2;
}
rep2 = rep1;
}
rep1 = rep0;
rep0 = distance;
}
len = m_RepLenDecoder.Decode(m_RangeDecoder, posState) + Base.kMatchMinLen;
state.UpdateRep();
}
else
{
rep3 = rep2;
rep2 = rep1;
rep1 = rep0;
len = Base.kMatchMinLen + m_LenDecoder.Decode(m_RangeDecoder, posState);
state.UpdateMatch();
uint posSlot = m_PosSlotDecoder[Base.GetLenToPosState(len)].Decode(m_RangeDecoder);
if (posSlot >= Base.kStartPosModelIndex)
{
int numDirectBits = (int)((posSlot >> 1) - 1);
rep0 = ((2 | (posSlot & 1)) << numDirectBits);
if (posSlot < Base.kEndPosModelIndex)
rep0 += BitTreeDecoder.ReverseDecode(m_PosDecoders,
rep0 - posSlot - 1, m_RangeDecoder, numDirectBits);
else
{
rep0 += (m_RangeDecoder.DecodeDirectBits(
numDirectBits - Base.kNumAlignBits) << Base.kNumAlignBits);
rep0 += m_PosAlignDecoder.ReverseDecode(m_RangeDecoder);
}
}
else
rep0 = posSlot;
}
if (rep0 >= m_OutWindow.TrainSize + nowPos64 || rep0 >= m_DictionarySizeCheck)
{
if (rep0 == 0xFFFFFFFF)
break;
throw new DataErrorException();
}
m_OutWindow.CopyBlock(rep0, len);
nowPos64 += len;
}
}
}
m_OutWindow.Flush();
m_OutWindow.ReleaseStream();
m_RangeDecoder.ReleaseStream();
}
public void SetDecoderProperties(byte[] properties)
{
if (properties.Length < 5)
throw new InvalidParamException();
int lc = properties[0] % 9;
int remainder = properties[0] / 9;
int lp = remainder % 5;
int pb = remainder / 5;
if (pb > Base.kNumPosStatesBitsMax)
throw new InvalidParamException();
UInt32 dictionarySize = 0;
for (int i = 0; i < 4; i++)
dictionarySize += ((UInt32)(properties[1 + i])) << (i * 8);
SetDictionarySize(dictionarySize);
SetLiteralProperties(lp, lc);
SetPosBitsProperties(pb);
}
public bool Train(System.IO.Stream stream)
{
_solid = true;
return m_OutWindow.Train(stream);
}
/*
public override bool CanRead { get { return true; }}
public override bool CanWrite { get { return true; }}
public override bool CanSeek { get { return true; }}
public override long Length { get { return 0; }}
public override long Position
{
get { return 0; }
set { }
}
public override void Flush() { }
public override int Read(byte[] buffer, int offset, int count)
{
return 0;
}
public override void Write(byte[] buffer, int offset, int count)
{
}
public override long Seek(long offset, System.IO.SeekOrigin origin)
{
return 0;
}
public override void SetLength(long value) {}
*/
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: c60a9ce2c6df6774498e337ad69a356b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 37dcefc9d952dc34f9fba085a160a968
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 73c80167cede90a4a8fc4938bab053c8
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,234 +0,0 @@
using System;
namespace SevenZip.Compression.RangeCoder
{
class Encoder
{
public const uint kTopValue = (1 << 24);
System.IO.Stream Stream;
public UInt64 Low;
public uint Range;
uint _cacheSize;
byte _cache;
long StartPosition;
public void SetStream(System.IO.Stream stream)
{
Stream = stream;
}
public void ReleaseStream()
{
Stream = null;
}
public void Init()
{
StartPosition = Stream.Position;
Low = 0;
Range = 0xFFFFFFFF;
_cacheSize = 1;
_cache = 0;
}
public void FlushData()
{
for (int i = 0; i < 5; i++)
ShiftLow();
}
public void FlushStream()
{
Stream.Flush();
}
public void CloseStream()
{
Stream.Close();
}
public void Encode(uint start, uint size, uint total)
{
Low += start * (Range /= total);
Range *= size;
while (Range < kTopValue)
{
Range <<= 8;
ShiftLow();
}
}
public void ShiftLow()
{
if ((uint)Low < (uint)0xFF000000 || (uint)(Low >> 32) == 1)
{
byte temp = _cache;
do
{
Stream.WriteByte((byte)(temp + (Low >> 32)));
temp = 0xFF;
}
while (--_cacheSize != 0);
_cache = (byte)(((uint)Low) >> 24);
}
_cacheSize++;
Low = ((uint)Low) << 8;
}
public void EncodeDirectBits(uint v, int numTotalBits)
{
for (int i = numTotalBits - 1; i >= 0; i--)
{
Range >>= 1;
if (((v >> i) & 1) == 1)
Low += Range;
if (Range < kTopValue)
{
Range <<= 8;
ShiftLow();
}
}
}
public void EncodeBit(uint size0, int numTotalBits, uint symbol)
{
uint newBound = (Range >> numTotalBits) * size0;
if (symbol == 0)
Range = newBound;
else
{
Low += newBound;
Range -= newBound;
}
while (Range < kTopValue)
{
Range <<= 8;
ShiftLow();
}
}
public long GetProcessedSizeAdd()
{
return _cacheSize +
Stream.Position - StartPosition + 4;
// (long)Stream.GetProcessedSize();
}
}
class Decoder
{
public const uint kTopValue = (1 << 24);
public uint Range;
public uint Code;
// public Buffer.InBuffer Stream = new Buffer.InBuffer(1 << 16);
public System.IO.Stream Stream;
public void Init(System.IO.Stream stream)
{
// Stream.Init(stream);
Stream = stream;
Code = 0;
Range = 0xFFFFFFFF;
for (int i = 0; i < 5; i++)
Code = (Code << 8) | (byte)Stream.ReadByte();
}
public void ReleaseStream()
{
// Stream.ReleaseStream();
Stream = null;
}
public void CloseStream()
{
Stream.Close();
}
public void Normalize()
{
while (Range < kTopValue)
{
Code = (Code << 8) | (byte)Stream.ReadByte();
Range <<= 8;
}
}
public void Normalize2()
{
if (Range < kTopValue)
{
Code = (Code << 8) | (byte)Stream.ReadByte();
Range <<= 8;
}
}
public uint GetThreshold(uint total)
{
return Code / (Range /= total);
}
public void Decode(uint start, uint size, uint total)
{
Code -= start * Range;
Range *= size;
Normalize();
}
public uint DecodeDirectBits(int numTotalBits)
{
uint range = Range;
uint code = Code;
uint result = 0;
for (int i = numTotalBits; i > 0; i--)
{
range >>= 1;
/*
result <<= 1;
if (code >= range)
{
code -= range;
result |= 1;
}
*/
uint t = (code - range) >> 31;
code -= range & (t - 1);
result = (result << 1) | (1 - t);
if (range < kTopValue)
{
code = (code << 8) | (byte)Stream.ReadByte();
range <<= 8;
}
}
Range = range;
Code = code;
return result;
}
public uint DecodeBit(uint size0, int numTotalBits)
{
uint newBound = (Range >> numTotalBits) * size0;
uint symbol;
if (Code < newBound)
{
symbol = 0;
Range = newBound;
}
else
{
symbol = 1;
Code -= newBound;
Range -= newBound;
}
Normalize();
return symbol;
}
// ulong GetProcessedSize() {return Stream.GetProcessedSize(); }
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: a855cbfe314340a43b3d71672dcbb058
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,117 +0,0 @@
using System;
namespace SevenZip.Compression.RangeCoder
{
struct BitEncoder
{
public const int kNumBitModelTotalBits = 11;
public const uint kBitModelTotal = (1 << kNumBitModelTotalBits);
const int kNumMoveBits = 5;
const int kNumMoveReducingBits = 2;
public const int kNumBitPriceShiftBits = 6;
uint Prob;
public void Init() { Prob = kBitModelTotal >> 1; }
public void UpdateModel(uint symbol)
{
if (symbol == 0)
Prob += (kBitModelTotal - Prob) >> kNumMoveBits;
else
Prob -= (Prob) >> kNumMoveBits;
}
public void Encode(Encoder encoder, uint symbol)
{
// encoder.EncodeBit(Prob, kNumBitModelTotalBits, symbol);
// UpdateModel(symbol);
uint newBound = (encoder.Range >> kNumBitModelTotalBits) * Prob;
if (symbol == 0)
{
encoder.Range = newBound;
Prob += (kBitModelTotal - Prob) >> kNumMoveBits;
}
else
{
encoder.Low += newBound;
encoder.Range -= newBound;
Prob -= (Prob) >> kNumMoveBits;
}
if (encoder.Range < Encoder.kTopValue)
{
encoder.Range <<= 8;
encoder.ShiftLow();
}
}
private static UInt32[] ProbPrices = new UInt32[kBitModelTotal >> kNumMoveReducingBits];
static BitEncoder()
{
const int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits);
for (int i = kNumBits - 1; i >= 0; i--)
{
UInt32 start = (UInt32)1 << (kNumBits - i - 1);
UInt32 end = (UInt32)1 << (kNumBits - i);
for (UInt32 j = start; j < end; j++)
ProbPrices[j] = ((UInt32)i << kNumBitPriceShiftBits) +
(((end - j) << kNumBitPriceShiftBits) >> (kNumBits - i - 1));
}
}
public uint GetPrice(uint symbol)
{
return ProbPrices[(((Prob - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];
}
public uint GetPrice0() { return ProbPrices[Prob >> kNumMoveReducingBits]; }
public uint GetPrice1() { return ProbPrices[(kBitModelTotal - Prob) >> kNumMoveReducingBits]; }
}
struct BitDecoder
{
public const int kNumBitModelTotalBits = 11;
public const uint kBitModelTotal = (1 << kNumBitModelTotalBits);
const int kNumMoveBits = 5;
uint Prob;
public void UpdateModel(int numMoveBits, uint symbol)
{
if (symbol == 0)
Prob += (kBitModelTotal - Prob) >> numMoveBits;
else
Prob -= (Prob) >> numMoveBits;
}
public void Init() { Prob = kBitModelTotal >> 1; }
public uint Decode(RangeCoder.Decoder rangeDecoder)
{
uint newBound = (uint)(rangeDecoder.Range >> kNumBitModelTotalBits) * (uint)Prob;
if (rangeDecoder.Code < newBound)
{
rangeDecoder.Range = newBound;
Prob += (kBitModelTotal - Prob) >> kNumMoveBits;
if (rangeDecoder.Range < Decoder.kTopValue)
{
rangeDecoder.Code = (rangeDecoder.Code << 8) | (byte)rangeDecoder.Stream.ReadByte();
rangeDecoder.Range <<= 8;
}
return 0;
}
else
{
rangeDecoder.Range -= newBound;
rangeDecoder.Code -= newBound;
Prob -= (Prob) >> kNumMoveBits;
if (rangeDecoder.Range < Decoder.kTopValue)
{
rangeDecoder.Code = (rangeDecoder.Code << 8) | (byte)rangeDecoder.Stream.ReadByte();
rangeDecoder.Range <<= 8;
}
return 1;
}
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: f3fd3305ff6e02448a7b0470cfe65b77
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,157 +0,0 @@
using System;
namespace SevenZip.Compression.RangeCoder
{
struct BitTreeEncoder
{
BitEncoder[] Models;
int NumBitLevels;
public BitTreeEncoder(int numBitLevels)
{
NumBitLevels = numBitLevels;
Models = new BitEncoder[1 << numBitLevels];
}
public void Init()
{
for (uint i = 1; i < (1 << NumBitLevels); i++)
Models[i].Init();
}
public void Encode(Encoder rangeEncoder, UInt32 symbol)
{
UInt32 m = 1;
for (int bitIndex = NumBitLevels; bitIndex > 0; )
{
bitIndex--;
UInt32 bit = (symbol >> bitIndex) & 1;
Models[m].Encode(rangeEncoder, bit);
m = (m << 1) | bit;
}
}
public void ReverseEncode(Encoder rangeEncoder, UInt32 symbol)
{
UInt32 m = 1;
for (UInt32 i = 0; i < NumBitLevels; i++)
{
UInt32 bit = symbol & 1;
Models[m].Encode(rangeEncoder, bit);
m = (m << 1) | bit;
symbol >>= 1;
}
}
public UInt32 GetPrice(UInt32 symbol)
{
UInt32 price = 0;
UInt32 m = 1;
for (int bitIndex = NumBitLevels; bitIndex > 0; )
{
bitIndex--;
UInt32 bit = (symbol >> bitIndex) & 1;
price += Models[m].GetPrice(bit);
m = (m << 1) + bit;
}
return price;
}
public UInt32 ReverseGetPrice(UInt32 symbol)
{
UInt32 price = 0;
UInt32 m = 1;
for (int i = NumBitLevels; i > 0; i--)
{
UInt32 bit = symbol & 1;
symbol >>= 1;
price += Models[m].GetPrice(bit);
m = (m << 1) | bit;
}
return price;
}
public static UInt32 ReverseGetPrice(BitEncoder[] Models, UInt32 startIndex,
int NumBitLevels, UInt32 symbol)
{
UInt32 price = 0;
UInt32 m = 1;
for (int i = NumBitLevels; i > 0; i--)
{
UInt32 bit = symbol & 1;
symbol >>= 1;
price += Models[startIndex + m].GetPrice(bit);
m = (m << 1) | bit;
}
return price;
}
public static void ReverseEncode(BitEncoder[] Models, UInt32 startIndex,
Encoder rangeEncoder, int NumBitLevels, UInt32 symbol)
{
UInt32 m = 1;
for (int i = 0; i < NumBitLevels; i++)
{
UInt32 bit = symbol & 1;
Models[startIndex + m].Encode(rangeEncoder, bit);
m = (m << 1) | bit;
symbol >>= 1;
}
}
}
struct BitTreeDecoder
{
BitDecoder[] Models;
int NumBitLevels;
public BitTreeDecoder(int numBitLevels)
{
NumBitLevels = numBitLevels;
Models = new BitDecoder[1 << numBitLevels];
}
public void Init()
{
for (uint i = 1; i < (1 << NumBitLevels); i++)
Models[i].Init();
}
public uint Decode(RangeCoder.Decoder rangeDecoder)
{
uint m = 1;
for (int bitIndex = NumBitLevels; bitIndex > 0; bitIndex--)
m = (m << 1) + Models[m].Decode(rangeDecoder);
return m - ((uint)1 << NumBitLevels);
}
public uint ReverseDecode(RangeCoder.Decoder rangeDecoder)
{
uint m = 1;
uint symbol = 0;
for (int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
{
uint bit = Models[m].Decode(rangeDecoder);
m <<= 1;
m += bit;
symbol |= (bit << bitIndex);
}
return symbol;
}
public static uint ReverseDecode(BitDecoder[] Models, UInt32 startIndex,
RangeCoder.Decoder rangeDecoder, int NumBitLevels)
{
uint m = 1;
uint symbol = 0;
for (int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
{
uint bit = Models[startIndex + m].Decode(rangeDecoder);
m <<= 1;
m += bit;
symbol |= (bit << bitIndex);
}
return symbol;
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: ef79f786b772db344a4792a5cba382ff
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,157 +0,0 @@
// ICoder.h
using System;
namespace SevenZip
{
/// <summary>
/// The exception that is thrown when an error in input stream occurs during decoding.
/// </summary>
class DataErrorException : ApplicationException
{
public DataErrorException(): base("Data Error") { }
}
/// <summary>
/// The exception that is thrown when the value of an argument is outside the allowable range.
/// </summary>
class InvalidParamException : ApplicationException
{
public InvalidParamException(): base("Invalid Parameter") { }
}
public interface ICodeProgress
{
/// <summary>
/// Callback progress.
/// </summary>
/// <param name="inSize">
/// input size. -1 if unknown.
/// </param>
/// <param name="outSize">
/// output size. -1 if unknown.
/// </param>
void SetProgress(Int64 inSize, Int64 outSize);
};
public interface ICoder
{
/// <summary>
/// Codes streams.
/// </summary>
/// <param name="inStream">
/// input Stream.
/// </param>
/// <param name="outStream">
/// output Stream.
/// </param>
/// <param name="inSize">
/// input Size. -1 if unknown.
/// </param>
/// <param name="outSize">
/// output Size. -1 if unknown.
/// </param>
/// <param name="progress">
/// callback progress reference.
/// </param>
/// <exception cref="SevenZip.DataErrorException">
/// if input stream is not valid
/// </exception>
void Code(System.IO.Stream inStream, System.IO.Stream outStream,
Int64 inSize, Int64 outSize, ICodeProgress progress);
};
/*
public interface ICoder2
{
void Code(ISequentialInStream []inStreams,
const UInt64 []inSizes,
ISequentialOutStream []outStreams,
UInt64 []outSizes,
ICodeProgress progress);
};
*/
/// <summary>
/// Provides the fields that represent properties idenitifiers for compressing.
/// </summary>
public enum CoderPropID
{
/// <summary>
/// Specifies default property.
/// </summary>
DefaultProp = 0,
/// <summary>
/// Specifies size of dictionary.
/// </summary>
DictionarySize,
/// <summary>
/// Specifies size of memory for PPM*.
/// </summary>
UsedMemorySize,
/// <summary>
/// Specifies order for PPM methods.
/// </summary>
Order,
/// <summary>
/// Specifies Block Size.
/// </summary>
BlockSize,
/// <summary>
/// Specifies number of postion state bits for LZMA (0 <= x <= 4).
/// </summary>
PosStateBits,
/// <summary>
/// Specifies number of literal context bits for LZMA (0 <= x <= 8).
/// </summary>
LitContextBits,
/// <summary>
/// Specifies number of literal position bits for LZMA (0 <= x <= 4).
/// </summary>
LitPosBits,
/// <summary>
/// Specifies number of fast bytes for LZ*.
/// </summary>
NumFastBytes,
/// <summary>
/// Specifies match finder. LZMA: "BT2", "BT4" or "BT4B".
/// </summary>
MatchFinder,
/// <summary>
/// Specifies the number of match finder cyckes.
/// </summary>
MatchFinderCycles,
/// <summary>
/// Specifies number of passes.
/// </summary>
NumPasses,
/// <summary>
/// Specifies number of algorithm.
/// </summary>
Algorithm,
/// <summary>
/// Specifies the number of threads.
/// </summary>
NumThreads,
/// <summary>
/// Specifies mode with end marker.
/// </summary>
EndMarker
};
public interface ISetCoderProperties
{
void SetCoderProperties(CoderPropID[] propIDs, object[] properties);
};
public interface IWriteCoderProperties
{
void WriteCoderProperties(System.IO.Stream outStream);
}
public interface ISetDecoderProperties
{
void SetDecoderProperties(byte[] properties);
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 9f4fba00efa28594ea18888f574d028a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 59ab7ccacd9a9944bb9456da235d6760
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,14 +0,0 @@
using System;
namespace UnityFS
{
[Flags]
public enum ArchiveFlags
{
CompressionTypeMask = 0x3f,
BlocksAndDirectoryInfoCombined = 0x40,
BlocksInfoAtTheEnd = 0x80,
OldWebPluginCompatibility = 0x100,
BlockInfoNeedPaddingAtStart = 0x200
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 099de05eebdffaf4baeed3290dc98aaf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,51 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace UnityFS
{
public static class BinaryReaderExtensions
{
public static void AlignStream(this BinaryReader reader, int alignment)
{
var pos = reader.BaseStream.Position;
var mod = pos % alignment;
if (mod != 0)
{
reader.BaseStream.Position += alignment - mod;
}
}
public static string ReadAlignedString(this BinaryReader reader)
{
var length = reader.ReadInt32();
if (length > 0 && length <= reader.BaseStream.Length - reader.BaseStream.Position)
{
var stringData = reader.ReadBytes(length);
var result = Encoding.UTF8.GetString(stringData);
reader.AlignStream(4);
return result;
}
return "";
}
public static string ReadStringToNull(this BinaryReader reader, int maxLength = 32767)
{
var bytes = new List<byte>();
int count = 0;
while (reader.BaseStream.Position != reader.BaseStream.Length && count < maxLength)
{
var b = reader.ReadByte();
if (b == 0)
{
break;
}
bytes.Add(b);
count++;
}
return Encoding.UTF8.GetString(bytes.ToArray());
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: a84e427dd05adde44b4345b3fd49007a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,33 +0,0 @@
using System;
using System.IO;
using System.Text;
namespace UnityFS
{
public static class BinaryWriterExtensions
{
public static void AlignStream(this BinaryWriter writer, int alignment)
{
var pos = writer.BaseStream.Position;
var mod = pos % alignment;
if (mod != 0)
{
writer.Write(new byte[alignment - mod]);
}
}
public static void WriteAlignedString(this BinaryWriter writer, string str)
{
var bytes = Encoding.UTF8.GetBytes(str);
writer.Write(bytes.Length);
writer.Write(bytes);
writer.AlignStream(4);
}
public static void WriteNullEndString(this BinaryWriter writer, string str)
{
writer.Write(Encoding.UTF8.GetBytes(str));
writer.Write((byte)0);
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 02eda21769c083346a5bd9b7dca49427
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,24 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace UnityFS
{
public class BundleSubFile
{
public string file;
public byte[] data;
}
public class BundleFileInfo
{
public string signature;
public uint version;
public string unityVersion;
public string unityRevision;
public ArchiveFlags flags;
public List<BundleSubFile> files;
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 1a72550a949e322419b9c5d6e4fe495d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,212 +0,0 @@
using LZ4;
using System;
using System.IO;
using System.Linq;
using UnityEngine;
namespace UnityFS
{
public class BundleFileReader
{
private Header m_Header;
private StorageBlock[] m_BlocksInfo;
private Node[] m_DirectoryInfo;
private StreamFile[] fileList;
public BundleFileReader()
{
}
public void Load(EndianBinaryReader reader)
{
Debug.Log($"reader. pos:{reader.Position} length:{reader.BaseStream.Length}");
m_Header = new Header();
m_Header.signature = reader.ReadStringToNull();
m_Header.version = reader.ReadUInt32();
m_Header.unityVersion = reader.ReadStringToNull();
m_Header.unityRevision = reader.ReadStringToNull();
System.Diagnostics.Debug.Assert(m_Header.signature == "UnityFS");
m_Header.size = reader.ReadInt64();
Debug.Log($"header size:{m_Header.size}");
m_Header.compressedBlocksInfoSize = reader.ReadUInt32();
m_Header.uncompressedBlocksInfoSize = reader.ReadUInt32();
m_Header.flags = (ArchiveFlags)reader.ReadUInt32();
if (m_Header.signature != "UnityFS")
{
reader.ReadByte();
}
ReadMetadata(reader);
using (var blocksStream = CreateBlocksStream())
{
ReadBlocks(reader, blocksStream);
ReadFiles(blocksStream);
}
}
public BundleFileInfo CreateBundleFileInfo()
{
return new BundleFileInfo
{
signature = m_Header.signature,
version = m_Header.version,
unityVersion = m_Header.unityVersion,
unityRevision = m_Header.unityRevision,
files = fileList.Select(f => new BundleSubFile { file = f.path, data = f.stream.ReadAllBytes() }).ToList(),
};
}
private byte[] ReadBlocksInfoAndDirectoryMetadataUnCompressedBytes(EndianBinaryReader reader)
{
byte[] metadataUncompressBytes;
if (m_Header.version >= 7)
{
reader.AlignStream(16);
}
if ((m_Header.flags & ArchiveFlags.BlocksInfoAtTheEnd) != 0)
{
var position = reader.Position;
reader.Position = reader.BaseStream.Length - m_Header.compressedBlocksInfoSize;
metadataUncompressBytes = reader.ReadBytes((int)m_Header.compressedBlocksInfoSize);
reader.Position = position;
}
else //0x40 BlocksAndDirectoryInfoCombined
{
metadataUncompressBytes = reader.ReadBytes((int)m_Header.compressedBlocksInfoSize);
}
return metadataUncompressBytes;
}
private byte[] DecompressBytes(CompressionType compressionType, byte[] compressedBytes, uint uncompressedSize)
{
switch (compressionType)
{
case CompressionType.None:
{
return compressedBytes;
}
case CompressionType.Lzma:
{
var uncompressedStream = new MemoryStream((int)(uncompressedSize));
using (var compressedStream = new MemoryStream(compressedBytes))
{
ComparessHelper.Decompress7Zip(compressedStream, uncompressedStream, m_Header.compressedBlocksInfoSize, m_Header.uncompressedBlocksInfoSize);
}
return uncompressedStream.ReadAllBytes();
}
case CompressionType.Lz4:
case CompressionType.Lz4HC:
{
var uncompressedBytes = new byte[uncompressedSize];
var numWrite = LZ4Codec.Decode(compressedBytes, 0, compressedBytes.Length, uncompressedBytes, 0, uncompressedBytes.Length, true);
if (numWrite != uncompressedSize)
{
throw new IOException($"Lz4 decompression error, write {numWrite} bytes but expected {uncompressedSize} bytes");
}
return uncompressedBytes;
}
default:
throw new IOException($"Unsupported compression type {compressionType}");
}
}
private void ReadMetadata(EndianBinaryReader reader)
{
byte[] compressMetadataBytes = ReadBlocksInfoAndDirectoryMetadataUnCompressedBytes(reader);
MemoryStream metadataStream = new MemoryStream(DecompressBytes((CompressionType)(m_Header.flags & ArchiveFlags.CompressionTypeMask), compressMetadataBytes, m_Header.uncompressedBlocksInfoSize));
using (var blocksInfoReader = new EndianBinaryReader(metadataStream))
{
var uncompressedDataHash = blocksInfoReader.ReadBytes(16);
var blocksInfoCount = blocksInfoReader.ReadInt32();
m_BlocksInfo = new StorageBlock[blocksInfoCount];
for (int i = 0; i < blocksInfoCount; i++)
{
m_BlocksInfo[i] = new StorageBlock
{
uncompressedSize = blocksInfoReader.ReadUInt32(),
compressedSize = blocksInfoReader.ReadUInt32(),
flags = (StorageBlockFlags)blocksInfoReader.ReadUInt16()
};
}
var nodesCount = blocksInfoReader.ReadInt32();
m_DirectoryInfo = new Node[nodesCount];
for (int i = 0; i < nodesCount; i++)
{
m_DirectoryInfo[i] = new Node
{
offset = blocksInfoReader.ReadInt64(),
size = blocksInfoReader.ReadInt64(),
flags = blocksInfoReader.ReadUInt32(),
path = blocksInfoReader.ReadStringToNull(),
};
}
}
if (m_Header.flags.HasFlag(ArchiveFlags.BlockInfoNeedPaddingAtStart))
{
reader.AlignStream(16);
}
}
private Stream CreateBlocksStream()
{
Stream blocksStream;
var uncompressedSizeSum = m_BlocksInfo.Sum(x => x.uncompressedSize);
if (uncompressedSizeSum >= int.MaxValue)
{
throw new Exception($"too fig file");
}
else
{
blocksStream = new MemoryStream((int)uncompressedSizeSum);
}
return blocksStream;
}
public void ReadFiles(Stream blocksStream)
{
fileList = new StreamFile[m_DirectoryInfo.Length];
for (int i = 0; i < m_DirectoryInfo.Length; i++)
{
var node = m_DirectoryInfo[i];
var file = new StreamFile();
fileList[i] = file;
file.path = node.path;
file.fileName = Path.GetFileName(node.path);
if (node.size >= int.MaxValue)
{
throw new Exception($"exceed max file size");
/*var memoryMappedFile = MemoryMappedFile.CreateNew(null, entryinfo_size);
file.stream = memoryMappedFile.CreateViewStream();*/
//var extractPath = path + "_unpacked" + Path.DirectorySeparatorChar;
//Directory.CreateDirectory(extractPath);
//file.stream = new FileStream(extractPath + file.fileName, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
}
file.stream = new MemoryStream((int)node.size);
blocksStream.Position = node.offset;
blocksStream.CopyTo(file.stream, node.size);
file.stream.Position = 0;
}
}
private void ReadBlocks(EndianBinaryReader reader, Stream blocksStream)
{
foreach (var blockInfo in m_BlocksInfo)
{
var compressedSize = (int)blockInfo.compressedSize;
byte[] compressedBlockBytes = reader.ReadBytes(compressedSize);
var compressionType = (CompressionType)(blockInfo.flags & StorageBlockFlags.CompressionTypeMask);
byte[] uncompressedBlockBytes = DecompressBytes(compressionType, compressedBlockBytes, blockInfo.uncompressedSize);
blocksStream.Write(uncompressedBlockBytes, 0, uncompressedBlockBytes.Length);
}
blocksStream.Position = 0;
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: f9b938458cc610e4d8a910c4499693cf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,112 +0,0 @@
using LZ4;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace UnityFS
{
public class BundleFileWriter
{
private readonly BundleFileInfo _bundle;
private readonly List<Node> _files = new List<Node>();
private readonly List<StorageBlock> _blocks = new List<StorageBlock>();
private readonly EndianBinaryWriter _blockDirectoryMetadataStream = new EndianBinaryWriter(new MemoryStream());
private byte[] _blockBytes;
public BundleFileWriter(BundleFileInfo bundle)
{
_bundle = bundle;
}
public void Write(EndianBinaryWriter output)
{
InitBlockAndDirectories();
output.WriteNullEndString(_bundle.signature);
output.Write(_bundle.version);
output.WriteNullEndString(_bundle.unityVersion);
output.WriteNullEndString(_bundle.unityRevision);
BuildBlockDirectoryMetadata();
long sizePos = output.Position;
output.Write(0L);
output.Write((uint)_blockDirectoryMetadataStream.Length);
output.Write((uint)_blockDirectoryMetadataStream.Length);
ArchiveFlags flags = ArchiveFlags.BlocksAndDirectoryInfoCombined | (uint)CompressionType.None;
output.Write((uint)flags);
if (_bundle.version >= 7)
{
output.AlignStream(16);
}
byte[] metadataBytes = _blockDirectoryMetadataStream.BaseStream.ReadAllBytes();
output.Write(metadataBytes, 0, metadataBytes.Length);
byte[] dataBytes = _blockBytes;
output.Write(dataBytes, 0, dataBytes.Length);
output.Position = sizePos;
output.Write(output.Length);
}
private void InitBlockAndDirectories()
{
var dataStream = new MemoryStream();
foreach(var file in _bundle.files)
{
byte[] data = file.data;
_files.Add(new Node { path = file.file, flags = 0, offset = dataStream.Length, size = data.LongLength });
dataStream.Write(data, 0, data.Length);
}
byte[] dataBytes = dataStream.ToArray();
var compressedBlockStream = new MemoryStream(dataBytes.Length / 2);
int blockByteSize = 128 * 1024;
long dataSize = dataBytes.Length;
byte[] tempCompressBlock = new byte[blockByteSize * 2];
for(long i = 0, blockNum = (dataSize + blockByteSize - 1) / blockByteSize; i < blockNum; i++)
{
long curBlockSize = Math.Min(dataSize, blockByteSize);
dataSize -= curBlockSize;
int compressedSize = LZ4Codec.Encode(dataBytes, (int)(i * blockByteSize), (int)curBlockSize, tempCompressBlock, 0, tempCompressBlock.Length);
compressedBlockStream.Write(tempCompressBlock, 0, compressedSize);
_blocks.Add(new StorageBlock { flags = (StorageBlockFlags)(int)CompressionType.Lz4, compressedSize = (uint)compressedSize, uncompressedSize = (uint)curBlockSize });
//Debug.Log($"== block[{i}] uncompressedSize:{curBlockSize} compressedSize:{compressedSize} totalblocksize:{compressedBlockStream.Length}");
}
_blockBytes = compressedBlockStream.ToArray();
}
private void BuildBlockDirectoryMetadata()
{
var hash = new byte[16];
_blockDirectoryMetadataStream.Write(hash, 0, 16);
_blockDirectoryMetadataStream.Write((uint)_blocks.Count);
foreach(var b in _blocks)
{
_blockDirectoryMetadataStream.Write(b.uncompressedSize);
_blockDirectoryMetadataStream.Write(b.compressedSize);
_blockDirectoryMetadataStream.Write((ushort)b.flags);
}
_blockDirectoryMetadataStream.Write((uint)_files.Count);
foreach(var f in _files)
{
_blockDirectoryMetadataStream.Write(f.offset);
_blockDirectoryMetadataStream.Write(f.size);
_blockDirectoryMetadataStream.Write(f.flags);
_blockDirectoryMetadataStream.WriteNullEndString(f.path);
}
//Debug.Log($"block and directory metadata size:{_blockDirectoryMetadataStream.Length}");
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: d6705163b267de54a868f5e84f6c7024
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,11 +0,0 @@
namespace UnityFS
{
public enum CompressionType
{
None,
Lzma,
Lz4,
Lz4HC,
Lzham
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: ddcd6644c83d2a94f9668d6e913bd80e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,107 +0,0 @@
using System;
using System.IO;
namespace UnityFS
{
public class EndianBinaryReader : BinaryReader
{
private readonly byte[] buffer;
public EndianType Endian;
public EndianBinaryReader(Stream stream, EndianType endian = EndianType.BigEndian) : base(stream)
{
Endian = endian;
buffer = new byte[8];
}
public long Position
{
get => BaseStream.Position;
set => BaseStream.Position = value;
}
private unsafe void ReadBufferBigEndian(byte* dst, byte[] src, int size)
{
System.Diagnostics.Debug.Assert(BitConverter.IsLittleEndian);
for (int i = 0; i < size; i++)
{
dst[i] = src[size - i - 1];
}
}
public override short ReadInt16()
{
return (short)ReadUInt16();
}
public unsafe override ushort ReadUInt16()
{
if (Endian == EndianType.BigEndian)
{
Read(buffer, 0, 2);
ushort x = 0;
ReadBufferBigEndian((byte*)&x, buffer, 2);
return x;
}
return base.ReadUInt16();
}
public override int ReadInt32()
{
return (int)ReadUInt32();
}
public unsafe override uint ReadUInt32()
{
if (Endian == EndianType.BigEndian)
{
Read(buffer, 0, 4);
uint x = 0;
ReadBufferBigEndian((byte*)&x, buffer, 4);
return x;
}
return base.ReadUInt32();
}
public override long ReadInt64()
{
return (long)ReadUInt64();
}
public unsafe override ulong ReadUInt64()
{
if (Endian == EndianType.BigEndian)
{
Read(buffer, 0, 8);
ulong x = 0;
ReadBufferBigEndian((byte*)&x, buffer, 8);
return x;
}
return base.ReadUInt64();
}
public override float ReadSingle()
{
if (Endian == EndianType.BigEndian)
{
Read(buffer, 0, 4);
Array.Reverse(buffer, 0, 4);
return BitConverter.ToSingle(buffer, 0);
}
return base.ReadSingle();
}
public override double ReadDouble()
{
if (Endian == EndianType.BigEndian)
{
Read(buffer, 0, 8);
Array.Reverse(buffer);
return BitConverter.ToDouble(buffer, 0);
}
return base.ReadDouble();
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 9b02c037f0fa1014da65773804248d8d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,107 +0,0 @@
using System;
using System.IO;
namespace UnityFS
{
public class EndianBinaryWriter : BinaryWriter
{
private readonly byte[] buffer;
public EndianType Endian;
public EndianBinaryWriter(Stream stream, EndianType endian = EndianType.BigEndian) : base(stream)
{
Endian = endian;
buffer = new byte[8];
}
public long Position
{
get => BaseStream.Position;
set => BaseStream.Position = value;
}
public long Length => BaseStream.Length;
public override void Write(short x)
{
Write((ushort)x);
}
private unsafe void WriteBufferBigEndian(byte[] dst, byte* src, int size)
{
System.Diagnostics.Debug.Assert(BitConverter.IsLittleEndian);
for(int i = 0; i < size; i++)
{
dst[i] = src[size - i - 1];
}
}
public unsafe override void Write(ushort x)
{
if (Endian == EndianType.BigEndian)
{
WriteBufferBigEndian(buffer, (byte*)&x, 2);
Write(buffer, 0, 2);
return;
}
base.Write(x);
}
public override void Write(int x)
{
Write((uint)x);
}
public unsafe override void Write(uint x)
{
if (Endian == EndianType.BigEndian)
{
WriteBufferBigEndian(buffer, (byte*)&x, 4);
Write(buffer, 0, 4);
return;
}
base.Write(x);
}
public override void Write(long x)
{
Write((ulong)x);
}
public unsafe override void Write(ulong x)
{
if (Endian == EndianType.BigEndian)
{
WriteBufferBigEndian(buffer, (byte*)&x, 8);
Write(buffer, 0, 8);
return;
}
base.Write(x);
}
public override void Write(float x)
{
if (Endian == EndianType.BigEndian)
{
var buf = BitConverter.GetBytes(x);
Array.Reverse(buf, 0, 4);
Write(buf, 0, 4);
return;
}
base.Write(x);
}
public override void Write(double x)
{
if (Endian == EndianType.BigEndian)
{
var buf = BitConverter.GetBytes(x);
Array.Reverse(buf, 0, 8);
Write(buf, 0, 8);
return;
}
base.Write(x);
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 4107364c7434b2042ad647b28e322513
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,14 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace UnityFS
{
public enum EndianType
{
LittleEndian,
BigEndian
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 2f6cbab4506c18248b410a164be891d2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,53 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityFS;
namespace HybridCLR.Editor.UnityBinFileReader
{
public class Dataunity3dPatcher
{
public void ApplyPatch(string dataunity3dFile, List<string> hotUpdateAssemblies)
{
var reader = new BundleFileReader();
using (var fs = new EndianBinaryReader(new MemoryStream(File.ReadAllBytes(dataunity3dFile))))
{
reader.Load(fs);
}
var info = reader.CreateBundleFileInfo();
//Debug.Log($"name:{info.signature} version:{info.version} files:{info.files.Count}");
//foreach (var file in info.files)
//{
// Debug.Log($"file:{file.file} size:{file.data.Length}");
//}
var globalgamemanagersFile = info.files.Find(f => f.file == "globalgamemanagers");
//Debug.LogFormat("gobalgamemanagers origin size:{0}", globalgamemanagersFile.data.Length);
var ggdBinFile = new UnityBinFile();
ggdBinFile.LoadFromStream(new MemoryStream(globalgamemanagersFile.data));
ggdBinFile.AddScriptingAssemblies(hotUpdateAssemblies);
byte[] patchedGlobalgamedatasBytes = ggdBinFile.CreatePatchedBytes();
//Debug.LogFormat("gobalgamemanagers post patche size:{0}", patchedGlobalgamedatasBytes.Length);
globalgamemanagersFile.data = patchedGlobalgamedatasBytes;
var writer = new BundleFileWriter(info);
var output = new MemoryStream();
writer.Write(new EndianBinaryWriter(output));
Debug.Log($"patch file:{dataunity3dFile} size:{output.Length}");
//string bakFile = dataunity3dFile + ".bak";
//if (!File.Exists(bakFile))
//{
// File.Copy(dataunity3dFile, bakFile);
//}
File.WriteAllBytes(dataunity3dFile, output.ToArray());
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 653a22d285c79f44a8113c5571b2d26b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,14 +0,0 @@
namespace UnityFS
{
public class Header
{
public string signature;
public uint version;
public string unityVersion;
public string unityRevision;
public long size;
public uint compressedBlocksInfoSize;
public uint uncompressedBlocksInfoSize;
public ArchiveFlags flags;
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: f121e0520fa65c240884d43fd00b3c2a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,10 +0,0 @@
namespace UnityFS
{
public class Node
{
public long offset;
public long size;
public uint flags;
public string path;
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: e3eea8a6a32b6ac4ba609b39715e25e2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,50 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace UnityFS
{
public class ScriptingAssembliesJsonPatcher
{
[Serializable]
private class ScriptingAssemblies
{
public List<string> names;
public List<int> types;
}
private string _file;
ScriptingAssemblies _scriptingAssemblies;
public void Load(string file)
{
_file = file;
string content = File.ReadAllText(file);
_scriptingAssemblies = JsonUtility.FromJson<ScriptingAssemblies>(content);
}
public void AddScriptingAssemblies(List<string> assemblies)
{
foreach (string name in assemblies)
{
if (!_scriptingAssemblies.names.Contains(name))
{
_scriptingAssemblies.names.Add(name);
_scriptingAssemblies.types.Add(16); // user dll type
Debug.Log($"[PatchScriptAssembliesJson] add hotfix assembly:{name} to {_file}");
}
}
}
public void Save(string jsonFile)
{
string content = JsonUtility.ToJson(_scriptingAssemblies);
File.WriteAllText(jsonFile, content);
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 8f2dd29d56a640d4ebd1c2fd374b7638
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,49 +0,0 @@
using System;
using System.IO;
using SevenZip.Compression.LZMA;
namespace UnityFS
{
public static class ComparessHelper
{
public static MemoryStream Decompress7Zip(MemoryStream inStream)
{
var decoder = new Decoder();
inStream.Seek(0, SeekOrigin.Begin);
var newOutStream = new MemoryStream();
var properties = new byte[5];
if (inStream.Read(properties, 0, 5) != 5)
throw new Exception("input .lzma is too short");
long outSize = 0;
for (var i = 0; i < 8; i++)
{
var v = inStream.ReadByte();
if (v < 0)
throw new Exception("Can't Read 1");
outSize |= ((long)(byte)v) << (8 * i);
}
decoder.SetDecoderProperties(properties);
var compressedSize = inStream.Length - inStream.Position;
decoder.Code(inStream, newOutStream, compressedSize, outSize, null);
newOutStream.Position = 0;
return newOutStream;
}
public static void Decompress7Zip(Stream compressedStream, Stream decompressedStream, long compressedSize, long decompressedSize)
{
var basePosition = compressedStream.Position;
var decoder = new Decoder();
var properties = new byte[5];
if (compressedStream.Read(properties, 0, 5) != 5)
throw new Exception("input .lzma is too short");
decoder.SetDecoderProperties(properties);
decoder.Code(compressedStream, decompressedStream, compressedSize - 5, decompressedSize, null);
compressedStream.Position = basePosition + compressedSize;
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 6606a654e10b3ba48b76b566b903b353
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,9 +0,0 @@
namespace UnityFS
{
public class StorageBlock
{
public uint compressedSize;
public uint uncompressedSize;
public StorageBlockFlags flags;
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 40dc58bec5631f14c9c17c8a486496d4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,11 +0,0 @@
using System;
namespace UnityFS
{
[Flags]
public enum StorageBlockFlags
{
CompressionTypeMask = 0x3f,
Streamed = 0x40
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 79b9ed6799d3caf459cf2dfae5765a23
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,32 +0,0 @@
using System.IO;
namespace UnityFS
{
public static class StreamExtensions
{
private const int BufferSize = 81920;
public static void CopyTo(this Stream source, Stream destination, long size)
{
var buffer = new byte[BufferSize];
for (var left = size; left > 0; left -= BufferSize)
{
int toRead = BufferSize < left ? BufferSize : (int)left;
int read = source.Read(buffer, 0, toRead);
destination.Write(buffer, 0, read);
if (read != toRead)
{
return;
}
}
}
public static byte[] ReadAllBytes(this Stream source)
{
source.Position = 0;
var bytes = new byte[source.Length];
source.Read(bytes, 0, bytes.Length);
return bytes;
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 2262fbf5672028a48b0c63821d7ff0c0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,11 +0,0 @@
using System.IO;
namespace UnityFS
{
public class StreamFile
{
public string path;
public string fileName;
public Stream stream;
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: fad7df04825c947489aad0d5d0c191a7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,124 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using System.Text;
using System.Reflection;
using System;
using System.Linq;
namespace UnityFS
{
/// <summary>
/// Unity 生成的二进制文件(本代码不支持5.x之前的版本)
/// </summary>
public unsafe class UnityBinFile
{
/*
* MonoManager: idx: 6;
* type: metaData.types[objects[6].typeID]
*/
public const int kMonoManagerIdx = 6;
public FileHeader header;
public MetaData metaData;
public ScriptsData scriptsData;
private Stream _originStream;
public void LoadFromStream(Stream source)
{
_originStream = source;
using (var br = new BinaryReader(source, Encoding.UTF8, true))
{
header.LoadFromStream(br);
// 按理说 metaData 应该新开一个buffer来避免加载时的对齐逻辑问题但由于 sizeof(Header) = 20已经对齐到4了所以可以连续读
metaData.LoadFromStream(br, header.dataOffset);
scriptsData = metaData.GetScriptData(br);
}
}
public void Load(string path)
{
LoadFromStream(new MemoryStream(File.ReadAllBytes(path)));
}
public void AddScriptingAssemblies(List<string> assemblies)
{
foreach (string name in assemblies)
{
if (!scriptsData.dllNames.Contains(name))
{
scriptsData.dllNames.Add(name);
scriptsData.dllTypes.Add(16); // user dll type
Debug.Log($"[PatchScriptAssembliesJson] add dll:{name} to globalgamemanagers");
}
}
}
public byte[] CreatePatchedBytes()
{
var fsR = _originStream;
fsR.Position = 0;
var brR = new BinaryReader(fsR, Encoding.UTF8, true);
var ms = new MemoryStream((int)(header.fileSize * 1.5f));
var bw = new BinaryWriter(ms, Encoding.UTF8, true);
/*
* data
* dll data MetaData dataOffset
*/
ms.Position = header.dataOffset;
Dictionary<long, ObjectInfo> newObjInfos = new Dictionary<long, ObjectInfo>();
foreach (var kv in metaData.objects)
{
long objID = kv.Key;
ObjectInfo objInfo = kv.Value;
byte[] buff = new byte[objInfo.size];
fsR.Position = objInfo.realPos;
brR.Read(buff, 0, buff.Length);
{// unity 的数据偏移貌似会对齐到 8
int newPos = (((int)ms.Position + 7) >> 3) << 3;
int gapSize = newPos - (int)ms.Position;
for (int i = 0; i < gapSize; i++)
bw.Write((byte)0);
objInfo.dataPos = (uint)ms.Position - header.dataOffset; // 重定位数据偏移
}
if (objID != kMonoManagerIdx)
bw.Write(buff, 0, buff.Length);
else
objInfo.size = (uint)scriptsData.SaveToStream(bw);
newObjInfos.Add(objID, objInfo);
}
metaData.objects = newObjInfos;
header.fileSize = (uint)ms.Position;
ms.Position = 0;
header.SaveToStream(bw);
metaData.SaveToStream(bw);
brR.Close();
// 写入新文件
ms.Position = 0;
return ms.ToArray();
}
public void Save(string newPath)
{
byte[] patchedBytes = CreatePatchedBytes();
File.WriteAllBytes(newPath, patchedBytes);
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 7f9902041e9a1ff4c9f2d65d6384530d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,397 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using static UnityFS.UnityBinUtils;
namespace UnityFS
{
public struct FileHeader
{
public const int kSize = 20;
public uint dataSize => fileSize - metadataSize;
public uint metadataSize;
public uint fileSize;
public uint version;
public uint dataOffset;
public byte endianess;
public void LoadFromStream(BinaryReader br)
{
long startPos = br.BaseStream.Position;
metadataSize = br.ReadUInt32();
fileSize = br.ReadUInt32();
version = br.ReadUInt32();
dataOffset = br.ReadUInt32();
endianess = br.ReadByte();
br.BaseStream.Position = startPos + kSize;
SwapEndianess();
}
public long SaveToStream(BinaryWriter bw)
{
SwapEndianess();
long startPos = bw.BaseStream.Position;
bw.Write(metadataSize);
bw.Write(fileSize);
bw.Write(version);
bw.Write(dataOffset);
bw.Write(endianess);
bw.BaseStream.Position = startPos + kSize;
return kSize;
}
void SwapEndianess()
{
SwapUInt(ref metadataSize);
SwapUInt(ref fileSize);
SwapUInt(ref version);
SwapUInt(ref dataOffset);
}
}
public struct MetaData
{
public long dataStartPos;
public string version;
public uint platform;
public bool enableTypeTree;
public int typeCount;
public ObjectType[] types;
public int objectCount;
public Dictionary<long, ObjectInfo> objects;
public int scriptTypeCount;
public ScriptType[] scriptTypes;
public int externalsCount;
public ExternalInfo[] externals;
#if UNITY_2019_2_OR_NEWER
public int refTypeCount;
public ObjectType[] refTypes;
#endif
public string dummyStr;
public void LoadFromStream(BinaryReader br, uint dataOffset)
{
long startPos = br.BaseStream.Position;
dataStartPos = startPos;
version = br.ReadRawString();
platform = br.ReadUInt32();
enableTypeTree = br.ReadBoolean();
typeCount = br.ReadInt32();
types = new ObjectType[typeCount];
for (int i = 0; i < typeCount; i++)
{
types[i].LoadFromStream(br);
}
objectCount = br.ReadInt32();
objects = new Dictionary<long, ObjectInfo>();
for(int i = 0; i < objectCount; i++)
{
long id = br.AlignedReadInt64();
ObjectInfo objInfo = new ObjectInfo();
objInfo.LoadFromStream(br);
objInfo.realPos = objInfo.dataPos + dataOffset;
objects.Add(id, objInfo);
}
scriptTypeCount = br.ReadInt32();
scriptTypes = new ScriptType[scriptTypeCount];
for(int i = 0; i < scriptTypeCount; i++)
{
scriptTypes[i].LoadFromStream(br);
}
externalsCount = br.ReadInt32();
externals = new ExternalInfo[externalsCount];
for(int i = 0; i < externalsCount; i++)
{
externals[i].LoadFromStream(br);
}
#if UNITY_2019_2_OR_NEWER
refTypeCount = br.ReadInt32();
refTypes = new ObjectType[refTypeCount];
for(int i = 0; i < refTypeCount; i++)
{
refTypes[i].LoadFromStream(br);
}
#endif
dummyStr = br.ReadRawString();
}
public long SaveToStream(BinaryWriter bw)
{
long startPos = bw.BaseStream.Position;
bw.WriteRawString(version);
bw.Write(platform);
bw.Write(enableTypeTree);
bw.Write(typeCount);
foreach(var type in types)
type.SaveToStream(bw);
bw.Write(objectCount);
foreach (var kv in objects)
{
bw.AlignedWriteInt64(kv.Key);
kv.Value.SaveToStream(bw);
}
bw.Write(scriptTypeCount);
foreach(var st in scriptTypes)
st.SaveToStream(bw);
bw.Write(externalsCount);
foreach(var external in externals)
external.SaveToStream(bw);
#if UNITY_2019_2_OR_NEWER
bw.Write(refTypeCount);
foreach(var refT in refTypes)
refT.SaveToStream(bw);
#endif
bw.WriteRawString(dummyStr);
return bw.BaseStream.Position - startPos;
}
public ScriptsData GetScriptData(BinaryReader br)
{
ObjectInfo objInfo = objects[UnityBinFile.kMonoManagerIdx];
br.BaseStream.Seek(objInfo.realPos, SeekOrigin.Begin);
ScriptsData data = new ScriptsData();
data.LoadFromStream(br);
return data;
}
}
public struct ObjectType
{
public int typeID;
public bool isStriped;
public short scriptTypeIndex;
public bool needReadScriptHash; // dont save
public Hash scriptSigHash;
public Hash typeHash;
public void LoadFromStream(BinaryReader br)
{
typeID = br.ReadInt32();
isStriped = br.ReadBoolean();
scriptTypeIndex = br.ReadInt16();
needReadScriptHash = typeID == -1 || typeID == 0x72;
if(needReadScriptHash)
scriptSigHash.LoadFromStream(br);
typeHash.LoadFromStream(br);
// GlobalManagers does not has TypeTrees
}
public long SaveToStream(BinaryWriter bw)
{
long startPos = bw.BaseStream.Position;
bw.Write(typeID);
bw.Write(isStriped);
bw.Write(scriptTypeIndex);
if(needReadScriptHash)
scriptSigHash.SaveToStream(bw);
typeHash.SaveToStream(bw);
return bw.BaseStream.Position - startPos;
}
public int Size()
{
int ret = 0;
ret += sizeof(int);
ret += sizeof(bool);
ret += sizeof(short);
if (needReadScriptHash)
ret += Hash.kSize;
ret += Hash.kSize;
return ret;
}
}
public struct ObjectInfo
{
public const int kSize = 12;
public uint dataPos;
public uint size;
public uint typeID;
public uint realPos; // dataPos + Header.dataOffset; // dont save
public void LoadFromStream(BinaryReader br)
{
dataPos = br.ReadUInt32();
size = br.ReadUInt32();
typeID = br.ReadUInt32();
}
public long SaveToStream(BinaryWriter bw)
{
bw.Write(dataPos);
bw.Write(size);
bw.Write(typeID);
return kSize;
}
}
public struct ScriptType
{
public int localFileIndex;
public long localIdentifierOfBin;
public void LoadFromStream(BinaryReader br)
{
localFileIndex = br.ReadInt32();
localIdentifierOfBin = br.AlignedReadInt64();
}
public long SaveToStream(BinaryWriter bw)
{
long startPos = bw.BaseStream.Position;
bw.Write(localFileIndex);
bw.AlignedWriteInt64(localIdentifierOfBin);
return bw.BaseStream.Position - startPos;
}
}
public struct ExternalInfo
{
public string dummy;
public Hash guid;
public int type;
public string name;
public void LoadFromStream(BinaryReader br)
{
dummy = br.ReadRawString();
guid.LoadFromStream(br);
type = br.ReadInt32();
name = br.ReadRawString();
}
public long SaveToStream(BinaryWriter bw)
{
long startPos = bw.BaseStream.Position;
bw.WriteRawString(dummy);
guid.SaveToStream(bw);
bw.Write(type);
bw.WriteRawString(name);
return bw.BaseStream.Position - startPos;
}
}
public struct ScriptsData
{
public ScriptID[] scriptIDs;
public List<string> dllNames;
public List<int> dllTypes; // 16 is user type
public void LoadFromStream(BinaryReader br)
{
{
int count = br.ReadInt32();
scriptIDs = new ScriptID[count];
for(int i = 0; i < count; i++)
scriptIDs[i].LoadFromStream(br);
}
{
int count = br.ReadInt32();
dllNames = new List<string>(count);
for (var i = 0; i < count; i++)
dllNames.Add(br.ReadSizeString());
}
{
int count = br.ReadInt32();
dllTypes = new List<int>(count);
for(var i = 0; i < count; i++)
dllTypes.Add(br.ReadInt32());
}
}
public long SaveToStream(BinaryWriter bw)
{
long startPos = bw.BaseStream.Position;
bw.Write(scriptIDs.Length);
for(int i = 0; i < scriptIDs.Length; i++)
scriptIDs[i].SaveToStream(bw);
bw.Write(dllNames.Count);
for(int i = 0, imax = dllNames.Count; i < imax; i++)
bw.WriteSizeString(dllNames[i]);
bw.Write(dllTypes.Count);
for(int i = 0, imax = dllTypes.Count; i < imax; i++)
bw.Write(dllTypes[i]);
return bw.BaseStream.Position - startPos;
}
}
public struct ScriptID
{
public int fileID;
public long pathID; // localIdentifier
public void LoadFromStream(BinaryReader br)
{
fileID = br.ReadInt32();
pathID = br.ReadInt64();
}
public long SaveToStream(BinaryWriter bw)
{
bw.Write(fileID);
bw.Write(pathID);
return 4 + 8;
}
}
public struct Hash
{
public const int kSize = 16;
public int[] data;
public void LoadFromStream(BinaryReader br)
{
data = new int[4];
for(int i = 0; i < data.Length; i++)
{
data[i] = br.ReadInt32();
}
}
public long SaveToStream(BinaryWriter bw)
{
for(int i = 0; i < data.Length; i++)
{
bw.Write(data[i]);
}
return kSize;
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 10655ce82e730324db6ae297f77df04b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,78 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using System.Text;
namespace UnityFS
{
public static class UnityBinUtils
{
public static void SwapUInt(ref uint val)
{
val = (val >> 24) | ((val >> 8) & 0x0000ff00) | ((val << 8) & 0x00ff0000) | (val << 24);
}
public static string ReadRawString(this BinaryReader br)
{
long startPos = br.BaseStream.Position;
while (true)
{
byte val = br.ReadByte();
if(val == 0)
break;
}
int size = (int)(br.BaseStream.Position - startPos);
br.BaseStream.Position = startPos;
byte[] buffer = br.ReadBytes(size);
string ret = Encoding.UTF8.GetString(buffer, 0, size - 1);
return ret;
}
public static void WriteRawString(this BinaryWriter bw, string str)
{
byte[] buffer = Encoding.UTF8.GetBytes(str);
bw.Write(buffer, 0, buffer.Length);
bw.Write((byte)0);
}
public static string ReadSizeString(this BinaryReader br)
{
int size = br.ReadInt32();
byte[] buff = br.ReadBytes(size);
br.BaseStream.AlignOffset4();
string ret = Encoding.UTF8.GetString(buff);
return ret;
}
public static void WriteSizeString(this BinaryWriter bw, string str)
{
byte[] buff = Encoding.UTF8.GetBytes(str);
bw.Write(buff.Length);
bw.Write(buff, 0, buff.Length);
bw.BaseStream.AlignOffset4();
}
public static void AlignOffset4(this Stream stream)
{
int offset = (((int)stream.Position + 3) >> 2) << 2;
stream.Position = offset;
}
public static long AlignedReadInt64(this BinaryReader br)
{
br.BaseStream.AlignOffset4();
return br.ReadInt64();
}
public static void AlignedWriteInt64(this BinaryWriter bw, long val)
{
bw.BaseStream.AlignOffset4();
bw.Write(val);
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 12a24c30a3914be418be10cfebfa9649
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -116,8 +116,8 @@ namespace MonoHook
static void SetupFlushICacheFunc() static void SetupFlushICacheFunc()
{ {
string processorType = SystemInfo.processorType.ToLowerInvariant(); string processorType = SystemInfo.processorType;
if (processorType.Contains("intel") || processorType.Contains("amd")) if (processorType.Contains("Intel") || processorType.Contains("AMD"))
return; return;
if (IntPtr.Size == 4) if (IntPtr.Size == 4)

View File

@ -16,11 +16,7 @@ namespace MonoHook
static HookUtils() static HookUtils()
{ {
try jit_write_protect_supported = pthread_jit_write_protect_supported_np() != 0;
{
jit_write_protect_supported = pthread_jit_write_protect_supported_np() != 0;
}
catch { }
PropertyInfo p_SystemPageSize = typeof(Environment).GetProperty("SystemPageSize"); PropertyInfo p_SystemPageSize = typeof(Environment).GetProperty("SystemPageSize");
if (p_SystemPageSize == null) if (p_SystemPageSize == null)
@ -39,16 +35,6 @@ namespace MonoHook
public static void MemCpy_Jit(void* pDst, byte[] src) public static void MemCpy_Jit(void* pDst, byte[] src)
{ {
if (!jit_write_protect_supported)
{
fixed(void * pSrc = &src[0])
{
MemCpy(pDst, pSrc, src.Length);
}
return;
}
fixed(void * p = &src[0]) fixed(void * p = &src[0])
{ {
memcpy_jit(new IntPtr(pDst), new IntPtr(p), src.Length); memcpy_jit(new IntPtr(pDst), new IntPtr(p), src.Length);

View File

@ -12,7 +12,7 @@ using System.IO;
namespace HybridCLR.MonoHook namespace HybridCLR.MonoHook
{ {
#if UNITY_2021_1_OR_NEWER && !UNITY_2023_1_OR_NEWER #if UNITY_2021 && UNITY_IOS
[InitializeOnLoad] [InitializeOnLoad]
public class CopyStrippedAOTAssembliesHook public class CopyStrippedAOTAssembliesHook
{ {

View File

@ -12,7 +12,7 @@ using System.IO;
namespace HybridCLR.MonoHook namespace HybridCLR.MonoHook
{ {
#if UNITY_2022 || UNITY_2023_1_OR_NEWER #if UNITY_2022
[InitializeOnLoad] [InitializeOnLoad]
public class GetIl2CppFolderHook public class GetIl2CppFolderHook
{ {

View File

@ -12,7 +12,7 @@ using System.IO;
namespace HybridCLR.MonoHook namespace HybridCLR.MonoHook
{ {
#if UNITY_2021_1_OR_NEWER && (UNITY_WEBGL || UNITY_WEIXINMINIGAME) #if UNITY_2021_1_OR_NEWER && UNITY_WEBGL
[InitializeOnLoad] [InitializeOnLoad]
public class PatchScriptingAssembliesJsonHook public class PatchScriptingAssembliesJsonHook
{ {
@ -35,29 +35,12 @@ namespace HybridCLR.MonoHook
private static string BuildMainWindowTitle() private static string BuildMainWindowTitle()
{ {
var cacheDir = $"{Application.dataPath}/../Library/PlayerDataCache"; string tempJsonPath = $"{Application.dataPath}/../Library/PlayerDataCache/WebGL/Data/ScriptingAssemblies.json";
if (Directory.Exists(cacheDir)) if (File.Exists(tempJsonPath))
{ {
foreach (var tempJsonPath in Directory.GetDirectories(cacheDir, "*", SearchOption.TopDirectoryOnly)) var patcher = new PatchScriptingAssemblyList();
{ patcher.PathScriptingAssembilesFile(Path.GetDirectoryName(tempJsonPath));
string dirName = Path.GetFileName(tempJsonPath);
#if UNITY_WEIXINMINIGAME
if (!dirName.Contains("WeixinMiniGame"))
{
continue;
}
#else
if (!dirName.Contains("WebGL"))
{
continue;
}
#endif
var patcher = new PatchScriptingAssemblyList();
patcher.PathScriptingAssembilesFile(tempJsonPath);
}
} }
string newTitle = BuildMainWindowTitleProxy(); string newTitle = BuildMainWindowTitleProxy();
return newTitle; return newTitle;
} }

View File

@ -14,6 +14,20 @@ namespace HybridCLR.Editor.ABI
public int Index { get; set; } public int Index { get; set; }
//public bool IsNative2ManagedByAddress => Type.PorType >= ParamOrReturnType.STRUCT_NOT_PASS_AS_VALUE;
public bool IsPassToManagedByAddress => Type.GetParamSlotNum() > 1;
public bool IsPassToNativeByAddress => Type.PorType == ParamOrReturnType.STRUCTURE_AS_REF_PARAM;
public string Native2ManagedParamValue(PlatformABI canv)
{
return IsPassToManagedByAddress ? $"(uint64_t)&__arg{Index}" : $"*(uint64_t*)&__arg{Index}";
}
public string Managed2NativeParamValue(PlatformABI canv)
{
return IsPassToNativeByAddress ? $"(uint64_t)(localVarBase+argVarIndexs[{Index}])" : $"*({Type.GetTypeName()}*)(localVarBase+argVarIndexs[{Index}])";
}
} }
public class ReturnInfo public class ReturnInfo
@ -22,6 +36,11 @@ namespace HybridCLR.Editor.ABI
public bool IsVoid => Type.PorType == ParamOrReturnType.VOID; public bool IsVoid => Type.PorType == ParamOrReturnType.VOID;
public int GetParamSlotNum(PlatformABI canv)
{
return Type.GetParamSlotNum();
}
public override string ToString() public override string ToString()
{ {
return Type.GetTypeName(); return Type.GetTypeName();

View File

@ -19,9 +19,25 @@ namespace HybridCLR.Editor.ABI
U8, U8,
R4, R4,
R8, R8,
I, ARM64_HFA_FLOAT_2,
U, VALUE_TYPE_SIZE_LESS_EQUAL_8,
TYPEDBYREF, I16, // 8 < size <= 16
STRUCT, STRUCT_NOT_PASS_AS_VALUE, // struct pass not as value
STRUCTURE_AS_REF_PARAM, // size > 16
ARM64_HFA_FLOAT_3,
ARM64_HFA_FLOAT_4,
ARM64_HFA_DOUBLE_2,
ARM64_HFA_DOUBLE_3,
ARM64_HFA_DOUBLE_4,
ARM64_HVA_8,
ARM64_HVA_16,
STRUCTURE_ALIGN1, // size > 16
STRUCTURE_ALIGN2,
STRUCTURE_ALIGN4,
STRUCTURE_ALIGN8,
SPECIAL_STRUCTURE_ALIGN1,
SPECIAL_STRUCTURE_ALIGN2,
SPECIAL_STRUCTURE_ALIGN4,
SPECIAL_STRUCTURE_ALIGN8,
} }
} }

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 0b1df5760b488fa43a68843c46fda63a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,138 @@
using dnlib.DotNet;
using HybridCLR.Editor.Meta;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HybridCLR.Editor.ABI
{
public class HFATypeInfo
{
public TypeSig Type { get; set; }
public int Count { get; set; }
}
public class TypeCreatorArm64 : TypeCreatorBase
{
public override bool IsArch32 => false;
protected override TypeInfo OptimizeSigType(TypeInfo type, bool returnType)
{
if (!type.IsGeneralValueType)
{
return type;
}
int typeSize = type.Size;
if (typeSize <= 8)
{
return TypeInfo.s_i8;
}
if (typeSize <= 16)
{
return TypeInfo.s_i16;
}
if (returnType)
{
return type.PorType != ParamOrReturnType.STRUCTURE_ALIGN1 ? new TypeInfo(ParamOrReturnType.STRUCTURE_ALIGN1, typeSize) : type;
}
return TypeInfo.s_ref;
}
private static bool IsNotHFAFastCheck(int typeSize)
{
return typeSize % 4 != 0 || typeSize > 32;
}
private static bool ComputHFATypeInfo0(TypeSig type, HFATypeInfo typeInfo)
{
TypeDef typeDef = type.ToTypeDefOrRef().ResolveTypeDefThrow();
List<TypeSig> klassInst = type.ToGenericInstSig()?.GenericArguments?.ToList();
GenericArgumentContext ctx = klassInst != null ? new GenericArgumentContext(klassInst, null) : null;
var fields = typeDef.Fields;// typeDef.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (FieldDef field in fields)
{
if (field.IsStatic)
{
continue;
}
TypeSig ftype = ctx != null ? MetaUtil.Inflate(field.FieldType, ctx) : field.FieldType;
switch (ftype.ElementType)
{
case ElementType.R4:
case ElementType.R8:
{
if (ftype == typeInfo.Type || typeInfo.Type == null)
{
typeInfo.Type = ftype;
++typeInfo.Count;
}
else
{
return false;
}
break;
}
case ElementType.ValueType:
{
if (!ComputHFATypeInfo0(ftype, typeInfo))
{
return false;
}
break;
}
case ElementType.GenericInst:
{
if (!ftype.IsValueType || !ComputHFATypeInfo0(ftype, typeInfo))
{
return false;
}
break;
}
default: return false;
}
}
return typeInfo.Count <= 4;
}
private static bool ComputHFATypeInfo(TypeSig type, int typeSize, out HFATypeInfo typeInfo)
{
typeInfo = new HFATypeInfo();
if (IsNotHFAFastCheck(typeSize))
{
return false;
}
bool ok = ComputHFATypeInfo0(type, typeInfo);
if (ok && typeInfo.Count >= 1 && typeInfo.Count <= 4)
{
int fieldSize = typeInfo.Type.ElementType == ElementType.R4 ? 4 : 8;
return typeSize == fieldSize * typeInfo.Count;
}
return false;
}
protected override bool TryCreateCustomValueTypeInfo(TypeSig type, int typeSize, int typeAligment, out TypeInfo typeInfo)
{
if (ComputHFATypeInfo(type, typeSize, out HFATypeInfo hfaTypeInfo))
{
bool isFloat = hfaTypeInfo.Type.ElementType == ElementType.R4;
switch (hfaTypeInfo.Count)
{
case 1: typeInfo = isFloat ? TypeInfo.s_r4 : TypeInfo.s_r8; break;
case 2: typeInfo = isFloat ? TypeInfo.s_vf2 : TypeInfo.s_vd2; break;
case 3: typeInfo = isFloat ? TypeInfo.s_vf3 : TypeInfo.s_vd3; break;
case 4: typeInfo = isFloat ? TypeInfo.s_vf4 : TypeInfo.s_vd4; break;
default: throw new NotSupportedException();
}
return true;
}
typeInfo = null;
return false;
}
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: dc0b3921c07ef224cb3656391f4317c3 guid: a22846b73022cb2458d1c40549ab6877
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2

View File

@ -9,21 +9,39 @@ using UnityEngine;
namespace HybridCLR.Editor.ABI namespace HybridCLR.Editor.ABI
{ {
public class TypeCreator public abstract class TypeCreatorBase
{ {
public abstract bool IsArch32 { get; }
public TypeInfo GetNativeIntTypeInfo() => IsArch32 ? TypeInfo.s_i4 : TypeInfo.s_i8;
public ValueTypeSizeAligmentCalculator Calculator => IsArch32 ? ValueTypeSizeAligmentCalculator.Caculator32 : ValueTypeSizeAligmentCalculator.Caculator64;
private readonly Dictionary<TypeSig, (int, int)> _typeSizeCache = new Dictionary<TypeSig, (int, int)>(TypeEqualityComparer.Instance);
private readonly Dictionary<TypeSig, TypeInfo> _typeInfoCache = new Dictionary<TypeSig, TypeInfo>(TypeEqualityComparer.Instance); private readonly Dictionary<TypeSig, TypeInfo> _typeInfoCache = new Dictionary<TypeSig, TypeInfo>(TypeEqualityComparer.Instance);
private int _nextStructId = 0; public (int Size, int Aligment) ComputeSizeAndAligment(TypeSig t)
{
if (_typeSizeCache.TryGetValue(t, out var sizeAndAligment))
{
return sizeAndAligment;
}
sizeAndAligment = Calculator.SizeAndAligmentOf(t);
_typeSizeCache.Add(t, sizeAndAligment);
return sizeAndAligment;
}
public TypeInfo CreateTypeInfo(TypeSig type) public TypeInfo CreateTypeInfo(TypeSig type)
{ {
type = type.RemovePinnedAndModifiers();
if (!_typeInfoCache.TryGetValue(type, out var typeInfo)) if (!_typeInfoCache.TryGetValue(type, out var typeInfo))
{ {
typeInfo = CreateTypeInfo0(type); typeInfo = CreateTypeInfo0(type);
_typeInfoCache.Add(type, typeInfo); _typeInfoCache.Add(type, typeInfo);
} }
return typeInfo; return new TypeInfo(typeInfo.PorType, typeInfo.Size);
} }
TypeInfo CreateTypeInfo0(TypeSig type) TypeInfo CreateTypeInfo0(TypeSig type)
@ -31,7 +49,7 @@ namespace HybridCLR.Editor.ABI
type = type.RemovePinnedAndModifiers(); type = type.RemovePinnedAndModifiers();
if (type.IsByRef) if (type.IsByRef)
{ {
return TypeInfo.s_u; return GetNativeIntTypeInfo();
} }
switch (type.ElementType) switch (type.ElementType)
{ {
@ -48,8 +66,8 @@ namespace HybridCLR.Editor.ABI
case ElementType.U8: return TypeInfo.s_u8; case ElementType.U8: return TypeInfo.s_u8;
case ElementType.R4: return TypeInfo.s_r4; case ElementType.R4: return TypeInfo.s_r4;
case ElementType.R8: return TypeInfo.s_r8; case ElementType.R8: return TypeInfo.s_r8;
case ElementType.I: return TypeInfo.s_i; case ElementType.U: return IsArch32 ? TypeInfo.s_u4 : TypeInfo.s_u8;
case ElementType.U: case ElementType.I:
case ElementType.String: case ElementType.String:
case ElementType.Ptr: case ElementType.Ptr:
case ElementType.ByRef: case ElementType.ByRef:
@ -61,14 +79,14 @@ namespace HybridCLR.Editor.ABI
case ElementType.Module: case ElementType.Module:
case ElementType.Var: case ElementType.Var:
case ElementType.MVar: case ElementType.MVar:
return TypeInfo.s_u; return GetNativeIntTypeInfo();
case ElementType.TypedByRef: return TypeInfo.s_typedByRef; case ElementType.TypedByRef: return CreateValueType(type);
case ElementType.ValueType: case ElementType.ValueType:
{ {
TypeDef typeDef = type.ToTypeDefOrRef().ResolveTypeDef(); TypeDef typeDef = type.ToTypeDefOrRef().ResolveTypeDef();
if (typeDef == null) if (typeDef == null)
{ {
throw new Exception($"type:{type} definition could not be found. Please try `HybridCLR/Genergate/LinkXml`, then Build once to generate the AOT dll, and then regenerate the bridge function"); throw new Exception($"type:{type} 未能找到定义。请尝试 `HybridCLR/Genergate/LinkXml`然后Build一次生成AOT dll再重新生成桥接函数");
} }
if (typeDef.IsEnum) if (typeDef.IsEnum)
{ {
@ -81,7 +99,7 @@ namespace HybridCLR.Editor.ABI
GenericInstSig gis = (GenericInstSig)type; GenericInstSig gis = (GenericInstSig)type;
if (!gis.GenericType.IsValueType) if (!gis.GenericType.IsValueType)
{ {
return TypeInfo.s_u; return GetNativeIntTypeInfo();
} }
TypeDef typeDef = gis.GenericType.ToTypeDefOrRef().ResolveTypeDef(); TypeDef typeDef = gis.GenericType.ToTypeDefOrRef().ResolveTypeDef();
if (typeDef.IsEnum) if (typeDef.IsEnum)
@ -94,9 +112,46 @@ namespace HybridCLR.Editor.ABI
} }
} }
protected static TypeInfo CreateGeneralValueType(TypeSig type, int size, int aligment)
{
System.Diagnostics.Debug.Assert(size % aligment == 0);
switch (aligment)
{
case 1: return new TypeInfo(ParamOrReturnType.STRUCTURE_ALIGN1, size);
case 2: return new TypeInfo(ParamOrReturnType.STRUCTURE_ALIGN2, size);
case 4: return new TypeInfo(ParamOrReturnType.STRUCTURE_ALIGN4, size);
case 8: return new TypeInfo(ParamOrReturnType.STRUCTURE_ALIGN8, size);
default: throw new NotSupportedException($"type:{type} not support aligment:{aligment}");
}
}
protected virtual bool TryCreateCustomValueTypeInfo(TypeSig type, int typeSize, int typeAligment, out TypeInfo typeInfo)
{
typeInfo = null;
return false;
}
protected TypeInfo CreateValueType(TypeSig type) protected TypeInfo CreateValueType(TypeSig type)
{ {
return new TypeInfo(ParamOrReturnType.STRUCT, type, _nextStructId++); (int typeSize, int typeAligment) = ComputeSizeAndAligment(type);
if (TryCreateCustomValueTypeInfo(type, typeSize, typeAligment, out var typeInfo))
{
//Debug.Log($"[{GetType().Name}] CustomeValueType:{type} => {typeInfo.CreateSigName()}");
return typeInfo;
}
else
{
// 64位下结构体内存对齐规则是一样的
return CreateGeneralValueType(type, typeSize, typeAligment);
}
}
protected abstract TypeInfo OptimizeSigType(TypeInfo type, bool returnType);
public virtual void OptimizeMethod(MethodDesc method)
{
method.TransfromSigTypes(OptimizeSigType);
} }
} }
} }

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 6ea025f5b275726479ba55e956574898 guid: b63c5bf995a6d624dbd10d9df6cb6a7a
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2

View File

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HybridCLR.Editor.ABI
{
public static class TypeCreatorFactory
{
public static TypeCreatorBase CreateTypeCreator(PlatformABI abi)
{
switch(abi)
{
case PlatformABI.Arm64: return new TypeCreatorArm64();
case PlatformABI.Universal32: return new TypeCreatorUniversal32();
case PlatformABI.Universal64: return new TypeCreatorUniversal64();
case PlatformABI.WebGL32: return new TypeCreatorWebGL32();
default: throw new NotSupportedException(abi.ToString());
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More