├── .gitattributes ├── .gitignore ├── AssetBundleBuilder.cs ├── AssetBundleTools.cs ├── BinaryWriterExtensions.cs ├── CRC.cs ├── CommonString.cs ├── EditorAssetBundle.cs ├── EditorBuildTarget.cs ├── EditorClassIDType.cs ├── EditorComponent.cs ├── EditorExtension.cs ├── EditorGameObject.cs ├── EditorNamedObject.cs ├── EditorObject.cs ├── EditorPPtr.cs ├── EditorTextAsset.cs ├── EditorTransform.cs ├── EndianBinaryWriter.cs ├── Examples ├── ExampleModule.cs └── UrBadAtTheGameComponent.cs ├── ICoder.cs ├── IMatchFinder.cs ├── LZ4 ├── ILZ4Service.cs ├── LZ4Codec.Safe.cs ├── LZ4Codec.Safe32.Dirty.cs ├── LZ4Codec.Safe32HC.Dirty.cs ├── LZ4Codec.Safe64.Dirty.cs ├── LZ4Codec.Safe64HC.Dirty.cs └── LZ4Codec.cs ├── LZ4Codec.cs ├── LZ4CodecPartial.cs ├── LzBinTree.cs ├── LzInWindow.cs ├── LzOutWindow.cs ├── LzmaBase.cs ├── LzmaDecoder.cs ├── LzmaEncoder.cs ├── PPtr.cs ├── PrefabAPI.csproj ├── PrefabAPI.sln ├── PrefabBuilder.cs ├── Properties └── AssemblyInfo.cs ├── README.md ├── RangeCoder.cs ├── RangeCoderBit.cs ├── RangeCoderBitTree.cs ├── Safe32LZ4Service.cs ├── Safe64LZ4Service.cs ├── SerializedType.cs ├── SerializedTypeStorage.cs ├── SevenZipHelper.cs ├── TypeTreeNode.cs └── prefab api.zip /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Dd]ebugPublic/ 19 | [Rr]elease/ 20 | [Rr]eleases/ 21 | x64/ 22 | x86/ 23 | bld/ 24 | [Bb]in/ 25 | [Oo]bj/ 26 | [Ll]og/ 27 | 28 | # Visual Studio 2015/2017 cache/options directory 29 | .vs/ 30 | # Uncomment if you have tasks that create the project's static files in wwwroot 31 | #wwwroot/ 32 | 33 | # Visual Studio 2017 auto generated files 34 | Generated\ Files/ 35 | 36 | # MSTest test Results 37 | [Tt]est[Rr]esult*/ 38 | [Bb]uild[Ll]og.* 39 | 40 | # NUNIT 41 | *.VisualState.xml 42 | TestResult.xml 43 | 44 | # Build Results of an ATL Project 45 | [Dd]ebugPS/ 46 | [Rr]eleasePS/ 47 | dlldata.c 48 | 49 | # Benchmark Results 50 | BenchmarkDotNet.Artifacts/ 51 | 52 | # .NET Core 53 | project.lock.json 54 | project.fragment.lock.json 55 | artifacts/ 56 | 57 | # StyleCop 58 | StyleCopReport.xml 59 | 60 | # Files built by Visual Studio 61 | *_i.c 62 | *_p.c 63 | *_h.h 64 | *.ilk 65 | *.meta 66 | *.obj 67 | *.iobj 68 | *.pch 69 | *.pdb 70 | *.ipdb 71 | *.pgc 72 | *.pgd 73 | *.rsp 74 | *.sbr 75 | *.tlb 76 | *.tli 77 | *.tlh 78 | *.tmp 79 | *.tmp_proj 80 | *_wpftmp.csproj 81 | *.log 82 | *.vspscc 83 | *.vssscc 84 | .builds 85 | *.pidb 86 | *.svclog 87 | *.scc 88 | 89 | # Chutzpah Test files 90 | _Chutzpah* 91 | 92 | # Visual C++ cache files 93 | ipch/ 94 | *.aps 95 | *.ncb 96 | *.opendb 97 | *.opensdf 98 | *.sdf 99 | *.cachefile 100 | *.VC.db 101 | *.VC.VC.opendb 102 | 103 | # Visual Studio profiler 104 | *.psess 105 | *.vsp 106 | *.vspx 107 | *.sap 108 | 109 | # Visual Studio Trace Files 110 | *.e2e 111 | 112 | # TFS 2012 Local Workspace 113 | $tf/ 114 | 115 | # Guidance Automation Toolkit 116 | *.gpState 117 | 118 | # ReSharper is a .NET coding add-in 119 | _ReSharper*/ 120 | *.[Rr]e[Ss]harper 121 | *.DotSettings.user 122 | 123 | # JustCode is a .NET coding add-in 124 | .JustCode 125 | 126 | # TeamCity is a build add-in 127 | _TeamCity* 128 | 129 | # DotCover is a Code Coverage Tool 130 | *.dotCover 131 | 132 | # AxoCover is a Code Coverage Tool 133 | .axoCover/* 134 | !.axoCover/settings.json 135 | 136 | # Visual Studio code coverage results 137 | *.coverage 138 | *.coveragexml 139 | 140 | # NCrunch 141 | _NCrunch_* 142 | .*crunch*.local.xml 143 | nCrunchTemp_* 144 | 145 | # MightyMoose 146 | *.mm.* 147 | AutoTest.Net/ 148 | 149 | # Web workbench (sass) 150 | .sass-cache/ 151 | 152 | # Installshield output folder 153 | [Ee]xpress/ 154 | 155 | # DocProject is a documentation generator add-in 156 | DocProject/buildhelp/ 157 | DocProject/Help/*.HxT 158 | DocProject/Help/*.HxC 159 | DocProject/Help/*.hhc 160 | DocProject/Help/*.hhk 161 | DocProject/Help/*.hhp 162 | DocProject/Help/Html2 163 | DocProject/Help/html 164 | 165 | # Click-Once directory 166 | publish/ 167 | 168 | # Publish Web Output 169 | *.[Pp]ublish.xml 170 | *.azurePubxml 171 | # Note: Comment the next line if you want to checkin your web deploy settings, 172 | # but database connection strings (with potential passwords) will be unencrypted 173 | *.pubxml 174 | *.publishproj 175 | 176 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 177 | # checkin your Azure Web App publish settings, but sensitive information contained 178 | # in these scripts will be unencrypted 179 | PublishScripts/ 180 | 181 | # NuGet Packages 182 | *.nupkg 183 | # The packages folder can be ignored because of Package Restore 184 | **/[Pp]ackages/* 185 | # except build/, which is used as an MSBuild target. 186 | !**/[Pp]ackages/build/ 187 | # Uncomment if necessary however generally it will be regenerated when needed 188 | #!**/[Pp]ackages/repositories.config 189 | # NuGet v3's project.json files produces more ignorable files 190 | *.nuget.props 191 | *.nuget.targets 192 | 193 | # Microsoft Azure Build Output 194 | csx/ 195 | *.build.csdef 196 | 197 | # Microsoft Azure Emulator 198 | ecf/ 199 | rcf/ 200 | 201 | # Windows Store app package directories and files 202 | AppPackages/ 203 | BundleArtifacts/ 204 | Package.StoreAssociation.xml 205 | _pkginfo.txt 206 | *.appx 207 | 208 | # Visual Studio cache files 209 | # files ending in .cache can be ignored 210 | *.[Cc]ache 211 | # but keep track of directories ending in .cache 212 | !*.[Cc]ache/ 213 | 214 | # Others 215 | ClientBin/ 216 | ~$* 217 | *~ 218 | *.dbmdl 219 | *.dbproj.schemaview 220 | *.jfm 221 | *.pfx 222 | *.publishsettings 223 | orleans.codegen.cs 224 | 225 | # Including strong name files can present a security risk 226 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 227 | #*.snk 228 | 229 | # Since there are multiple workflows, uncomment next line to ignore bower_components 230 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 231 | #bower_components/ 232 | 233 | # RIA/Silverlight projects 234 | Generated_Code/ 235 | 236 | # Backup & report files from converting an old project file 237 | # to a newer Visual Studio version. Backup files are not needed, 238 | # because we have git ;-) 239 | _UpgradeReport_Files/ 240 | Backup*/ 241 | UpgradeLog*.XML 242 | UpgradeLog*.htm 243 | ServiceFabricBackup/ 244 | *.rptproj.bak 245 | 246 | # SQL Server files 247 | *.mdf 248 | *.ldf 249 | *.ndf 250 | 251 | # Business Intelligence projects 252 | *.rdl.data 253 | *.bim.layout 254 | *.bim_*.settings 255 | *.rptproj.rsuser 256 | 257 | # Microsoft Fakes 258 | FakesAssemblies/ 259 | 260 | # GhostDoc plugin setting file 261 | *.GhostDoc.xml 262 | 263 | # Node.js Tools for Visual Studio 264 | .ntvs_analysis.dat 265 | node_modules/ 266 | 267 | # Visual Studio 6 build log 268 | *.plg 269 | 270 | # Visual Studio 6 workspace options file 271 | *.opt 272 | 273 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 274 | *.vbw 275 | 276 | # Visual Studio LightSwitch build output 277 | **/*.HTMLClient/GeneratedArtifacts 278 | **/*.DesktopClient/GeneratedArtifacts 279 | **/*.DesktopClient/ModelManifest.xml 280 | **/*.Server/GeneratedArtifacts 281 | **/*.Server/ModelManifest.xml 282 | _Pvt_Extensions 283 | 284 | # Paket dependency manager 285 | .paket/paket.exe 286 | paket-files/ 287 | 288 | # FAKE - F# Make 289 | .fake/ 290 | 291 | # JetBrains Rider 292 | .idea/ 293 | *.sln.iml 294 | 295 | # CodeRush personal settings 296 | .cr/personal 297 | 298 | # Python Tools for Visual Studio (PTVS) 299 | __pycache__/ 300 | *.pyc 301 | 302 | # Cake - Uncomment if you are using it 303 | # tools/** 304 | # !tools/packages.config 305 | 306 | # Tabs Studio 307 | *.tss 308 | 309 | # Telerik's JustMock configuration file 310 | *.jmconfig 311 | 312 | # BizTalk build output 313 | *.btp.cs 314 | *.btm.cs 315 | *.odx.cs 316 | *.xsd.cs 317 | 318 | # OpenCover UI analysis results 319 | OpenCover/ 320 | 321 | # Azure Stream Analytics local run output 322 | ASALocalRun/ 323 | 324 | # MSBuild Binary and Structured Log 325 | *.binlog 326 | 327 | # NVidia Nsight GPU debugger configuration file 328 | *.nvuser 329 | 330 | # MFractors (Xamarin productivity tool) working folder 331 | .mfractor/ 332 | 333 | # Local History for Visual Studio 334 | .localhistory/ 335 | -------------------------------------------------------------------------------- /AssetBundleTools.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Reflection; 6 | using System.IO; 7 | using UnityEngine; 8 | 9 | namespace PrefabAPI 10 | { 11 | public static class AssetBundleTools 12 | { 13 | public static EditorClassIDType GetClassFromType() where T : EditorObject 14 | { 15 | return GetClassFromType(typeof(T)); 16 | } 17 | 18 | public static List GetChildren(this Transform transform) 19 | { 20 | List children = new List(); 21 | foreach(Transform c in transform) 22 | { 23 | children.Add(c); 24 | } 25 | return children; 26 | } 27 | 28 | public static List GetChildObjects(this Transform transform) 29 | { 30 | List children = new List(); 31 | foreach (Transform c in transform) 32 | { 33 | children.Add(c.gameObject); 34 | } 35 | return children; 36 | } 37 | 38 | public static string ToStringBetter(this IEnumerable enumerable) 39 | { 40 | string s = "{ "; 41 | bool firstTime = true; 42 | foreach (T val in enumerable) 43 | { 44 | if (!firstTime) 45 | { 46 | s += ", "; 47 | } 48 | s += val; 49 | firstTime = false; 50 | } 51 | s += " }"; 52 | return s; 53 | } 54 | 55 | public static EditorClassIDType GetClassFromType(Type t) 56 | { 57 | if (t == typeof(EditorAssetBundle)) 58 | return EditorClassIDType.AssetBundle; 59 | else if (t == typeof(EditorGameObject)) 60 | return EditorClassIDType.GameObject; 61 | else if (t == typeof(EditorTextAsset)) 62 | return EditorClassIDType.TextAsset; 63 | else if (t == typeof(EditorTransform)) 64 | return EditorClassIDType.Transform; 65 | return EditorClassIDType.Object; 66 | } 67 | 68 | public static List GetFieldsOfType(this object anything, BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) 69 | { 70 | Type t = anything.GetType(); 71 | Type tt = typeof(T); 72 | FieldInfo[] f = t.GetFields(flags); 73 | List rf = new List(); 74 | foreach (FieldInfo i in f) 75 | { 76 | if (i.FieldType == tt) 77 | { 78 | rf.Add(i); 79 | } 80 | } 81 | return rf; 82 | } 83 | 84 | public static List GetFieldsOfType(this object anything, Type type, BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) 85 | { 86 | Type t = anything.GetType(); 87 | Type tt = type; 88 | FieldInfo[] f = t.GetFields(flags); 89 | List rf = new List(); 90 | foreach (FieldInfo i in f) 91 | { 92 | if (i.FieldType == tt) 93 | { 94 | rf.Add(i); 95 | } 96 | } 97 | return rf; 98 | } 99 | 100 | public static List GetFieldsOfType(this object anything, IEnumerable types, BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) 101 | { 102 | Type t = anything.GetType(); 103 | FieldInfo[] f = t.GetFields(flags); 104 | List rf = new List(); 105 | foreach (FieldInfo i in f) 106 | { 107 | if (types.Contains(i.FieldType)) 108 | { 109 | rf.Add(i); 110 | } 111 | } 112 | return rf; 113 | } 114 | 115 | public static List GetFieldsOfType(this object anything, string typeName, TypeNameComprareType comprareType, BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) 116 | { 117 | Type t = anything.GetType(); 118 | FieldInfo[] f = t.GetFields(flags); 119 | List rf = new List(); 120 | foreach (FieldInfo i in f) 121 | { 122 | if (comprareType == TypeNameComprareType.Contains ? i.FieldType.ToString().Contains(typeName) : (i.FieldType.ToString() == typeName)) 123 | { 124 | rf.Add(i); 125 | } 126 | } 127 | return rf; 128 | } 129 | 130 | public static byte[] ToBytes(this short val) 131 | { 132 | var buff = BitConverter.GetBytes(val); 133 | Array.Reverse(buff); 134 | return buff; 135 | } 136 | 137 | public static byte[] ToBytes(this int val) 138 | { 139 | var buff = BitConverter.GetBytes(val); 140 | Array.Reverse(buff); 141 | return buff; 142 | } 143 | 144 | public static byte[] ToBytes(this long val) 145 | { 146 | var buff = BitConverter.GetBytes(val); 147 | Array.Reverse(buff); 148 | return buff; 149 | } 150 | 151 | public static byte[] ToBytes(this ushort val) 152 | { 153 | var buff = BitConverter.GetBytes(val); 154 | Array.Reverse(buff); 155 | return buff; 156 | } 157 | 158 | public static byte[] ToBytes(this uint val) 159 | { 160 | var buff = BitConverter.GetBytes(val); 161 | Array.Reverse(buff); 162 | return buff; 163 | } 164 | 165 | public static byte[] ToBytes(this ulong val) 166 | { 167 | var buff = BitConverter.GetBytes(val); 168 | Array.Reverse(buff); 169 | return buff; 170 | } 171 | 172 | public static byte[] ToBytes(this float val) 173 | { 174 | var buff = BitConverter.GetBytes(val); 175 | Array.Reverse(buff); 176 | return buff; 177 | } 178 | 179 | public static byte[] ToBytes(this double val) 180 | { 181 | var buff = BitConverter.GetBytes(val); 182 | Array.Reverse(buff); 183 | return buff; 184 | } 185 | 186 | public static byte[] ToBytes(this bool val) 187 | { 188 | return new byte[] { (byte)(val ? 1 : 0) }; 189 | } 190 | 191 | public static byte[] ToBytesLittle(this short val) 192 | { 193 | byte[] buff = new byte[2]; 194 | buff[0] = (byte)val; 195 | buff[1] = (byte)(val >> 8); 196 | return buff; 197 | } 198 | 199 | public static byte[] ToBytesLittle(this int val) 200 | { 201 | byte[] buff = new byte[4]; 202 | buff[0] = (byte)val; 203 | buff[1] = (byte)(val >> 8); 204 | buff[2] = (byte)(val >> 16); 205 | buff[3] = (byte)(val >> 24); 206 | return buff; 207 | } 208 | 209 | public static byte[] ToBytesLittle(this long val) 210 | { 211 | byte[] buff = new byte[8]; 212 | int i = 0; 213 | int num = 0; 214 | while (i < 8) 215 | { 216 | buff[i] = (byte)(val >> num); 217 | i++; 218 | num += 8; 219 | } 220 | return buff; 221 | } 222 | 223 | public static byte[] ToBytesLittle(this ushort val) 224 | { 225 | byte[] buff = new byte[2]; 226 | buff[0] = (byte)val; 227 | buff[1] = (byte)(val >> 8); 228 | return buff; 229 | } 230 | 231 | public static byte[] ToBytesLittle(this uint val) 232 | { 233 | byte[] buff = new byte[4]; 234 | buff[0] = (byte)val; 235 | buff[1] = (byte)(val >> 8); 236 | buff[2] = (byte)(val >> 16); 237 | buff[3] = (byte)(val >> 24); 238 | return buff; 239 | } 240 | 241 | public static byte[] ToBytesLittle(this ulong val) 242 | { 243 | byte[] buff = new byte[8]; 244 | int i = 0; 245 | int num = 0; 246 | while (i < 8) 247 | { 248 | buff[i] = (byte)(val >> num); 249 | i++; 250 | num += 8; 251 | } 252 | return buff; 253 | } 254 | 255 | public static byte[] ToBytesLittle(this float val) 256 | { 257 | using (BinaryWriter stream = new BinaryWriter(new MemoryStream())) 258 | { 259 | stream.Write(val); 260 | return stream.BaseStream.ReadToEnd(); 261 | } 262 | } 263 | 264 | public static byte[] ToBytesLittle(this double val) 265 | { 266 | using (BinaryWriter stream = new BinaryWriter(new MemoryStream())) 267 | { 268 | stream.Write(val); 269 | return stream.BaseStream.ReadToEnd(); 270 | } 271 | } 272 | 273 | public static byte[] ToBytesLittle(this bool val) 274 | { 275 | return new byte[] { (byte)(val ? 1 : 0) }; 276 | } 277 | 278 | 279 | public static byte[] ToBytes(this string val) 280 | { 281 | return Encoding.UTF8.GetBytes(val); 282 | } 283 | 284 | public static byte[] ToBytesPlusNull(this string val) 285 | { 286 | return val.ToBytes().Concat(new byte[] { 0 }).ToArray(); 287 | } 288 | 289 | public static byte[] ToBytes(this SerializedType type, bool enableTypeTree) 290 | { 291 | List result = new List(); 292 | result.AddRange(type.classID.ToBytesLittle()); 293 | result.AddRange(type.m_IsStrippedType.ToBytesLittle()); 294 | result.AddRange(type.m_ScriptTypeIndex.ToBytesLittle()); 295 | if (type.classID == 114) 296 | { 297 | result.AddRange(type.m_ScriptID); //Hash128 298 | } 299 | result.AddRange(type.m_OldTypeHash); //Hash128 300 | if (enableTypeTree) 301 | { 302 | result.AddRange(type.m_Nodes.ToBytes(type.stringBuffer)); 303 | } 304 | return result.ToArray(); 305 | } 306 | 307 | 308 | public static List Convert(this List self, Func convertor) 309 | { 310 | List result = new List(); 311 | foreach (T element in self) 312 | { 313 | result.Add(convertor(element)); 314 | } 315 | return result; 316 | } 317 | 318 | public static byte[] ToBytes(this List nodes, byte[] stringBuffer) 319 | { 320 | List result = new List(); 321 | result.AddRange(nodes.Count.ToBytesLittle()); 322 | result.AddRange(stringBuffer.Length.ToBytesLittle()); 323 | foreach (TypeTreeNode typeTreeNode in nodes) 324 | { 325 | result.AddRange(((ushort)typeTreeNode.m_Version).ToBytesLittle()); 326 | result.Add((byte)typeTreeNode.m_Level); 327 | result.Add((byte)typeTreeNode.m_IsArray); 328 | result.AddRange(typeTreeNode.m_TypeStrOffset.ToBytesLittle()); 329 | result.AddRange(typeTreeNode.m_NameStrOffset.ToBytesLittle()); 330 | result.AddRange(typeTreeNode.m_ByteSize.ToBytesLittle()); 331 | result.AddRange(typeTreeNode.m_Index.ToBytesLittle()); 332 | result.AddRange(typeTreeNode.m_MetaFlag.ToBytesLittle()); 333 | } 334 | 335 | result.AddRange(stringBuffer); 336 | 337 | return result.ToArray(); 338 | } 339 | 340 | public enum TypeNameComprareType 341 | { 342 | Equals, 343 | Contains 344 | } 345 | } 346 | } 347 | -------------------------------------------------------------------------------- /BinaryWriterExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Reflection; 6 | using System.Text; 7 | using UnityEngine; 8 | 9 | namespace PrefabAPI 10 | { 11 | public static class BinaryWriterExtensions 12 | { 13 | /*public static void AlignStream(this BinaryReader reader) 14 | { 15 | reader.AlignStream(4); 16 | } 17 | 18 | public static void AlignStream(this BinaryReader reader, int alignment) 19 | { 20 | var pos = reader.BaseStream.Position; 21 | var mod = pos % alignment; 22 | if (mod != 0) 23 | { 24 | reader.BaseStream.Position += alignment - mod; 25 | } 26 | } 27 | 28 | public static string WriteAlignedString(this BinaryWriter reader, string stringData, int length) 29 | { 30 | if (length > 0 && length <= reader.BaseStream.Length - reader.BaseStream.Position) 31 | { 32 | var result = Encoding.UTF8.GetBytes(stringData); 33 | var stringData = reader.ReadBytes(length); 34 | reader.AlignStream(4); 35 | return result; 36 | } 37 | return ""; 38 | } 39 | 40 | public static void WriteStringArray(this BinaryWriter reader, string[] array) 41 | { 42 | WriteArray(reader.WriteAlignedString, array); 43 | } 44 | */ 45 | 46 | public static void AlignStream(this BinaryWriter write) 47 | { 48 | write.AlignStream(4); 49 | } 50 | 51 | public static void AlignStream(this BinaryWriter write, int alignment) 52 | { 53 | var pos = write.BaseStream.Position; 54 | var mod = pos % alignment; 55 | if (mod != 0) 56 | { 57 | write.BaseStream.Position += alignment - mod; 58 | } 59 | } 60 | 61 | public static void Write(this BinaryWriter write, Quaternion q) 62 | { 63 | write.Write(q.x); 64 | write.Write(q.y); 65 | write.Write(q.z); 66 | write.Write(q.w); 67 | } 68 | 69 | public static void Write(this BinaryWriter write, Vector2 v) 70 | { 71 | write.Write(v.x); 72 | write.Write(v.y); 73 | } 74 | 75 | public static void Write(this BinaryWriter write, Vector3 v) 76 | { 77 | write.Write(v.x); 78 | write.Write(v.y); 79 | write.Write(v.z); 80 | } 81 | 82 | public static void WriteStringToNull(this BinaryWriter bw, string str) 83 | { 84 | byte[] bytes = Encoding.UTF8.GetBytes(str); 85 | foreach (byte b in bytes) 86 | { 87 | bw.Write(b); 88 | } 89 | bw.Write((byte)0); 90 | } 91 | 92 | public static void WriteString(this BinaryWriter bw, string str) 93 | { 94 | byte[] bytes = Encoding.UTF8.GetBytes(str); 95 | foreach (byte b in bytes) 96 | { 97 | bw.Write(b); 98 | } 99 | } 100 | 101 | public static void WriteAlignedString(this BinaryWriter write, string toWrite, int overrideAlignment = -1) 102 | { 103 | var result = Encoding.UTF8.GetBytes(toWrite); 104 | write.Write(result.Length); 105 | write.Write(result); 106 | write.AlignStream(overrideAlignment > 0 ? overrideAlignment : 4); 107 | } 108 | 109 | public static void Insert(this BinaryWriter bw, byte[] bytes, long pos) 110 | { 111 | byte[] streambytes = bw.BaseStream.ReadToEnd(pos); 112 | if (bw.BaseStream.CanSeek) 113 | { 114 | bw.BaseStream.Position = pos; 115 | } 116 | bw.Write(bytes); 117 | bw.Write(streambytes); 118 | bw.BaseStream.Position = bw.BaseStream.ReadToEnd(pos).Length; 119 | } 120 | 121 | public static void Insert(this BinaryWriter bw, string val, long pos) 122 | { 123 | bw.Insert(Encoding.UTF8.GetBytes(val), pos); 124 | } 125 | 126 | public static void Insert(this BinaryWriter bw, int val, long pos) 127 | { 128 | var buff = BitConverter.GetBytes(val); 129 | bw.Insert(buff, pos); 130 | } 131 | 132 | public static void Insert(this BinaryWriter bw, long val, long pos) 133 | { 134 | var buff = BitConverter.GetBytes(val); 135 | bw.Insert(buff, pos); 136 | } 137 | 138 | public static void Insert(this BinaryWriter bw, short val, long pos) 139 | { 140 | var buff = BitConverter.GetBytes(val); 141 | Array.Reverse(buff); 142 | bw.Insert(buff, pos); 143 | } 144 | 145 | public static byte[] ReadToEnd(this Stream stream, long startFrom = 0) 146 | { 147 | long originalPosition = 0; 148 | if (stream.CanSeek) 149 | { 150 | originalPosition = stream.Position; 151 | stream.Position = startFrom; 152 | } 153 | try 154 | { 155 | byte[] readBuffer = new byte[4096]; 156 | 157 | int totalBytesRead = 0; 158 | int bytesRead; 159 | 160 | while ((bytesRead = stream.Read(readBuffer, totalBytesRead, readBuffer.Length - totalBytesRead)) > 0) 161 | { 162 | totalBytesRead += bytesRead; 163 | 164 | if (totalBytesRead == readBuffer.Length) 165 | { 166 | int nextByte = stream.ReadByte(); 167 | if (nextByte != -1) 168 | { 169 | byte[] temp = new byte[readBuffer.Length * 2]; 170 | Buffer.BlockCopy(readBuffer, 0, temp, 0, readBuffer.Length); 171 | Buffer.SetByte(temp, totalBytesRead, (byte)nextByte); 172 | readBuffer = temp; 173 | totalBytesRead++; 174 | } 175 | } 176 | } 177 | 178 | byte[] buffer = readBuffer; 179 | if (readBuffer.Length != totalBytesRead) 180 | { 181 | buffer = new byte[totalBytesRead]; 182 | Buffer.BlockCopy(readBuffer, 0, buffer, 0, totalBytesRead); 183 | } 184 | return buffer; 185 | } 186 | finally 187 | { 188 | if (stream.CanSeek) 189 | { 190 | stream.Position = originalPosition; 191 | } 192 | } 193 | } 194 | 195 | public static FieldInfo inf = typeof(FileStream).GetField("access", BindingFlags.NonPublic | BindingFlags.Instance); 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /CRC.cs: -------------------------------------------------------------------------------- 1 | // Common/CRC.cs 2 | 3 | namespace SevenZip 4 | { 5 | class CRC 6 | { 7 | public static readonly uint[] Table; 8 | 9 | static CRC() 10 | { 11 | Table = new uint[256]; 12 | const uint kPoly = 0xEDB88320; 13 | for (uint i = 0; i < 256; i++) 14 | { 15 | uint r = i; 16 | for (int j = 0; j < 8; j++) 17 | if ((r & 1) != 0) 18 | r = (r >> 1) ^ kPoly; 19 | else 20 | r >>= 1; 21 | Table[i] = r; 22 | } 23 | } 24 | 25 | uint _value = 0xFFFFFFFF; 26 | 27 | public void Init() { _value = 0xFFFFFFFF; } 28 | 29 | public void UpdateByte(byte b) 30 | { 31 | _value = Table[(((byte)(_value)) ^ b)] ^ (_value >> 8); 32 | } 33 | 34 | public void Update(byte[] data, uint offset, uint size) 35 | { 36 | for (uint i = 0; i < size; i++) 37 | _value = Table[(((byte)(_value)) ^ data[offset + i])] ^ (_value >> 8); 38 | } 39 | 40 | public uint GetDigest() { return _value ^ 0xFFFFFFFF; } 41 | 42 | static uint CalculateDigest(byte[] data, uint offset, uint size) 43 | { 44 | CRC crc = new CRC(); 45 | // crc.Init(); 46 | crc.Update(data, offset, size); 47 | return crc.GetDigest(); 48 | } 49 | 50 | static bool VerifyDigest(uint digest, byte[] data, uint offset, uint size) 51 | { 52 | return (CalculateDigest(data, offset, size) == digest); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /CommonString.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace PrefabAPI 4 | { 5 | public static class CommonString 6 | { 7 | public static readonly Dictionary StringBuffer = new Dictionary 8 | { 9 | {0, "AABB"}, 10 | {5, "AnimationClip"}, 11 | {19, "AnimationCurve"}, 12 | {34, "AnimationState"}, 13 | {49, "Array"}, 14 | {55, "Base"}, 15 | {60, "BitField"}, 16 | {69, "bitset"}, 17 | {76, "bool"}, 18 | {81, "char"}, 19 | {86, "ColorRGBA"}, 20 | {96, "Component"}, 21 | {106, "data"}, 22 | {111, "deque"}, 23 | {117, "double"}, 24 | {124, "dynamic_array"}, 25 | {138, "FastPropertyName"}, 26 | {155, "first"}, 27 | {161, "float"}, 28 | {167, "Font"}, 29 | {172, "GameObject"}, 30 | {183, "Generic Mono"}, 31 | {196, "GradientNEW"}, 32 | {208, "GUID"}, 33 | {213, "GUIStyle"}, 34 | {222, "int"}, 35 | {226, "list"}, 36 | {231, "long long"}, 37 | {241, "map"}, 38 | {245, "Matrix4x4f"}, 39 | {256, "MdFour"}, 40 | {263, "MonoBehaviour"}, 41 | {277, "MonoScript"}, 42 | {288, "m_ByteSize"}, 43 | {299, "m_Curve"}, 44 | {307, "m_EditorClassIdentifier"}, 45 | {331, "m_EditorHideFlags"}, 46 | {349, "m_Enabled"}, 47 | {359, "m_ExtensionPtr"}, 48 | {374, "m_GameObject"}, 49 | {387, "m_Index"}, 50 | {395, "m_IsArray"}, 51 | {405, "m_IsStatic"}, 52 | {416, "m_MetaFlag"}, 53 | {427, "m_Name"}, 54 | {434, "m_ObjectHideFlags"}, 55 | {452, "m_PrefabInternal"}, 56 | {469, "m_PrefabParentObject"}, 57 | {490, "m_Script"}, 58 | {499, "m_StaticEditorFlags"}, 59 | {519, "m_Type"}, 60 | {526, "m_Version"}, 61 | {536, "Object"}, 62 | {543, "pair"}, 63 | {548, "PPtr"}, 64 | {564, "PPtr"}, 65 | {581, "PPtr"}, 66 | {596, "PPtr"}, 67 | {616, "PPtr"}, 68 | {633, "PPtr"}, 69 | {646, "PPtr"}, 70 | {659, "PPtr"}, 71 | {672, "PPtr"}, 72 | {688, "PPtr"}, 73 | {702, "PPtr"}, 74 | {718, "PPtr"}, 75 | {734, "Prefab"}, 76 | {741, "Quaternionf"}, 77 | {753, "Rectf"}, 78 | {759, "RectInt"}, 79 | {767, "RectOffset"}, 80 | {778, "second"}, 81 | {785, "set"}, 82 | {789, "short"}, 83 | {795, "size"}, 84 | {800, "SInt16"}, 85 | {807, "SInt32"}, 86 | {814, "SInt64"}, 87 | {821, "SInt8"}, 88 | {827, "staticvector"}, 89 | {840, "string"}, 90 | {847, "TextAsset"}, 91 | {857, "TextMesh"}, 92 | {866, "Texture"}, 93 | {874, "Texture2D"}, 94 | {884, "Transform"}, 95 | {894, "TypelessData"}, 96 | {907, "UInt16"}, 97 | {914, "UInt32"}, 98 | {921, "UInt64"}, 99 | {928, "UInt8"}, 100 | {934, "unsigned int"}, 101 | {947, "unsigned long long"}, 102 | {966, "unsigned short"}, 103 | {981, "vector"}, 104 | {988, "Vector2f"}, 105 | {997, "Vector3f"}, 106 | {1006, "Vector4f"}, 107 | {1015, "m_ScriptingClassIdentifier"}, 108 | {1042, "Gradient"}, 109 | {1051, "Type*"}, 110 | {1057, "int2_storage"}, 111 | {1070, "int3_storage"}, 112 | {1083, "BoundsInt"}, 113 | {1093, "m_CorrespondingSourceObject"}, 114 | {1121, "m_PrefabInstance"}, 115 | {1138, "m_PrefabAsset"}, 116 | {1152, "FileSize"}, 117 | {1161, "Hash128"} 118 | }; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /EditorAssetBundle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace PrefabAPI 8 | { 9 | public class AssetInfo 10 | { 11 | public int preloadIndex; 12 | public int preloadSize; 13 | public PPtr asset; 14 | 15 | public AssetInfo() 16 | { 17 | } 18 | 19 | public void Write(BinaryWriter write) 20 | { 21 | write.Write(preloadIndex); 22 | write.Write(preloadSize); 23 | asset.Write(write); 24 | } 25 | } 26 | 27 | public sealed class EditorAssetBundle : EditorNamedObject 28 | { 29 | public PPtr[] m_PreloadTable; 30 | public KeyValuePair[] m_Container; 31 | 32 | public EditorAssetBundle() 33 | { 34 | } 35 | 36 | public override void Write(BinaryWriter write) 37 | { 38 | base.Write(write); 39 | write.Write(m_PreloadTable.Length); 40 | foreach(PPtr pptr in m_PreloadTable) 41 | { 42 | pptr.Write(write); 43 | } 44 | write.Write(m_Container.Length); 45 | foreach(KeyValuePair container in m_Container) 46 | { 47 | write.WriteAlignedString(container.Key); 48 | container.Value.Write(write); 49 | } 50 | write.Write(new byte[20]); 51 | write.Write((byte)1); 52 | write.Write(new byte[3]); 53 | write.WriteAlignedString(m_Name); 54 | var mod = write.BaseStream.Position % 4; 55 | write.Write(new byte[12 - mod]); 56 | write.Write((byte)3); 57 | write.Write(new byte[3]); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /EditorBuildTarget.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace PrefabAPI 7 | { 8 | public enum EditorBuildTarget 9 | { 10 | NoTarget = -2, 11 | DashboardWidget = 1, 12 | StandaloneOSX = 2, 13 | StandaloneOSXPPC = 3, 14 | StandaloneOSXIntel = 4, 15 | StandaloneWindows, 16 | WebPlayer, 17 | WebPlayerStreamed, 18 | Wii = 8, 19 | iOS = 9, 20 | PS3, 21 | XBOX360, 22 | Android = 13, 23 | StandaloneGLESEmu = 14, 24 | NaCl = 16, 25 | StandaloneLinux = 17, 26 | FlashPlayer = 18, 27 | StandaloneWindows64 = 19, 28 | WebGL, 29 | WSAPlayer, 30 | StandaloneLinux64 = 24, 31 | StandaloneLinuxUniversal, 32 | WP8Player, 33 | StandaloneOSXIntel64, 34 | BlackBerry, 35 | Tizen, 36 | PSP2, 37 | PS4, 38 | PSM, 39 | XboxOne, 40 | SamsungTV, 41 | N3DS, 42 | WiiU, 43 | tvOS, 44 | Switch, 45 | Lumin, 46 | Stadia, 47 | CloudRendering, 48 | GameCoreXboxSeries, 49 | GameCoreXboxOne, 50 | PS5, 51 | UnknownPlatform = 9999 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /EditorClassIDType.cs: -------------------------------------------------------------------------------- 1 | // official Class ID Reference: https://docs.unity3d.com/Manual/ClassIDReference.html 2 | namespace PrefabAPI 3 | { 4 | public enum EditorClassIDType 5 | { 6 | UnknownType = -1, 7 | Object = 0, 8 | GameObject = 1, 9 | Component = 2, 10 | LevelGameManager = 3, 11 | Transform = 4, 12 | TimeManager = 5, 13 | GlobalGameManager = 6, 14 | Behaviour = 8, 15 | GameManager = 9, 16 | AudioManager = 11, 17 | ParticleAnimator = 12, 18 | InputManager = 13, 19 | EllipsoidParticleEmitter = 15, 20 | Pipeline = 17, 21 | EditorExtension = 18, 22 | Physics2DSettings = 19, 23 | Camera = 20, 24 | Material = 21, 25 | MeshRenderer = 23, 26 | Renderer = 25, 27 | ParticleRenderer = 26, 28 | Texture = 27, 29 | Texture2D = 28, 30 | OcclusionCullingSettings = 29, 31 | GraphicsSettings = 30, 32 | MeshFilter = 33, 33 | OcclusionPortal = 41, 34 | Mesh = 43, 35 | Skybox = 45, 36 | QualitySettings = 47, 37 | Shader = 48, 38 | TextAsset = 49, 39 | Rigidbody2D = 50, 40 | Physics2DManager = 51, 41 | Collider2D = 53, 42 | Rigidbody = 54, 43 | PhysicsManager = 55, 44 | Collider = 56, 45 | Joint = 57, 46 | CircleCollider2D = 58, 47 | HingeJoint = 59, 48 | PolygonCollider2D = 60, 49 | BoxCollider2D = 61, 50 | PhysicsMaterial2D = 62, 51 | MeshCollider = 64, 52 | BoxCollider = 65, 53 | CompositeCollider2D = 66, 54 | EdgeCollider2D = 68, 55 | CapsuleCollider2D = 70, 56 | ComputeShader = 72, 57 | AnimationClip = 74, 58 | ConstantForce = 75, 59 | WorldParticleCollider = 76, 60 | TagManager = 78, 61 | AudioListener = 81, 62 | AudioSource = 82, 63 | AudioClip = 83, 64 | RenderTexture = 84, 65 | CustomRenderTexture = 86, 66 | MeshParticleEmitter = 87, 67 | ParticleEmitter = 88, 68 | Cubemap = 89, 69 | Avatar = 90, 70 | AnimatorController = 91, 71 | GUILayer = 92, 72 | RuntimeAnimatorController = 93, 73 | ScriptMapper = 94, 74 | Animator = 95, 75 | TrailRenderer = 96, 76 | DelayedCallManager = 98, 77 | TextMesh = 102, 78 | RenderSettings = 104, 79 | Light = 108, 80 | CGProgram = 109, 81 | BaseAnimationTrack = 110, 82 | Animation = 111, 83 | MonoBehaviour = 114, 84 | MonoScript = 115, 85 | MonoManager = 116, 86 | Texture3D = 117, 87 | NewAnimationTrack = 118, 88 | Projector = 119, 89 | LineRenderer = 120, 90 | Flare = 121, 91 | Halo = 122, 92 | LensFlare = 123, 93 | FlareLayer = 124, 94 | HaloLayer = 125, 95 | NavMeshAreas = 126, 96 | NavMeshProjectSettings = 126, 97 | HaloManager = 127, 98 | Font = 128, 99 | PlayerSettings = 129, 100 | NamedObject = 130, 101 | GUITexture = 131, 102 | GUIText = 132, 103 | GUIElement = 133, 104 | PhysicMaterial = 134, 105 | SphereCollider = 135, 106 | CapsuleCollider = 136, 107 | SkinnedMeshRenderer = 137, 108 | FixedJoint = 138, 109 | RaycastCollider = 140, 110 | BuildSettings = 141, 111 | AssetBundle = 142, 112 | CharacterController = 143, 113 | CharacterJoint = 144, 114 | SpringJoint = 145, 115 | WheelCollider = 146, 116 | ResourceManager = 147, 117 | NetworkView = 148, 118 | NetworkManager = 149, 119 | PreloadData = 150, 120 | MovieTexture = 152, 121 | ConfigurableJoint = 153, 122 | TerrainCollider = 154, 123 | MasterServerInterface = 155, 124 | TerrainData = 156, 125 | LightmapSettings = 157, 126 | WebCamTexture = 158, 127 | EditorSettings = 159, 128 | InteractiveCloth = 160, 129 | ClothRenderer = 161, 130 | EditorUserSettings = 162, 131 | SkinnedCloth = 163, 132 | AudioReverbFilter = 164, 133 | AudioHighPassFilter = 165, 134 | AudioChorusFilter = 166, 135 | AudioReverbZone = 167, 136 | AudioEchoFilter = 168, 137 | AudioLowPassFilter = 169, 138 | AudioDistortionFilter = 170, 139 | SparseTexture = 171, 140 | AudioBehaviour = 180, 141 | AudioFilter = 181, 142 | WindZone = 182, 143 | Cloth = 183, 144 | SubstanceArchive = 184, 145 | ProceduralMaterial = 185, 146 | ProceduralTexture = 186, 147 | Texture2DArray = 187, 148 | CubemapArray = 188, 149 | OffMeshLink = 191, 150 | OcclusionArea = 192, 151 | Tree = 193, 152 | NavMeshObsolete = 194, 153 | NavMeshAgent = 195, 154 | NavMeshSettings = 196, 155 | LightProbesLegacy = 197, 156 | ParticleSystem = 198, 157 | ParticleSystemRenderer = 199, 158 | ShaderVariantCollection = 200, 159 | LODGroup = 205, 160 | BlendTree = 206, 161 | Motion = 207, 162 | NavMeshObstacle = 208, 163 | SortingGroup = 210, 164 | SpriteRenderer = 212, 165 | Sprite = 213, 166 | CachedSpriteAtlas = 214, 167 | ReflectionProbe = 215, 168 | ReflectionProbes = 216, 169 | Terrain = 218, 170 | LightProbeGroup = 220, 171 | AnimatorOverrideController = 221, 172 | CanvasRenderer = 222, 173 | Canvas = 223, 174 | RectTransform = 224, 175 | CanvasGroup = 225, 176 | BillboardAsset = 226, 177 | BillboardRenderer = 227, 178 | SpeedTreeWindAsset = 228, 179 | AnchoredJoint2D = 229, 180 | Joint2D = 230, 181 | SpringJoint2D = 231, 182 | DistanceJoint2D = 232, 183 | HingeJoint2D = 233, 184 | SliderJoint2D = 234, 185 | WheelJoint2D = 235, 186 | ClusterInputManager = 236, 187 | BaseVideoTexture = 237, 188 | NavMeshData = 238, 189 | AudioMixer = 240, 190 | AudioMixerController = 241, 191 | AudioMixerGroupController = 243, 192 | AudioMixerEffectController = 244, 193 | AudioMixerSnapshotController = 245, 194 | PhysicsUpdateBehaviour2D = 246, 195 | ConstantForce2D = 247, 196 | Effector2D = 248, 197 | AreaEffector2D = 249, 198 | PointEffector2D = 250, 199 | PlatformEffector2D = 251, 200 | SurfaceEffector2D = 252, 201 | BuoyancyEffector2D = 253, 202 | RelativeJoint2D = 254, 203 | FixedJoint2D = 255, 204 | FrictionJoint2D = 256, 205 | TargetJoint2D = 257, 206 | LightProbes = 258, 207 | LightProbeProxyVolume = 259, 208 | SampleClip = 271, 209 | AudioMixerSnapshot = 272, 210 | AudioMixerGroup = 273, 211 | NScreenBridge = 280, 212 | AssetBundleManifest = 290, 213 | UnityAdsManager = 292, 214 | RuntimeInitializeOnLoadManager = 300, 215 | CloudWebServicesManager = 301, 216 | UnityAnalyticsManager = 303, 217 | CrashReportManager = 304, 218 | PerformanceReportingManager = 305, 219 | UnityConnectSettings = 310, 220 | AvatarMask = 319, 221 | PlayableDirector = 320, 222 | VideoPlayer = 328, 223 | VideoClip = 329, 224 | ParticleSystemForceField = 330, 225 | SpriteMask = 331, 226 | WorldAnchor = 362, 227 | OcclusionCullingData = 363, 228 | //kLargestRuntimeClassID = 364 229 | SmallestEditorClassID = 1000, 230 | PrefabInstance = 1001, 231 | EditorExtensionImpl = 1002, 232 | AssetImporter = 1003, 233 | AssetDatabaseV1 = 1004, 234 | Mesh3DSImporter = 1005, 235 | TextureImporter = 1006, 236 | ShaderImporter = 1007, 237 | ComputeShaderImporter = 1008, 238 | AudioImporter = 1020, 239 | HierarchyState = 1026, 240 | GUIDSerializer = 1027, 241 | AssetMetaData = 1028, 242 | DefaultAsset = 1029, 243 | DefaultImporter = 1030, 244 | TextScriptImporter = 1031, 245 | SceneAsset = 1032, 246 | NativeFormatImporter = 1034, 247 | MonoImporter = 1035, 248 | AssetServerCache = 1037, 249 | LibraryAssetImporter = 1038, 250 | ModelImporter = 1040, 251 | FBXImporter = 1041, 252 | TrueTypeFontImporter = 1042, 253 | MovieImporter = 1044, 254 | EditorBuildSettings = 1045, 255 | DDSImporter = 1046, 256 | InspectorExpandedState = 1048, 257 | AnnotationManager = 1049, 258 | PluginImporter = 1050, 259 | EditorUserBuildSettings = 1051, 260 | PVRImporter = 1052, 261 | ASTCImporter = 1053, 262 | KTXImporter = 1054, 263 | IHVImageFormatImporter = 1055, 264 | AnimatorStateTransition = 1101, 265 | AnimatorState = 1102, 266 | HumanTemplate = 1105, 267 | AnimatorStateMachine = 1107, 268 | PreviewAnimationClip = 1108, 269 | AnimatorTransition = 1109, 270 | SpeedTreeImporter = 1110, 271 | AnimatorTransitionBase = 1111, 272 | SubstanceImporter = 1112, 273 | LightmapParameters = 1113, 274 | LightingDataAsset = 1120, 275 | GISRaster = 1121, 276 | GISRasterImporter = 1122, 277 | CadImporter = 1123, 278 | SketchUpImporter = 1124, 279 | BuildReport = 1125, 280 | PackedAssets = 1126, 281 | VideoClipImporter = 1127, 282 | ActivationLogComponent = 2000, 283 | //kLargestEditorClassID = 2001 284 | //kClassIdOutOfHierarchy = 100000 285 | //int = 100000, 286 | //bool = 100001, 287 | //float = 100002, 288 | MonoObject = 100003, 289 | Collision = 100004, 290 | Vector3f = 100005, 291 | RootMotionData = 100006, 292 | Collision2D = 100007, 293 | AudioMixerLiveUpdateFloat = 100008, 294 | AudioMixerLiveUpdateBool = 100009, 295 | Polygon2D = 100010, 296 | //void = 100011, 297 | TilemapCollider2D = 19719996, 298 | AssetImporterLog = 41386430, 299 | VFXRenderer = 73398921, 300 | SerializableManagedRefTestClass = 76251197, 301 | Grid = 156049354, 302 | ScenesUsingAssets = 156483287, 303 | ArticulationBody = 171741748, 304 | Preset = 181963792, 305 | EmptyObject = 277625683, 306 | IConstraint = 285090594, 307 | TestObjectWithSpecialLayoutOne = 293259124, 308 | AssemblyDefinitionReferenceImporter = 294290339, 309 | SiblingDerived = 334799969, 310 | TestObjectWithSerializedMapStringNonAlignedStruct = 342846651, 311 | SubDerived = 367388927, 312 | AssetImportInProgressProxy = 369655926, 313 | PluginBuildInfo = 382020655, 314 | EditorProjectAccess = 426301858, 315 | PrefabImporter = 468431735, 316 | TestObjectWithSerializedArray = 478637458, 317 | TestObjectWithSerializedAnimationCurve = 478637459, 318 | TilemapRenderer = 483693784, 319 | ScriptableCamera = 488575907, 320 | SpriteAtlasAsset = 612988286, 321 | SpriteAtlasDatabase = 638013454, 322 | AudioBuildInfo = 641289076, 323 | CachedSpriteAtlasRuntimeData = 644342135, 324 | RendererFake = 646504946, 325 | AssemblyDefinitionReferenceAsset = 662584278, 326 | BuiltAssetBundleInfoSet = 668709126, 327 | SpriteAtlas = 687078895, 328 | RayTracingShaderImporter = 747330370, 329 | RayTracingShader = 825902497, 330 | LightingSettings = 850595691, 331 | PlatformModuleSetup = 877146078, 332 | VersionControlSettings = 890905787, 333 | AimConstraint = 895512359, 334 | VFXManager = 937362698, 335 | VisualEffectSubgraph = 994735392, 336 | VisualEffectSubgraphOperator = 994735403, 337 | VisualEffectSubgraphBlock = 994735404, 338 | LocalizationImporter = 1027052791, 339 | Derived = 1091556383, 340 | PropertyModificationsTargetTestObject = 1111377672, 341 | ReferencesArtifactGenerator = 1114811875, 342 | AssemblyDefinitionAsset = 1152215463, 343 | SceneVisibilityState = 1154873562, 344 | LookAtConstraint = 1183024399, 345 | SpriteAtlasImporter = 1210832254, 346 | MultiArtifactTestImporter = 1223240404, 347 | GameObjectRecorder = 1268269756, 348 | LightingDataAssetParent = 1325145578, 349 | PresetManager = 1386491679, 350 | TestObjectWithSpecialLayoutTwo = 1392443030, 351 | StreamingManager = 1403656975, 352 | LowerResBlitTexture = 1480428607, 353 | StreamingController = 1542919678, 354 | RenderPassAttachment = 1571458007, 355 | TestObjectVectorPairStringBool = 1628831178, 356 | GridLayout = 1742807556, 357 | AssemblyDefinitionImporter = 1766753193, 358 | ParentConstraint = 1773428102, 359 | FakeComponent = 1803986026, 360 | PositionConstraint = 1818360608, 361 | RotationConstraint = 1818360609, 362 | ScaleConstraint = 1818360610, 363 | Tilemap = 1839735485, 364 | PackageManifest = 1896753125, 365 | PackageManifestImporter = 1896753126, 366 | TerrainLayer = 1953259897, 367 | SpriteShapeRenderer = 1971053207, 368 | NativeObjectType = 1977754360, 369 | TestObjectWithSerializedMapStringBool = 1981279845, 370 | SerializableManagedHost = 1995898324, 371 | VisualEffectAsset = 2058629509, 372 | VisualEffectImporter = 2058629510, 373 | VisualEffectResource = 2058629511, 374 | VisualEffectObject = 2059678085, 375 | VisualEffect = 2083052967, 376 | LocalizationAsset = 2083778819, 377 | ScriptedImporter = 2089858483 378 | } 379 | } 380 | -------------------------------------------------------------------------------- /EditorComponent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace PrefabAPI 8 | { 9 | public abstract class EditorComponent : EditorExtension 10 | { 11 | public PPtr m_GameObject; 12 | 13 | public EditorComponent() 14 | { 15 | } 16 | 17 | public override void Write(BinaryWriter write) 18 | { 19 | base.Write(write); 20 | m_GameObject.Write(write); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /EditorExtension.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace PrefabAPI 7 | { 8 | public abstract class EditorExtension : EditorObject 9 | { 10 | public EditorExtension() 11 | { 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /EditorGameObject.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace PrefabAPI 8 | { 9 | public sealed class EditorGameObject : EditorExtension 10 | { 11 | public PPtr[] m_Components; 12 | public string m_Name; 13 | public int m_Layer; 14 | 15 | public EditorTransform m_Transform; 16 | 17 | public EditorGameObject() 18 | { 19 | } 20 | 21 | public EditorTransform TryGetTransform(List manualObjects) 22 | { 23 | if(m_Transform != null) 24 | { 25 | return m_Transform; 26 | } 27 | if (m_Components != null) 28 | { 29 | foreach (PPtr pptr in m_Components) 30 | { 31 | if(pptr != null && pptr.TryGet(manualObjects, out var comp)) 32 | { 33 | if(comp != null && comp is EditorTransform transform) 34 | { 35 | m_Transform = transform; 36 | return transform; 37 | } 38 | } 39 | } 40 | } 41 | return null; 42 | } 43 | 44 | public override void Write(BinaryWriter write) 45 | { 46 | base.Write(write); 47 | write.Write(m_Components.Length); 48 | foreach(PPtr p in m_Components) 49 | { 50 | p.Write(write); 51 | } 52 | write.Write(m_Layer); 53 | write.WriteAlignedString(m_Name); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /EditorNamedObject.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace PrefabAPI 8 | { 9 | public class EditorNamedObject : EditorExtension 10 | { 11 | public string m_Name; 12 | 13 | public EditorNamedObject() 14 | { 15 | } 16 | 17 | public override void Write(BinaryWriter write) 18 | { 19 | base.Write(write); 20 | write.WriteAlignedString(m_Name); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /EditorObject.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Collections.Specialized; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace PrefabAPI 8 | { 9 | public class EditorObject 10 | { 11 | public long m_PathID; 12 | public int[] version; 13 | public EditorClassIDType type; 14 | public SerializedType serializedType; 15 | public uint byteSize; 16 | 17 | public EditorObject() 18 | { 19 | } 20 | 21 | public virtual void Write(BinaryWriter write) 22 | { 23 | } 24 | 25 | protected bool HasStructMember(string name) 26 | { 27 | return serializedType?.m_Nodes != null && serializedType.m_Nodes.Any(x => x.m_Name == name); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /EditorPPtr.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace PrefabAPI 7 | { 8 | public class EditorPPtr : PPtr where T : EditorObject 9 | { 10 | public EditorPPtr(T obj) 11 | { 12 | this.obj = obj; 13 | } 14 | 15 | public void PostProcess(List overallObjects) 16 | { 17 | if (!overallObjects.Contains(obj)) 18 | { 19 | overallObjects.Add(obj); 20 | } 21 | } 22 | 23 | public void PostProcess(List overallObjects, int insertAt) 24 | { 25 | if (!overallObjects.Contains(obj)) 26 | { 27 | overallObjects.Insert(insertAt, obj); 28 | } 29 | } 30 | 31 | public PPtr ToPPtr(List overallObjects, int offset = 0) 32 | { 33 | PPtr d = new PPtr(); 34 | d.m_FileID = 0; 35 | d.m_PathID = overallObjects.IndexOf(obj) + 2 + offset; 36 | return d; 37 | } 38 | 39 | public EditorObject obj; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /EditorTextAsset.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | using System.Text; 7 | 8 | namespace PrefabAPI 9 | { 10 | public sealed class EditorTextAsset : EditorNamedObject 11 | { 12 | public byte[] m_Script; 13 | 14 | public override void Write(BinaryWriter write) 15 | { 16 | base.Write(write); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /EditorTransform.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using Vector2 = UnityEngine.Vector2; 7 | using Vector3 = UnityEngine.Vector3; 8 | using Quaternion = UnityEngine.Quaternion; 9 | 10 | namespace PrefabAPI 11 | { 12 | public class EditorTransform : EditorComponent 13 | { 14 | public Quaternion m_LocalRotation; 15 | public Vector3 m_LocalPosition; 16 | public Vector3 m_LocalScale; 17 | public PPtr[] m_Children; 18 | public PPtr m_Father; 19 | 20 | private EditorTransform actualFather; 21 | 22 | public EditorTransform TryGetFather(List manualObjects) 23 | { 24 | if(actualFather != null) 25 | { 26 | return actualFather; 27 | } 28 | if(m_Father != null && m_Father.TryGet(manualObjects, out var father)) 29 | { 30 | actualFather = father; 31 | return actualFather; 32 | } 33 | return null; 34 | } 35 | 36 | public EditorTransform() 37 | { 38 | } 39 | 40 | public override void Write(BinaryWriter write) 41 | { 42 | base.Write(write); 43 | write.Write(m_LocalRotation); 44 | write.Write(m_LocalPosition); 45 | write.Write(m_LocalScale); 46 | write.Write(m_Children.Length); 47 | foreach(PPtr p in m_Children) 48 | { 49 | p.Write(write); 50 | } 51 | m_Father.Write(write); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /EndianBinaryWriter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.IO; 5 | 6 | namespace PrefabAPI 7 | { 8 | public enum EndianType 9 | { 10 | LittleEndian, 11 | BigEndian 12 | } 13 | 14 | public class EndianBinaryWriter : BinaryWriter 15 | { 16 | public EndianType endian; 17 | 18 | public EndianBinaryWriter(Stream stream, EndianType endian = EndianType.BigEndian) : base(stream) 19 | { 20 | this.endian = endian; 21 | } 22 | 23 | public long Position 24 | { 25 | get => BaseStream.Position; 26 | } 27 | 28 | public void SetPosition(long val) 29 | { 30 | BaseStream.Position = val; 31 | } 32 | 33 | public override void Write(short val) 34 | { 35 | if (endian == EndianType.BigEndian) 36 | { 37 | var buff = BitConverter.GetBytes(val); 38 | Array.Reverse(buff); 39 | base.Write(buff, 0, 2); 40 | return; 41 | } 42 | base.Write(val); 43 | } 44 | 45 | public override void Write(int val) 46 | { 47 | if (endian == EndianType.BigEndian) 48 | { 49 | var buff = BitConverter.GetBytes(val); 50 | Array.Reverse(buff); 51 | base.Write(buff, 0, 4); 52 | return; 53 | } 54 | base.Write(val); 55 | } 56 | 57 | public override void Write(long val) 58 | { 59 | if (endian == EndianType.BigEndian) 60 | { 61 | var buff = BitConverter.GetBytes(val); 62 | Array.Reverse(buff); 63 | base.Write(buff, 0, 8); 64 | return; 65 | } 66 | base.Write(val); 67 | } 68 | 69 | public override void Write(ushort val) 70 | { 71 | if (endian == EndianType.BigEndian) 72 | { 73 | var buff = BitConverter.GetBytes(val); 74 | Array.Reverse(buff); 75 | base.Write(buff, 0, 2); 76 | return; 77 | } 78 | base.Write(val); 79 | } 80 | 81 | public override void Write(uint val) 82 | { 83 | if (endian == EndianType.BigEndian) 84 | { 85 | var buff = BitConverter.GetBytes(val); 86 | Array.Reverse(buff); 87 | base.Write(buff, 0, 4); 88 | return; 89 | } 90 | base.Write(val); 91 | } 92 | 93 | public override void Write(ulong val) 94 | { 95 | if (endian == EndianType.BigEndian) 96 | { 97 | var buff = BitConverter.GetBytes(val); 98 | Array.Reverse(buff); 99 | base.Write(buff, 0, 8); 100 | return; 101 | } 102 | base.Write(val); 103 | } 104 | 105 | public override void Write(float val) 106 | { 107 | if (endian == EndianType.BigEndian) 108 | { 109 | var buff = BitConverter.GetBytes(val); 110 | Array.Reverse(buff); 111 | base.Write(buff, 0, 4); 112 | return; 113 | } 114 | base.Write(val); 115 | } 116 | 117 | public override void Write(double val) 118 | { 119 | if (endian == EndianType.BigEndian) 120 | { 121 | var buff = BitConverter.GetBytes(val); 122 | Array.Reverse(buff); 123 | base.Write(buff, 0, 8); 124 | return; 125 | } 126 | base.Write(val); 127 | } 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /Examples/ExampleModule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using UnityEngine; 6 | using PrefabAPI; 7 | using Gungeon; 8 | 9 | namespace PrefabAPI 10 | { 11 | public class ExampleModule : ETGModule 12 | { 13 | public override void Init() 14 | { 15 | } 16 | 17 | public override void Start() 18 | { 19 | ETGModConsole.Commands.AddUnit("spawnprefab", delegate(string[] args) 20 | { 21 | if(args.Length > 0) 22 | { 23 | GameObject go = PrefabBuilder.builtObjects?.Find((GameObject g) => g.name == args[0]); 24 | if(go == null) 25 | { 26 | go = PrefabBuilder.BuildObject(args[0]); 27 | tk2dSprite.AddComponent(go, AmmonomiconController.ForceInstance.EncounterIconCollection, UnityEngine.Random.Range(0, AmmonomiconController.ForceInstance.EncounterIconCollection.spriteDefinitions.Length)); 28 | } 29 | UnityEngine.Object.Instantiate(go, GameManager.Instance.PrimaryPlayer.sprite.WorldBottomLeft, Quaternion.identity); 30 | } 31 | }); 32 | ETGModConsole.Commands.AddUnit("clone_bullet_kin", delegate (string[] args) 33 | { 34 | GameObject go = PrefabBuilder.Clone(Game.Enemies["bullet_kin"].gameObject); 35 | go.AddComponent(); 36 | ETGModConsole.Log("aiactor != null: " + (go.GetComponent() != null)); 37 | AIActor.Spawn(go.GetComponent(), GameManager.Instance.PrimaryPlayer.CurrentRoom.GetRandomAvailableCellDumb(), GameManager.Instance.PrimaryPlayer.CurrentRoom, false, AIActor.AwakenAnimationType.Default, true); 38 | }); 39 | } 40 | 41 | public override void Exit() 42 | { 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Examples/UrBadAtTheGameComponent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using UnityEngine; 6 | 7 | namespace PrefabAPI 8 | { 9 | public class UrBadAtTheGameComponent : BraveBehaviour 10 | { 11 | public void Start() 12 | { 13 | if(GameManager.Instance.PrimaryPlayer != null) 14 | { 15 | GameManager.Instance.PrimaryPlayer.OnReceivedDamage += UrBadAtTheGame; 16 | } 17 | } 18 | 19 | protected override void OnDestroy() 20 | { 21 | if (GameManager.Instance.PrimaryPlayer != null) 22 | { 23 | GameManager.Instance.PrimaryPlayer.OnReceivedDamage -= UrBadAtTheGame; 24 | } 25 | base.OnDestroy(); 26 | } 27 | 28 | public void UrBadAtTheGame(PlayerController p) 29 | { 30 | if (!TextBoxManager.HasTextBox(transform)) 31 | { 32 | List badAtTheGame = new List 33 | { 34 | "Ur so bad at the game haha", 35 | "just get good lol", 36 | "all you have to do is dodge the bullets, it's not that hard!", 37 | "even i play better than you" 38 | }; 39 | TextBoxManager.ShowTextBox(sprite.WorldTopCenter + new Vector2(0f, 0.5f), transform, 3f, BraveUtility.RandomElement(badAtTheGame), "", false, TextBoxManager.BoxSlideOrientation.NO_ADJUSTMENT, false, false); 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /ICoder.cs: -------------------------------------------------------------------------------- 1 | // ICoder.h 2 | 3 | using System; 4 | 5 | namespace SevenZip 6 | { 7 | /// 8 | /// The exception that is thrown when an error in input stream occurs during decoding. 9 | /// 10 | class DataErrorException : ApplicationException 11 | { 12 | public DataErrorException(): base("Data Error") { } 13 | } 14 | 15 | /// 16 | /// The exception that is thrown when the value of an argument is outside the allowable range. 17 | /// 18 | class InvalidParamException : ApplicationException 19 | { 20 | public InvalidParamException(): base("Invalid Parameter") { } 21 | } 22 | 23 | public interface ICodeProgress 24 | { 25 | /// 26 | /// Callback progress. 27 | /// 28 | /// 29 | /// input size. -1 if unknown. 30 | /// 31 | /// 32 | /// output size. -1 if unknown. 33 | /// 34 | void SetProgress(Int64 inSize, Int64 outSize); 35 | }; 36 | 37 | public interface ICoder 38 | { 39 | /// 40 | /// Codes streams. 41 | /// 42 | /// 43 | /// input Stream. 44 | /// 45 | /// 46 | /// output Stream. 47 | /// 48 | /// 49 | /// input Size. -1 if unknown. 50 | /// 51 | /// 52 | /// output Size. -1 if unknown. 53 | /// 54 | /// 55 | /// callback progress reference. 56 | /// 57 | /// 58 | /// if input stream is not valid 59 | /// 60 | void Code(System.IO.Stream inStream, System.IO.Stream outStream, 61 | Int64 inSize, Int64 outSize, ICodeProgress progress); 62 | }; 63 | 64 | /* 65 | public interface ICoder2 66 | { 67 | void Code(ISequentialInStream []inStreams, 68 | const UInt64 []inSizes, 69 | ISequentialOutStream []outStreams, 70 | UInt64 []outSizes, 71 | ICodeProgress progress); 72 | }; 73 | */ 74 | 75 | /// 76 | /// Provides the fields that represent properties idenitifiers for compressing. 77 | /// 78 | public enum CoderPropID 79 | { 80 | /// 81 | /// Specifies default property. 82 | /// 83 | DefaultProp = 0, 84 | /// 85 | /// Specifies size of dictionary. 86 | /// 87 | DictionarySize, 88 | /// 89 | /// Specifies size of memory for PPM*. 90 | /// 91 | UsedMemorySize, 92 | /// 93 | /// Specifies order for PPM methods. 94 | /// 95 | Order, 96 | /// 97 | /// Specifies Block Size. 98 | /// 99 | BlockSize, 100 | /// 101 | /// Specifies number of postion state bits for LZMA (0 <= x <= 4). 102 | /// 103 | PosStateBits, 104 | /// 105 | /// Specifies number of literal context bits for LZMA (0 <= x <= 8). 106 | /// 107 | LitContextBits, 108 | /// 109 | /// Specifies number of literal position bits for LZMA (0 <= x <= 4). 110 | /// 111 | LitPosBits, 112 | /// 113 | /// Specifies number of fast bytes for LZ*. 114 | /// 115 | NumFastBytes, 116 | /// 117 | /// Specifies match finder. LZMA: "BT2", "BT4" or "BT4B". 118 | /// 119 | MatchFinder, 120 | /// 121 | /// Specifies the number of match finder cyckes. 122 | /// 123 | MatchFinderCycles, 124 | /// 125 | /// Specifies number of passes. 126 | /// 127 | NumPasses, 128 | /// 129 | /// Specifies number of algorithm. 130 | /// 131 | Algorithm, 132 | /// 133 | /// Specifies the number of threads. 134 | /// 135 | NumThreads, 136 | /// 137 | /// Specifies mode with end marker. 138 | /// 139 | EndMarker 140 | }; 141 | 142 | 143 | public interface ISetCoderProperties 144 | { 145 | void SetCoderProperties(CoderPropID[] propIDs, object[] properties); 146 | }; 147 | 148 | public interface IWriteCoderProperties 149 | { 150 | void WriteCoderProperties(System.IO.Stream outStream); 151 | } 152 | 153 | public interface ISetDecoderProperties 154 | { 155 | void SetDecoderProperties(byte[] properties); 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /IMatchFinder.cs: -------------------------------------------------------------------------------- 1 | // IMatchFinder.cs 2 | 3 | using System; 4 | 5 | namespace SevenZip.Compression.LZ 6 | { 7 | interface IInWindowStream 8 | { 9 | void SetStream(System.IO.Stream inStream); 10 | void Init(); 11 | void ReleaseStream(); 12 | Byte GetIndexByte(Int32 index); 13 | UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit); 14 | UInt32 GetNumAvailableBytes(); 15 | } 16 | 17 | interface IMatchFinder : IInWindowStream 18 | { 19 | void Create(UInt32 historySize, UInt32 keepAddBufferBefore, 20 | UInt32 matchMaxLen, UInt32 keepAddBufferAfter); 21 | UInt32 GetMatches(UInt32[] distances); 22 | void Skip(UInt32 num); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /LZ4/ILZ4Service.cs: -------------------------------------------------------------------------------- 1 | #region license 2 | 3 | /* 4 | Copyright (c) 2013, Milosz Krajewski 5 | All rights reserved. 6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided 7 | that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright notice, this list of conditions 9 | and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions 11 | and the following disclaimer in the documentation and/or other materials provided with the distribution. 12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 13 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 14 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 15 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 16 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 18 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 19 | IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 20 | */ 21 | 22 | #endregion 23 | 24 | namespace LZ4 25 | { 26 | internal interface ILZ4Service 27 | { 28 | string CodecName { get; } 29 | int Encode(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset, int outputLength); 30 | int EncodeHC(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset, int outputLength); 31 | int Decode(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset, int outputLength, bool knownOutputLength); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /LZ4/LZ4Codec.Safe32.Dirty.cs: -------------------------------------------------------------------------------- 1 | #region LZ4 original 2 | 3 | /* 4 | LZ4 - Fast LZ compression algorithm 5 | Copyright (C) 2011-2012, Yann Collet. 6 | BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are 10 | met: 11 | 12 | * Redistributions of source code must retain the above copyright 13 | notice, this list of conditions and the following disclaimer. 14 | * Redistributions in binary form must reproduce the above 15 | copyright notice, this list of conditions and the following disclaimer 16 | in the documentation and/or other materials provided with the 17 | distribution. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | You can contact the author at : 32 | - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html 33 | - LZ4 source repository : http://code.google.com/p/lz4/ 34 | */ 35 | 36 | #endregion 37 | 38 | #region LZ4 port 39 | 40 | /* 41 | Copyright (c) 2013, Milosz Krajewski 42 | All rights reserved. 43 | 44 | Redistribution and use in source and binary forms, with or without modification, are permitted provided 45 | that the following conditions are met: 46 | 47 | * Redistributions of source code must retain the above copyright notice, this list of conditions 48 | and the following disclaimer. 49 | 50 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions 51 | and the following disclaimer in the documentation and/or other materials provided with the distribution. 52 | 53 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 54 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 55 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 56 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 57 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 58 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 59 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 60 | IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 61 | */ 62 | 63 | #endregion 64 | 65 | // ReSharper disable CheckNamespace 66 | // ReSharper disable InconsistentNaming 67 | // ReSharper disable TooWideLocalVariableScope 68 | // ReSharper disable JoinDeclarationAndInitializer 69 | // ReSharper disable RedundantIfElseBlock 70 | 71 | namespace LZ4ps 72 | { 73 | public static partial class LZ4Codec 74 | { 75 | #region LZ4_compressCtx 76 | 77 | private static int LZ4_compressCtx_safe32( 78 | int[] hash_table, 79 | byte[] src, 80 | byte[] dst, 81 | int src_0, 82 | int dst_0, 83 | int src_len, 84 | int dst_maxlen) 85 | { 86 | var debruijn32 = DEBRUIJN_TABLE_32; 87 | int _i; 88 | 89 | // ---- preprocessed source start here ---- 90 | // r93 91 | var src_p = src_0; 92 | var src_base = src_0; 93 | var src_anchor = src_p; 94 | var src_end = src_p + src_len; 95 | var src_mflimit = src_end - MFLIMIT; 96 | 97 | var dst_p = dst_0; 98 | var dst_end = dst_p + dst_maxlen; 99 | 100 | var src_LASTLITERALS = src_end - LASTLITERALS; 101 | var src_LASTLITERALS_1 = src_LASTLITERALS - 1; 102 | 103 | var src_LASTLITERALS_STEPSIZE_1 = src_LASTLITERALS - (STEPSIZE_32 - 1); 104 | var dst_LASTLITERALS_1 = dst_end - (1 + LASTLITERALS); 105 | var dst_LASTLITERALS_3 = dst_end - (2 + 1 + LASTLITERALS); 106 | 107 | int length; 108 | 109 | uint h, h_fwd; 110 | 111 | // Init 112 | if (src_len < MINLENGTH) goto _last_literals; 113 | 114 | // First Byte 115 | hash_table[(((Peek4(src, src_p)) * 2654435761u) >> HASH_ADJUST)] = (src_p - src_base); 116 | src_p++; 117 | h_fwd = (((Peek4(src, src_p)) * 2654435761u) >> HASH_ADJUST); 118 | 119 | // Main Loop 120 | while (true) 121 | { 122 | var findMatchAttempts = (1 << SKIPSTRENGTH) + 3; 123 | var src_p_fwd = src_p; 124 | int src_ref; 125 | int dst_token; 126 | 127 | // Find a match 128 | do 129 | { 130 | h = h_fwd; 131 | var step = findMatchAttempts++ >> SKIPSTRENGTH; 132 | src_p = src_p_fwd; 133 | src_p_fwd = src_p + step; 134 | 135 | if (src_p_fwd > src_mflimit) goto _last_literals; 136 | 137 | h_fwd = (((Peek4(src, src_p_fwd)) * 2654435761u) >> HASH_ADJUST); 138 | src_ref = src_base + hash_table[h]; 139 | hash_table[h] = (src_p - src_base); 140 | } while ((src_ref < src_p - MAX_DISTANCE) || (!Equal4(src, src_ref, src_p))); 141 | 142 | // Catch up 143 | while ((src_p > src_anchor) && (src_ref > src_0) && (src[src_p - 1] == src[src_ref - 1])) 144 | { 145 | src_p--; 146 | src_ref--; 147 | } 148 | 149 | // Encode Literal length 150 | length = (src_p - src_anchor); 151 | dst_token = dst_p++; 152 | 153 | if (dst_p + length + (length >> 8) > dst_LASTLITERALS_3) return 0; // Check output limit 154 | 155 | if (length >= RUN_MASK) 156 | { 157 | var len = length - RUN_MASK; 158 | dst[dst_token] = (RUN_MASK << ML_BITS); 159 | if (len > 254) 160 | { 161 | do 162 | { 163 | dst[dst_p++] = 255; 164 | len -= 255; 165 | } while (len > 254); 166 | dst[dst_p++] = (byte)len; 167 | BlockCopy(src, src_anchor, dst, dst_p, length); 168 | dst_p += length; 169 | goto _next_match; 170 | } 171 | else 172 | dst[dst_p++] = (byte)len; 173 | } 174 | else 175 | { 176 | dst[dst_token] = (byte)(length << ML_BITS); 177 | } 178 | 179 | // Copy Literals 180 | if (length > 0) 181 | { 182 | _i = dst_p + length; 183 | WildCopy(src, src_anchor, dst, dst_p, _i); 184 | dst_p = _i; 185 | } 186 | 187 | _next_match: 188 | // Encode Offset 189 | Poke2(dst, dst_p, (ushort)(src_p - src_ref)); 190 | dst_p += 2; 191 | 192 | // Start Counting 193 | src_p += MINMATCH; 194 | src_ref += MINMATCH; // MinMatch already verified 195 | src_anchor = src_p; 196 | 197 | while (src_p < src_LASTLITERALS_STEPSIZE_1) 198 | { 199 | var diff = (int)Xor4(src, src_ref, src_p); 200 | if (diff == 0) 201 | { 202 | src_p += STEPSIZE_32; 203 | src_ref += STEPSIZE_32; 204 | continue; 205 | } 206 | src_p += debruijn32[((uint)((diff) & -(diff)) * 0x077CB531u) >> 27]; 207 | goto _endCount; 208 | } 209 | 210 | if ((src_p < src_LASTLITERALS_1) && (Equal2(src, src_ref, src_p))) 211 | { 212 | src_p += 2; 213 | src_ref += 2; 214 | } 215 | if ((src_p < src_LASTLITERALS) && (src[src_ref] == src[src_p])) src_p++; 216 | 217 | _endCount: 218 | // Encode MatchLength 219 | length = (src_p - src_anchor); 220 | 221 | if (dst_p + (length >> 8) > dst_LASTLITERALS_1) return 0; // Check output limit 222 | 223 | if (length >= ML_MASK) 224 | { 225 | dst[dst_token] += ML_MASK; 226 | length -= ML_MASK; 227 | for (; length > 509; length -= 510) 228 | { 229 | dst[dst_p++] = 255; 230 | dst[dst_p++] = 255; 231 | } 232 | if (length > 254) 233 | { 234 | length -= 255; 235 | dst[dst_p++] = 255; 236 | } 237 | dst[dst_p++] = (byte)length; 238 | } 239 | else 240 | { 241 | dst[dst_token] += (byte)length; 242 | } 243 | 244 | // Test end of chunk 245 | if (src_p > src_mflimit) 246 | { 247 | src_anchor = src_p; 248 | break; 249 | } 250 | 251 | // Fill table 252 | hash_table[(((Peek4(src, src_p - 2)) * 2654435761u) >> HASH_ADJUST)] = (src_p - 2 - src_base); 253 | 254 | // Test next position 255 | 256 | h = (((Peek4(src, src_p)) * 2654435761u) >> HASH_ADJUST); 257 | src_ref = src_base + hash_table[h]; 258 | hash_table[h] = (src_p - src_base); 259 | 260 | if ((src_ref > src_p - (MAX_DISTANCE + 1)) && (Equal4(src, src_ref, src_p))) 261 | { 262 | dst_token = dst_p++; 263 | dst[dst_token] = 0; 264 | goto _next_match; 265 | } 266 | 267 | // Prepare next loop 268 | src_anchor = src_p++; 269 | h_fwd = (((Peek4(src, src_p)) * 2654435761u) >> HASH_ADJUST); 270 | } 271 | 272 | _last_literals: 273 | // Encode Last Literals 274 | { 275 | var lastRun = (src_end - src_anchor); 276 | 277 | if (dst_p + lastRun + 1 + ((lastRun + 255 - RUN_MASK) / 255) > dst_end) return 0; 278 | 279 | if (lastRun >= RUN_MASK) 280 | { 281 | dst[dst_p++] = (RUN_MASK << ML_BITS); 282 | lastRun -= RUN_MASK; 283 | for (; lastRun > 254; lastRun -= 255) dst[dst_p++] = 255; 284 | dst[dst_p++] = (byte)lastRun; 285 | } 286 | else dst[dst_p++] = (byte)(lastRun << ML_BITS); 287 | BlockCopy(src, src_anchor, dst, dst_p, src_end - src_anchor); 288 | dst_p += src_end - src_anchor; 289 | } 290 | 291 | // End 292 | return ((dst_p) - dst_0); 293 | } 294 | 295 | #endregion 296 | 297 | #region LZ4_compress64kCtx 298 | 299 | private static int LZ4_compress64kCtx_safe32( 300 | ushort[] hash_table, 301 | byte[] src, 302 | byte[] dst, 303 | int src_0, 304 | int dst_0, 305 | int src_len, 306 | int dst_maxlen) 307 | { 308 | var debruijn32 = DEBRUIJN_TABLE_32; 309 | int _i; 310 | 311 | // ---- preprocessed source start here ---- 312 | // r93 313 | var src_p = src_0; 314 | var src_anchor = src_p; 315 | var src_base = src_p; 316 | var src_end = src_p + src_len; 317 | var src_mflimit = src_end - MFLIMIT; 318 | 319 | var dst_p = dst_0; 320 | var dst_end = dst_p + dst_maxlen; 321 | 322 | var src_LASTLITERALS = src_end - LASTLITERALS; 323 | var src_LASTLITERALS_1 = src_LASTLITERALS - 1; 324 | 325 | var src_LASTLITERALS_STEPSIZE_1 = src_LASTLITERALS - (STEPSIZE_32 - 1); 326 | var dst_LASTLITERALS_1 = dst_end - (1 + LASTLITERALS); 327 | var dst_LASTLITERALS_3 = dst_end - (2 + 1 + LASTLITERALS); 328 | 329 | int len, length; 330 | 331 | uint h, h_fwd; 332 | 333 | // Init 334 | if (src_len < MINLENGTH) goto _last_literals; 335 | 336 | // First Byte 337 | src_p++; 338 | h_fwd = (((Peek4(src, src_p)) * 2654435761u) >> HASH64K_ADJUST); 339 | 340 | // Main Loop 341 | while (true) 342 | { 343 | var findMatchAttempts = (1 << SKIPSTRENGTH) + 3; 344 | var src_p_fwd = src_p; 345 | int src_ref; 346 | int dst_token; 347 | 348 | // Find a match 349 | do 350 | { 351 | h = h_fwd; 352 | var step = findMatchAttempts++ >> SKIPSTRENGTH; 353 | src_p = src_p_fwd; 354 | src_p_fwd = src_p + step; 355 | 356 | if (src_p_fwd > src_mflimit) goto _last_literals; 357 | 358 | h_fwd = (((Peek4(src, src_p_fwd)) * 2654435761u) >> HASH64K_ADJUST); 359 | src_ref = src_base + hash_table[h]; 360 | hash_table[h] = (ushort)(src_p - src_base); 361 | } while (!Equal4(src, src_ref, src_p)); 362 | 363 | // Catch up 364 | while ((src_p > src_anchor) && (src_ref > src_0) && (src[src_p - 1] == src[src_ref - 1])) 365 | { 366 | src_p--; 367 | src_ref--; 368 | } 369 | 370 | // Encode Literal length 371 | length = (src_p - src_anchor); 372 | dst_token = dst_p++; 373 | 374 | if (dst_p + length + (length >> 8) > dst_LASTLITERALS_3) return 0; // Check output limit 375 | 376 | if (length >= RUN_MASK) 377 | { 378 | len = length - RUN_MASK; 379 | dst[dst_token] = (RUN_MASK << ML_BITS); 380 | if (len > 254) 381 | { 382 | do 383 | { 384 | dst[dst_p++] = 255; 385 | len -= 255; 386 | } while (len > 254); 387 | dst[dst_p++] = (byte)len; 388 | BlockCopy(src, src_anchor, dst, dst_p, length); 389 | dst_p += length; 390 | goto _next_match; 391 | } 392 | else 393 | { 394 | dst[dst_p++] = (byte)len; 395 | } 396 | } 397 | else 398 | { 399 | dst[dst_token] = (byte)(length << ML_BITS); 400 | } 401 | 402 | // Copy Literals 403 | if (length > 0) 404 | { 405 | _i = dst_p + length; 406 | WildCopy(src, src_anchor, dst, dst_p, _i); 407 | dst_p = _i; 408 | } 409 | 410 | _next_match: 411 | // Encode Offset 412 | Poke2(dst, dst_p, (ushort)(src_p - src_ref)); 413 | dst_p += 2; 414 | 415 | // Start Counting 416 | src_p += MINMATCH; 417 | src_ref += MINMATCH; // MinMatch verified 418 | src_anchor = src_p; 419 | 420 | while (src_p < src_LASTLITERALS_STEPSIZE_1) 421 | { 422 | var diff = (int)Xor4(src, src_ref, src_p); 423 | if (diff == 0) 424 | { 425 | src_p += STEPSIZE_32; 426 | src_ref += STEPSIZE_32; 427 | continue; 428 | } 429 | src_p += debruijn32[((uint)((diff) & -(diff)) * 0x077CB531u) >> 27]; 430 | goto _endCount; 431 | } 432 | 433 | if ((src_p < src_LASTLITERALS_1) && (Equal2(src, src_ref, src_p))) 434 | { 435 | src_p += 2; 436 | src_ref += 2; 437 | } 438 | if ((src_p < src_LASTLITERALS) && (src[src_ref] == src[src_p])) src_p++; 439 | 440 | _endCount: 441 | 442 | // Encode MatchLength 443 | len = (src_p - src_anchor); 444 | 445 | if (dst_p + (len >> 8) > dst_LASTLITERALS_1) return 0; // Check output limit 446 | 447 | if (len >= ML_MASK) 448 | { 449 | dst[dst_token] += ML_MASK; 450 | len -= ML_MASK; 451 | for (; len > 509; len -= 510) 452 | { 453 | dst[dst_p++] = 255; 454 | dst[dst_p++] = 255; 455 | } 456 | if (len > 254) 457 | { 458 | len -= 255; 459 | dst[dst_p++] = 255; 460 | } 461 | dst[dst_p++] = (byte)len; 462 | } 463 | else 464 | { 465 | dst[dst_token] += (byte)len; 466 | } 467 | 468 | // Test end of chunk 469 | if (src_p > src_mflimit) 470 | { 471 | src_anchor = src_p; 472 | break; 473 | } 474 | 475 | // Fill table 476 | hash_table[(((Peek4(src, src_p - 2)) * 2654435761u) >> HASH64K_ADJUST)] = (ushort)(src_p - 2 - src_base); 477 | 478 | // Test next position 479 | 480 | h = (((Peek4(src, src_p)) * 2654435761u) >> HASH64K_ADJUST); 481 | src_ref = src_base + hash_table[h]; 482 | hash_table[h] = (ushort)(src_p - src_base); 483 | 484 | if (Equal4(src, src_ref, src_p)) 485 | { 486 | dst_token = dst_p++; 487 | dst[dst_token] = 0; 488 | goto _next_match; 489 | } 490 | 491 | // Prepare next loop 492 | src_anchor = src_p++; 493 | h_fwd = (((Peek4(src, src_p)) * 2654435761u) >> HASH64K_ADJUST); 494 | } 495 | 496 | _last_literals: 497 | // Encode Last Literals 498 | var lastRun = (src_end - src_anchor); 499 | if (dst_p + lastRun + 1 + (lastRun - RUN_MASK + 255) / 255 > dst_end) return 0; 500 | if (lastRun >= RUN_MASK) 501 | { 502 | dst[dst_p++] = (RUN_MASK << ML_BITS); 503 | lastRun -= RUN_MASK; 504 | for (; lastRun > 254; lastRun -= 255) dst[dst_p++] = 255; 505 | dst[dst_p++] = (byte)lastRun; 506 | } 507 | else 508 | { 509 | dst[dst_p++] = (byte)(lastRun << ML_BITS); 510 | } 511 | BlockCopy(src, src_anchor, dst, dst_p, src_end - src_anchor); 512 | dst_p += src_end - src_anchor; 513 | 514 | // End 515 | return ((dst_p) - dst_0); 516 | } 517 | 518 | #endregion 519 | 520 | #region LZ4_uncompress 521 | 522 | private static int LZ4_uncompress_safe32( 523 | byte[] src, 524 | byte[] dst, 525 | int src_0, 526 | int dst_0, 527 | int dst_len) 528 | { 529 | var dec32table = DECODER_TABLE_32; 530 | int _i; 531 | 532 | // ---- preprocessed source start here ---- 533 | // r93 534 | var src_p = src_0; 535 | int dst_ref; 536 | 537 | var dst_p = dst_0; 538 | var dst_end = dst_p + dst_len; 539 | int dst_cpy; 540 | 541 | var dst_LASTLITERALS = dst_end - LASTLITERALS; 542 | var dst_COPYLENGTH = dst_end - COPYLENGTH; 543 | var dst_COPYLENGTH_STEPSIZE_4 = dst_end - COPYLENGTH - (STEPSIZE_32 - 4); 544 | 545 | byte token; 546 | 547 | // Main Loop 548 | while (true) 549 | { 550 | int length; 551 | 552 | // get runlength 553 | token = src[src_p++]; 554 | if ((length = (token >> ML_BITS)) == RUN_MASK) 555 | { 556 | int len; 557 | for (; (len = src[src_p++]) == 255; length += 255) 558 | { 559 | /* do nothing */ 560 | } 561 | length += len; 562 | } 563 | 564 | // copy literals 565 | dst_cpy = dst_p + length; 566 | 567 | if (dst_cpy > dst_COPYLENGTH) 568 | { 569 | if (dst_cpy != dst_end) goto _output_error; // Error : not enough place for another match (min 4) + 5 literals 570 | BlockCopy(src, src_p, dst, dst_p, length); 571 | src_p += length; 572 | break; // EOF 573 | } 574 | if (dst_p < dst_cpy) 575 | { 576 | _i = WildCopy(src, src_p, dst, dst_p, dst_cpy); 577 | src_p += _i; 578 | dst_p += _i; 579 | } 580 | src_p -= (dst_p - dst_cpy); 581 | dst_p = dst_cpy; 582 | 583 | // get offset 584 | dst_ref = (dst_cpy) - Peek2(src, src_p); 585 | src_p += 2; 586 | if (dst_ref < dst_0) goto _output_error; // Error : offset outside destination buffer 587 | 588 | // get matchlength 589 | if ((length = (token & ML_MASK)) == ML_MASK) 590 | { 591 | for (; src[src_p] == 255; length += 255) src_p++; 592 | length += src[src_p++]; 593 | } 594 | 595 | // copy repeated sequence 596 | if ((dst_p - dst_ref) < STEPSIZE_32) 597 | { 598 | const int dec64 = 0; 599 | dst[dst_p + 0] = dst[dst_ref + 0]; 600 | dst[dst_p + 1] = dst[dst_ref + 1]; 601 | dst[dst_p + 2] = dst[dst_ref + 2]; 602 | dst[dst_p + 3] = dst[dst_ref + 3]; 603 | dst_p += 4; 604 | dst_ref += 4; 605 | dst_ref -= dec32table[dst_p - dst_ref]; 606 | Copy4(dst, dst_ref, dst_p); 607 | dst_p += STEPSIZE_32 - 4; 608 | dst_ref -= dec64; 609 | } 610 | else 611 | { 612 | Copy4(dst, dst_ref, dst_p); 613 | dst_p += 4; 614 | dst_ref += 4; 615 | } 616 | dst_cpy = dst_p + length - (STEPSIZE_32 - 4); 617 | 618 | if (dst_cpy > dst_COPYLENGTH_STEPSIZE_4) 619 | { 620 | if (dst_cpy > dst_LASTLITERALS) goto _output_error; // Error : last 5 bytes must be literals 621 | if (dst_p < dst_COPYLENGTH) 622 | { 623 | _i = SecureCopy(dst, dst_ref, dst_p, dst_COPYLENGTH); 624 | dst_ref += _i; 625 | dst_p += _i; 626 | } 627 | 628 | while (dst_p < dst_cpy) dst[dst_p++] = dst[dst_ref++]; 629 | dst_p = dst_cpy; 630 | continue; 631 | } 632 | 633 | if (dst_p < dst_cpy) 634 | { 635 | SecureCopy(dst, dst_ref, dst_p, dst_cpy); 636 | } 637 | dst_p = dst_cpy; // correction 638 | } 639 | 640 | // end of decoding 641 | return ((src_p) - src_0); 642 | 643 | // write overflow error detected 644 | _output_error: 645 | return (-((src_p) - src_0)); 646 | } 647 | 648 | #endregion 649 | 650 | #region LZ4_uncompress_unknownOutputSize 651 | 652 | private static int LZ4_uncompress_unknownOutputSize_safe32( 653 | byte[] src, 654 | byte[] dst, 655 | int src_0, 656 | int dst_0, 657 | int src_len, 658 | int dst_maxlen) 659 | { 660 | var dec32table = DECODER_TABLE_32; 661 | int _i; 662 | 663 | // ---- preprocessed source start here ---- 664 | // r93 665 | var src_p = src_0; 666 | var src_end = src_p + src_len; 667 | int dst_ref; 668 | 669 | var dst_p = dst_0; 670 | var dst_end = dst_p + dst_maxlen; 671 | int dst_cpy; 672 | 673 | var src_LASTLITERALS_3 = (src_end - (2 + 1 + LASTLITERALS)); 674 | var src_LASTLITERALS_1 = (src_end - (LASTLITERALS + 1)); 675 | var dst_COPYLENGTH = (dst_end - COPYLENGTH); 676 | var dst_COPYLENGTH_STEPSIZE_4 = (dst_end - (COPYLENGTH + (STEPSIZE_32 - 4))); 677 | var dst_LASTLITERALS = (dst_end - LASTLITERALS); 678 | var dst_MFLIMIT = (dst_end - MFLIMIT); 679 | 680 | // Special case 681 | if (src_p == src_end) goto _output_error; // A correctly formed null-compressed LZ4 must have at least one byte (token=0) 682 | 683 | // Main Loop 684 | while (true) 685 | { 686 | byte token; 687 | int length; 688 | 689 | // get runlength 690 | token = src[src_p++]; 691 | if ((length = (token >> ML_BITS)) == RUN_MASK) 692 | { 693 | var s = 255; 694 | while ((src_p < src_end) && (s == 255)) length += (s = src[src_p++]); 695 | } 696 | 697 | // copy literals 698 | dst_cpy = dst_p + length; 699 | 700 | if ((dst_cpy > dst_MFLIMIT) || (src_p + length > src_LASTLITERALS_3)) 701 | { 702 | if (dst_cpy > dst_end) goto _output_error; // Error : writes beyond output buffer 703 | if (src_p + length != src_end) goto _output_error; // Error : LZ4 format requires to consume all input at this stage (no match within the last 11 bytes, and at least 8 remaining input bytes for another match+literals) 704 | BlockCopy(src, src_p, dst, dst_p, length); 705 | dst_p += length; 706 | break; // Necessarily EOF, due to parsing restrictions 707 | } 708 | if (dst_p < dst_cpy) 709 | { 710 | _i = WildCopy(src, src_p, dst, dst_p, dst_cpy); 711 | src_p += _i; 712 | dst_p += _i; 713 | } 714 | src_p -= (dst_p - dst_cpy); 715 | dst_p = dst_cpy; 716 | 717 | // get offset 718 | dst_ref = (dst_cpy) - Peek2(src, src_p); 719 | src_p += 2; 720 | if (dst_ref < dst_0) goto _output_error; // Error : offset outside of destination buffer 721 | 722 | // get matchlength 723 | if ((length = (token & ML_MASK)) == ML_MASK) 724 | { 725 | while (src_p < src_LASTLITERALS_1) // Error : a minimum input bytes must remain for LASTLITERALS + token 726 | { 727 | int s = src[src_p++]; 728 | length += s; 729 | if (s == 255) continue; 730 | break; 731 | } 732 | } 733 | 734 | // copy repeated sequence 735 | if (dst_p - dst_ref < STEPSIZE_32) 736 | { 737 | const int dec64 = 0; 738 | dst[dst_p + 0] = dst[dst_ref + 0]; 739 | dst[dst_p + 1] = dst[dst_ref + 1]; 740 | dst[dst_p + 2] = dst[dst_ref + 2]; 741 | dst[dst_p + 3] = dst[dst_ref + 3]; 742 | dst_p += 4; 743 | dst_ref += 4; 744 | dst_ref -= dec32table[dst_p - dst_ref]; 745 | Copy4(dst, dst_ref, dst_p); 746 | dst_p += STEPSIZE_32 - 4; 747 | dst_ref -= dec64; 748 | } 749 | else 750 | { 751 | Copy4(dst, dst_ref, dst_p); 752 | dst_p += 4; 753 | dst_ref += 4; 754 | } 755 | dst_cpy = dst_p + length - (STEPSIZE_32 - 4); 756 | 757 | if (dst_cpy > dst_COPYLENGTH_STEPSIZE_4) 758 | { 759 | if (dst_cpy > dst_LASTLITERALS) goto _output_error; // Error : last 5 bytes must be literals 760 | if (dst_p < dst_COPYLENGTH) 761 | { 762 | _i = SecureCopy(dst, dst_ref, dst_p, dst_COPYLENGTH); 763 | dst_ref += _i; 764 | dst_p += _i; 765 | } 766 | 767 | while (dst_p < dst_cpy) dst[dst_p++] = dst[dst_ref++]; 768 | dst_p = dst_cpy; 769 | continue; 770 | } 771 | 772 | if (dst_p < dst_cpy) 773 | { 774 | SecureCopy(dst, dst_ref, dst_p, dst_cpy); 775 | } 776 | dst_p = dst_cpy; // correction 777 | } 778 | 779 | // end of decoding 780 | return ((dst_p) - dst_0); 781 | 782 | // write overflow error detected 783 | _output_error: 784 | return (-((src_p) - src_0)); 785 | } 786 | 787 | #endregion 788 | } 789 | } 790 | 791 | // ReSharper restore RedundantIfElseBlock 792 | // ReSharper restore JoinDeclarationAndInitializer 793 | // ReSharper restore TooWideLocalVariableScope 794 | // ReSharper restore InconsistentNaming 795 | // ReSharper restore CheckNamespace 796 | -------------------------------------------------------------------------------- /LZ4/LZ4Codec.Safe32HC.Dirty.cs: -------------------------------------------------------------------------------- 1 | #region LZ4 original 2 | 3 | /* 4 | LZ4 - Fast LZ compression algorithm 5 | Copyright (C) 2011-2012, Yann Collet. 6 | BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are 10 | met: 11 | 12 | * Redistributions of source code must retain the above copyright 13 | notice, this list of conditions and the following disclaimer. 14 | * Redistributions in binary form must reproduce the above 15 | copyright notice, this list of conditions and the following disclaimer 16 | in the documentation and/or other materials provided with the 17 | distribution. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | You can contact the author at : 32 | - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html 33 | - LZ4 source repository : http://code.google.com/p/lz4/ 34 | */ 35 | 36 | #endregion 37 | 38 | #region LZ4 port 39 | 40 | /* 41 | Copyright (c) 2013, Milosz Krajewski 42 | All rights reserved. 43 | 44 | Redistribution and use in source and binary forms, with or without modification, are permitted provided 45 | that the following conditions are met: 46 | 47 | * Redistributions of source code must retain the above copyright notice, this list of conditions 48 | and the following disclaimer. 49 | 50 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions 51 | and the following disclaimer in the documentation and/or other materials provided with the distribution. 52 | 53 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 54 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 55 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 56 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 57 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 58 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 59 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 60 | IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 61 | */ 62 | 63 | #endregion 64 | 65 | // ReSharper disable InconsistentNaming 66 | 67 | namespace LZ4ps 68 | { 69 | public static partial class LZ4Codec 70 | { 71 | // Update chains up to ip (excluded) 72 | private static void LZ4HC_Insert_32(LZ4HC_Data_Structure ctx, int src_p) 73 | { 74 | var chainTable = ctx.chainTable; 75 | var hashTable = ctx.hashTable; 76 | var nextToUpdate = ctx.nextToUpdate; 77 | var src = ctx.src; 78 | var src_base = ctx.src_base; 79 | 80 | while (nextToUpdate < src_p) 81 | { 82 | var p = nextToUpdate; 83 | var delta = (p) - (hashTable[(((Peek4(src, p)) * 2654435761u) >> HASHHC_ADJUST)] + src_base); 84 | if (delta > MAX_DISTANCE) delta = MAX_DISTANCE; 85 | chainTable[(p) & MAXD_MASK] = (ushort)delta; 86 | hashTable[(((Peek4(src, p)) * 2654435761u) >> HASHHC_ADJUST)] = ((p) - src_base); 87 | nextToUpdate++; 88 | } 89 | 90 | ctx.nextToUpdate = nextToUpdate; 91 | } 92 | 93 | private static int LZ4HC_CommonLength_32(LZ4HC_Data_Structure ctx, int p1, int p2) 94 | { 95 | var debruijn32 = DEBRUIJN_TABLE_32; 96 | var src = ctx.src; 97 | var src_LASTLITERALS = ctx.src_LASTLITERALS; 98 | 99 | var p1t = p1; 100 | 101 | while (p1t < src_LASTLITERALS - (STEPSIZE_32 - 1)) 102 | { 103 | var diff = (int)Xor4(src, p2, p1t); 104 | if (diff == 0) 105 | { 106 | p1t += STEPSIZE_32; 107 | p2 += STEPSIZE_32; 108 | continue; 109 | } 110 | p1t += debruijn32[((uint)((diff) & -(diff)) * 0x077CB531u) >> 27]; 111 | return (p1t - p1); 112 | } 113 | if ((p1t < (src_LASTLITERALS - 1)) && (Equal2(src, p2, p1t))) 114 | { 115 | p1t += 2; 116 | p2 += 2; 117 | } 118 | if ((p1t < src_LASTLITERALS) && (src[p2] == src[p1t])) p1t++; 119 | return (p1t - p1); 120 | } 121 | 122 | private static int LZ4HC_InsertAndFindBestMatch_32(LZ4HC_Data_Structure ctx, int src_p, ref int src_match) 123 | { 124 | var chainTable = ctx.chainTable; 125 | var hashTable = ctx.hashTable; 126 | var src = ctx.src; 127 | var src_base = ctx.src_base; 128 | 129 | var nbAttempts = MAX_NB_ATTEMPTS; 130 | int repl = 0, ml = 0; 131 | ushort delta = 0; 132 | 133 | // HC4 match finder 134 | LZ4HC_Insert_32(ctx, src_p); 135 | var src_ref = (hashTable[(((Peek4(src, src_p)) * 2654435761u) >> HASHHC_ADJUST)] + src_base); 136 | 137 | 138 | // Detect repetitive sequences of length <= 4 139 | if (src_ref >= src_p - 4) // potential repetition 140 | { 141 | if (Equal4(src, src_ref, src_p)) // confirmed 142 | { 143 | delta = (ushort)(src_p - src_ref); 144 | repl = ml = LZ4HC_CommonLength_32(ctx, src_p + MINMATCH, src_ref + MINMATCH) + MINMATCH; 145 | src_match = src_ref; 146 | } 147 | src_ref = ((src_ref) - chainTable[(src_ref) & MAXD_MASK]); 148 | } 149 | 150 | while ((src_ref >= src_p - MAX_DISTANCE) && (nbAttempts != 0)) 151 | { 152 | nbAttempts--; 153 | if (src[(src_ref + ml)] == src[(src_p + ml)]) 154 | { 155 | if (Equal4(src, src_ref, src_p)) 156 | { 157 | var mlt = LZ4HC_CommonLength_32(ctx, src_p + MINMATCH, src_ref + MINMATCH) + MINMATCH; 158 | if (mlt > ml) 159 | { 160 | ml = mlt; 161 | src_match = src_ref; 162 | } 163 | } 164 | } 165 | src_ref = ((src_ref) - chainTable[(src_ref) & MAXD_MASK]); 166 | } 167 | 168 | 169 | // Complete table 170 | if (repl != 0) 171 | { 172 | var src_ptr = src_p; 173 | 174 | var end = src_p + repl - (MINMATCH - 1); 175 | while (src_ptr < end - delta) 176 | { 177 | chainTable[(src_ptr) & MAXD_MASK] = delta; // Pre-Load 178 | src_ptr++; 179 | } 180 | do 181 | { 182 | chainTable[(src_ptr) & MAXD_MASK] = delta; 183 | hashTable[(((Peek4(src, src_ptr)) * 2654435761u) >> HASHHC_ADJUST)] = ((src_ptr) - src_base); // Head of chain 184 | src_ptr++; 185 | } while (src_ptr < end); 186 | ctx.nextToUpdate = end; 187 | } 188 | 189 | return ml; 190 | } 191 | 192 | private static int LZ4HC_InsertAndGetWiderMatch_32( 193 | LZ4HC_Data_Structure ctx, int src_p, int startLimit, int longest, ref int matchpos, ref int startpos) 194 | { 195 | var chainTable = ctx.chainTable; 196 | var hashTable = ctx.hashTable; 197 | var src = ctx.src; 198 | var src_base = ctx.src_base; 199 | var src_LASTLITERALS = ctx.src_LASTLITERALS; 200 | var debruijn32 = DEBRUIJN_TABLE_32; 201 | var nbAttempts = MAX_NB_ATTEMPTS; 202 | var delta = (src_p - startLimit); 203 | 204 | // First Match 205 | LZ4HC_Insert_32(ctx, src_p); 206 | var src_ref = (hashTable[(((Peek4(src, src_p)) * 2654435761u) >> HASHHC_ADJUST)] + src_base); 207 | 208 | while ((src_ref >= src_p - MAX_DISTANCE) && (nbAttempts != 0)) 209 | { 210 | nbAttempts--; 211 | if (src[(startLimit + longest)] == src[(src_ref - delta + longest)]) 212 | { 213 | if (Equal4(src, src_ref, src_p)) 214 | { 215 | var reft = src_ref + MINMATCH; 216 | var ipt = src_p + MINMATCH; 217 | var startt = src_p; 218 | 219 | while (ipt < src_LASTLITERALS - (STEPSIZE_32 - 1)) 220 | { 221 | var diff = (int)Xor4(src, reft, ipt); 222 | if (diff == 0) 223 | { 224 | ipt += STEPSIZE_32; 225 | reft += STEPSIZE_32; 226 | continue; 227 | } 228 | ipt += debruijn32[((uint)((diff) & -(diff)) * 0x077CB531u) >> 27]; 229 | goto _endCount; 230 | } 231 | if ((ipt < (src_LASTLITERALS - 1)) && (Equal2(src, reft, ipt))) 232 | { 233 | ipt += 2; 234 | reft += 2; 235 | } 236 | if ((ipt < src_LASTLITERALS) && (src[reft] == src[ipt])) ipt++; 237 | 238 | _endCount: 239 | reft = src_ref; 240 | 241 | while ((startt > startLimit) && (reft > src_base) && (src[startt - 1] == src[reft - 1])) 242 | { 243 | startt--; 244 | reft--; 245 | } 246 | 247 | if ((ipt - startt) > longest) 248 | { 249 | longest = (ipt - startt); 250 | matchpos = reft; 251 | startpos = startt; 252 | } 253 | } 254 | } 255 | src_ref = ((src_ref) - chainTable[(src_ref) & MAXD_MASK]); 256 | } 257 | 258 | return longest; 259 | } 260 | 261 | private static int LZ4_encodeSequence_32( 262 | LZ4HC_Data_Structure ctx, ref int src_p, ref int dst_p, ref int src_anchor, int matchLength, int src_ref, int dst_end) 263 | { 264 | int len; 265 | var src = ctx.src; 266 | var dst = ctx.dst; 267 | 268 | // Encode Literal length 269 | var length = src_p - src_anchor; 270 | var dst_token = dst_p++; 271 | if ((dst_p + length + (2 + 1 + LASTLITERALS) + (length >> 8)) > dst_end) return 1; // Check output limit 272 | if (length >= RUN_MASK) 273 | { 274 | dst[dst_token] = (RUN_MASK << ML_BITS); 275 | len = length - RUN_MASK; 276 | for (; len > 254; len -= 255) dst[dst_p++] = 255; 277 | dst[dst_p++] = (byte)len; 278 | } 279 | else 280 | { 281 | dst[dst_token] = (byte)(length << ML_BITS); 282 | } 283 | 284 | // Copy Literals 285 | if (length > 0) 286 | { 287 | var _i = dst_p + length; 288 | src_anchor += WildCopy(src, src_anchor, dst, dst_p, _i); 289 | dst_p = _i; 290 | } 291 | 292 | // Encode Offset 293 | Poke2(dst, dst_p, (ushort)(src_p - src_ref)); 294 | dst_p += 2; 295 | 296 | // Encode MatchLength 297 | len = (matchLength - MINMATCH); 298 | if (dst_p + (1 + LASTLITERALS) + (length >> 8) > dst_end) return 1; // Check output limit 299 | if (len >= ML_MASK) 300 | { 301 | dst[dst_token] += ML_MASK; 302 | len -= ML_MASK; 303 | for (; len > 509; len -= 510) 304 | { 305 | dst[(dst_p)++] = 255; 306 | dst[(dst_p)++] = 255; 307 | } 308 | if (len > 254) 309 | { 310 | len -= 255; 311 | dst[(dst_p)++] = 255; 312 | } 313 | dst[(dst_p)++] = (byte)len; 314 | } 315 | else 316 | { 317 | dst[dst_token] += (byte)len; 318 | } 319 | 320 | // Prepare next loop 321 | src_p += matchLength; 322 | src_anchor = src_p; 323 | 324 | return 0; 325 | } 326 | 327 | private static int LZ4_compressHCCtx_32(LZ4HC_Data_Structure ctx) 328 | { 329 | var src = ctx.src; 330 | var dst = ctx.dst; 331 | var src_0 = ctx.src_base; 332 | var src_end = ctx.src_end; 333 | var dst_0 = ctx.dst_base; 334 | var dst_len = ctx.dst_len; 335 | var dst_end = ctx.dst_end; 336 | 337 | var src_p = src_0; 338 | var src_anchor = src_p; 339 | var src_mflimit = src_end - MFLIMIT; 340 | 341 | var dst_p = dst_0; 342 | 343 | var src_ref = 0; 344 | var start2 = 0; 345 | var ref2 = 0; 346 | var start3 = 0; 347 | var ref3 = 0; 348 | 349 | src_p++; 350 | 351 | // Main Loop 352 | while (src_p < src_mflimit) 353 | { 354 | var ml = LZ4HC_InsertAndFindBestMatch_32(ctx, src_p, ref src_ref); 355 | if (ml == 0) 356 | { 357 | src_p++; 358 | continue; 359 | } 360 | 361 | // saved, in case we would skip too much 362 | var start0 = src_p; 363 | var ref0 = src_ref; 364 | var ml0 = ml; 365 | 366 | _Search2: 367 | var ml2 = src_p + ml < src_mflimit 368 | ? LZ4HC_InsertAndGetWiderMatch_32(ctx, src_p + ml - 2, src_p + 1, ml, ref ref2, ref start2) 369 | : ml; 370 | 371 | if (ml2 == ml) // No better match 372 | { 373 | if (LZ4_encodeSequence_32(ctx, ref src_p, ref dst_p, ref src_anchor, ml, src_ref, dst_end) != 0) return 0; 374 | continue; 375 | } 376 | 377 | if (start0 < src_p) 378 | { 379 | if (start2 < src_p + ml0) // empirical 380 | { 381 | src_p = start0; 382 | src_ref = ref0; 383 | ml = ml0; 384 | } 385 | } 386 | 387 | // Here, start0==ip 388 | if ((start2 - src_p) < 3) // First Match too small : removed 389 | { 390 | ml = ml2; 391 | src_p = start2; 392 | src_ref = ref2; 393 | goto _Search2; 394 | } 395 | 396 | _Search3: 397 | // Currently we have : 398 | // ml2 > ml1, and 399 | // ip1+3 <= ip2 (usually < ip1+ml1) 400 | if ((start2 - src_p) < OPTIMAL_ML) 401 | { 402 | var new_ml = ml; 403 | if (new_ml > OPTIMAL_ML) new_ml = OPTIMAL_ML; 404 | if (src_p + new_ml > start2 + ml2 - MINMATCH) new_ml = (start2 - src_p) + ml2 - MINMATCH; 405 | var correction = new_ml - (start2 - src_p); 406 | if (correction > 0) 407 | { 408 | start2 += correction; 409 | ref2 += correction; 410 | ml2 -= correction; 411 | } 412 | } 413 | // Now, we have start2 = ip+new_ml, with new_ml=min(ml, OPTIMAL_ML=18) 414 | 415 | var ml3 = start2 + ml2 < src_mflimit 416 | ? LZ4HC_InsertAndGetWiderMatch_32(ctx, start2 + ml2 - 3, start2, ml2, ref ref3, ref start3) 417 | : ml2; 418 | 419 | if (ml3 == ml2) // No better match : 2 sequences to encode 420 | { 421 | // ip & ref are known; Now for ml 422 | if (start2 < src_p + ml) ml = (start2 - src_p); 423 | // Now, encode 2 sequences 424 | if (LZ4_encodeSequence_32(ctx, ref src_p, ref dst_p, ref src_anchor, ml, src_ref, dst_end) != 0) return 0; 425 | src_p = start2; 426 | if (LZ4_encodeSequence_32(ctx, ref src_p, ref dst_p, ref src_anchor, ml2, ref2, dst_end) != 0) return 0; 427 | continue; 428 | } 429 | 430 | if (start3 < src_p + ml + 3) // Not enough space for match 2 : remove it 431 | { 432 | if (start3 >= (src_p + ml)) // can write Seq1 immediately ==> Seq2 is removed, so Seq3 becomes Seq1 433 | { 434 | if (start2 < src_p + ml) 435 | { 436 | var correction = (src_p + ml - start2); 437 | start2 += correction; 438 | ref2 += correction; 439 | ml2 -= correction; 440 | if (ml2 < MINMATCH) 441 | { 442 | start2 = start3; 443 | ref2 = ref3; 444 | ml2 = ml3; 445 | } 446 | } 447 | 448 | if (LZ4_encodeSequence_32(ctx, ref src_p, ref dst_p, ref src_anchor, ml, src_ref, dst_end) != 0) return 0; 449 | src_p = start3; 450 | src_ref = ref3; 451 | ml = ml3; 452 | 453 | start0 = start2; 454 | ref0 = ref2; 455 | ml0 = ml2; 456 | goto _Search2; 457 | } 458 | 459 | start2 = start3; 460 | ref2 = ref3; 461 | ml2 = ml3; 462 | goto _Search3; 463 | } 464 | 465 | // OK, now we have 3 ascending matches; let's write at least the first one 466 | // ip & ref are known; Now for ml 467 | if (start2 < src_p + ml) 468 | { 469 | if ((start2 - src_p) < ML_MASK) 470 | { 471 | if (ml > OPTIMAL_ML) ml = OPTIMAL_ML; 472 | if (src_p + ml > start2 + ml2 - MINMATCH) ml = (start2 - src_p) + ml2 - MINMATCH; 473 | var correction = ml - (start2 - src_p); 474 | if (correction > 0) 475 | { 476 | start2 += correction; 477 | ref2 += correction; 478 | ml2 -= correction; 479 | } 480 | } 481 | else 482 | { 483 | ml = (start2 - src_p); 484 | } 485 | } 486 | if (LZ4_encodeSequence_32(ctx, ref src_p, ref dst_p, ref src_anchor, ml, src_ref, dst_end) != 0) return 0; 487 | 488 | src_p = start2; 489 | src_ref = ref2; 490 | ml = ml2; 491 | 492 | start2 = start3; 493 | ref2 = ref3; 494 | ml2 = ml3; 495 | 496 | goto _Search3; 497 | } 498 | 499 | // Encode Last Literals 500 | { 501 | var lastRun = (src_end - src_anchor); 502 | if ((dst_p - dst_0) + lastRun + 1 + ((lastRun + 255 - RUN_MASK) / 255) > (uint)dst_len) return 0; // Check output limit 503 | if (lastRun >= RUN_MASK) 504 | { 505 | dst[dst_p++] = (RUN_MASK << ML_BITS); 506 | lastRun -= RUN_MASK; 507 | for (; lastRun > 254; lastRun -= 255) dst[dst_p++] = 255; 508 | dst[dst_p++] = (byte)lastRun; 509 | } 510 | else 511 | { 512 | dst[dst_p++] = (byte)(lastRun << ML_BITS); 513 | } 514 | BlockCopy(src, src_anchor, dst, dst_p, src_end - src_anchor); 515 | dst_p += src_end - src_anchor; 516 | } 517 | 518 | // End 519 | return (dst_p - dst_0); 520 | } 521 | } 522 | } 523 | 524 | // ReSharper restore InconsistentNaming 525 | -------------------------------------------------------------------------------- /LZ4/LZ4Codec.Safe64HC.Dirty.cs: -------------------------------------------------------------------------------- 1 | #region LZ4 original 2 | 3 | /* 4 | LZ4 - Fast LZ compression algorithm 5 | Copyright (C) 2011-2012, Yann Collet. 6 | BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are 10 | met: 11 | 12 | * Redistributions of source code must retain the above copyright 13 | notice, this list of conditions and the following disclaimer. 14 | * Redistributions in binary form must reproduce the above 15 | copyright notice, this list of conditions and the following disclaimer 16 | in the documentation and/or other materials provided with the 17 | distribution. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | You can contact the author at : 32 | - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html 33 | - LZ4 source repository : http://code.google.com/p/lz4/ 34 | */ 35 | 36 | #endregion 37 | 38 | #region LZ4 port 39 | 40 | /* 41 | Copyright (c) 2013, Milosz Krajewski 42 | All rights reserved. 43 | 44 | Redistribution and use in source and binary forms, with or without modification, are permitted provided 45 | that the following conditions are met: 46 | 47 | * Redistributions of source code must retain the above copyright notice, this list of conditions 48 | and the following disclaimer. 49 | 50 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions 51 | and the following disclaimer in the documentation and/or other materials provided with the distribution. 52 | 53 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 54 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 55 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 56 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 57 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 58 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 59 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 60 | IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 61 | */ 62 | 63 | #endregion 64 | 65 | // ReSharper disable InconsistentNaming 66 | 67 | namespace LZ4ps 68 | { 69 | public static partial class LZ4Codec 70 | { 71 | private static void LZ4HC_Insert_64(LZ4HC_Data_Structure ctx, int src_p) 72 | { 73 | var chainTable = ctx.chainTable; 74 | var hashTable = ctx.hashTable; 75 | var src = ctx.src; 76 | var src_base = ctx.src_base; 77 | var nextToUpdate = ctx.nextToUpdate; 78 | 79 | while (nextToUpdate < src_p) 80 | { 81 | var p = nextToUpdate; 82 | var delta = (p) - (hashTable[(((Peek4(src, p)) * 2654435761u) >> HASHHC_ADJUST)] + src_base); 83 | if (delta > MAX_DISTANCE) delta = MAX_DISTANCE; 84 | chainTable[(p) & MAXD_MASK] = (ushort)delta; 85 | hashTable[(((Peek4(src, p)) * 2654435761u) >> HASHHC_ADJUST)] = ((p) - src_base); 86 | nextToUpdate++; 87 | } 88 | 89 | ctx.nextToUpdate = nextToUpdate; 90 | } 91 | 92 | private static int LZ4HC_CommonLength_64(LZ4HC_Data_Structure ctx, int p1, int p2) 93 | { 94 | var debruijn64 = DEBRUIJN_TABLE_64; 95 | var src = ctx.src; 96 | var src_LASTLITERALS = ctx.src_LASTLITERALS; 97 | var p1t = p1; 98 | 99 | while (p1t < src_LASTLITERALS - (STEPSIZE_64 - 1)) 100 | { 101 | var diff = (long)Xor8(src, p2, p1t); 102 | if (diff == 0) 103 | { 104 | p1t += STEPSIZE_64; 105 | p2 += STEPSIZE_64; 106 | continue; 107 | } 108 | p1t += debruijn64[((ulong)((diff) & -(diff)) * 0x0218A392CDABBD3FL) >> 58]; 109 | return (p1t - p1); 110 | } 111 | if ((p1t < (src_LASTLITERALS - 3)) && (Equal4(src, p2, p1t))) 112 | { 113 | p1t += 4; 114 | p2 += 4; 115 | } 116 | if ((p1t < (src_LASTLITERALS - 1)) && (Equal2(src, p2, p1t))) 117 | { 118 | p1t += 2; 119 | p2 += 2; 120 | } 121 | if ((p1t < src_LASTLITERALS) && (src[p2] == src[p1t])) p1t++; 122 | return (p1t - p1); 123 | } 124 | 125 | private static int LZ4HC_InsertAndFindBestMatch_64(LZ4HC_Data_Structure ctx, int src_p, ref int matchpos) 126 | { 127 | var chainTable = ctx.chainTable; 128 | var hashTable = ctx.hashTable; 129 | var src = ctx.src; 130 | var src_base = ctx.src_base; 131 | var nbAttempts = MAX_NB_ATTEMPTS; 132 | int repl = 0, ml = 0; 133 | ushort delta = 0; 134 | 135 | // HC4 match finder 136 | LZ4HC_Insert_64(ctx, src_p); 137 | var src_ref = (hashTable[(((Peek4(src, src_p)) * 2654435761u) >> HASHHC_ADJUST)] + src_base); 138 | 139 | // Detect repetitive sequences of length <= 4 140 | if (src_ref >= src_p - 4) // potential repetition 141 | { 142 | if (Equal4(src, src_ref, src_p)) // confirmed 143 | { 144 | delta = (ushort)(src_p - src_ref); 145 | repl = ml = LZ4HC_CommonLength_64(ctx, src_p + MINMATCH, src_ref + MINMATCH) + MINMATCH; 146 | matchpos = src_ref; 147 | } 148 | src_ref = ((src_ref) - chainTable[(src_ref) & MAXD_MASK]); 149 | } 150 | 151 | 152 | while ((src_ref >= src_p - MAX_DISTANCE) && (nbAttempts != 0)) 153 | { 154 | nbAttempts--; 155 | if (src[src_ref + ml] == src[src_p + ml]) 156 | { 157 | if (Equal4(src, src_ref, src_p)) 158 | { 159 | var mlt = LZ4HC_CommonLength_64(ctx, src_p + MINMATCH, src_ref + MINMATCH) + MINMATCH; 160 | if (mlt > ml) 161 | { 162 | ml = mlt; 163 | matchpos = src_ref; 164 | } 165 | } 166 | } 167 | src_ref = ((src_ref) - chainTable[(src_ref) & MAXD_MASK]); 168 | } 169 | 170 | 171 | // Complete table 172 | if (repl != 0) 173 | { 174 | var ptr = src_p; 175 | 176 | var end = src_p + repl - (MINMATCH - 1); 177 | while (ptr < end - delta) 178 | { 179 | chainTable[(ptr) & MAXD_MASK] = delta; // Pre-Load 180 | ptr++; 181 | } 182 | do 183 | { 184 | chainTable[(ptr) & MAXD_MASK] = delta; 185 | hashTable[(((Peek4(src, ptr)) * 2654435761u) >> HASHHC_ADJUST)] = ((ptr) - src_base); // Head of chain 186 | ptr++; 187 | } while (ptr < end); 188 | ctx.nextToUpdate = end; 189 | } 190 | 191 | return ml; 192 | } 193 | 194 | private static int LZ4HC_InsertAndGetWiderMatch_64(LZ4HC_Data_Structure ctx, int src_p, int startLimit, int longest, ref int matchpos, ref int startpos) 195 | { 196 | var debruijn64 = DEBRUIJN_TABLE_64; 197 | var chainTable = ctx.chainTable; 198 | var hashTable = ctx.hashTable; 199 | var src = ctx.src; 200 | var src_base = ctx.src_base; 201 | var src_LASTLITERALS = ctx.src_LASTLITERALS; 202 | var nbAttempts = MAX_NB_ATTEMPTS; 203 | var delta = (src_p - startLimit); 204 | 205 | // First Match 206 | LZ4HC_Insert_64(ctx, src_p); 207 | var src_ref = (hashTable[(((Peek4(src, src_p)) * 2654435761u) >> HASHHC_ADJUST)] + src_base); 208 | 209 | while ((src_ref >= src_p - MAX_DISTANCE) && (nbAttempts != 0)) 210 | { 211 | nbAttempts--; 212 | if (src[startLimit + longest] == src[src_ref - delta + longest]) 213 | { 214 | if (Equal4(src, src_ref, src_p)) 215 | { 216 | var reft = src_ref + MINMATCH; 217 | var ipt = src_p + MINMATCH; 218 | var startt = src_p; 219 | 220 | while (ipt < src_LASTLITERALS - (STEPSIZE_64 - 1)) 221 | { 222 | var diff = (long)Xor8(src, reft, ipt); 223 | if (diff == 0) 224 | { 225 | ipt += STEPSIZE_64; 226 | reft += STEPSIZE_64; 227 | continue; 228 | } 229 | ipt += debruijn64[((ulong)((diff) & -(diff)) * 0x0218A392CDABBD3FL) >> 58]; 230 | goto _endCount; 231 | } 232 | if ((ipt < (src_LASTLITERALS - 3)) && (Equal4(src, reft, ipt))) 233 | { 234 | ipt += 4; 235 | reft += 4; 236 | } 237 | if ((ipt < (src_LASTLITERALS - 1)) && (Equal2(src, reft, ipt))) 238 | { 239 | ipt += 2; 240 | reft += 2; 241 | } 242 | if ((ipt < src_LASTLITERALS) && (src[reft] == src[ipt])) ipt++; 243 | 244 | _endCount: 245 | reft = src_ref; 246 | 247 | while ((startt > startLimit) && (reft > src_base) && (src[startt - 1] == src[reft - 1])) 248 | { 249 | startt--; 250 | reft--; 251 | } 252 | 253 | if ((ipt - startt) > longest) 254 | { 255 | longest = (ipt - startt); 256 | matchpos = reft; 257 | startpos = startt; 258 | } 259 | } 260 | } 261 | src_ref = ((src_ref) - chainTable[(src_ref) & MAXD_MASK]); 262 | } 263 | 264 | return longest; 265 | } 266 | 267 | private static int LZ4_encodeSequence_64(LZ4HC_Data_Structure ctx, ref int src_p, ref int dst_p, ref int src_anchor, int matchLength, int src_ref) 268 | { 269 | var src = ctx.src; 270 | var dst = ctx.dst; 271 | var dst_end = ctx.dst_end; 272 | int len; 273 | 274 | // Encode Literal length 275 | var length = (src_p - src_anchor); 276 | var dst_token = (dst_p)++; 277 | if ((dst_p + length + (2 + 1 + LASTLITERALS) + (length >> 8)) > dst_end) return 1; // Check output limit 278 | if (length >= RUN_MASK) 279 | { 280 | dst[dst_token] = (RUN_MASK << ML_BITS); 281 | len = length - RUN_MASK; 282 | for (; len > 254; len -= 255) dst[dst_p++] = 255; 283 | dst[dst_p++] = (byte)len; 284 | } 285 | else 286 | { 287 | dst[dst_token] = (byte)(length << ML_BITS); 288 | } 289 | 290 | // Copy Literals 291 | if (length > 0) 292 | { 293 | var _i = dst_p + length; 294 | src_anchor += WildCopy(src, src_anchor, dst, dst_p, _i); 295 | dst_p = _i; 296 | } 297 | 298 | // Encode Offset 299 | Poke2(dst, dst_p, (ushort)(src_p - src_ref)); 300 | dst_p += 2; 301 | 302 | // Encode MatchLength 303 | len = (matchLength - MINMATCH); 304 | if (dst_p + (1 + LASTLITERALS) + (length >> 8) > dst_end) return 1; // Check output limit 305 | if (len >= ML_MASK) 306 | { 307 | dst[dst_token] += ML_MASK; 308 | len -= ML_MASK; 309 | for (; len > 509; len -= 510) 310 | { 311 | dst[dst_p++] = 255; 312 | dst[dst_p++] = 255; 313 | } 314 | if (len > 254) 315 | { 316 | len -= 255; 317 | dst[dst_p++] = 255; 318 | } 319 | dst[dst_p++] = (byte)len; 320 | } 321 | else 322 | { 323 | dst[dst_token] += (byte)len; 324 | } 325 | 326 | // Prepare next loop 327 | src_p += matchLength; 328 | src_anchor = src_p; 329 | 330 | return 0; 331 | } 332 | 333 | private static int LZ4_compressHCCtx_64(LZ4HC_Data_Structure ctx) 334 | { 335 | var src = ctx.src; 336 | var src_p = ctx.src_base; 337 | var src_end = ctx.src_end; 338 | var dst_0 = ctx.dst_base; 339 | var src_anchor = src_p; 340 | var src_mflimit = src_end - MFLIMIT; 341 | var dst = ctx.dst; 342 | var dst_len = ctx.dst_len; 343 | var dst_p = ctx.dst_base; 344 | 345 | var xxx_ref = 0; 346 | var start2 = 0; 347 | var ref2 = 0; 348 | var start3 = 0; 349 | var ref3 = 0; 350 | 351 | src_p++; 352 | 353 | // Main Loop 354 | while (src_p < src_mflimit) 355 | { 356 | var ml = LZ4HC_InsertAndFindBestMatch_64(ctx, src_p, ref xxx_ref); 357 | if (ml == 0) 358 | { 359 | src_p++; 360 | continue; 361 | } 362 | 363 | // saved, in case we would skip too much 364 | var start0 = src_p; 365 | var ref0 = xxx_ref; 366 | var ml0 = ml; 367 | 368 | _Search2: 369 | var ml2 = src_p + ml < src_mflimit 370 | ? LZ4HC_InsertAndGetWiderMatch_64(ctx, src_p + ml - 2, src_p + 1, ml, ref ref2, ref start2) 371 | : ml; 372 | 373 | if (ml2 == ml) // No better match 374 | { 375 | if (LZ4_encodeSequence_64(ctx, ref src_p, ref dst_p, ref src_anchor, ml, xxx_ref) != 0) return 0; 376 | continue; 377 | } 378 | 379 | if (start0 < src_p) 380 | { 381 | if (start2 < src_p + ml0) // empirical 382 | { 383 | src_p = start0; 384 | xxx_ref = ref0; 385 | ml = ml0; 386 | } 387 | } 388 | 389 | // Here, start0==ip 390 | if ((start2 - src_p) < 3) // First Match too small : removed 391 | { 392 | ml = ml2; 393 | src_p = start2; 394 | xxx_ref = ref2; 395 | goto _Search2; 396 | } 397 | 398 | _Search3: 399 | // Currently we have : 400 | // ml2 > ml1, and 401 | // ip1+3 <= ip2 (usually < ip1+ml1) 402 | if ((start2 - src_p) < OPTIMAL_ML) 403 | { 404 | var new_ml = ml; 405 | if (new_ml > OPTIMAL_ML) new_ml = OPTIMAL_ML; 406 | if (src_p + new_ml > start2 + ml2 - MINMATCH) new_ml = (start2 - src_p) + ml2 - MINMATCH; 407 | var correction = new_ml - (start2 - src_p); 408 | if (correction > 0) 409 | { 410 | start2 += correction; 411 | ref2 += correction; 412 | ml2 -= correction; 413 | } 414 | } 415 | // Now, we have start2 = ip+new_ml, with new_ml=min(ml, OPTIMAL_ML=18) 416 | 417 | var ml3 = start2 + ml2 < src_mflimit 418 | ? LZ4HC_InsertAndGetWiderMatch_64(ctx, start2 + ml2 - 3, start2, ml2, ref ref3, ref start3) 419 | : ml2; 420 | 421 | if (ml3 == ml2) // No better match : 2 sequences to encode 422 | { 423 | // ip & ref are known; Now for ml 424 | if (start2 < src_p + ml) ml = (start2 - src_p); 425 | // Now, encode 2 sequences 426 | if (LZ4_encodeSequence_64(ctx, ref src_p, ref dst_p, ref src_anchor, ml, xxx_ref) != 0) return 0; 427 | src_p = start2; 428 | if (LZ4_encodeSequence_64(ctx, ref src_p, ref dst_p, ref src_anchor, ml2, ref2) != 0) return 0; 429 | continue; 430 | } 431 | 432 | if (start3 < src_p + ml + 3) // Not enough space for match 2 : remove it 433 | { 434 | if (start3 >= (src_p + ml)) // can write Seq1 immediately ==> Seq2 is removed, so Seq3 becomes Seq1 435 | { 436 | if (start2 < src_p + ml) 437 | { 438 | var correction = (src_p + ml - start2); 439 | start2 += correction; 440 | ref2 += correction; 441 | ml2 -= correction; 442 | if (ml2 < MINMATCH) 443 | { 444 | start2 = start3; 445 | ref2 = ref3; 446 | ml2 = ml3; 447 | } 448 | } 449 | 450 | if (LZ4_encodeSequence_64(ctx, ref src_p, ref dst_p, ref src_anchor, ml, xxx_ref) != 0) return 0; 451 | src_p = start3; 452 | xxx_ref = ref3; 453 | ml = ml3; 454 | 455 | start0 = start2; 456 | ref0 = ref2; 457 | ml0 = ml2; 458 | goto _Search2; 459 | } 460 | 461 | start2 = start3; 462 | ref2 = ref3; 463 | ml2 = ml3; 464 | goto _Search3; 465 | } 466 | 467 | // OK, now we have 3 ascending matches; let's write at least the first one 468 | // ip & ref are known; Now for ml 469 | if (start2 < src_p + ml) 470 | { 471 | if ((start2 - src_p) < ML_MASK) 472 | { 473 | if (ml > OPTIMAL_ML) ml = OPTIMAL_ML; 474 | if (src_p + ml > start2 + ml2 - MINMATCH) ml = (start2 - src_p) + ml2 - MINMATCH; 475 | var correction = ml - (start2 - src_p); 476 | if (correction > 0) 477 | { 478 | start2 += correction; 479 | ref2 += correction; 480 | ml2 -= correction; 481 | } 482 | } 483 | else 484 | { 485 | ml = (start2 - src_p); 486 | } 487 | } 488 | if (LZ4_encodeSequence_64(ctx, ref src_p, ref dst_p, ref src_anchor, ml, xxx_ref) != 0) return 0; 489 | 490 | src_p = start2; 491 | xxx_ref = ref2; 492 | ml = ml2; 493 | 494 | start2 = start3; 495 | ref2 = ref3; 496 | ml2 = ml3; 497 | 498 | goto _Search3; 499 | } 500 | 501 | // Encode Last Literals 502 | { 503 | var lastRun = (src_end - src_anchor); 504 | if ((dst_p - dst_0) + lastRun + 1 + ((lastRun + 255 - RUN_MASK) / 255) > (uint)dst_len) return 0; // Check output limit 505 | if (lastRun >= RUN_MASK) 506 | { 507 | dst[dst_p++] = (RUN_MASK << ML_BITS); 508 | lastRun -= RUN_MASK; 509 | for (; lastRun > 254; lastRun -= 255) dst[dst_p++] = 255; 510 | dst[dst_p++] = (byte)lastRun; 511 | } 512 | else 513 | { 514 | dst[dst_p++] = (byte)(lastRun << ML_BITS); 515 | } 516 | BlockCopy(src, src_anchor, dst, dst_p, src_end - src_anchor); 517 | dst_p += src_end - src_anchor; 518 | } 519 | 520 | // End 521 | return (dst_p - dst_0); 522 | } 523 | } 524 | } 525 | 526 | // ReSharper restore InconsistentNaming 527 | -------------------------------------------------------------------------------- /LZ4/LZ4Codec.cs: -------------------------------------------------------------------------------- 1 | #region license 2 | 3 | /* 4 | Copyright (c) 2013, Milosz Krajewski 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without modification, are permitted provided 8 | that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright notice, this list of conditions 11 | and the following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions 14 | and the following disclaimer in the documentation and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 17 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 19 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 20 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 23 | IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | */ 25 | 26 | #endregion 27 | 28 | using System; 29 | 30 | /* 31 | NOTE: 32 | This file is shared between LZ4pn and LZ4ps. 33 | If you would like to modify this file please keep in mind that your changes will 34 | affect both projects. 35 | Use 'UNSAFE' conditional define to differentiate 36 | */ 37 | 38 | // ReSharper disable InconsistentNaming 39 | 40 | #if UNSAFE 41 | namespace LZ4pn 42 | #else 43 | namespace LZ4ps 44 | #endif 45 | { 46 | public static partial class LZ4Codec 47 | { 48 | #region configuration 49 | 50 | /// 51 | /// Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.) 52 | /// Increasing memory usage improves compression ratio 53 | /// Reduced memory usage can improve speed, due to cache effect 54 | /// Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache 55 | /// 56 | private const int MEMORY_USAGE = 14; 57 | 58 | /// 59 | /// Decreasing this value will make the algorithm skip faster data segments considered "incompressible" 60 | /// This may decrease compression ratio dramatically, but will be faster on incompressible data 61 | /// Increasing this value will make the algorithm search more before declaring a segment "incompressible" 62 | /// This could improve compression a bit, but will be slower on incompressible data 63 | /// The default value (6) is recommended 64 | /// 65 | private const int NOTCOMPRESSIBLE_DETECTIONLEVEL = 6; 66 | 67 | #if !UNSAFE 68 | 69 | /// Buffer length when Buffer.BlockCopy becomes faster than straight loop. 70 | /// Please note that safe implementation REQUIRES it to be greater (not even equal) than 8. 71 | private const int BLOCK_COPY_LIMIT = 16; 72 | 73 | #endif 74 | 75 | #endregion 76 | 77 | #region consts 78 | 79 | private const int MINMATCH = 4; 80 | #pragma warning disable 162 81 | // ReSharper disable once UnreachableCode 82 | private const int SKIPSTRENGTH = 83 | NOTCOMPRESSIBLE_DETECTIONLEVEL > 2 84 | ? NOTCOMPRESSIBLE_DETECTIONLEVEL 85 | : 2; 86 | #pragma warning restore 162 87 | private const int COPYLENGTH = 8; 88 | private const int LASTLITERALS = 5; 89 | private const int MFLIMIT = COPYLENGTH + MINMATCH; 90 | private const int MINLENGTH = MFLIMIT + 1; 91 | private const int MAXD_LOG = 16; 92 | private const int MAXD = 1 << MAXD_LOG; 93 | private const int MAXD_MASK = MAXD - 1; 94 | private const int MAX_DISTANCE = (1 << MAXD_LOG) - 1; 95 | private const int ML_BITS = 4; 96 | private const int ML_MASK = (1 << ML_BITS) - 1; 97 | private const int RUN_BITS = 8 - ML_BITS; 98 | private const int RUN_MASK = (1 << RUN_BITS) - 1; 99 | private const int STEPSIZE_64 = 8; 100 | private const int STEPSIZE_32 = 4; 101 | 102 | private const int LZ4_64KLIMIT = (1 << 16) + (MFLIMIT - 1); 103 | 104 | private const int HASH_LOG = MEMORY_USAGE - 2; 105 | private const int HASH_TABLESIZE = 1 << HASH_LOG; 106 | private const int HASH_ADJUST = (MINMATCH * 8) - HASH_LOG; 107 | 108 | private const int HASH64K_LOG = HASH_LOG + 1; 109 | private const int HASH64K_TABLESIZE = 1 << HASH64K_LOG; 110 | private const int HASH64K_ADJUST = (MINMATCH * 8) - HASH64K_LOG; 111 | 112 | private const int HASHHC_LOG = MAXD_LOG - 1; 113 | private const int HASHHC_TABLESIZE = 1 << HASHHC_LOG; 114 | private const int HASHHC_ADJUST = (MINMATCH * 8) - HASHHC_LOG; 115 | //private const int HASHHC_MASK = HASHHC_TABLESIZE - 1; 116 | 117 | private static readonly int[] DECODER_TABLE_32 = { 0, 3, 2, 3, 0, 0, 0, 0 }; 118 | private static readonly int[] DECODER_TABLE_64 = { 0, 0, 0, -1, 0, 1, 2, 3 }; 119 | 120 | private static readonly int[] DEBRUIJN_TABLE_32 = { 121 | 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 122 | 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 123 | }; 124 | 125 | private static readonly int[] DEBRUIJN_TABLE_64 = { 126 | 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 127 | 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 128 | 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 129 | 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 130 | }; 131 | 132 | private const int MAX_NB_ATTEMPTS = 256; 133 | private const int OPTIMAL_ML = (ML_MASK - 1) + MINMATCH; 134 | 135 | #endregion 136 | 137 | #region public interface (common) 138 | 139 | /// Gets maximum the length of the output. 140 | /// Length of the input. 141 | /// Maximum number of bytes needed for compressed buffer. 142 | public static int MaximumOutputLength(int inputLength) 143 | { 144 | return inputLength + (inputLength / 255) + 16; 145 | } 146 | 147 | #endregion 148 | 149 | #region internal interface (common) 150 | 151 | internal static void CheckArguments( 152 | byte[] input, int inputOffset, ref int inputLength, 153 | byte[] output, int outputOffset, ref int outputLength) 154 | { 155 | if (inputLength < 0) inputLength = input.Length - inputOffset; 156 | if (inputLength == 0) 157 | { 158 | outputLength = 0; 159 | return; 160 | } 161 | 162 | if (input == null) throw new ArgumentNullException("input"); 163 | if (inputOffset < 0 || inputOffset + inputLength > input.Length) 164 | throw new ArgumentException("inputOffset and inputLength are invalid for given input"); 165 | 166 | if (outputLength < 0) outputLength = output.Length - outputOffset; 167 | if (output == null) throw new ArgumentNullException("output"); 168 | if (outputOffset < 0 || outputOffset + outputLength > output.Length) 169 | throw new ArgumentException("outputOffset and outputLength are invalid for given output"); 170 | } 171 | 172 | #endregion 173 | } 174 | } 175 | 176 | // ReSharper restore InconsistentNaming -------------------------------------------------------------------------------- /LZ4CodecPartial.cs: -------------------------------------------------------------------------------- 1 | #region license 2 | 3 | /* 4 | Copyright (c) 2013-2017, Milosz Krajewski 5 | All rights reserved. 6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided 7 | that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright notice, this list of conditions 9 | and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions 11 | and the following disclaimer in the documentation and/or other materials provided with the distribution. 12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 13 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 14 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 15 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 16 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 18 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 19 | IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 20 | */ 21 | 22 | #endregion 23 | 24 | using System; 25 | using System.Runtime.CompilerServices; 26 | using LZ4.Services; 27 | using Microsoft.Win32; 28 | 29 | namespace LZ4 30 | { 31 | public static partial class LZ4Codec 32 | { 33 | /// Determines whether VS2015 runtime is installed. 34 | /// Note, on Mono the Registry class is not available at all, 35 | /// so access to it have to be isolated. 36 | /// true it VS2010 runtime is installed, false otherwise. 37 | [MethodImpl(MethodImplOptions.NoInlining)] 38 | private static bool Has2015Runtime() 39 | { 40 | var keyName = 41 | IntPtr.Size == 4 ? @"SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x86" : 42 | IntPtr.Size == 8 ? @"SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64" : 43 | null; 44 | if (keyName == null) 45 | return false; 46 | 47 | var key = Registry.LocalMachine.OpenSubKey(keyName, false); 48 | if (key == null) 49 | return false; 50 | 51 | var value = key.GetValue(@"Major"); 52 | if (value == null) 53 | return false; 54 | 55 | return Convert.ToUInt32(value) == 14; 56 | } 57 | 58 | // ReSharper disable InconsistentNaming 59 | 60 | /// Initializes codecs from LZ4mm. 61 | [MethodImpl(MethodImplOptions.NoInlining)] 62 | private static void InitializeLZ4mm() 63 | { 64 | _service_MM32 = null; 65 | _service_MM64 = null; 66 | } 67 | 68 | /// Initializes codecs from LZ4cc. 69 | [MethodImpl(MethodImplOptions.NoInlining)] 70 | private static void InitializeLZ4cc() 71 | { 72 | _service_CC32 = null; 73 | _service_CC64 = null; 74 | } 75 | 76 | /// Initializes codecs from LZ4n. 77 | [MethodImpl(MethodImplOptions.NoInlining)] 78 | private static void InitializeLZ4n() 79 | { 80 | _service_N32 = null; 81 | _service_N64 = null; 82 | } 83 | 84 | /// Initializes codecs from LZ4s. 85 | [MethodImpl(MethodImplOptions.NoInlining)] 86 | private static void InitializeLZ4s() 87 | { 88 | _service_S32 = TryService(); 89 | _service_S64 = TryService(); 90 | } 91 | 92 | // ReSharper restore InconsistentNaming 93 | } 94 | } -------------------------------------------------------------------------------- /LzBinTree.cs: -------------------------------------------------------------------------------- 1 | // LzBinTree.cs 2 | 3 | using System; 4 | 5 | namespace SevenZip.Compression.LZ 6 | { 7 | public class BinTree : InWindow, IMatchFinder 8 | { 9 | UInt32 _cyclicBufferPos; 10 | UInt32 _cyclicBufferSize = 0; 11 | UInt32 _matchMaxLen; 12 | 13 | UInt32[] _son; 14 | UInt32[] _hash; 15 | 16 | UInt32 _cutValue = 0xFF; 17 | UInt32 _hashMask; 18 | UInt32 _hashSizeSum = 0; 19 | 20 | bool HASH_ARRAY = true; 21 | 22 | const UInt32 kHash2Size = 1 << 10; 23 | const UInt32 kHash3Size = 1 << 16; 24 | const UInt32 kBT2HashSize = 1 << 16; 25 | const UInt32 kStartMaxLen = 1; 26 | const UInt32 kHash3Offset = kHash2Size; 27 | const UInt32 kEmptyHashValue = 0; 28 | const UInt32 kMaxValForNormalize = ((UInt32)1 << 31) - 1; 29 | 30 | UInt32 kNumHashDirectBytes = 0; 31 | UInt32 kMinMatchCheck = 4; 32 | UInt32 kFixHashSize = kHash2Size + kHash3Size; 33 | 34 | public void SetType(int numHashBytes) 35 | { 36 | HASH_ARRAY = (numHashBytes > 2); 37 | if (HASH_ARRAY) 38 | { 39 | kNumHashDirectBytes = 0; 40 | kMinMatchCheck = 4; 41 | kFixHashSize = kHash2Size + kHash3Size; 42 | } 43 | else 44 | { 45 | kNumHashDirectBytes = 2; 46 | kMinMatchCheck = 2 + 1; 47 | kFixHashSize = 0; 48 | } 49 | } 50 | 51 | public new void SetStream(System.IO.Stream stream) { base.SetStream(stream); } 52 | public new void ReleaseStream() { base.ReleaseStream(); } 53 | 54 | public new void Init() 55 | { 56 | base.Init(); 57 | for (UInt32 i = 0; i < _hashSizeSum; i++) 58 | _hash[i] = kEmptyHashValue; 59 | _cyclicBufferPos = 0; 60 | ReduceOffsets(-1); 61 | } 62 | 63 | public new void MovePos() 64 | { 65 | if (++_cyclicBufferPos >= _cyclicBufferSize) 66 | _cyclicBufferPos = 0; 67 | base.MovePos(); 68 | if (_pos == kMaxValForNormalize) 69 | Normalize(); 70 | } 71 | 72 | public new Byte GetIndexByte(Int32 index) { return base.GetIndexByte(index); } 73 | 74 | public new UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit) 75 | { return base.GetMatchLen(index, distance, limit); } 76 | 77 | public new UInt32 GetNumAvailableBytes() { return base.GetNumAvailableBytes(); } 78 | 79 | public void Create(UInt32 historySize, UInt32 keepAddBufferBefore, 80 | UInt32 matchMaxLen, UInt32 keepAddBufferAfter) 81 | { 82 | if (historySize > kMaxValForNormalize - 256) 83 | throw new Exception(); 84 | _cutValue = 16 + (matchMaxLen >> 1); 85 | 86 | UInt32 windowReservSize = (historySize + keepAddBufferBefore + 87 | matchMaxLen + keepAddBufferAfter) / 2 + 256; 88 | 89 | base.Create(historySize + keepAddBufferBefore, matchMaxLen + keepAddBufferAfter, windowReservSize); 90 | 91 | _matchMaxLen = matchMaxLen; 92 | 93 | UInt32 cyclicBufferSize = historySize + 1; 94 | if (_cyclicBufferSize != cyclicBufferSize) 95 | _son = new UInt32[(_cyclicBufferSize = cyclicBufferSize) * 2]; 96 | 97 | UInt32 hs = kBT2HashSize; 98 | 99 | if (HASH_ARRAY) 100 | { 101 | hs = historySize - 1; 102 | hs |= (hs >> 1); 103 | hs |= (hs >> 2); 104 | hs |= (hs >> 4); 105 | hs |= (hs >> 8); 106 | hs >>= 1; 107 | hs |= 0xFFFF; 108 | if (hs > (1 << 24)) 109 | hs >>= 1; 110 | _hashMask = hs; 111 | hs++; 112 | hs += kFixHashSize; 113 | } 114 | if (hs != _hashSizeSum) 115 | _hash = new UInt32[_hashSizeSum = hs]; 116 | } 117 | 118 | public UInt32 GetMatches(UInt32[] distances) 119 | { 120 | UInt32 lenLimit; 121 | if (_pos + _matchMaxLen <= _streamPos) 122 | lenLimit = _matchMaxLen; 123 | else 124 | { 125 | lenLimit = _streamPos - _pos; 126 | if (lenLimit < kMinMatchCheck) 127 | { 128 | MovePos(); 129 | return 0; 130 | } 131 | } 132 | 133 | UInt32 offset = 0; 134 | UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0; 135 | UInt32 cur = _bufferOffset + _pos; 136 | UInt32 maxLen = kStartMaxLen; // to avoid items for len < hashSize; 137 | UInt32 hashValue, hash2Value = 0, hash3Value = 0; 138 | 139 | if (HASH_ARRAY) 140 | { 141 | UInt32 temp = CRC.Table[_bufferBase[cur]] ^ _bufferBase[cur + 1]; 142 | hash2Value = temp & (kHash2Size - 1); 143 | temp ^= ((UInt32)(_bufferBase[cur + 2]) << 8); 144 | hash3Value = temp & (kHash3Size - 1); 145 | hashValue = (temp ^ (CRC.Table[_bufferBase[cur + 3]] << 5)) & _hashMask; 146 | } 147 | else 148 | hashValue = _bufferBase[cur] ^ ((UInt32)(_bufferBase[cur + 1]) << 8); 149 | 150 | UInt32 curMatch = _hash[kFixHashSize + hashValue]; 151 | if (HASH_ARRAY) 152 | { 153 | UInt32 curMatch2 = _hash[hash2Value]; 154 | UInt32 curMatch3 = _hash[kHash3Offset + hash3Value]; 155 | _hash[hash2Value] = _pos; 156 | _hash[kHash3Offset + hash3Value] = _pos; 157 | if (curMatch2 > matchMinPos) 158 | if (_bufferBase[_bufferOffset + curMatch2] == _bufferBase[cur]) 159 | { 160 | distances[offset++] = maxLen = 2; 161 | distances[offset++] = _pos - curMatch2 - 1; 162 | } 163 | if (curMatch3 > matchMinPos) 164 | if (_bufferBase[_bufferOffset + curMatch3] == _bufferBase[cur]) 165 | { 166 | if (curMatch3 == curMatch2) 167 | offset -= 2; 168 | distances[offset++] = maxLen = 3; 169 | distances[offset++] = _pos - curMatch3 - 1; 170 | curMatch2 = curMatch3; 171 | } 172 | if (offset != 0 && curMatch2 == curMatch) 173 | { 174 | offset -= 2; 175 | maxLen = kStartMaxLen; 176 | } 177 | } 178 | 179 | _hash[kFixHashSize + hashValue] = _pos; 180 | 181 | UInt32 ptr0 = (_cyclicBufferPos << 1) + 1; 182 | UInt32 ptr1 = (_cyclicBufferPos << 1); 183 | 184 | UInt32 len0, len1; 185 | len0 = len1 = kNumHashDirectBytes; 186 | 187 | if (kNumHashDirectBytes != 0) 188 | { 189 | if (curMatch > matchMinPos) 190 | { 191 | if (_bufferBase[_bufferOffset + curMatch + kNumHashDirectBytes] != 192 | _bufferBase[cur + kNumHashDirectBytes]) 193 | { 194 | distances[offset++] = maxLen = kNumHashDirectBytes; 195 | distances[offset++] = _pos - curMatch - 1; 196 | } 197 | } 198 | } 199 | 200 | UInt32 count = _cutValue; 201 | 202 | while(true) 203 | { 204 | if(curMatch <= matchMinPos || count-- == 0) 205 | { 206 | _son[ptr0] = _son[ptr1] = kEmptyHashValue; 207 | break; 208 | } 209 | UInt32 delta = _pos - curMatch; 210 | UInt32 cyclicPos = ((delta <= _cyclicBufferPos) ? 211 | (_cyclicBufferPos - delta) : 212 | (_cyclicBufferPos - delta + _cyclicBufferSize)) << 1; 213 | 214 | UInt32 pby1 = _bufferOffset + curMatch; 215 | UInt32 len = Math.Min(len0, len1); 216 | if (_bufferBase[pby1 + len] == _bufferBase[cur + len]) 217 | { 218 | while(++len != lenLimit) 219 | if (_bufferBase[pby1 + len] != _bufferBase[cur + len]) 220 | break; 221 | if (maxLen < len) 222 | { 223 | distances[offset++] = maxLen = len; 224 | distances[offset++] = delta - 1; 225 | if (len == lenLimit) 226 | { 227 | _son[ptr1] = _son[cyclicPos]; 228 | _son[ptr0] = _son[cyclicPos + 1]; 229 | break; 230 | } 231 | } 232 | } 233 | if (_bufferBase[pby1 + len] < _bufferBase[cur + len]) 234 | { 235 | _son[ptr1] = curMatch; 236 | ptr1 = cyclicPos + 1; 237 | curMatch = _son[ptr1]; 238 | len1 = len; 239 | } 240 | else 241 | { 242 | _son[ptr0] = curMatch; 243 | ptr0 = cyclicPos; 244 | curMatch = _son[ptr0]; 245 | len0 = len; 246 | } 247 | } 248 | MovePos(); 249 | return offset; 250 | } 251 | 252 | public void Skip(UInt32 num) 253 | { 254 | do 255 | { 256 | UInt32 lenLimit; 257 | if (_pos + _matchMaxLen <= _streamPos) 258 | lenLimit = _matchMaxLen; 259 | else 260 | { 261 | lenLimit = _streamPos - _pos; 262 | if (lenLimit < kMinMatchCheck) 263 | { 264 | MovePos(); 265 | continue; 266 | } 267 | } 268 | 269 | UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0; 270 | UInt32 cur = _bufferOffset + _pos; 271 | 272 | UInt32 hashValue; 273 | 274 | if (HASH_ARRAY) 275 | { 276 | UInt32 temp = CRC.Table[_bufferBase[cur]] ^ _bufferBase[cur + 1]; 277 | UInt32 hash2Value = temp & (kHash2Size - 1); 278 | _hash[hash2Value] = _pos; 279 | temp ^= ((UInt32)(_bufferBase[cur + 2]) << 8); 280 | UInt32 hash3Value = temp & (kHash3Size - 1); 281 | _hash[kHash3Offset + hash3Value] = _pos; 282 | hashValue = (temp ^ (CRC.Table[_bufferBase[cur + 3]] << 5)) & _hashMask; 283 | } 284 | else 285 | hashValue = _bufferBase[cur] ^ ((UInt32)(_bufferBase[cur + 1]) << 8); 286 | 287 | UInt32 curMatch = _hash[kFixHashSize + hashValue]; 288 | _hash[kFixHashSize + hashValue] = _pos; 289 | 290 | UInt32 ptr0 = (_cyclicBufferPos << 1) + 1; 291 | UInt32 ptr1 = (_cyclicBufferPos << 1); 292 | 293 | UInt32 len0, len1; 294 | len0 = len1 = kNumHashDirectBytes; 295 | 296 | UInt32 count = _cutValue; 297 | while (true) 298 | { 299 | if (curMatch <= matchMinPos || count-- == 0) 300 | { 301 | _son[ptr0] = _son[ptr1] = kEmptyHashValue; 302 | break; 303 | } 304 | 305 | UInt32 delta = _pos - curMatch; 306 | UInt32 cyclicPos = ((delta <= _cyclicBufferPos) ? 307 | (_cyclicBufferPos - delta) : 308 | (_cyclicBufferPos - delta + _cyclicBufferSize)) << 1; 309 | 310 | UInt32 pby1 = _bufferOffset + curMatch; 311 | UInt32 len = Math.Min(len0, len1); 312 | if (_bufferBase[pby1 + len] == _bufferBase[cur + len]) 313 | { 314 | while (++len != lenLimit) 315 | if (_bufferBase[pby1 + len] != _bufferBase[cur + len]) 316 | break; 317 | if (len == lenLimit) 318 | { 319 | _son[ptr1] = _son[cyclicPos]; 320 | _son[ptr0] = _son[cyclicPos + 1]; 321 | break; 322 | } 323 | } 324 | if (_bufferBase[pby1 + len] < _bufferBase[cur + len]) 325 | { 326 | _son[ptr1] = curMatch; 327 | ptr1 = cyclicPos + 1; 328 | curMatch = _son[ptr1]; 329 | len1 = len; 330 | } 331 | else 332 | { 333 | _son[ptr0] = curMatch; 334 | ptr0 = cyclicPos; 335 | curMatch = _son[ptr0]; 336 | len0 = len; 337 | } 338 | } 339 | MovePos(); 340 | } 341 | while (--num != 0); 342 | } 343 | 344 | void NormalizeLinks(UInt32[] items, UInt32 numItems, UInt32 subValue) 345 | { 346 | for (UInt32 i = 0; i < numItems; i++) 347 | { 348 | UInt32 value = items[i]; 349 | if (value <= subValue) 350 | value = kEmptyHashValue; 351 | else 352 | value -= subValue; 353 | items[i] = value; 354 | } 355 | } 356 | 357 | void Normalize() 358 | { 359 | UInt32 subValue = _pos - _cyclicBufferSize; 360 | NormalizeLinks(_son, _cyclicBufferSize * 2, subValue); 361 | NormalizeLinks(_hash, _hashSizeSum, subValue); 362 | ReduceOffsets((Int32)subValue); 363 | } 364 | 365 | public void SetCutValue(UInt32 cutValue) { _cutValue = cutValue; } 366 | } 367 | } 368 | -------------------------------------------------------------------------------- /LzInWindow.cs: -------------------------------------------------------------------------------- 1 | // LzInWindow.cs 2 | 3 | using System; 4 | 5 | namespace SevenZip.Compression.LZ 6 | { 7 | public class InWindow 8 | { 9 | public Byte[] _bufferBase = null; // pointer to buffer with data 10 | System.IO.Stream _stream; 11 | UInt32 _posLimit; // offset (from _buffer) of first byte when new block reading must be done 12 | bool _streamEndWasReached; // if (true) then _streamPos shows real end of stream 13 | 14 | UInt32 _pointerToLastSafePosition; 15 | 16 | public UInt32 _bufferOffset; 17 | 18 | public UInt32 _blockSize; // Size of Allocated memory block 19 | public UInt32 _pos; // offset (from _buffer) of curent byte 20 | UInt32 _keepSizeBefore; // how many BYTEs must be kept in buffer before _pos 21 | UInt32 _keepSizeAfter; // how many BYTEs must be kept buffer after _pos 22 | public UInt32 _streamPos; // offset (from _buffer) of first not read byte from Stream 23 | 24 | public void MoveBlock() 25 | { 26 | UInt32 offset = (UInt32)(_bufferOffset) + _pos - _keepSizeBefore; 27 | // we need one additional byte, since MovePos moves on 1 byte. 28 | if (offset > 0) 29 | offset--; 30 | 31 | UInt32 numBytes = (UInt32)(_bufferOffset) + _streamPos - offset; 32 | 33 | // check negative offset ???? 34 | for (UInt32 i = 0; i < numBytes; i++) 35 | _bufferBase[i] = _bufferBase[offset + i]; 36 | _bufferOffset -= offset; 37 | } 38 | 39 | public virtual void ReadBlock() 40 | { 41 | if (_streamEndWasReached) 42 | return; 43 | while (true) 44 | { 45 | int size = (int)((0 - _bufferOffset) + _blockSize - _streamPos); 46 | if (size == 0) 47 | return; 48 | int numReadBytes = _stream.Read(_bufferBase, (int)(_bufferOffset + _streamPos), size); 49 | if (numReadBytes == 0) 50 | { 51 | _posLimit = _streamPos; 52 | UInt32 pointerToPostion = _bufferOffset + _posLimit; 53 | if (pointerToPostion > _pointerToLastSafePosition) 54 | _posLimit = (UInt32)(_pointerToLastSafePosition - _bufferOffset); 55 | 56 | _streamEndWasReached = true; 57 | return; 58 | } 59 | _streamPos += (UInt32)numReadBytes; 60 | if (_streamPos >= _pos + _keepSizeAfter) 61 | _posLimit = _streamPos - _keepSizeAfter; 62 | } 63 | } 64 | 65 | void Free() { _bufferBase = null; } 66 | 67 | public void Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, UInt32 keepSizeReserv) 68 | { 69 | _keepSizeBefore = keepSizeBefore; 70 | _keepSizeAfter = keepSizeAfter; 71 | UInt32 blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv; 72 | if (_bufferBase == null || _blockSize != blockSize) 73 | { 74 | Free(); 75 | _blockSize = blockSize; 76 | _bufferBase = new Byte[_blockSize]; 77 | } 78 | _pointerToLastSafePosition = _blockSize - keepSizeAfter; 79 | } 80 | 81 | public void SetStream(System.IO.Stream stream) { _stream = stream; } 82 | public void ReleaseStream() { _stream = null; } 83 | 84 | public void Init() 85 | { 86 | _bufferOffset = 0; 87 | _pos = 0; 88 | _streamPos = 0; 89 | _streamEndWasReached = false; 90 | ReadBlock(); 91 | } 92 | 93 | public void MovePos() 94 | { 95 | _pos++; 96 | if (_pos > _posLimit) 97 | { 98 | UInt32 pointerToPostion = _bufferOffset + _pos; 99 | if (pointerToPostion > _pointerToLastSafePosition) 100 | MoveBlock(); 101 | ReadBlock(); 102 | } 103 | } 104 | 105 | public Byte GetIndexByte(Int32 index) { return _bufferBase[_bufferOffset + _pos + index]; } 106 | 107 | // index + limit have not to exceed _keepSizeAfter; 108 | public UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit) 109 | { 110 | if (_streamEndWasReached) 111 | if ((_pos + index) + limit > _streamPos) 112 | limit = _streamPos - (UInt32)(_pos + index); 113 | distance++; 114 | // Byte *pby = _buffer + (size_t)_pos + index; 115 | UInt32 pby = _bufferOffset + _pos + (UInt32)index; 116 | 117 | UInt32 i; 118 | for (i = 0; i < limit && _bufferBase[pby + i] == _bufferBase[pby + i - distance]; i++); 119 | return i; 120 | } 121 | 122 | public UInt32 GetNumAvailableBytes() { return _streamPos - _pos; } 123 | 124 | public void ReduceOffsets(Int32 subValue) 125 | { 126 | _bufferOffset += (UInt32)subValue; 127 | _posLimit -= (UInt32)subValue; 128 | _pos -= (UInt32)subValue; 129 | _streamPos -= (UInt32)subValue; 130 | } 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /LzOutWindow.cs: -------------------------------------------------------------------------------- 1 | // LzOutWindow.cs 2 | 3 | namespace SevenZip.Compression.LZ 4 | { 5 | public class OutWindow 6 | { 7 | byte[] _buffer = null; 8 | uint _pos; 9 | uint _windowSize = 0; 10 | uint _streamPos; 11 | System.IO.Stream _stream; 12 | 13 | public uint TrainSize = 0; 14 | 15 | public void Create(uint windowSize) 16 | { 17 | if (_windowSize != windowSize) 18 | { 19 | // System.GC.Collect(); 20 | _buffer = new byte[windowSize]; 21 | } 22 | _windowSize = windowSize; 23 | _pos = 0; 24 | _streamPos = 0; 25 | } 26 | 27 | public void Init(System.IO.Stream stream, bool solid) 28 | { 29 | ReleaseStream(); 30 | _stream = stream; 31 | if (!solid) 32 | { 33 | _streamPos = 0; 34 | _pos = 0; 35 | TrainSize = 0; 36 | } 37 | } 38 | 39 | public bool Train(System.IO.Stream stream) 40 | { 41 | long len = stream.Length; 42 | uint size = (len < _windowSize) ? (uint)len : _windowSize; 43 | TrainSize = size; 44 | stream.Position = len - size; 45 | _streamPos = _pos = 0; 46 | while (size > 0) 47 | { 48 | uint curSize = _windowSize - _pos; 49 | if (size < curSize) 50 | curSize = size; 51 | int numReadBytes = stream.Read(_buffer, (int)_pos, (int)curSize); 52 | if (numReadBytes == 0) 53 | return false; 54 | size -= (uint)numReadBytes; 55 | _pos += (uint)numReadBytes; 56 | _streamPos += (uint)numReadBytes; 57 | if (_pos == _windowSize) 58 | _streamPos = _pos = 0; 59 | } 60 | return true; 61 | } 62 | 63 | public void ReleaseStream() 64 | { 65 | Flush(); 66 | _stream = null; 67 | } 68 | 69 | public void Flush() 70 | { 71 | uint size = _pos - _streamPos; 72 | if (size == 0) 73 | return; 74 | _stream.Write(_buffer, (int)_streamPos, (int)size); 75 | if (_pos >= _windowSize) 76 | _pos = 0; 77 | _streamPos = _pos; 78 | } 79 | 80 | public void CopyBlock(uint distance, uint len) 81 | { 82 | uint pos = _pos - distance - 1; 83 | if (pos >= _windowSize) 84 | pos += _windowSize; 85 | for (; len > 0; len--) 86 | { 87 | if (pos >= _windowSize) 88 | pos = 0; 89 | _buffer[_pos++] = _buffer[pos++]; 90 | if (_pos >= _windowSize) 91 | Flush(); 92 | } 93 | } 94 | 95 | public void PutByte(byte b) 96 | { 97 | _buffer[_pos++] = b; 98 | if (_pos >= _windowSize) 99 | Flush(); 100 | } 101 | 102 | public byte GetByte(uint distance) 103 | { 104 | uint pos = _pos - distance - 1; 105 | if (pos >= _windowSize) 106 | pos += _windowSize; 107 | return _buffer[pos]; 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /LzmaBase.cs: -------------------------------------------------------------------------------- 1 | // LzmaBase.cs 2 | 3 | namespace SevenZip.Compression.LZMA 4 | { 5 | internal abstract class Base 6 | { 7 | public const uint kNumRepDistances = 4; 8 | public const uint kNumStates = 12; 9 | 10 | // static byte []kLiteralNextStates = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5}; 11 | // static byte []kMatchNextStates = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10}; 12 | // static byte []kRepNextStates = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11}; 13 | // static byte []kShortRepNextStates = {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11}; 14 | 15 | public struct State 16 | { 17 | public uint Index; 18 | public void Init() { Index = 0; } 19 | public void UpdateChar() 20 | { 21 | if (Index < 4) Index = 0; 22 | else if (Index < 10) Index -= 3; 23 | else Index -= 6; 24 | } 25 | public void UpdateMatch() { Index = (uint)(Index < 7 ? 7 : 10); } 26 | public void UpdateRep() { Index = (uint)(Index < 7 ? 8 : 11); } 27 | public void UpdateShortRep() { Index = (uint)(Index < 7 ? 9 : 11); } 28 | public bool IsCharState() { return Index < 7; } 29 | } 30 | 31 | public const int kNumPosSlotBits = 6; 32 | public const int kDicLogSizeMin = 0; 33 | // public const int kDicLogSizeMax = 30; 34 | // public const uint kDistTableSizeMax = kDicLogSizeMax * 2; 35 | 36 | public const int kNumLenToPosStatesBits = 2; // it's for speed optimization 37 | public const uint kNumLenToPosStates = 1 << kNumLenToPosStatesBits; 38 | 39 | public const uint kMatchMinLen = 2; 40 | 41 | public static uint GetLenToPosState(uint len) 42 | { 43 | len -= kMatchMinLen; 44 | if (len < kNumLenToPosStates) 45 | return len; 46 | return (uint)(kNumLenToPosStates - 1); 47 | } 48 | 49 | public const int kNumAlignBits = 4; 50 | public const uint kAlignTableSize = 1 << kNumAlignBits; 51 | public const uint kAlignMask = (kAlignTableSize - 1); 52 | 53 | public const uint kStartPosModelIndex = 4; 54 | public const uint kEndPosModelIndex = 14; 55 | public const uint kNumPosModels = kEndPosModelIndex - kStartPosModelIndex; 56 | 57 | public const uint kNumFullDistances = 1 << ((int)kEndPosModelIndex / 2); 58 | 59 | public const uint kNumLitPosStatesBitsEncodingMax = 4; 60 | public const uint kNumLitContextBitsMax = 8; 61 | 62 | public const int kNumPosStatesBitsMax = 4; 63 | public const uint kNumPosStatesMax = (1 << kNumPosStatesBitsMax); 64 | public const int kNumPosStatesBitsEncodingMax = 4; 65 | public const uint kNumPosStatesEncodingMax = (1 << kNumPosStatesBitsEncodingMax); 66 | 67 | public const int kNumLowLenBits = 3; 68 | public const int kNumMidLenBits = 3; 69 | public const int kNumHighLenBits = 8; 70 | public const uint kNumLowLenSymbols = 1 << kNumLowLenBits; 71 | public const uint kNumMidLenSymbols = 1 << kNumMidLenBits; 72 | public const uint kNumLenSymbols = kNumLowLenSymbols + kNumMidLenSymbols + 73 | (1 << kNumHighLenBits); 74 | public const uint kMatchMaxLen = kMatchMinLen + kNumLenSymbols - 1; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /LzmaDecoder.cs: -------------------------------------------------------------------------------- 1 | // LzmaDecoder.cs 2 | 3 | using System; 4 | 5 | namespace SevenZip.Compression.LZMA 6 | { 7 | using RangeCoder; 8 | 9 | public class Decoder : ICoder, ISetDecoderProperties // ,System.IO.Stream 10 | { 11 | class LenDecoder 12 | { 13 | BitDecoder m_Choice = new BitDecoder(); 14 | BitDecoder m_Choice2 = new BitDecoder(); 15 | BitTreeDecoder[] m_LowCoder = new BitTreeDecoder[Base.kNumPosStatesMax]; 16 | BitTreeDecoder[] m_MidCoder = new BitTreeDecoder[Base.kNumPosStatesMax]; 17 | BitTreeDecoder m_HighCoder = new BitTreeDecoder(Base.kNumHighLenBits); 18 | uint m_NumPosStates = 0; 19 | 20 | public void Create(uint numPosStates) 21 | { 22 | for (uint posState = m_NumPosStates; posState < numPosStates; posState++) 23 | { 24 | m_LowCoder[posState] = new BitTreeDecoder(Base.kNumLowLenBits); 25 | m_MidCoder[posState] = new BitTreeDecoder(Base.kNumMidLenBits); 26 | } 27 | m_NumPosStates = numPosStates; 28 | } 29 | 30 | public void Init() 31 | { 32 | m_Choice.Init(); 33 | for (uint posState = 0; posState < m_NumPosStates; posState++) 34 | { 35 | m_LowCoder[posState].Init(); 36 | m_MidCoder[posState].Init(); 37 | } 38 | m_Choice2.Init(); 39 | m_HighCoder.Init(); 40 | } 41 | 42 | public uint Decode(RangeCoder.Decoder rangeDecoder, uint posState) 43 | { 44 | if (m_Choice.Decode(rangeDecoder) == 0) 45 | return m_LowCoder[posState].Decode(rangeDecoder); 46 | else 47 | { 48 | uint symbol = Base.kNumLowLenSymbols; 49 | if (m_Choice2.Decode(rangeDecoder) == 0) 50 | symbol += m_MidCoder[posState].Decode(rangeDecoder); 51 | else 52 | { 53 | symbol += Base.kNumMidLenSymbols; 54 | symbol += m_HighCoder.Decode(rangeDecoder); 55 | } 56 | return symbol; 57 | } 58 | } 59 | } 60 | 61 | class LiteralDecoder 62 | { 63 | struct Decoder2 64 | { 65 | BitDecoder[] m_Decoders; 66 | public void Create() { m_Decoders = new BitDecoder[0x300]; } 67 | public void Init() { for (int i = 0; i < 0x300; i++) m_Decoders[i].Init(); } 68 | 69 | public byte DecodeNormal(RangeCoder.Decoder rangeDecoder) 70 | { 71 | uint symbol = 1; 72 | do 73 | symbol = (symbol << 1) | m_Decoders[symbol].Decode(rangeDecoder); 74 | while (symbol < 0x100); 75 | return (byte)symbol; 76 | } 77 | 78 | public byte DecodeWithMatchByte(RangeCoder.Decoder rangeDecoder, byte matchByte) 79 | { 80 | uint symbol = 1; 81 | do 82 | { 83 | uint matchBit = (uint)(matchByte >> 7) & 1; 84 | matchByte <<= 1; 85 | uint bit = m_Decoders[((1 + matchBit) << 8) + symbol].Decode(rangeDecoder); 86 | symbol = (symbol << 1) | bit; 87 | if (matchBit != bit) 88 | { 89 | while (symbol < 0x100) 90 | symbol = (symbol << 1) | m_Decoders[symbol].Decode(rangeDecoder); 91 | break; 92 | } 93 | } 94 | while (symbol < 0x100); 95 | return (byte)symbol; 96 | } 97 | } 98 | 99 | Decoder2[] m_Coders; 100 | int m_NumPrevBits; 101 | int m_NumPosBits; 102 | uint m_PosMask; 103 | 104 | public void Create(int numPosBits, int numPrevBits) 105 | { 106 | if (m_Coders != null && m_NumPrevBits == numPrevBits && 107 | m_NumPosBits == numPosBits) 108 | return; 109 | m_NumPosBits = numPosBits; 110 | m_PosMask = ((uint)1 << numPosBits) - 1; 111 | m_NumPrevBits = numPrevBits; 112 | uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits); 113 | m_Coders = new Decoder2[numStates]; 114 | for (uint i = 0; i < numStates; i++) 115 | m_Coders[i].Create(); 116 | } 117 | 118 | public void Init() 119 | { 120 | uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits); 121 | for (uint i = 0; i < numStates; i++) 122 | m_Coders[i].Init(); 123 | } 124 | 125 | uint GetState(uint pos, byte prevByte) 126 | { return ((pos & m_PosMask) << m_NumPrevBits) + (uint)(prevByte >> (8 - m_NumPrevBits)); } 127 | 128 | public byte DecodeNormal(RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte) 129 | { return m_Coders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder); } 130 | 131 | public byte DecodeWithMatchByte(RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte, byte matchByte) 132 | { return m_Coders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte); } 133 | }; 134 | 135 | LZ.OutWindow m_OutWindow = new LZ.OutWindow(); 136 | RangeCoder.Decoder m_RangeDecoder = new RangeCoder.Decoder(); 137 | 138 | BitDecoder[] m_IsMatchDecoders = new BitDecoder[Base.kNumStates << Base.kNumPosStatesBitsMax]; 139 | BitDecoder[] m_IsRepDecoders = new BitDecoder[Base.kNumStates]; 140 | BitDecoder[] m_IsRepG0Decoders = new BitDecoder[Base.kNumStates]; 141 | BitDecoder[] m_IsRepG1Decoders = new BitDecoder[Base.kNumStates]; 142 | BitDecoder[] m_IsRepG2Decoders = new BitDecoder[Base.kNumStates]; 143 | BitDecoder[] m_IsRep0LongDecoders = new BitDecoder[Base.kNumStates << Base.kNumPosStatesBitsMax]; 144 | 145 | BitTreeDecoder[] m_PosSlotDecoder = new BitTreeDecoder[Base.kNumLenToPosStates]; 146 | BitDecoder[] m_PosDecoders = new BitDecoder[Base.kNumFullDistances - Base.kEndPosModelIndex]; 147 | 148 | BitTreeDecoder m_PosAlignDecoder = new BitTreeDecoder(Base.kNumAlignBits); 149 | 150 | LenDecoder m_LenDecoder = new LenDecoder(); 151 | LenDecoder m_RepLenDecoder = new LenDecoder(); 152 | 153 | LiteralDecoder m_LiteralDecoder = new LiteralDecoder(); 154 | 155 | uint m_DictionarySize; 156 | uint m_DictionarySizeCheck; 157 | 158 | uint m_PosStateMask; 159 | 160 | public Decoder() 161 | { 162 | m_DictionarySize = 0xFFFFFFFF; 163 | for (int i = 0; i < Base.kNumLenToPosStates; i++) 164 | m_PosSlotDecoder[i] = new BitTreeDecoder(Base.kNumPosSlotBits); 165 | } 166 | 167 | void SetDictionarySize(uint dictionarySize) 168 | { 169 | if (m_DictionarySize != dictionarySize) 170 | { 171 | m_DictionarySize = dictionarySize; 172 | m_DictionarySizeCheck = Math.Max(m_DictionarySize, 1); 173 | uint blockSize = Math.Max(m_DictionarySizeCheck, (1 << 12)); 174 | m_OutWindow.Create(blockSize); 175 | } 176 | } 177 | 178 | void SetLiteralProperties(int lp, int lc) 179 | { 180 | if (lp > 8) 181 | throw new InvalidParamException(); 182 | if (lc > 8) 183 | throw new InvalidParamException(); 184 | m_LiteralDecoder.Create(lp, lc); 185 | } 186 | 187 | void SetPosBitsProperties(int pb) 188 | { 189 | if (pb > Base.kNumPosStatesBitsMax) 190 | throw new InvalidParamException(); 191 | uint numPosStates = (uint)1 << pb; 192 | m_LenDecoder.Create(numPosStates); 193 | m_RepLenDecoder.Create(numPosStates); 194 | m_PosStateMask = numPosStates - 1; 195 | } 196 | 197 | bool _solid = false; 198 | void Init(System.IO.Stream inStream, System.IO.Stream outStream) 199 | { 200 | m_RangeDecoder.Init(inStream); 201 | m_OutWindow.Init(outStream, _solid); 202 | 203 | uint i; 204 | for (i = 0; i < Base.kNumStates; i++) 205 | { 206 | for (uint j = 0; j <= m_PosStateMask; j++) 207 | { 208 | uint index = (i << Base.kNumPosStatesBitsMax) + j; 209 | m_IsMatchDecoders[index].Init(); 210 | m_IsRep0LongDecoders[index].Init(); 211 | } 212 | m_IsRepDecoders[i].Init(); 213 | m_IsRepG0Decoders[i].Init(); 214 | m_IsRepG1Decoders[i].Init(); 215 | m_IsRepG2Decoders[i].Init(); 216 | } 217 | 218 | m_LiteralDecoder.Init(); 219 | for (i = 0; i < Base.kNumLenToPosStates; i++) 220 | m_PosSlotDecoder[i].Init(); 221 | // m_PosSpecDecoder.Init(); 222 | for (i = 0; i < Base.kNumFullDistances - Base.kEndPosModelIndex; i++) 223 | m_PosDecoders[i].Init(); 224 | 225 | m_LenDecoder.Init(); 226 | m_RepLenDecoder.Init(); 227 | m_PosAlignDecoder.Init(); 228 | } 229 | 230 | public void Code(System.IO.Stream inStream, System.IO.Stream outStream, long inSize, long outSize, ICodeProgress progress) 231 | { 232 | Init(inStream, outStream); 233 | 234 | Base.State state = new Base.State(); 235 | state.Init(); 236 | uint rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0; 237 | 238 | uint nowPos64 = 0; 239 | uint outSize64 = (uint)outSize; 240 | if (nowPos64 < outSize64) 241 | { 242 | if (m_IsMatchDecoders[state.Index << Base.kNumPosStatesBitsMax].Decode(m_RangeDecoder) != 0) 243 | throw new DataErrorException(); 244 | state.UpdateChar(); 245 | byte b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, 0, 0); 246 | m_OutWindow.PutByte(b); 247 | nowPos64++; 248 | } 249 | while (nowPos64 < outSize64) 250 | { 251 | // UInt64 next = Math.Min(nowPos64 + (1 << 18), outSize64); 252 | // while(nowPos64 < next) 253 | { 254 | uint posState = (uint)nowPos64 & m_PosStateMask; 255 | if (m_IsMatchDecoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode(m_RangeDecoder) == 0) 256 | { 257 | byte b; 258 | byte prevByte = m_OutWindow.GetByte(0); 259 | if (!state.IsCharState()) 260 | b = m_LiteralDecoder.DecodeWithMatchByte(m_RangeDecoder, 261 | (uint)nowPos64, prevByte, m_OutWindow.GetByte(rep0)); 262 | else 263 | b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, (uint)nowPos64, prevByte); 264 | m_OutWindow.PutByte(b); 265 | state.UpdateChar(); 266 | nowPos64++; 267 | } 268 | else 269 | { 270 | uint len; 271 | if (m_IsRepDecoders[state.Index].Decode(m_RangeDecoder) == 1) 272 | { 273 | if (m_IsRepG0Decoders[state.Index].Decode(m_RangeDecoder) == 0) 274 | { 275 | if (m_IsRep0LongDecoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode(m_RangeDecoder) == 0) 276 | { 277 | state.UpdateShortRep(); 278 | m_OutWindow.PutByte(m_OutWindow.GetByte(rep0)); 279 | nowPos64++; 280 | continue; 281 | } 282 | } 283 | else 284 | { 285 | uint distance; 286 | if (m_IsRepG1Decoders[state.Index].Decode(m_RangeDecoder) == 0) 287 | { 288 | distance = rep1; 289 | } 290 | else 291 | { 292 | if (m_IsRepG2Decoders[state.Index].Decode(m_RangeDecoder) == 0) 293 | distance = rep2; 294 | else 295 | { 296 | distance = rep3; 297 | rep3 = rep2; 298 | } 299 | rep2 = rep1; 300 | } 301 | rep1 = rep0; 302 | rep0 = distance; 303 | } 304 | len = m_RepLenDecoder.Decode(m_RangeDecoder, posState) + Base.kMatchMinLen; 305 | state.UpdateRep(); 306 | } 307 | else 308 | { 309 | rep3 = rep2; 310 | rep2 = rep1; 311 | rep1 = rep0; 312 | len = Base.kMatchMinLen + m_LenDecoder.Decode(m_RangeDecoder, posState); 313 | state.UpdateMatch(); 314 | uint posSlot = m_PosSlotDecoder[Base.GetLenToPosState(len)].Decode(m_RangeDecoder); 315 | if (posSlot >= Base.kStartPosModelIndex) 316 | { 317 | int numDirectBits = (int)((posSlot >> 1) - 1); 318 | rep0 = ((2 | (posSlot & 1)) << numDirectBits); 319 | if (posSlot < Base.kEndPosModelIndex) 320 | rep0 += BitTreeDecoder.ReverseDecode(m_PosDecoders, 321 | rep0 - posSlot - 1, m_RangeDecoder, numDirectBits); 322 | else 323 | { 324 | rep0 += (m_RangeDecoder.DecodeDirectBits( 325 | numDirectBits - Base.kNumAlignBits) << Base.kNumAlignBits); 326 | rep0 += m_PosAlignDecoder.ReverseDecode(m_RangeDecoder); 327 | } 328 | } 329 | else 330 | rep0 = posSlot; 331 | } 332 | if (rep0 >= m_OutWindow.TrainSize + nowPos64 || rep0 >= m_DictionarySizeCheck) 333 | { 334 | if (rep0 == 0xFFFFFFFF) 335 | break; 336 | throw new DataErrorException(); 337 | } 338 | m_OutWindow.CopyBlock(rep0, len); 339 | nowPos64 += len; 340 | } 341 | } 342 | } 343 | m_OutWindow.Flush(); 344 | m_OutWindow.ReleaseStream(); 345 | m_RangeDecoder.ReleaseStream(); 346 | } 347 | 348 | public void SetDecoderProperties(byte[] properties) 349 | { 350 | if (properties.Length < 5) 351 | throw new InvalidParamException(); 352 | int lc = properties[0] % 9; 353 | int remainder = properties[0] / 9; 354 | int lp = remainder % 5; 355 | int pb = remainder / 5; 356 | if (pb > Base.kNumPosStatesBitsMax) 357 | throw new InvalidParamException(); 358 | UInt32 dictionarySize = 0; 359 | for (int i = 0; i < 4; i++) 360 | dictionarySize += ((UInt32)(properties[1 + i])) << (i * 8); 361 | SetDictionarySize(dictionarySize); 362 | SetLiteralProperties(lp, lc); 363 | SetPosBitsProperties(pb); 364 | } 365 | 366 | public bool Train(System.IO.Stream stream) 367 | { 368 | _solid = true; 369 | return m_OutWindow.Train(stream); 370 | } 371 | 372 | /* 373 | public override bool CanRead { get { return true; }} 374 | public override bool CanWrite { get { return true; }} 375 | public override bool CanSeek { get { return true; }} 376 | public override long Length { get { return 0; }} 377 | public override long Position 378 | { 379 | get { return 0; } 380 | set { } 381 | } 382 | public override void Flush() { } 383 | public override int Read(byte[] buffer, int offset, int count) 384 | { 385 | return 0; 386 | } 387 | public override void Write(byte[] buffer, int offset, int count) 388 | { 389 | } 390 | public override long Seek(long offset, System.IO.SeekOrigin origin) 391 | { 392 | return 0; 393 | } 394 | public override void SetLength(long value) {} 395 | */ 396 | } 397 | } 398 | -------------------------------------------------------------------------------- /PPtr.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using System.IO; 4 | using System.CodeDom; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | 8 | namespace PrefabAPI 9 | { 10 | public class PPtr where T : EditorObject 11 | { 12 | public int m_FileID; 13 | public long m_PathID; 14 | 15 | public PPtr() 16 | { 17 | } 18 | 19 | public static PPtr CreatePPtr(EditorObject obj, IEnumerable allObjects, int pathOffset = 0) 20 | { 21 | return new PPtr() { m_FileID = 0, m_PathID = allObjects.ToList().IndexOf(obj) + 2 + pathOffset }; 22 | } 23 | 24 | public void Write(BinaryWriter write) 25 | { 26 | write.Write(m_FileID); 27 | write.Write(m_PathID); 28 | } 29 | 30 | public byte[] ToBytes(EndianType endian) 31 | { 32 | using (EndianBinaryWriter writer = new EndianBinaryWriter(new MemoryStream(), endian)) 33 | { 34 | writer.Write(m_FileID); 35 | writer.Write(m_PathID); 36 | return writer.BaseStream.ReadToEnd(); 37 | } 38 | } 39 | 40 | public static PPtr Empty 41 | { 42 | get 43 | { 44 | return new PPtr { m_FileID = 0, m_PathID = 0 }; 45 | } 46 | } 47 | 48 | public bool TryGet(List manualObjects, out T result) 49 | { 50 | if (manualObjects.Count <= m_PathID) 51 | { 52 | var obj = manualObjects[(int)m_PathID - 2]; 53 | if (obj is T variable) 54 | { 55 | result = variable; 56 | return true; 57 | } 58 | } 59 | 60 | result = null; 61 | return false; 62 | } 63 | 64 | public T Get(List manualObjects) 65 | { 66 | if (m_PathID <= manualObjects.Count) 67 | { 68 | var obj = manualObjects[(int)m_PathID - 2]; 69 | if (obj is T variable) 70 | { 71 | return variable; 72 | } 73 | } 74 | 75 | return null; 76 | } 77 | 78 | public bool IsNull => m_PathID == 0 || m_FileID < 0; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /PrefabAPI.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {2F4C7C3A-3F0C-408A-B39E-62E67E415B34} 8 | Library 9 | Properties 10 | PrefabAPI 11 | PrefabAPI 12 | v3.5 13 | 512 14 | true 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | ..\..\..\Documents\ModDependencies\Assembly-CSharp.dll 36 | 37 | 38 | ..\..\..\Documents\ModDependencies\Assembly-CSharp.Base.mm.dll 39 | 40 | 41 | ..\..\..\Documents\ModDependencies\Ionic.Zip.dll 42 | 43 | 44 | ..\..\..\Documents\ModDependencies\Mono.Cecil.dll 45 | 46 | 47 | ..\..\..\Documents\ModDependencies\Mono.Security.dll 48 | 49 | 50 | ..\..\..\Documents\ModDependencies\MonoMod.RuntimeDetour.dll 51 | 52 | 53 | ..\..\..\Documents\ModDependencies\MonoMod.Utils.dll 54 | 55 | 56 | ..\..\..\Documents\ModDependencies\Newtonsoft.Json.dll 57 | 58 | 59 | ..\..\..\Documents\ModDependencies\PlayMaker.dll 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | ..\..\..\Documents\ModDependencies\UnityEngine.dll 69 | 70 | 71 | ..\..\..\Documents\ModDependencies\UnityEngine.AnimationModule.dll 72 | 73 | 74 | ..\..\..\Documents\ModDependencies\UnityEngine.Base.mm.dll 75 | 76 | 77 | ..\..\..\Documents\ModDependencies\UnityEngine.CoreModule.dll 78 | 79 | 80 | ..\..\..\Documents\ModDependencies\UnityEngine.CoreModule.Base.mm.dll 81 | 82 | 83 | ..\..\..\Documents\ModDependencies\UnityEngine.ImageConversionModule.dll 84 | 85 | 86 | ..\..\..\Documents\ModDependencies\UnityEngine.JSONSerializeModule.dll 87 | 88 | 89 | ..\..\..\Documents\ModDependencies\UnityEngine.ParticleSystemModule.dll 90 | 91 | 92 | ..\..\..\Documents\ModDependencies\UnityEngine.TextRenderingModule.dll 93 | 94 | 95 | ..\..\..\Documents\ModDependencies\UnityEngine.UI.dll 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /PrefabAPI.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31321.278 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PrefabAPI", "PrefabAPI.csproj", "{2F4C7C3A-3F0C-408A-B39E-62E67E415B34}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {2F4C7C3A-3F0C-408A-B39E-62E67E415B34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {2F4C7C3A-3F0C-408A-B39E-62E67E415B34}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {2F4C7C3A-3F0C-408A-B39E-62E67E415B34}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {2F4C7C3A-3F0C-408A-B39E-62E67E415B34}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {40A7EDA1-9941-4B6B-9997-D9AD5E4BB1DC} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /PrefabBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Reflection; 6 | using System.Text; 7 | using UnityEngine; 8 | 9 | namespace PrefabAPI 10 | { 11 | public static class PrefabBuilder 12 | { 13 | public static void Init() 14 | { 15 | if (m_initialized) 16 | { 17 | return; 18 | } 19 | m_assetBundles = new List(); 20 | m_initialized = true; 21 | builtObjects = new List(); 22 | } 23 | 24 | public static GameObject BuildObject(string name) 25 | { 26 | if(m_assetBundles == null || builtObjects == null) 27 | { 28 | Init(); 29 | } 30 | byte[] bundleBytes = AssetBundleBuilder.BuildBundleFile("runtimebundle" + m_bundlesBuilt); 31 | m_bundlesBuilt++; 32 | AssetBundle bundle = AssetBundle.LoadFromMemory(bundleBytes); 33 | m_assetBundles.Add(bundle); 34 | GameObject prefab = bundle.LoadAsset("object"); 35 | prefab.name = name; 36 | builtObjects.Add(prefab); 37 | return prefab; 38 | } 39 | 40 | public static GameObject Clone(GameObject toClone) 41 | { 42 | GameObject clone = BuildObject(toClone.name + " Clone"); 43 | Dictionary, int> componentsInChildren = new Dictionary, int>(); 44 | Dictionary, int> gameObjectsInChildren = new Dictionary, int>(); 45 | List> gameObjects = new List>(); 46 | foreach (Component c in toClone.GetComponents()) 47 | { 48 | if (clone.GetComponent(c.GetType()) == null) 49 | { 50 | clone.AddComponent(c.GetType()); 51 | } 52 | foreach (PropertyInfo inf in c.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) 53 | { 54 | if (inf.CanWrite && inf.CanRead) 55 | { 56 | try 57 | { 58 | object val = inf.GetValue(c, new object[0]); 59 | bool overrideSet = false; 60 | if (val is Component) 61 | { 62 | if (toClone.GetComponentsInChildren().ToList().Contains(val as Component)) 63 | { 64 | componentsInChildren.Add(new Tuple(inf, clone.GetComponent(c.GetType())), toClone.GetComponentsInChildren().ToList().IndexOf((val as Component))); 65 | overrideSet = true; 66 | } 67 | } 68 | else if (val is GameObject go) 69 | { 70 | if(toClone.transform.GetChildObjects().Contains(val as GameObject)) 71 | { 72 | gameObjectsInChildren.Add(new Tuple(inf, clone.GetComponent(c.GetType())), toClone.transform.GetChildObjects().IndexOf(val as GameObject)); 73 | overrideSet = true; 74 | } 75 | else if (go == toClone.gameObject) 76 | { 77 | gameObjects.Add(new Tuple(inf, clone.GetComponent(c.GetType()))); 78 | } 79 | } 80 | if (!overrideSet) 81 | { 82 | inf.SetValue(clone.GetComponent(c.GetType()), val, new object[0]); 83 | } 84 | } 85 | catch { } 86 | } 87 | } 88 | foreach (FieldInfo inf in c.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) 89 | { 90 | object val = inf.GetValue(c); 91 | bool overrideSet = false; 92 | if (val is Component) 93 | { 94 | if (toClone.GetComponentsInChildren().ToList().Contains(val as Component)) 95 | { 96 | componentsInChildren.Add(new Tuple(inf, clone.GetComponent(c.GetType())), toClone.GetComponentsInChildren().ToList().IndexOf((val as Component))); 97 | overrideSet = true; 98 | } 99 | } 100 | else if (val is GameObject go) 101 | { 102 | if (toClone.transform.GetChildObjects().Contains(val as GameObject)) 103 | { 104 | gameObjectsInChildren.Add(new Tuple(inf, clone.GetComponent(c.GetType())), toClone.transform.GetChildObjects().IndexOf(val as GameObject)); 105 | overrideSet = true; 106 | } 107 | else if(go == toClone.gameObject) 108 | { 109 | gameObjects.Add(new Tuple(inf, clone.GetComponent(c.GetType()))); 110 | } 111 | } 112 | if (!overrideSet) 113 | { 114 | inf.SetValue(clone.GetComponent(c.GetType()), val); 115 | } 116 | } 117 | foreach (Type inter in c.GetType().GetInterfaces()) 118 | { 119 | foreach (PropertyInfo inf in inter.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) 120 | { 121 | if (inf.CanWrite && inf.CanRead) 122 | { 123 | try 124 | { 125 | object val = inf.GetValue(c, new object[0]); 126 | bool overrideSet = false; 127 | if (val is Component) 128 | { 129 | if (toClone.GetComponentsInChildren().ToList().Contains(val as Component)) 130 | { 131 | componentsInChildren.Add(new Tuple(inf, clone.GetComponent(c.GetType())), toClone.GetComponentsInChildren().ToList().IndexOf((val as Component))); 132 | overrideSet = true; 133 | } 134 | } 135 | else if (val is GameObject go) 136 | { 137 | if (toClone.transform.GetChildObjects().Contains(val as GameObject)) 138 | { 139 | gameObjectsInChildren.Add(new Tuple(inf, clone.GetComponent(c.GetType())), toClone.transform.GetChildObjects().IndexOf(val as GameObject)); 140 | overrideSet = true; 141 | } 142 | else if (go == toClone.gameObject) 143 | { 144 | gameObjects.Add(new Tuple(inf, clone.GetComponent(c.GetType()))); 145 | } 146 | } 147 | if (!overrideSet) 148 | { 149 | inf.SetValue(clone.GetComponent(c.GetType()), val, new object[0]); 150 | } 151 | } 152 | catch { } 153 | } 154 | } 155 | } 156 | } 157 | foreach (Transform child in toClone.transform) 158 | { 159 | GameObject childClone = CloneChild(child.gameObject, toClone, out var cip, out var goip, out var gos); 160 | componentsInChildren.AddRange(cip); 161 | gameObjectsInChildren.AddRange(goip); 162 | gameObjects.AddRange(gos); 163 | childClone.transform.parent = clone.transform; 164 | childClone.transform.localPosition = child.localPosition; 165 | childClone.transform.localRotation = child.localRotation; 166 | childClone.transform.localScale = child.localScale; 167 | } 168 | foreach(KeyValuePair, int> kvp in componentsInChildren) 169 | { 170 | MemberInfo mi = kvp.Key.First; 171 | Component c = clone.GetComponentsInChildren()[kvp.Value]; 172 | if(mi is PropertyInfo) 173 | { 174 | PropertyInfo pi = mi as PropertyInfo; 175 | try 176 | { 177 | pi.SetValue(kvp.Key.Second, c, new object[0]); 178 | } 179 | catch { } 180 | } 181 | else if(mi is FieldInfo) 182 | { 183 | FieldInfo fi = mi as FieldInfo; 184 | fi.SetValue(kvp.Key.Second, c); 185 | } 186 | } 187 | foreach (KeyValuePair, int> kvp in gameObjectsInChildren) 188 | { 189 | MemberInfo mi = kvp.Key.First; 190 | GameObject go = clone.transform.GetChildObjects()[kvp.Value]; 191 | if (mi is PropertyInfo) 192 | { 193 | PropertyInfo pi = mi as PropertyInfo; 194 | try 195 | { 196 | pi.SetValue(kvp.Key.Second, go, new object[0]); 197 | } 198 | catch { } 199 | } 200 | else if (mi is FieldInfo) 201 | { 202 | FieldInfo fi = mi as FieldInfo; 203 | fi.SetValue(kvp.Key.Second, go); 204 | } 205 | } 206 | foreach(Tuple t in gameObjects) 207 | { 208 | MemberInfo mi = t.First; 209 | GameObject go = clone; 210 | if (mi is PropertyInfo) 211 | { 212 | PropertyInfo pi = mi as PropertyInfo; 213 | try 214 | { 215 | pi.SetValue(t.Second, go, new object[0]); 216 | } 217 | catch { } 218 | } 219 | else if (mi is FieldInfo) 220 | { 221 | FieldInfo fi = mi as FieldInfo; 222 | fi.SetValue(t.Second, go); 223 | } 224 | } 225 | return clone; 226 | } 227 | 228 | private static GameObject CloneChild(GameObject toClone, GameObject ultimateParent, out Dictionary, int> componentsInChildren, out Dictionary, int> gameObjectsInChildren, out List> gameObjects) 230 | { 231 | GameObject clone = BuildObject(toClone.name + " Clone"); 232 | componentsInChildren = new Dictionary, int>(); 233 | gameObjectsInChildren = new Dictionary, int>(); 234 | gameObjects = new List>(); 235 | foreach (Component c in toClone.GetComponents()) 236 | { 237 | if (clone.GetComponent(c.GetType()) == null) 238 | { 239 | clone.AddComponent(c.GetType()); 240 | } 241 | foreach (PropertyInfo inf in c.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) 242 | { 243 | if (inf.CanWrite && inf.CanRead) 244 | { 245 | try 246 | { 247 | object val = inf.GetValue(c, new object[0]); 248 | bool overrideSet = false; 249 | if (val is Component) 250 | { 251 | if (ultimateParent.GetComponentsInChildren().ToList().Contains(val as Component)) 252 | { 253 | componentsInChildren.Add(new Tuple(inf, clone.GetComponent(c.GetType())), ultimateParent.GetComponentsInChildren().ToList().IndexOf((val as Component))); 254 | overrideSet = true; 255 | } 256 | } 257 | else if (val is GameObject go) 258 | { 259 | if (ultimateParent.transform.GetChildObjects().Contains(val as GameObject)) 260 | { 261 | gameObjectsInChildren.Add(new Tuple(inf, clone.GetComponent(c.GetType())), ultimateParent.transform.GetChildObjects().IndexOf(val as GameObject)); 262 | overrideSet = true; 263 | } 264 | else if (go == toClone.gameObject) 265 | { 266 | gameObjects.Add(new Tuple(inf, clone.GetComponent(c.GetType()))); 267 | } 268 | } 269 | if (!overrideSet) 270 | { 271 | inf.SetValue(clone.GetComponent(c.GetType()), val, new object[0]); 272 | } 273 | } 274 | catch { } 275 | } 276 | } 277 | foreach (FieldInfo inf in c.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) 278 | { 279 | object val = inf.GetValue(c); 280 | bool overrideSet = false; 281 | if (val is Component) 282 | { 283 | if (ultimateParent.GetComponentsInChildren().ToList().Contains(val as Component)) 284 | { 285 | componentsInChildren.Add(new Tuple(inf, clone.GetComponent(c.GetType())), ultimateParent.GetComponentsInChildren().ToList().IndexOf((val as Component))); 286 | overrideSet = true; 287 | } 288 | } 289 | else if (val is GameObject go) 290 | { 291 | if (ultimateParent.transform.GetChildObjects().Contains(val as GameObject)) 292 | { 293 | gameObjectsInChildren.Add(new Tuple(inf, clone.GetComponent(c.GetType())), ultimateParent.transform.GetChildObjects().IndexOf(val as GameObject)); 294 | overrideSet = true; 295 | } 296 | else if (go == toClone.gameObject) 297 | { 298 | gameObjects.Add(new Tuple(inf, clone.GetComponent(c.GetType()))); 299 | } 300 | } 301 | if (!overrideSet) 302 | { 303 | inf.SetValue(clone.GetComponent(c.GetType()), val); 304 | } 305 | } 306 | foreach (Type inter in c.GetType().GetInterfaces()) 307 | { 308 | foreach (PropertyInfo inf in inter.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) 309 | { 310 | if (inf.CanWrite && inf.CanRead) 311 | { 312 | try 313 | { 314 | object val = inf.GetValue(c, new object[0]); 315 | bool overrideSet = false; 316 | if (val is Component) 317 | { 318 | if (ultimateParent.GetComponentsInChildren().ToList().Contains(val as Component)) 319 | { 320 | componentsInChildren.Add(new Tuple(inf, clone.GetComponent(c.GetType())), ultimateParent.GetComponentsInChildren().ToList().IndexOf((val as Component))); 321 | overrideSet = true; 322 | } 323 | } 324 | else if (val is GameObject go) 325 | { 326 | if (ultimateParent.transform.GetChildObjects().Contains(val as GameObject)) 327 | { 328 | gameObjectsInChildren.Add(new Tuple(inf, clone.GetComponent(c.GetType())), ultimateParent.transform.GetChildObjects().IndexOf(val as GameObject)); 329 | overrideSet = true; 330 | } 331 | else if (go == toClone.gameObject) 332 | { 333 | gameObjects.Add(new Tuple(inf, clone.GetComponent(c.GetType()))); 334 | } 335 | } 336 | if (!overrideSet) 337 | { 338 | inf.SetValue(clone.GetComponent(c.GetType()), val, new object[0]); 339 | } 340 | } 341 | catch { } 342 | } 343 | } 344 | } 345 | } 346 | foreach (Transform child in toClone.transform) 347 | { 348 | GameObject childClone = CloneChild(child.gameObject, clone, out var cip, out var goip, out var gos); 349 | componentsInChildren.AddRange(cip); 350 | gameObjectsInChildren.AddRange(goip); 351 | gameObjects.AddRange(gos); 352 | childClone.transform.parent = clone.transform; 353 | childClone.transform.localPosition = child.localPosition; 354 | childClone.transform.localRotation = child.localRotation; 355 | childClone.transform.localScale = child.localScale; 356 | } 357 | return clone; 358 | } 359 | 360 | private static bool m_initialized; 361 | private static int m_bundlesBuilt; 362 | private static List m_assetBundles; 363 | public static List builtObjects; 364 | } 365 | } 366 | -------------------------------------------------------------------------------- /Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("PrefabAPI")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("PrefabAPI")] 13 | [assembly: AssemblyCopyright("Copyright © 2021")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("2f4c7c3a-3f0c-408a-b39e-62e67e415b34")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PrefabAPI 2 | PrefabAPI allows you to create custom prefabs with one simple method, without needing to use any asset bundles, and it even works in runtime. 3 | -------------------------------------------------------------------------------- /RangeCoder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using PrefabAPI; 4 | 5 | namespace SevenZip.Compression.RangeCoder 6 | { 7 | class Encoder 8 | { 9 | public const uint kTopValue = (1 << 24); 10 | 11 | System.IO.Stream Stream; 12 | 13 | public UInt64 Low; 14 | public uint Range; 15 | uint _cacheSize; 16 | byte _cache; 17 | 18 | long StartPosition; 19 | 20 | public void SetStream(System.IO.Stream stream) 21 | { 22 | Stream = stream; 23 | } 24 | 25 | public void ReleaseStream() 26 | { 27 | Stream = null; 28 | } 29 | 30 | public void Init() 31 | { 32 | StartPosition = Stream.Position; 33 | 34 | Low = 0; 35 | Range = 0xFFFFFFFF; 36 | _cacheSize = 1; 37 | _cache = 0; 38 | } 39 | 40 | public void FlushData() 41 | { 42 | for (int i = 0; i < 5; i++) 43 | ShiftLow(); 44 | } 45 | 46 | public void FlushStream() 47 | { 48 | Stream.Flush(); 49 | } 50 | 51 | public void CloseStream() 52 | { 53 | Stream.Close(); 54 | } 55 | 56 | public void Encode(uint start, uint size, uint total) 57 | { 58 | Low += start * (Range /= total); 59 | Range *= size; 60 | while (Range < kTopValue) 61 | { 62 | Range <<= 8; 63 | ShiftLow(); 64 | } 65 | } 66 | 67 | public void ShiftLow() 68 | { 69 | if ((uint)Low < (uint)0xFF000000 || (uint)(Low >> 32) == 1) 70 | { 71 | byte temp = _cache; 72 | do 73 | { 74 | Stream.WriteByte((byte)(temp + (Low >> 32))); 75 | temp = 0xFF; 76 | } 77 | while (--_cacheSize != 0); 78 | _cache = (byte)(((uint)Low) >> 24); 79 | } 80 | _cacheSize++; 81 | Low = ((uint)Low) << 8; 82 | } 83 | 84 | public void EncodeDirectBits(uint v, int numTotalBits) 85 | { 86 | for (int i = numTotalBits - 1; i >= 0; i--) 87 | { 88 | Range >>= 1; 89 | if (((v >> i) & 1) == 1) 90 | Low += Range; 91 | if (Range < kTopValue) 92 | { 93 | Range <<= 8; 94 | ShiftLow(); 95 | } 96 | } 97 | } 98 | 99 | public void EncodeBit(uint size0, int numTotalBits, uint symbol) 100 | { 101 | uint newBound = (Range >> numTotalBits) * size0; 102 | if (symbol == 0) 103 | Range = newBound; 104 | else 105 | { 106 | Low += newBound; 107 | Range -= newBound; 108 | } 109 | while (Range < kTopValue) 110 | { 111 | Range <<= 8; 112 | ShiftLow(); 113 | } 114 | } 115 | 116 | public long GetProcessedSizeAdd() 117 | { 118 | return _cacheSize + 119 | Stream.Position - StartPosition + 4; 120 | // (long)Stream.GetProcessedSize(); 121 | } 122 | } 123 | 124 | class Decoder 125 | { 126 | public const uint kTopValue = (1 << 24); 127 | public uint Range; 128 | public uint Code; 129 | // public Buffer.InBuffer Stream = new Buffer.InBuffer(1 << 16); 130 | public System.IO.Stream Stream; 131 | 132 | public void Init(System.IO.Stream stream) 133 | { 134 | // Stream.Init(stream); 135 | Stream = stream; 136 | 137 | Code = 0; 138 | Range = 0xFFFFFFFF; 139 | for (int i = 0; i < 5; i++) 140 | { 141 | byte b = (byte)Stream.ReadByte(); 142 | Code = (Code << 8) | b; 143 | } 144 | } 145 | 146 | public void ReleaseStream() 147 | { 148 | // Stream.ReleaseStream(); 149 | Stream = null; 150 | } 151 | 152 | public void CloseStream() 153 | { 154 | Stream.Close(); 155 | } 156 | 157 | public void Normalize() 158 | { 159 | while (Range < kTopValue) 160 | { 161 | byte b = (byte)Stream.ReadByte(); 162 | Code = (Code << 8) | b; 163 | Range <<= 8; 164 | } 165 | } 166 | 167 | public void Normalize2() 168 | { 169 | if (Range < kTopValue) 170 | { 171 | byte b = (byte)Stream.ReadByte(); 172 | Code = (Code << 8) | b; 173 | Range <<= 8; 174 | } 175 | } 176 | 177 | public uint GetThreshold(uint total) 178 | { 179 | return Code / (Range /= total); 180 | } 181 | 182 | public void Decode(uint start, uint size, uint total) 183 | { 184 | Code -= start * Range; 185 | Range *= size; 186 | Normalize(); 187 | } 188 | 189 | public uint DecodeDirectBits(int numTotalBits) 190 | { 191 | uint range = Range; 192 | uint code = Code; 193 | uint result = 0; 194 | for (int i = numTotalBits; i > 0; i--) 195 | { 196 | range >>= 1; 197 | /* 198 | result <<= 1; 199 | if (code >= range) 200 | { 201 | code -= range; 202 | result |= 1; 203 | } 204 | */ 205 | uint t = (code - range) >> 31; 206 | code -= range & (t - 1); 207 | result = (result << 1) | (1 - t); 208 | if (range < kTopValue) 209 | { 210 | byte b = (byte)Stream.ReadByte(); 211 | code = (code << 8) | b; 212 | range <<= 8; 213 | } 214 | } 215 | Range = range; 216 | Code = code; 217 | return result; 218 | } 219 | 220 | public uint DecodeBit(uint size0, int numTotalBits) 221 | { 222 | uint newBound = (Range >> numTotalBits) * size0; 223 | uint symbol; 224 | if (Code < newBound) 225 | { 226 | symbol = 0; 227 | Range = newBound; 228 | } 229 | else 230 | { 231 | symbol = 1; 232 | Code -= newBound; 233 | Range -= newBound; 234 | } 235 | Normalize(); 236 | return symbol; 237 | } 238 | 239 | // ulong GetProcessedSize() {return Stream.GetProcessedSize(); } 240 | } 241 | } 242 | -------------------------------------------------------------------------------- /RangeCoderBit.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SevenZip.Compression.RangeCoder 4 | { 5 | struct BitEncoder 6 | { 7 | public const int kNumBitModelTotalBits = 11; 8 | public const uint kBitModelTotal = (1 << kNumBitModelTotalBits); 9 | const int kNumMoveBits = 5; 10 | const int kNumMoveReducingBits = 2; 11 | public const int kNumBitPriceShiftBits = 6; 12 | 13 | uint Prob; 14 | 15 | public void Init() { Prob = kBitModelTotal >> 1; } 16 | 17 | public void UpdateModel(uint symbol) 18 | { 19 | if (symbol == 0) 20 | Prob += (kBitModelTotal - Prob) >> kNumMoveBits; 21 | else 22 | Prob -= (Prob) >> kNumMoveBits; 23 | } 24 | 25 | public void Encode(Encoder encoder, uint symbol) 26 | { 27 | // encoder.EncodeBit(Prob, kNumBitModelTotalBits, symbol); 28 | // UpdateModel(symbol); 29 | uint newBound = (encoder.Range >> kNumBitModelTotalBits) * Prob; 30 | if (symbol == 0) 31 | { 32 | encoder.Range = newBound; 33 | Prob += (kBitModelTotal - Prob) >> kNumMoveBits; 34 | } 35 | else 36 | { 37 | encoder.Low += newBound; 38 | encoder.Range -= newBound; 39 | Prob -= (Prob) >> kNumMoveBits; 40 | } 41 | if (encoder.Range < Encoder.kTopValue) 42 | { 43 | encoder.Range <<= 8; 44 | encoder.ShiftLow(); 45 | } 46 | } 47 | 48 | private static UInt32[] ProbPrices = new UInt32[kBitModelTotal >> kNumMoveReducingBits]; 49 | 50 | static BitEncoder() 51 | { 52 | const int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits); 53 | for (int i = kNumBits - 1; i >= 0; i--) 54 | { 55 | UInt32 start = (UInt32)1 << (kNumBits - i - 1); 56 | UInt32 end = (UInt32)1 << (kNumBits - i); 57 | for (UInt32 j = start; j < end; j++) 58 | ProbPrices[j] = ((UInt32)i << kNumBitPriceShiftBits) + 59 | (((end - j) << kNumBitPriceShiftBits) >> (kNumBits - i - 1)); 60 | } 61 | } 62 | 63 | public uint GetPrice(uint symbol) 64 | { 65 | return ProbPrices[(((Prob - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits]; 66 | } 67 | public uint GetPrice0() { return ProbPrices[Prob >> kNumMoveReducingBits]; } 68 | public uint GetPrice1() { return ProbPrices[(kBitModelTotal - Prob) >> kNumMoveReducingBits]; } 69 | } 70 | 71 | struct BitDecoder 72 | { 73 | public const int kNumBitModelTotalBits = 11; 74 | public const uint kBitModelTotal = (1 << kNumBitModelTotalBits); 75 | const int kNumMoveBits = 5; 76 | 77 | uint Prob; 78 | 79 | public void UpdateModel(int numMoveBits, uint symbol) 80 | { 81 | if (symbol == 0) 82 | Prob += (kBitModelTotal - Prob) >> numMoveBits; 83 | else 84 | Prob -= (Prob) >> numMoveBits; 85 | } 86 | 87 | public void Init() { Prob = kBitModelTotal >> 1; } 88 | 89 | public uint Decode(RangeCoder.Decoder rangeDecoder) 90 | { 91 | uint newBound = (uint)(rangeDecoder.Range >> kNumBitModelTotalBits) * (uint)Prob; 92 | if (rangeDecoder.Code < newBound) 93 | { 94 | rangeDecoder.Range = newBound; 95 | Prob += (kBitModelTotal - Prob) >> kNumMoveBits; 96 | if (rangeDecoder.Range < Decoder.kTopValue) 97 | { 98 | byte b = (byte)rangeDecoder.Stream.ReadByte(); 99 | rangeDecoder.Code = (rangeDecoder.Code << 8) | b; 100 | rangeDecoder.Range <<= 8; 101 | } 102 | return 0; 103 | } 104 | else 105 | { 106 | rangeDecoder.Range -= newBound; 107 | rangeDecoder.Code -= newBound; 108 | Prob -= (Prob) >> kNumMoveBits; 109 | if (rangeDecoder.Range < Decoder.kTopValue) 110 | { 111 | byte b = (byte)rangeDecoder.Stream.ReadByte(); 112 | rangeDecoder.Code = (rangeDecoder.Code << 8) | b; 113 | rangeDecoder.Range <<= 8; 114 | } 115 | return 1; 116 | } 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /RangeCoderBitTree.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SevenZip.Compression.RangeCoder 4 | { 5 | struct BitTreeEncoder 6 | { 7 | BitEncoder[] Models; 8 | int NumBitLevels; 9 | 10 | public BitTreeEncoder(int numBitLevels) 11 | { 12 | NumBitLevels = numBitLevels; 13 | Models = new BitEncoder[1 << numBitLevels]; 14 | } 15 | 16 | public void Init() 17 | { 18 | for (uint i = 1; i < (1 << NumBitLevels); i++) 19 | Models[i].Init(); 20 | } 21 | 22 | public void Encode(Encoder rangeEncoder, UInt32 symbol) 23 | { 24 | UInt32 m = 1; 25 | for (int bitIndex = NumBitLevels; bitIndex > 0; ) 26 | { 27 | bitIndex--; 28 | UInt32 bit = (symbol >> bitIndex) & 1; 29 | Models[m].Encode(rangeEncoder, bit); 30 | m = (m << 1) | bit; 31 | } 32 | } 33 | 34 | public void ReverseEncode(Encoder rangeEncoder, UInt32 symbol) 35 | { 36 | UInt32 m = 1; 37 | for (UInt32 i = 0; i < NumBitLevels; i++) 38 | { 39 | UInt32 bit = symbol & 1; 40 | Models[m].Encode(rangeEncoder, bit); 41 | m = (m << 1) | bit; 42 | symbol >>= 1; 43 | } 44 | } 45 | 46 | public UInt32 GetPrice(UInt32 symbol) 47 | { 48 | UInt32 price = 0; 49 | UInt32 m = 1; 50 | for (int bitIndex = NumBitLevels; bitIndex > 0; ) 51 | { 52 | bitIndex--; 53 | UInt32 bit = (symbol >> bitIndex) & 1; 54 | price += Models[m].GetPrice(bit); 55 | m = (m << 1) + bit; 56 | } 57 | return price; 58 | } 59 | 60 | public UInt32 ReverseGetPrice(UInt32 symbol) 61 | { 62 | UInt32 price = 0; 63 | UInt32 m = 1; 64 | for (int i = NumBitLevels; i > 0; i--) 65 | { 66 | UInt32 bit = symbol & 1; 67 | symbol >>= 1; 68 | price += Models[m].GetPrice(bit); 69 | m = (m << 1) | bit; 70 | } 71 | return price; 72 | } 73 | 74 | public static UInt32 ReverseGetPrice(BitEncoder[] Models, UInt32 startIndex, 75 | int NumBitLevels, UInt32 symbol) 76 | { 77 | UInt32 price = 0; 78 | UInt32 m = 1; 79 | for (int i = NumBitLevels; i > 0; i--) 80 | { 81 | UInt32 bit = symbol & 1; 82 | symbol >>= 1; 83 | price += Models[startIndex + m].GetPrice(bit); 84 | m = (m << 1) | bit; 85 | } 86 | return price; 87 | } 88 | 89 | public static void ReverseEncode(BitEncoder[] Models, UInt32 startIndex, 90 | Encoder rangeEncoder, int NumBitLevels, UInt32 symbol) 91 | { 92 | UInt32 m = 1; 93 | for (int i = 0; i < NumBitLevels; i++) 94 | { 95 | UInt32 bit = symbol & 1; 96 | Models[startIndex + m].Encode(rangeEncoder, bit); 97 | m = (m << 1) | bit; 98 | symbol >>= 1; 99 | } 100 | } 101 | } 102 | 103 | struct BitTreeDecoder 104 | { 105 | BitDecoder[] Models; 106 | int NumBitLevels; 107 | 108 | public BitTreeDecoder(int numBitLevels) 109 | { 110 | NumBitLevels = numBitLevels; 111 | Models = new BitDecoder[1 << numBitLevels]; 112 | } 113 | 114 | public void Init() 115 | { 116 | for (uint i = 1; i < (1 << NumBitLevels); i++) 117 | Models[i].Init(); 118 | } 119 | 120 | public uint Decode(RangeCoder.Decoder rangeDecoder) 121 | { 122 | uint m = 1; 123 | for (int bitIndex = NumBitLevels; bitIndex > 0; bitIndex--) 124 | m = (m << 1) + Models[m].Decode(rangeDecoder); 125 | return m - ((uint)1 << NumBitLevels); 126 | } 127 | 128 | public uint ReverseDecode(RangeCoder.Decoder rangeDecoder) 129 | { 130 | uint m = 1; 131 | uint symbol = 0; 132 | for (int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++) 133 | { 134 | uint bit = Models[m].Decode(rangeDecoder); 135 | m <<= 1; 136 | m += bit; 137 | symbol |= (bit << bitIndex); 138 | } 139 | return symbol; 140 | } 141 | 142 | public static uint ReverseDecode(BitDecoder[] Models, UInt32 startIndex, 143 | RangeCoder.Decoder rangeDecoder, int NumBitLevels) 144 | { 145 | uint m = 1; 146 | uint symbol = 0; 147 | for (int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++) 148 | { 149 | uint bit = Models[startIndex + m].Decode(rangeDecoder); 150 | m <<= 1; 151 | m += bit; 152 | symbol |= (bit << bitIndex); 153 | } 154 | return symbol; 155 | } 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /Safe32LZ4Service.cs: -------------------------------------------------------------------------------- 1 | #region license 2 | 3 | /* 4 | Copyright (c) 2013, Milosz Krajewski 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without modification, are permitted provided 8 | that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright notice, this list of conditions 11 | and the following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions 14 | and the following disclaimer in the documentation and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 17 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 19 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 20 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 23 | IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | */ 25 | 26 | #endregion 27 | 28 | namespace LZ4.Services 29 | { 30 | internal class Safe32LZ4Service: ILZ4Service 31 | { 32 | #region ILZ4Service Members 33 | 34 | public string CodecName 35 | { 36 | get { return "Safe 32"; } 37 | } 38 | 39 | public int Encode(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset, int outputLength) 40 | { 41 | return LZ4ps.LZ4Codec.Encode32(input, inputOffset, inputLength, output, outputOffset, outputLength); 42 | } 43 | 44 | public int Decode(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset, int outputLength, bool knownOutputLength) 45 | { 46 | return LZ4ps.LZ4Codec.Decode32(input, inputOffset, inputLength, output, outputOffset, outputLength, knownOutputLength); 47 | } 48 | 49 | public int EncodeHC(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset, int outputLength) 50 | { 51 | return LZ4ps.LZ4Codec.Encode32HC(input, inputOffset, inputLength, output, outputOffset, outputLength); 52 | } 53 | 54 | #endregion 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Safe64LZ4Service.cs: -------------------------------------------------------------------------------- 1 | #region license 2 | 3 | /* 4 | Copyright (c) 2013, Milosz Krajewski 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without modification, are permitted provided 8 | that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright notice, this list of conditions 11 | and the following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions 14 | and the following disclaimer in the documentation and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 17 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 19 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 20 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 23 | IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | */ 25 | 26 | #endregion 27 | 28 | namespace LZ4.Services 29 | { 30 | internal class Safe64LZ4Service: ILZ4Service 31 | { 32 | #region ILZ4Service Members 33 | 34 | public string CodecName 35 | { 36 | get { return "Safe 64"; } 37 | } 38 | 39 | public int Encode(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset, int outputLength) 40 | { 41 | return LZ4ps.LZ4Codec.Encode64(input, inputOffset, inputLength, output, outputOffset, outputLength); 42 | } 43 | 44 | public int Decode(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset, int outputLength, bool knownOutputLength) 45 | { 46 | return LZ4ps.LZ4Codec.Decode64(input, inputOffset, inputLength, output, outputOffset, outputLength, knownOutputLength); 47 | } 48 | 49 | public int EncodeHC(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset, int outputLength) 50 | { 51 | return LZ4ps.LZ4Codec.Encode64HC(input, inputOffset, inputLength, output, outputOffset, outputLength); 52 | } 53 | 54 | #endregion 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /SerializedType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace PrefabAPI 7 | { 8 | public class SerializedType 9 | { 10 | public int classID; 11 | public bool m_IsStrippedType; 12 | public short m_ScriptTypeIndex = -1; 13 | public List m_Nodes; 14 | public byte[] m_ScriptID; //Hash128 15 | public byte[] m_OldTypeHash; //Hash128 16 | public int[] m_TypeDependencies; 17 | public byte[] stringBuffer; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /SevenZipHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using SevenZip.Compression.LZMA; 4 | 5 | 6 | namespace PrefabAPI 7 | { 8 | public static class SevenZipHelper 9 | { 10 | 11 | 12 | static int dictionary = 1 << 23; 13 | 14 | // static Int32 posStateBits = 2; 15 | // static Int32 litContextBits = 3; // for normal files 16 | // UInt32 litContextBits = 0; // for 32-bit data 17 | // static Int32 litPosBits = 0; 18 | // UInt32 litPosBits = 2; // for 32-bit data 19 | // static Int32 algorithm = 2; 20 | // static Int32 numFastBytes = 128; 21 | 22 | static bool eos = false; 23 | 24 | 25 | 26 | 27 | 28 | static SevenZip.CoderPropID[] propIDs = 29 | { 30 | SevenZip.CoderPropID.DictionarySize, 31 | SevenZip.CoderPropID.PosStateBits, 32 | SevenZip.CoderPropID.LitContextBits, 33 | SevenZip.CoderPropID.LitPosBits, 34 | SevenZip.CoderPropID.Algorithm, 35 | SevenZip.CoderPropID.NumFastBytes, 36 | SevenZip.CoderPropID.MatchFinder, 37 | SevenZip.CoderPropID.EndMarker 38 | }; 39 | 40 | // these are the default properties, keeping it simple for now: 41 | static object[] properties = 42 | { 43 | (Int32)(dictionary), 44 | (Int32)(2), 45 | (Int32)(3), 46 | (Int32)(0), 47 | (Int32)(2), 48 | (Int32)(128), 49 | "bt4", 50 | eos 51 | }; 52 | 53 | public static byte[] Compress(byte[] inputBytes) 54 | { 55 | MemoryStream inStream = new MemoryStream(inputBytes); 56 | MemoryStream outStream = new MemoryStream(); 57 | Encoder encoder = new Encoder(); 58 | encoder.SetCoderProperties(propIDs, properties); 59 | encoder.WriteCoderProperties(outStream); 60 | encoder.Code(inStream, outStream, -1, -1, null); 61 | return outStream.ToArray(); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /TypeTreeNode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace PrefabAPI 7 | { 8 | public class TypeTreeNode 9 | { 10 | public string m_Type; 11 | public string m_Name; 12 | public int m_ByteSize; 13 | public int m_Index; 14 | public int m_IsArray; //m_TypeFlags 15 | public int m_Version; 16 | public int m_MetaFlag; 17 | public int m_Level; 18 | public uint m_TypeStrOffset; 19 | public uint m_NameStrOffset; 20 | public ulong m_RefTypeHash; 21 | 22 | public TypeTreeNode() { } 23 | 24 | public TypeTreeNode(string type, string name, int level, bool align) 25 | { 26 | m_Type = type; 27 | m_Name = name; 28 | m_Level = level; 29 | m_MetaFlag = align ? 0x4000 : 0; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /prefab api.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecialAPI/PrefabAPI/f379bbfb872af2abd7197a4825e3854a9c9898ae/prefab api.zip --------------------------------------------------------------------------------