From 8ceac9000c2e4867171dab0361cc18bfe8a2d883 Mon Sep 17 00:00:00 2001 From: benshoof Date: Fri, 22 Jan 2016 14:32:35 -0900 Subject: [PATCH] SharpCompress now endian neutral SharpCompress can now be used on machines with big endian architecture such as powerpc. All byte conversions now run through Mono's DataConverter (or a portable version for builds that don't allow unsafe code) instead of BitConverter, as BitConverter's behavior depends on the host cpu. --- SharpCompress/Common/GZip/GZipFilePart.cs | 3 +- SharpCompress/Common/Tar/Headers/TarHeader.cs | 14 +- .../Common/Zip/Headers/ZipFileEntry.cs | 5 +- .../Zip/WinzipAesCryptoStream.Portable.cs | 3 +- .../Common/Zip/WinzipAesCryptoStream.cs | 3 +- .../Zip/WinzipAesEncryptionData.Portable.cs | 5 +- .../Common/Zip/WinzipAesEncryptionData.cs | 5 +- SharpCompress/Common/Zip/ZipFilePart.cs | 7 +- .../Compressor/Deflate/GZipStream.cs | 3 +- .../Compressor/Deflate/ZlibBaseStream.cs | 11 +- SharpCompress/Compressor/LZMA/LzmaStream.cs | 3 +- SharpCompress/Compressor/PPMd/H/FreqData.cs | 13 +- SharpCompress/Compressor/PPMd/H/PPMContext.cs | 9 +- .../Compressor/PPMd/H/RarMemBlock.cs | 18 +- SharpCompress/Compressor/PPMd/H/RarNode.cs | 5 +- SharpCompress/Compressor/PPMd/H/State.cs | 5 +- .../Compressor/PPMd/PpmdProperties.cs | 7 +- SharpCompress/Compressor/Rar/VM/RarVM.cs | 22 +- .../Converter/DataConverter.Portable.cs | 237 +++ SharpCompress/Converter/DataConverter.cs | 1849 +++++++++++++++++ SharpCompress/Crypto/PBKDF2.cs | 21 +- SharpCompress/IO/MarkingBinaryReader.cs | 32 +- SharpCompress/SharpCompress.Portable.csproj | 1 + .../SharpCompress.PortableTest.csproj | 1 + SharpCompress/SharpCompress.Unsigned.csproj | 1 + .../SharpCompress.WindowsStore.csproj | 1 + SharpCompress/SharpCompress.csproj | 1 + SharpCompress/Utility.cs | 197 -- .../Writer/Zip/ZipCentralDirectoryEntry.cs | 29 +- SharpCompress/Writer/Zip/ZipWriter.cs | 31 +- 30 files changed, 2208 insertions(+), 334 deletions(-) create mode 100644 SharpCompress/Converter/DataConverter.Portable.cs create mode 100644 SharpCompress/Converter/DataConverter.cs diff --git a/SharpCompress/Common/GZip/GZipFilePart.cs b/SharpCompress/Common/GZip/GZipFilePart.cs index 5aab3dba..673e50ea 100644 --- a/SharpCompress/Common/GZip/GZipFilePart.cs +++ b/SharpCompress/Common/GZip/GZipFilePart.cs @@ -3,6 +3,7 @@ using System.IO; using SharpCompress.Common.Tar.Headers; using SharpCompress.Compressor; using SharpCompress.Compressor.Deflate; +using SharpCompress.Converter; namespace SharpCompress.Common.GZip { @@ -50,7 +51,7 @@ namespace SharpCompress.Common.GZip if (header[0] != 0x1F || header[1] != 0x8B || header[2] != 8) throw new ZlibException("Bad GZIP header."); - Int32 timet = BitConverter.ToInt32(header, 4); + Int32 timet = DataConverter.LittleEndian.GetInt32(header, 4); DateModified = TarHeader.Epoch.AddSeconds(timet); if ((header[3] & 0x04) == 0x04) { diff --git a/SharpCompress/Common/Tar/Headers/TarHeader.cs b/SharpCompress/Common/Tar/Headers/TarHeader.cs index 8323fc3f..fa59c1c3 100644 --- a/SharpCompress/Common/Tar/Headers/TarHeader.cs +++ b/SharpCompress/Common/Tar/Headers/TarHeader.cs @@ -4,6 +4,7 @@ using System.IO; using System.Net; #endif using System.Text; +using SharpCompress.Converter; namespace SharpCompress.Common.Tar.Headers { @@ -64,11 +65,7 @@ namespace SharpCompress.Common.Tar.Headers if (Size >= 0x1FFFFFFFF) { -#if PORTABLE || NETFX_CORE - byte[] bytes = BitConverter.GetBytes(Utility.HostToNetworkOrder(Size)); -#else - byte[] bytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(Size)); -#endif + byte[] bytes = DataConverter.BigEndian.GetBytes(Size); var bytes12 = new byte[12]; bytes.CopyTo(bytes12, 12 - bytes.Length); bytes12[0] |= 0x80; @@ -119,12 +116,7 @@ namespace SharpCompress.Common.Tar.Headers EntryType = (EntryType) buffer[156]; if ((buffer[124] & 0x80) == 0x80) // if size in binary { - long sizeBigEndian = BitConverter.ToInt64(buffer, 0x80); -#if PORTABLE || NETFX_CORE - Size = Utility.NetworkToHostOrder(sizeBigEndian); -#else - Size = IPAddress.NetworkToHostOrder(sizeBigEndian); -#endif + Size = DataConverter.BigEndian.GetInt64(buffer, 0x80); } else { diff --git a/SharpCompress/Common/Zip/Headers/ZipFileEntry.cs b/SharpCompress/Common/Zip/Headers/ZipFileEntry.cs index f5a813ed..08b4772e 100644 --- a/SharpCompress/Common/Zip/Headers/ZipFileEntry.cs +++ b/SharpCompress/Common/Zip/Headers/ZipFileEntry.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Text; +using SharpCompress.Converter; namespace SharpCompress.Common.Zip.Headers { @@ -68,13 +69,13 @@ namespace SharpCompress.Common.Zip.Headers { for (int i = 0; i < extra.Length-4;) { - ExtraDataType type = (ExtraDataType) BitConverter.ToUInt16(extra, i); + ExtraDataType type = (ExtraDataType)DataConverter.LittleEndian.GetUInt16(extra, i); if (!Enum.IsDefined(typeof (ExtraDataType), type)) { type = ExtraDataType.NotImplementedExtraData; } - ushort length = BitConverter.ToUInt16(extra, i + 2); + ushort length = DataConverter.LittleEndian.GetUInt16(extra, i + 2); byte[] data = new byte[length]; Buffer.BlockCopy(extra, i + 4, data, 0, length); Extra.Add(LocalEntryHeaderExtraFactory.Create(type,length,data)); diff --git a/SharpCompress/Common/Zip/WinzipAesCryptoStream.Portable.cs b/SharpCompress/Common/Zip/WinzipAesCryptoStream.Portable.cs index 1acbeefd..8611a76a 100644 --- a/SharpCompress/Common/Zip/WinzipAesCryptoStream.Portable.cs +++ b/SharpCompress/Common/Zip/WinzipAesCryptoStream.Portable.cs @@ -3,6 +3,7 @@ using System.IO; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Engines; using Org.BouncyCastle.Crypto.Parameters; +using SharpCompress.Converter; namespace SharpCompress.Common.Zip { @@ -113,7 +114,7 @@ namespace SharpCompress.Common.Zip : bytesRemaining; // update the counter - Array.Copy(BitConverter.GetBytes(nonce++), 0, counter, 0, 4); + DataConverter.LittleEndian.PutBytes(counter, 0, nonce++); // Determine if this is the final block if ((bytesToRead == bytesRemaining) && (totalBytesLeftToRead == 0)) diff --git a/SharpCompress/Common/Zip/WinzipAesCryptoStream.cs b/SharpCompress/Common/Zip/WinzipAesCryptoStream.cs index 9d8e14ca..ead9d548 100644 --- a/SharpCompress/Common/Zip/WinzipAesCryptoStream.cs +++ b/SharpCompress/Common/Zip/WinzipAesCryptoStream.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Security.Cryptography; +using SharpCompress.Converter; namespace SharpCompress.Common.Zip { @@ -117,7 +118,7 @@ namespace SharpCompress.Common.Zip : bytesRemaining; // update the counter - Array.Copy(BitConverter.GetBytes(nonce++), 0, counter, 0, 4); + DataConverter.LittleEndian.PutBytes(counter, 0, nonce++); // Determine if this is the final block if ((bytesToRead == bytesRemaining) && (totalBytesLeftToRead == 0)) diff --git a/SharpCompress/Common/Zip/WinzipAesEncryptionData.Portable.cs b/SharpCompress/Common/Zip/WinzipAesEncryptionData.Portable.cs index 0fe7050d..79a405cc 100644 --- a/SharpCompress/Common/Zip/WinzipAesEncryptionData.Portable.cs +++ b/SharpCompress/Common/Zip/WinzipAesEncryptionData.Portable.cs @@ -1,5 +1,6 @@ using System; using System.Text; +using SharpCompress.Converter; using SharpCompress.Crypto; namespace SharpCompress.Common.Zip @@ -56,10 +57,10 @@ namespace SharpCompress.Common.Zip generatedVerifyValue = paramz.GetBytes(2); - short verify = BitConverter.ToInt16(passwordVerifyValue, 0); + short verify = DataConverter.LittleEndian.GetInt16(passwordVerifyValue, 0); if (password != null) { - short generated = BitConverter.ToInt16(generatedVerifyValue, 0); + short generated = DataConverter.LittleEndian.GetInt16(generatedVerifyValue, 0); if (verify != generated) throw new InvalidFormatException("bad password"); } diff --git a/SharpCompress/Common/Zip/WinzipAesEncryptionData.cs b/SharpCompress/Common/Zip/WinzipAesEncryptionData.cs index eb37ac98..a5de3294 100644 --- a/SharpCompress/Common/Zip/WinzipAesEncryptionData.cs +++ b/SharpCompress/Common/Zip/WinzipAesEncryptionData.cs @@ -1,4 +1,5 @@ using System; +using SharpCompress.Converter; namespace SharpCompress.Common.Zip { @@ -54,10 +55,10 @@ namespace SharpCompress.Common.Zip IvBytes = rfc2898.GetBytes(KeySizeInBytes); generatedVerifyValue = rfc2898.GetBytes(2); - short verify = BitConverter.ToInt16(passwordVerifyValue, 0); + short verify = DataConverter.LittleEndian.GetInt16(passwordVerifyValue, 0); if (password != null) { - short generated = BitConverter.ToInt16(generatedVerifyValue, 0); + short generated = DataConverter.LittleEndian.GetInt16(generatedVerifyValue, 0); if (verify != generated) throw new InvalidFormatException("bad password"); } diff --git a/SharpCompress/Common/Zip/ZipFilePart.cs b/SharpCompress/Common/Zip/ZipFilePart.cs index 6052d593..43ec7122 100644 --- a/SharpCompress/Common/Zip/ZipFilePart.cs +++ b/SharpCompress/Common/Zip/ZipFilePart.cs @@ -7,6 +7,7 @@ using SharpCompress.Compressor.BZip2; using SharpCompress.Compressor.Deflate; using SharpCompress.Compressor.LZMA; using SharpCompress.Compressor.PPMd; +using SharpCompress.Converter; using SharpCompress.IO; namespace SharpCompress.Common.Zip @@ -108,19 +109,19 @@ namespace SharpCompress.Common.Zip { throw new InvalidFormatException("Winzip data length is not 7."); } - ushort method = BitConverter.ToUInt16(data.DataBytes, 0); + ushort method = DataConverter.LittleEndian.GetUInt16(data.DataBytes, 0); if (method != 0x01 && method != 0x02) { throw new InvalidFormatException("Unexpected vendor version number for WinZip AES metadata"); } - ushort vendorId = BitConverter.ToUInt16(data.DataBytes, 2); + ushort vendorId = DataConverter.LittleEndian.GetUInt16(data.DataBytes, 2); if (vendorId != 0x4541) { throw new InvalidFormatException("Unexpected vendor ID for WinZip AES metadata"); } - Header.CompressionMethod = (ZipCompressionMethod)BitConverter.ToUInt16(data.DataBytes, 5); + Header.CompressionMethod = (ZipCompressionMethod)DataConverter.LittleEndian.GetUInt16(data.DataBytes, 5); return CreateDecompressionStream(stream); } default: diff --git a/SharpCompress/Compressor/Deflate/GZipStream.cs b/SharpCompress/Compressor/Deflate/GZipStream.cs index 7b3215d9..308bc692 100644 --- a/SharpCompress/Compressor/Deflate/GZipStream.cs +++ b/SharpCompress/Compressor/Deflate/GZipStream.cs @@ -30,6 +30,7 @@ using System; using System.IO; using SharpCompress.Common; +using SharpCompress.Converter; namespace SharpCompress.Compressor.Deflate { @@ -417,7 +418,7 @@ namespace SharpCompress.Compressor.Deflate LastModified = DateTime.Now; TimeSpan delta = LastModified.Value - UnixEpoch; var timet = (Int32) delta.TotalSeconds; - Array.Copy(BitConverter.GetBytes(timet), 0, header, i, 4); + DataConverter.LittleEndian.PutBytes(header, i, timet); i += 4; // xflg diff --git a/SharpCompress/Compressor/Deflate/ZlibBaseStream.cs b/SharpCompress/Compressor/Deflate/ZlibBaseStream.cs index 1bfe1f6e..7d753dff 100644 --- a/SharpCompress/Compressor/Deflate/ZlibBaseStream.cs +++ b/SharpCompress/Compressor/Deflate/ZlibBaseStream.cs @@ -27,6 +27,7 @@ using System; using SharpCompress.Common; using SharpCompress.Common.Tar.Headers; +using SharpCompress.Converter; namespace SharpCompress.Compressor.Deflate { @@ -221,9 +222,9 @@ namespace SharpCompress.Compressor.Deflate { // Emit the GZIP trailer: CRC32 and size mod 2^32 int c1 = crc.Crc32Result; - _stream.Write(BitConverter.GetBytes(c1), 0, 4); + _stream.Write(DataConverter.LittleEndian.GetBytes(c1), 0, 4); int c2 = (Int32)(crc.TotalBytesRead & 0x00000000FFFFFFFF); - _stream.Write(BitConverter.GetBytes(c2), 0, 4); + _stream.Write(DataConverter.LittleEndian.GetBytes(c2), 0, 4); } else { @@ -267,9 +268,9 @@ namespace SharpCompress.Compressor.Deflate } - Int32 crc32_expected = BitConverter.ToInt32(trailer, 0); + Int32 crc32_expected = DataConverter.LittleEndian.GetInt32(trailer, 0); Int32 crc32_actual = crc.Crc32Result; - Int32 isize_expected = BitConverter.ToInt32(trailer, 4); + Int32 isize_expected = DataConverter.LittleEndian.GetInt32(trailer, 4); Int32 isize_actual = (Int32)(_z.TotalBytesOut & 0x00000000FFFFFFFF); if (crc32_actual != crc32_expected) @@ -405,7 +406,7 @@ namespace SharpCompress.Compressor.Deflate if (header[0] != 0x1F || header[1] != 0x8B || header[2] != 8) throw new ZlibException("Bad GZIP header."); - Int32 timet = BitConverter.ToInt32(header, 4); + Int32 timet = DataConverter.LittleEndian.GetInt32(header, 4); _GzipMtime = TarHeader.Epoch.AddSeconds(timet); totalBytesRead += n; if ((header[3] & 0x04) == 0x04) diff --git a/SharpCompress/Compressor/LZMA/LzmaStream.cs b/SharpCompress/Compressor/LZMA/LzmaStream.cs index 22522f9d..bc046e70 100644 --- a/SharpCompress/Compressor/LZMA/LzmaStream.cs +++ b/SharpCompress/Compressor/LZMA/LzmaStream.cs @@ -1,6 +1,7 @@ using System; using System.IO; using SharpCompress.Compressor.LZMA.LZ; +using SharpCompress.Converter; namespace SharpCompress.Compressor.LZMA { @@ -56,7 +57,7 @@ namespace SharpCompress.Compressor.LZMA if (!isLZMA2) { - dictionarySize = BitConverter.ToInt32(properties, 1); + dictionarySize = DataConverter.LittleEndian.GetInt32(properties, 1); outWindow.Create(dictionarySize); if (presetDictionary != null) outWindow.Train(presetDictionary); diff --git a/SharpCompress/Compressor/PPMd/H/FreqData.cs b/SharpCompress/Compressor/PPMd/H/FreqData.cs index a37ea93a..b94e01dd 100644 --- a/SharpCompress/Compressor/PPMd/H/FreqData.cs +++ b/SharpCompress/Compressor/PPMd/H/FreqData.cs @@ -1,4 +1,5 @@ using System.Text; +using SharpCompress.Converter; namespace SharpCompress.Compressor.PPMd.H { @@ -19,9 +20,9 @@ namespace SharpCompress.Compressor.PPMd.H internal int SummFreq { - get { return Utility.readShortLittleEndian(Memory, Address) & 0xffff; } + get { return DataConverter.LittleEndian.GetInt16(Memory, Address) & 0xffff; } - set { Utility.WriteLittleEndian(Memory, Address, (short) value); } + set { DataConverter.LittleEndian.PutBytes(Memory, Address, (short)value); } } internal FreqData Initialize(byte[] mem) @@ -31,12 +32,14 @@ namespace SharpCompress.Compressor.PPMd.H internal void IncrementSummFreq(int dSummFreq) { - Utility.incShortLittleEndian(Memory, Address, (short) dSummFreq); + short summFreq = DataConverter.LittleEndian.GetInt16(Memory, Address); + summFreq += (short)dSummFreq; + DataConverter.LittleEndian.PutBytes(Memory, Address, summFreq); } internal int GetStats() { - return Utility.readIntLittleEndian(Memory, Address + 2); + return DataConverter.LittleEndian.GetInt32(Memory, Address + 2); } internal virtual void SetStats(State state) @@ -46,7 +49,7 @@ namespace SharpCompress.Compressor.PPMd.H internal void SetStats(int state) { - Utility.WriteLittleEndian(Memory, Address + 2, state); + DataConverter.LittleEndian.PutBytes(Memory, Address + 2, state); } public override System.String ToString() diff --git a/SharpCompress/Compressor/PPMd/H/PPMContext.cs b/SharpCompress/Compressor/PPMd/H/PPMContext.cs index 8b36bf6d..f2029f96 100644 --- a/SharpCompress/Compressor/PPMd/H/PPMContext.cs +++ b/SharpCompress/Compressor/PPMd/H/PPMContext.cs @@ -1,4 +1,5 @@ using System.Text; +using SharpCompress.Converter; namespace SharpCompress.Compressor.PPMd.H { @@ -21,7 +22,7 @@ namespace SharpCompress.Compressor.PPMd.H { if (Memory != null) { - numStats = Utility.readShortLittleEndian(Memory, Address) & 0xffff; + numStats = DataConverter.LittleEndian.GetInt16(Memory, Address) & 0xffff; } return numStats; } @@ -31,7 +32,7 @@ namespace SharpCompress.Compressor.PPMd.H this.numStats = value & 0xffff; if (Memory != null) { - Utility.WriteLittleEndian(Memory, Address, (short) value); + DataConverter.LittleEndian.PutBytes(Memory, Address, (short) value); } } } @@ -103,7 +104,7 @@ namespace SharpCompress.Compressor.PPMd.H { if (Memory != null) { - suffix = Utility.readIntLittleEndian(Memory, Address + 8); + suffix = DataConverter.LittleEndian.GetInt32(Memory, Address + 8); } return suffix; } @@ -118,7 +119,7 @@ namespace SharpCompress.Compressor.PPMd.H this.suffix = suffix; if (Memory != null) { - Utility.WriteLittleEndian(Memory, Address + 8, suffix); + DataConverter.LittleEndian.PutBytes(Memory, Address + 8, suffix); } } diff --git a/SharpCompress/Compressor/PPMd/H/RarMemBlock.cs b/SharpCompress/Compressor/PPMd/H/RarMemBlock.cs index 52f601d8..0a71c529 100644 --- a/SharpCompress/Compressor/PPMd/H/RarMemBlock.cs +++ b/SharpCompress/Compressor/PPMd/H/RarMemBlock.cs @@ -1,3 +1,5 @@ +using SharpCompress.Converter; + namespace SharpCompress.Compressor.PPMd.H { internal class RarMemBlock : Pointer @@ -19,7 +21,7 @@ namespace SharpCompress.Compressor.PPMd.H { if (Memory != null) { - stamp = Utility.readShortLittleEndian(Memory, Address) & 0xffff; + stamp = DataConverter.LittleEndian.GetInt16(Memory, Address) & 0xffff; } return stamp; } @@ -29,7 +31,7 @@ namespace SharpCompress.Compressor.PPMd.H this.stamp = value; if (Memory != null) { - Utility.WriteLittleEndian(Memory, Address, (short) value); + DataConverter.LittleEndian.PutBytes(Memory, Address, (short)value); } } } @@ -60,7 +62,7 @@ namespace SharpCompress.Compressor.PPMd.H { if (Memory != null) { - next = Utility.readIntLittleEndian(Memory, Address + 4); + next = DataConverter.LittleEndian.GetInt32(Memory, Address + 4); } return next; } @@ -75,7 +77,7 @@ namespace SharpCompress.Compressor.PPMd.H this.next = next; if (Memory != null) { - Utility.WriteLittleEndian(Memory, Address + 4, next); + DataConverter.LittleEndian.PutBytes(Memory, Address + 4, next); } } @@ -83,7 +85,7 @@ namespace SharpCompress.Compressor.PPMd.H { if (Memory != null) { - NU = Utility.readShortLittleEndian(Memory, Address + 2) & 0xffff; + NU = DataConverter.LittleEndian.GetInt16(Memory, Address + 2) & 0xffff; } return NU; } @@ -93,7 +95,7 @@ namespace SharpCompress.Compressor.PPMd.H NU = nu & 0xffff; if (Memory != null) { - Utility.WriteLittleEndian(Memory, Address + 2, (short) nu); + DataConverter.LittleEndian.PutBytes(Memory, Address + 2, (short)nu); } } @@ -101,7 +103,7 @@ namespace SharpCompress.Compressor.PPMd.H { if (Memory != null) { - prev = Utility.readIntLittleEndian(Memory, Address + 8); + prev = DataConverter.LittleEndian.GetInt32(Memory, Address + 8); } return prev; } @@ -116,7 +118,7 @@ namespace SharpCompress.Compressor.PPMd.H this.prev = prev; if (Memory != null) { - Utility.WriteLittleEndian(Memory, Address + 8, prev); + DataConverter.LittleEndian.PutBytes(Memory, Address + 8, prev); } } } diff --git a/SharpCompress/Compressor/PPMd/H/RarNode.cs b/SharpCompress/Compressor/PPMd/H/RarNode.cs index 2369fb5a..ffb75c50 100644 --- a/SharpCompress/Compressor/PPMd/H/RarNode.cs +++ b/SharpCompress/Compressor/PPMd/H/RarNode.cs @@ -1,4 +1,5 @@ using System.Text; +using SharpCompress.Converter; namespace SharpCompress.Compressor.PPMd.H { @@ -17,7 +18,7 @@ namespace SharpCompress.Compressor.PPMd.H { if (Memory != null) { - next = Utility.readIntLittleEndian(Memory, Address); + next = DataConverter.LittleEndian.GetInt32(Memory, Address); } return next; } @@ -32,7 +33,7 @@ namespace SharpCompress.Compressor.PPMd.H this.next = next; if (Memory != null) { - Utility.WriteLittleEndian(Memory, Address, next); + DataConverter.LittleEndian.PutBytes(Memory, Address, next); } } diff --git a/SharpCompress/Compressor/PPMd/H/State.cs b/SharpCompress/Compressor/PPMd/H/State.cs index a459321e..687883c4 100644 --- a/SharpCompress/Compressor/PPMd/H/State.cs +++ b/SharpCompress/Compressor/PPMd/H/State.cs @@ -1,5 +1,6 @@ using System; using System.Text; +using SharpCompress.Converter; namespace SharpCompress.Compressor.PPMd.H { @@ -38,7 +39,7 @@ namespace SharpCompress.Compressor.PPMd.H internal int GetSuccessor() { - return Utility.readIntLittleEndian(Memory, Address + 2); + return DataConverter.LittleEndian.GetInt32(Memory, Address + 2); } internal void SetSuccessor(PPMContext successor) @@ -48,7 +49,7 @@ namespace SharpCompress.Compressor.PPMd.H internal void SetSuccessor(int successor) { - Utility.WriteLittleEndian(Memory, Address + 2, successor); + DataConverter.LittleEndian.PutBytes(Memory, Address + 2, successor); } internal void SetValues(StateRef state) diff --git a/SharpCompress/Compressor/PPMd/PpmdProperties.cs b/SharpCompress/Compressor/PPMd/PpmdProperties.cs index 9527835b..5875bcac 100644 --- a/SharpCompress/Compressor/PPMd/PpmdProperties.cs +++ b/SharpCompress/Compressor/PPMd/PpmdProperties.cs @@ -1,4 +1,5 @@ using System; +using SharpCompress.Converter; namespace SharpCompress.Compressor.PPMd { @@ -39,7 +40,7 @@ namespace SharpCompress.Compressor.PPMd { if (properties.Length == 2) { - ushort props = BitConverter.ToUInt16(properties, 0); + ushort props = DataConverter.LittleEndian.GetUInt16(properties, 0); AllocatorSize = (((props >> 4) & 0xff) + 1) << 20; ModelOrder = (props & 0x0f) + 1; ModelRestorationMethod = (I1.ModelRestorationMethod) (props >> 12); @@ -47,7 +48,7 @@ namespace SharpCompress.Compressor.PPMd else if (properties.Length == 5) { Version = PpmdVersion.H7z; - AllocatorSize = BitConverter.ToInt32(properties, 1); + AllocatorSize = DataConverter.LittleEndian.GetInt32(properties, 1); ModelOrder = properties[0]; } } @@ -72,7 +73,7 @@ namespace SharpCompress.Compressor.PPMd get { return - BitConverter.GetBytes( + DataConverter.LittleEndian.GetBytes( (ushort) ((ModelOrder - 1) + (((AllocatorSize >> 20) - 1) << 4) + ((ushort) ModelRestorationMethod << 12))); } diff --git a/SharpCompress/Compressor/Rar/VM/RarVM.cs b/SharpCompress/Compressor/Rar/VM/RarVM.cs index f1f25d34..27990a33 100644 --- a/SharpCompress/Compressor/Rar/VM/RarVM.cs +++ b/SharpCompress/Compressor/Rar/VM/RarVM.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using SharpCompress.Converter; namespace SharpCompress.Compressor.Rar.VM { @@ -77,11 +78,12 @@ namespace SharpCompress.Compressor.Rar.VM { if (IsVMMem(mem)) { - return Utility.readIntLittleEndian(mem, offset); + return DataConverter.LittleEndian.GetInt32(mem, offset); } else { - return Utility.readIntBigEndian(mem, offset); + return DataConverter.BigEndian.GetInt32(mem, offset); + } } } @@ -103,19 +105,11 @@ namespace SharpCompress.Compressor.Rar.VM { if (IsVMMem(mem)) { - Utility.WriteLittleEndian(mem, offset, value); - // Mem[offset + 0] = (byte) value; - // Mem[offset + 1] = (byte) (value >>> 8); - // Mem[offset + 2] = (byte) (value >>> 16); - // Mem[offset + 3] = (byte) (value >>> 24); + DataConverter.LittleEndian.PutBytes(mem, offset, value); } else { - Utility.writeIntBigEndian(mem, offset, value); - // Mem[offset + 3] = (byte) value; - // Mem[offset + 2] = (byte) (value >>> 8); - // Mem[offset + 1] = (byte) (value >>> 16); - // Mem[offset + 0] = (byte) (value >>> 24); + DataConverter.BigEndian.PutBytes(mem, offset, value); } } // #define SET_VALUE(ByteMode,Addr,Value) SetValue(ByteMode,(uint @@ -136,12 +130,12 @@ namespace SharpCompress.Compressor.Rar.VM if (cmdOp.Type == VMOpType.VM_OPREGMEM) { int pos = (cmdOp.Offset + cmdOp.Base) & VM_MEMMASK; - ret = Utility.readIntLittleEndian(Mem, pos); + ret = DataConverter.LittleEndian.GetInt32(Mem, pos); } else { int pos = cmdOp.Offset; - ret = Utility.readIntLittleEndian(Mem, pos); + ret = DataConverter.LittleEndian.GetInt32(Mem, pos); } return ret; } diff --git a/SharpCompress/Converter/DataConverter.Portable.cs b/SharpCompress/Converter/DataConverter.Portable.cs new file mode 100644 index 00000000..eec9846b --- /dev/null +++ b/SharpCompress/Converter/DataConverter.Portable.cs @@ -0,0 +1,237 @@ +using System; + +namespace SharpCompress.Converter +{ + // This is a portable version of Mono's DataConverter class with just the small subset of functionality + // needed by SharpCompress. Portable in this case means that it contains no unsafe code. + // + // This class simply wraps BitConverter and reverses byte arrays when endianess doesn't match the host's. + // + // Everything public in this class must match signatures in Mono's DataConverter. + + abstract class DataConverter + { + static readonly DataConverter copyConverter = new CopyConverter(); + static readonly DataConverter swapConverter = new SwapConverter(); + + static readonly bool isLittleEndian = BitConverter.IsLittleEndian; + + public static DataConverter LittleEndian + { + get { return isLittleEndian ? copyConverter : swapConverter; } + } + + public static DataConverter BigEndian + { + get { return isLittleEndian ? swapConverter : copyConverter; } + } + + public abstract Int16 GetInt16(byte[] data, int index); + public abstract UInt16 GetUInt16(byte[] data, int index); + public abstract Int32 GetInt32(byte[] data, int index); + public abstract UInt32 GetUInt32(byte[] data, int index); + public abstract Int64 GetInt64(byte[] data, int index); + public abstract UInt64 GetUInt64(byte[] data, int index); + + public abstract byte[] GetBytes(Int16 value); + public abstract byte[] GetBytes(UInt16 value); + public abstract byte[] GetBytes(Int32 value); + public abstract byte[] GetBytes(UInt32 value); + public abstract byte[] GetBytes(Int64 value); + public abstract byte[] GetBytes(UInt64 value); + + public void PutBytes(byte[] data, int index, Int16 value) + { + byte[] temp = GetBytes(value); + Array.Copy(temp, 0, data, index, 2); + } + + public void PutBytes(byte[] data, int index, UInt16 value) + { + byte[] temp = GetBytes(value); + Array.Copy(temp, 0, data, index, 2); + } + + public void PutBytes(byte[] data, int index, Int32 value) + { + byte[] temp = GetBytes(value); + Array.Copy(temp, 0, data, index, 4); + } + + public void PutBytes(byte[] data, int index, UInt32 value) + { + byte[] temp = GetBytes(value); + Array.Copy(temp, 0, data, index, 4); + } + + public void PutBytes(byte[] data, int index, Int64 value) + { + byte[] temp = GetBytes(value); + Array.Copy(temp, 0, data, index, 8); + } + + public void PutBytes(byte[] data, int index, UInt64 value) + { + byte[] temp = GetBytes(value); + Array.Copy(temp, 0, data, index, 8); + } + + // CopyConverter wraps BitConverter making all conversions host endian + class CopyConverter : DataConverter + { + public override Int16 GetInt16(byte[] data, int index) + { + return BitConverter.ToInt16(data, index); + } + + public override UInt16 GetUInt16(byte[] data, int index) + { + return BitConverter.ToUInt16(data, index); + } + + public override Int32 GetInt32(byte[] data, int index) + { + return BitConverter.ToInt32(data, index); + } + + public override UInt32 GetUInt32(byte[] data, int index) + { + return BitConverter.ToUInt32(data, index); + } + + public override Int64 GetInt64(byte[] data, int index) + { + return BitConverter.ToInt64(data, index); + } + + public override UInt64 GetUInt64(byte[] data, int index) + { + return BitConverter.ToUInt64(data, index); + } + + public override byte[] GetBytes(Int16 value) + { + return BitConverter.GetBytes(value); + } + + public override byte[] GetBytes(UInt16 value) + { + return BitConverter.GetBytes(value); + } + + public override byte[] GetBytes(Int32 value) + { + return BitConverter.GetBytes(value); + } + + public override byte[] GetBytes(UInt32 value) + { + return BitConverter.GetBytes(value); + } + + public override byte[] GetBytes(Int64 value) + { + return BitConverter.GetBytes(value); + } + + public override byte[] GetBytes(UInt64 value) + { + return BitConverter.GetBytes(value); + } + } + + // SwapConverter wraps and reverses BitConverter making all conversions the opposite of host endian + class SwapConverter : DataConverter + { + public override Int16 GetInt16(byte[] data, int index) + { + byte[] temp = new byte[2]; + Array.Copy(data, index, temp, 0, 2); + Array.Reverse(temp); + return BitConverter.ToInt16(temp, 0); + } + + public override UInt16 GetUInt16(byte[] data, int index) + { + byte[] temp = new byte[2]; + Array.Copy(data, index, temp, 0, 2); + Array.Reverse(temp); + return BitConverter.ToUInt16(temp, 0); + } + + public override Int32 GetInt32(byte[] data, int index) + { + byte[] temp = new byte[4]; + Array.Copy(data, index, temp, 0, 4); + Array.Reverse(temp); + return BitConverter.ToInt32(temp, 0); + } + + public override UInt32 GetUInt32(byte[] data, int index) + { + byte[] temp = new byte[4]; + Array.Copy(data, index, temp, 0, 4); + Array.Reverse(temp); + return BitConverter.ToUInt32(temp, 0); + } + + public override Int64 GetInt64(byte[] data, int index) + { + byte[] temp = new byte[8]; + Array.Copy(data, index, temp, 0, 8); + Array.Reverse(temp); + return BitConverter.ToInt64(temp, 0); + } + + public override UInt64 GetUInt64(byte[] data, int index) + { + byte[] temp = new byte[8]; + Array.Copy(data, index, temp, 0, 8); + Array.Reverse(temp); + return BitConverter.ToUInt64(temp, 0); + } + + public override byte[] GetBytes(Int16 value) + { + byte[] ret = BitConverter.GetBytes(value); + Array.Reverse(ret); + return ret; + } + + public override byte[] GetBytes(UInt16 value) + { + byte[] ret = BitConverter.GetBytes(value); + Array.Reverse(ret); + return ret; + } + + public override byte[] GetBytes(Int32 value) + { + byte[] ret = BitConverter.GetBytes(value); + Array.Reverse(ret); + return ret; + } + + public override byte[] GetBytes(UInt32 value) + { + byte[] ret = BitConverter.GetBytes(value); + Array.Reverse(ret); + return ret; + } + + public override byte[] GetBytes(Int64 value) + { + byte[] ret = BitConverter.GetBytes(value); + Array.Reverse(ret); + return ret; + } + + public override byte[] GetBytes(UInt64 value) + { + byte[] ret = BitConverter.GetBytes(value); + Array.Reverse(ret); + return ret; + } + } + } +} \ No newline at end of file diff --git a/SharpCompress/Converter/DataConverter.cs b/SharpCompress/Converter/DataConverter.cs new file mode 100644 index 00000000..0b2acd9f --- /dev/null +++ b/SharpCompress/Converter/DataConverter.cs @@ -0,0 +1,1849 @@ +// +// Authors: +// Miguel de Icaza (miguel@novell.com) +// +// See the following url for documentation: +// http://www.mono-project.com/Mono_DataConvert +// +// Compilation Options: +// MONO_DATACONVERTER_PUBLIC: +// Makes the class public instead of the default internal. +// +// MONO_DATACONVERTER_STATIC_METHODS: +// Exposes the public static methods. +// +// TODO: +// Support for "DoubleWordsAreSwapped" for ARM devices +// +// Copyright (C) 2006 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections; +using System.Text; +using System.Collections.Generic; + +#pragma warning disable 3021 + +namespace SharpCompress.Converter { + +#if MONO_DATACONVERTER_PUBLIC + public +#endif + unsafe abstract class DataConverter { + +// Disables the warning: CLS compliance checking will not be performed on +// `XXXX' because it is not visible from outside this assembly +#pragma warning disable 3019 + static readonly DataConverter SwapConv = new SwapConverter (); + static readonly DataConverter CopyConv = new CopyConverter (); + + public static readonly bool IsLittleEndian = BitConverter.IsLittleEndian; + + public abstract double GetDouble (byte [] data, int index); + public abstract float GetFloat (byte [] data, int index); + public abstract long GetInt64 (byte [] data, int index); + public abstract int GetInt32 (byte [] data, int index); + + public abstract short GetInt16 (byte [] data, int index); + + [CLSCompliant (false)] + public abstract uint GetUInt32 (byte [] data, int index); + [CLSCompliant (false)] + public abstract ushort GetUInt16 (byte [] data, int index); + [CLSCompliant (false)] + public abstract ulong GetUInt64 (byte [] data, int index); + + public abstract void PutBytes (byte [] dest, int destIdx, double value); + public abstract void PutBytes (byte [] dest, int destIdx, float value); + public abstract void PutBytes (byte [] dest, int destIdx, int value); + public abstract void PutBytes (byte [] dest, int destIdx, long value); + public abstract void PutBytes (byte [] dest, int destIdx, short value); + + [CLSCompliant (false)] + public abstract void PutBytes (byte [] dest, int destIdx, ushort value); + [CLSCompliant (false)] + public abstract void PutBytes (byte [] dest, int destIdx, uint value); + [CLSCompliant (false)] + public abstract void PutBytes (byte [] dest, int destIdx, ulong value); + + public byte[] GetBytes (double value) + { + byte [] ret = new byte [8]; + PutBytes (ret, 0, value); + return ret; + } + + public byte[] GetBytes (float value) + { + byte [] ret = new byte [4]; + PutBytes (ret, 0, value); + return ret; + } + + public byte[] GetBytes (int value) + { + byte [] ret = new byte [4]; + PutBytes (ret, 0, value); + return ret; + } + + public byte[] GetBytes (long value) + { + byte [] ret = new byte [8]; + PutBytes (ret, 0, value); + return ret; + } + + public byte[] GetBytes (short value) + { + byte [] ret = new byte [2]; + PutBytes (ret, 0, value); + return ret; + } + + [CLSCompliant (false)] + public byte[] GetBytes (ushort value) + { + byte [] ret = new byte [2]; + PutBytes (ret, 0, value); + return ret; + } + + [CLSCompliant (false)] + public byte[] GetBytes (uint value) + { + byte [] ret = new byte [4]; + PutBytes (ret, 0, value); + return ret; + } + + [CLSCompliant (false)] + public byte[] GetBytes (ulong value) + { + byte [] ret = new byte [8]; + PutBytes (ret, 0, value); + return ret; + } + + static public DataConverter LittleEndian { + get { + return BitConverter.IsLittleEndian ? CopyConv : SwapConv; + } + } + + static public DataConverter BigEndian { + get { + return BitConverter.IsLittleEndian ? SwapConv : CopyConv; + } + } + + static public DataConverter Native { + get { + return CopyConv; + } + } + + static int Align (int current, int align) + { + return ((current + align - 1) / align) * align; + } + + class PackContext { + // Buffer + public byte [] buffer; + int next; + + public string description; + public int i; // position in the description + public DataConverter conv; + public int repeat; + + // + // if align == -1, auto align to the size of the byte array + // if align == 0, do not do alignment + // Any other values aligns to that particular size + // + public int align; + + public void Add (byte [] group) + { + //Console.WriteLine ("Adding {0} bytes to {1} (next={2}", group.Length, + // buffer == null ? "null" : buffer.Length.ToString (), next); + + if (buffer == null){ + buffer = group; + next = group.Length; + return; + } + if (align != 0){ + if (align == -1) + next = Align (next, group.Length); + else + next = Align (next, align); + align = 0; + } + + if (next + group.Length > buffer.Length){ + byte [] nb = new byte [System.Math.Max (next, 16) * 2 + group.Length]; + Array.Copy (buffer, nb, buffer.Length); + Array.Copy (group, 0, nb, next, group.Length); + next = next + group.Length; + buffer = nb; + } else { + Array.Copy (group, 0, buffer, next, group.Length); + next += group.Length; + } + } + + public byte [] Get () + { + if (buffer == null) + return new byte [0]; + + if (buffer.Length != next){ + byte [] b = new byte [next]; + Array.Copy (buffer, b, next); + return b; + } + return buffer; + } + } + + // + // Format includes: + // Control: + // ^ Switch to big endian encoding + // _ Switch to little endian encoding + // % Switch to host (native) encoding + // ! aligns the next data type to its natural boundary (for strings this is 4). + // + // Types: + // s Int16 + // S UInt16 + // i Int32 + // I UInt32 + // l Int64 + // L UInt64 + // f float + // d double + // b byte + // c 1-byte signed character + // C 1-byte unsigned character + // z8 string encoded as UTF8 with 1-byte null terminator + // z6 string encoded as UTF16 with 2-byte null terminator + // z7 string encoded as UTF7 with 1-byte null terminator + // zb string encoded as BigEndianUnicode with 2-byte null terminator + // z3 string encoded as UTF32 with 4-byte null terminator + // z4 string encoded as UTF32 big endian with 4-byte null terminator + // $8 string encoded as UTF8 + // $6 string encoded as UTF16 + // $7 string encoded as UTF7 + // $b string encoded as BigEndianUnicode + // $3 string encoded as UTF32 + // $4 string encoded as UTF-32 big endian encoding + // x null byte + // + // Repeats, these are prefixes: + // N a number between 1 and 9, indicates a repeat count (process N items + // with the following datatype + // [N] For numbers larger than 9, use brackets, for example [20] + // * Repeat the next data type until the arguments are exhausted + // + static public byte [] Pack (string description, params object [] args) + { + int argn = 0; + PackContext b = new PackContext (); + b.conv = CopyConv; + b.description = description; + + for (b.i = 0; b.i < description.Length; ){ + object oarg; + + if (argn < args.Length) + oarg = args [argn]; + else { + if (b.repeat != 0) + break; + + oarg = null; + } + + int save = b.i; + + if (PackOne (b, oarg)){ + argn++; + if (b.repeat > 0){ + if (--b.repeat > 0) + b.i = save; + else + b.i++; + } else + b.i++; + } else + b.i++; + } + return b.Get (); + } + + static public byte [] PackEnumerable (string description, IEnumerable args) + { + PackContext b = new PackContext (); + b.conv = CopyConv; + b.description = description; + + IEnumerator enumerator = args.GetEnumerator (); + bool ok = enumerator.MoveNext (); + + for (b.i = 0; b.i < description.Length; ){ + object oarg; + + if (ok) + oarg = enumerator.Current; + else { + if (b.repeat != 0) + break; + oarg = null; + } + + int save = b.i; + + if (PackOne (b, oarg)){ + ok = enumerator.MoveNext (); + if (b.repeat > 0){ + if (--b.repeat > 0) + b.i = save; + else + b.i++; + } else + b.i++; + } else + b.i++; + } + return b.Get (); + } + + // + // Packs one datum `oarg' into the buffer `b', using the string format + // in `description' at position `i' + // + // Returns: true if we must pick the next object from the list + // + static bool PackOne (PackContext b, object oarg) + { + int n; + + switch (b.description [b.i]){ + case '^': + b.conv = BigEndian; + return false; + case '_': + b.conv = LittleEndian; + return false; + case '%': + b.conv = Native; + return false; + + case '!': + b.align = -1; + return false; + + case 'x': + b.Add (new byte [] { 0 }); + return false; + + // Type Conversions + case 'i': + b.Add (b.conv.GetBytes (Convert.ToInt32 (oarg))); + break; + + case 'I': + b.Add (b.conv.GetBytes (Convert.ToUInt32 (oarg))); + break; + + case 's': + b.Add (b.conv.GetBytes (Convert.ToInt16 (oarg))); + break; + + case 'S': + b.Add (b.conv.GetBytes (Convert.ToUInt16 (oarg))); + break; + + case 'l': + b.Add (b.conv.GetBytes (Convert.ToInt64 (oarg))); + break; + + case 'L': + b.Add (b.conv.GetBytes (Convert.ToUInt64 (oarg))); + break; + + case 'f': + b.Add (b.conv.GetBytes (Convert.ToSingle (oarg))); + break; + + case 'd': + b.Add (b.conv.GetBytes (Convert.ToDouble (oarg))); + break; + + case 'b': + b.Add (new byte [] { Convert.ToByte (oarg) }); + break; + + case 'c': + b.Add (new byte [] { (byte) (Convert.ToSByte (oarg)) }); + break; + + case 'C': + b.Add (new byte [] { Convert.ToByte (oarg) }); + break; + + // Repeat acount; + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + b.repeat = ((short) b.description [b.i]) - ((short) '0'); + return false; + + case '*': + b.repeat = Int32.MaxValue; + return false; + + case '[': + int count = -1, j; + + for (j = b.i+1; j < b.description.Length; j++){ + if (b.description [j] == ']') + break; + n = ((short) b.description [j]) - ((short) '0'); + if (n >= 0 && n <= 9){ + if (count == -1) + count = n; + else + count = count * 10 + n; + } + } + if (count == -1) + throw new ArgumentException ("invalid size specification"); + b.i = j; + b.repeat = count; + return false; + + case '$': case 'z': + bool add_null = b.description [b.i] == 'z'; + b.i++; + if (b.i >= b.description.Length) + throw new ArgumentException ("$ description needs a type specified", "description"); + char d = b.description [b.i]; + Encoding e; + + switch (d){ + case '8': + e = Encoding.UTF8; + n = 1; + break; + case '6': + e = Encoding.Unicode; + n = 2; + break; + case '7': +#if PCL + e = Encoding.GetEncoding ("utf-7"); +#else + e = Encoding.UTF7; +#endif + n = 1; + break; + case 'b': + e = Encoding.BigEndianUnicode; + n = 2; + break; + case '3': +#if PCL + e = Encoding.GetEncoding ("utf-32"); +#else + e = Encoding.GetEncoding (12000); +#endif + n = 4; + break; + case '4': +#if PCL + e = Encoding.GetEncoding ("utf-32BE"); +#else + e = Encoding.GetEncoding (12001); +#endif + n = 4; + break; + + default: + throw new ArgumentException ("Invalid format for $ specifier", "description"); + } + if (b.align == -1) + b.align = 4; + b.Add (e.GetBytes (Convert.ToString (oarg))); + if (add_null) + b.Add (new byte [n]); + break; + default: + throw new ArgumentException (String.Format ("invalid format specified `{0}'", + b.description [b.i])); + } + return true; + } + + static bool Prepare (byte [] buffer, ref int idx, int size, ref bool align) + { + if (align){ + idx = Align (idx, size); + align = false; + } + if (idx + size > buffer.Length){ + idx = buffer.Length; + return false; + } + return true; + } + + static public IList Unpack (string description, byte [] buffer, int startIndex) + { + DataConverter conv = CopyConv; + var result = new List (); + int idx = startIndex; + bool align = false; + int repeat = 0, n; + + for (int i = 0; i < description.Length && idx < buffer.Length; ){ + int save = i; + + switch (description [i]){ + case '^': + conv = BigEndian; + break; + case '_': + conv = LittleEndian; + break; + case '%': + conv = Native; + break; + case 'x': + idx++; + break; + + case '!': + align = true; + break; + + // Type Conversions + case 'i': + if (Prepare (buffer, ref idx, 4, ref align)){ + result.Add (conv.GetInt32 (buffer, idx)); + idx += 4; + } + break; + + case 'I': + if (Prepare (buffer, ref idx, 4, ref align)){ + result.Add (conv.GetUInt32 (buffer, idx)); + idx += 4; + } + break; + + case 's': + if (Prepare (buffer, ref idx, 2, ref align)){ + result.Add (conv.GetInt16 (buffer, idx)); + idx += 2; + } + break; + + case 'S': + if (Prepare (buffer, ref idx, 2, ref align)){ + result.Add (conv.GetUInt16 (buffer, idx)); + idx += 2; + } + break; + + case 'l': + if (Prepare (buffer, ref idx, 8, ref align)){ + result.Add (conv.GetInt64 (buffer, idx)); + idx += 8; + } + break; + + case 'L': + if (Prepare (buffer, ref idx, 8, ref align)){ + result.Add (conv.GetUInt64 (buffer, idx)); + idx += 8; + } + break; + + case 'f': + if (Prepare (buffer, ref idx, 4, ref align)){ + result.Add (conv.GetFloat (buffer, idx)); + idx += 4; + } + break; + + case 'd': + if (Prepare (buffer, ref idx, 8, ref align)){ + result.Add (conv.GetDouble (buffer, idx)); + idx += 8; + } + break; + + case 'b': + if (Prepare (buffer, ref idx, 1, ref align)){ + result.Add (buffer [idx]); + idx++; + } + break; + + case 'c': case 'C': + if (Prepare (buffer, ref idx, 1, ref align)){ + char c; + + if (description [i] == 'c') + c = ((char) ((sbyte)buffer [idx])); + else + c = ((char) ((byte)buffer [idx])); + + result.Add (c); + idx++; + } + break; + + // Repeat acount; + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + repeat = ((short) description [i]) - ((short) '0'); + save = i + 1; + break; + + case '*': + repeat = Int32.MaxValue; + break; + + case '[': + int count = -1, j; + + for (j = i+1; j < description.Length; j++){ + if (description [j] == ']') + break; + n = ((short) description [j]) - ((short) '0'); + if (n >= 0 && n <= 9){ + if (count == -1) + count = n; + else + count = count * 10 + n; + } + } + if (count == -1) + throw new ArgumentException ("invalid size specification"); + i = j; + save = i + 1; + repeat = count; + break; + + case '$': case 'z': + // bool with_null = description [i] == 'z'; + i++; + if (i >= description.Length) + throw new ArgumentException ("$ description needs a type specified", "description"); + char d = description [i]; + Encoding e; + if (align){ + idx = Align (idx, 4); + align = false; + } + if (idx >= buffer.Length) + break; + + switch (d){ + case '8': + e = Encoding.UTF8; + n = 1; + break; + case '6': + e = Encoding.Unicode; + n = 2; + break; + case '7': + e = Encoding.UTF7; + n = 1; + break; + case 'b': + e = Encoding.BigEndianUnicode; + n = 2; + break; + case '3': + e = Encoding.GetEncoding (12000); + n = 4; + break; + case '4': + e = Encoding.GetEncoding (12001); + n = 4; + break; + + default: + throw new ArgumentException ("Invalid format for $ specifier", "description"); + } + int k = idx; + switch (n){ + case 1: + for (; k < buffer.Length && buffer [k] != 0; k++) + ; + result.Add (e.GetChars (buffer, idx, k-idx)); + if (k == buffer.Length) + idx = k; + else + idx = k+1; + break; + + case 2: + for (; k < buffer.Length; k++){ + if (k+1 == buffer.Length){ + k++; + break; + } + if (buffer [k] == 0 && buffer [k+1] == 0) + break; + } + result.Add (e.GetChars (buffer, idx, k-idx)); + if (k == buffer.Length) + idx = k; + else + idx = k+2; + break; + + case 4: + for (; k < buffer.Length; k++){ + if (k+3 >= buffer.Length){ + k = buffer.Length; + break; + } + if (buffer[k]==0 && buffer[k+1] == 0 && buffer[k+2] == 0 && buffer[k+3]== 0) + break; + } + result.Add (e.GetChars (buffer, idx, k-idx)); + if (k == buffer.Length) + idx = k; + else + idx = k+4; + break; + } + break; + default: + throw new ArgumentException (String.Format ("invalid format specified `{0}'", + description [i])); + } + + if (repeat > 0){ + if (--repeat > 0) + i = save; + } else + i++; + } + return result; + } + + internal void Check (byte [] dest, int destIdx, int size) + { + if (dest == null) + throw new ArgumentNullException ("dest"); + if (destIdx < 0 || destIdx > dest.Length - size) + throw new ArgumentException ("destIdx"); + } + + class CopyConverter : DataConverter { + public override double GetDouble (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 8) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + double ret; + byte *b = (byte *)&ret; + + for (int i = 0; i < 8; i++) + b [i] = data [index+i]; + + return ret; + } + + public override ulong GetUInt64 (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 8) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + ulong ret; + byte *b = (byte *)&ret; + + for (int i = 0; i < 8; i++) + b [i] = data [index+i]; + + return ret; + } + + public override long GetInt64 (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 8) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + long ret; + byte *b = (byte *)&ret; + + for (int i = 0; i < 8; i++) + b [i] = data [index+i]; + + return ret; + } + + public override float GetFloat (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 4) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + float ret; + byte *b = (byte *)&ret; + + for (int i = 0; i < 4; i++) + b [i] = data [index+i]; + + return ret; + } + + public override int GetInt32 (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 4) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + int ret; + byte *b = (byte *)&ret; + + for (int i = 0; i < 4; i++) + b [i] = data [index+i]; + + return ret; + } + + public override uint GetUInt32 (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 4) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + uint ret; + byte *b = (byte *)&ret; + + for (int i = 0; i < 4; i++) + b [i] = data [index+i]; + + return ret; + } + + public override short GetInt16 (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 2) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + short ret; + byte *b = (byte *)&ret; + + for (int i = 0; i < 2; i++) + b [i] = data [index+i]; + + return ret; + } + + public override ushort GetUInt16 (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 2) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + ushort ret; + byte *b = (byte *)&ret; + + for (int i = 0; i < 2; i++) + b [i] = data [index+i]; + + return ret; + } + + public override void PutBytes (byte [] dest, int destIdx, double value) + { + Check (dest, destIdx, 8); + fixed (byte *target = &dest [destIdx]){ + long *source = (long *) &value; + + *((long *)target) = *source; + } + } + + public override void PutBytes (byte [] dest, int destIdx, float value) + { + Check (dest, destIdx, 4); + fixed (byte *target = &dest [destIdx]){ + uint *source = (uint *) &value; + + *((uint *)target) = *source; + } + } + + public override void PutBytes (byte [] dest, int destIdx, int value) + { + Check (dest, destIdx, 4); + fixed (byte *target = &dest [destIdx]){ + uint *source = (uint *) &value; + + *((uint *)target) = *source; + } + } + + public override void PutBytes (byte [] dest, int destIdx, uint value) + { + Check (dest, destIdx, 4); + fixed (byte *target = &dest [destIdx]){ + uint *source = (uint *) &value; + + *((uint *)target) = *source; + } + } + + public override void PutBytes (byte [] dest, int destIdx, long value) + { + Check (dest, destIdx, 8); + fixed (byte *target = &dest [destIdx]){ + long *source = (long *) &value; + + *((long*)target) = *source; + } + } + + public override void PutBytes (byte [] dest, int destIdx, ulong value) + { + Check (dest, destIdx, 8); + fixed (byte *target = &dest [destIdx]){ + ulong *source = (ulong *) &value; + + *((ulong *) target) = *source; + } + } + + public override void PutBytes (byte [] dest, int destIdx, short value) + { + Check (dest, destIdx, 2); + fixed (byte *target = &dest [destIdx]){ + ushort *source = (ushort *) &value; + + *((ushort *)target) = *source; + } + } + + public override void PutBytes (byte [] dest, int destIdx, ushort value) + { + Check (dest, destIdx, 2); + fixed (byte *target = &dest [destIdx]){ + ushort *source = (ushort *) &value; + + *((ushort *)target) = *source; + } + } + } + + class SwapConverter : DataConverter { + public override double GetDouble (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 8) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + double ret; + byte *b = (byte *)&ret; + + for (int i = 0; i < 8; i++) + b [7-i] = data [index+i]; + + return ret; + } + + public override ulong GetUInt64 (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 8) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + ulong ret; + byte *b = (byte *)&ret; + + for (int i = 0; i < 8; i++) + b [7-i] = data [index+i]; + + return ret; + } + + public override long GetInt64 (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 8) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + long ret; + byte *b = (byte *)&ret; + + for (int i = 0; i < 8; i++) + b [7-i] = data [index+i]; + + return ret; + } + + public override float GetFloat (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 4) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + float ret; + byte *b = (byte *)&ret; + + for (int i = 0; i < 4; i++) + b [3-i] = data [index+i]; + + return ret; + } + + public override int GetInt32 (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 4) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + int ret; + byte *b = (byte *)&ret; + + for (int i = 0; i < 4; i++) + b [3-i] = data [index+i]; + + return ret; + } + + public override uint GetUInt32 (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 4) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + uint ret; + byte *b = (byte *)&ret; + + for (int i = 0; i < 4; i++) + b [3-i] = data [index+i]; + + return ret; + } + + public override short GetInt16 (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 2) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + short ret; + byte *b = (byte *)&ret; + + for (int i = 0; i < 2; i++) + b [1-i] = data [index+i]; + + return ret; + } + + public override ushort GetUInt16 (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 2) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + ushort ret; + byte *b = (byte *)&ret; + + for (int i = 0; i < 2; i++) + b [1-i] = data [index+i]; + + return ret; + } + + public override void PutBytes (byte [] dest, int destIdx, double value) + { + Check (dest, destIdx, 8); + + fixed (byte *target = &dest [destIdx]){ + byte *source = (byte *) &value; + + for (int i = 0; i < 8; i++) + target [i] = source [7-i]; + } + } + + public override void PutBytes (byte [] dest, int destIdx, float value) + { + Check (dest, destIdx, 4); + + fixed (byte *target = &dest [destIdx]){ + byte *source = (byte *) &value; + + for (int i = 0; i < 4; i++) + target [i] = source [3-i]; + } + } + + public override void PutBytes (byte [] dest, int destIdx, int value) + { + Check (dest, destIdx, 4); + + fixed (byte *target = &dest [destIdx]){ + byte *source = (byte *) &value; + + for (int i = 0; i < 4; i++) + target [i] = source [3-i]; + } + } + + public override void PutBytes (byte [] dest, int destIdx, uint value) + { + Check (dest, destIdx, 4); + + fixed (byte *target = &dest [destIdx]){ + byte *source = (byte *) &value; + + for (int i = 0; i < 4; i++) + target [i] = source [3-i]; + } + } + + public override void PutBytes (byte [] dest, int destIdx, long value) + { + Check (dest, destIdx, 8); + + fixed (byte *target = &dest [destIdx]){ + byte *source = (byte *) &value; + + for (int i = 0; i < 8; i++) + target [i] = source [7-i]; + } + } + + public override void PutBytes (byte [] dest, int destIdx, ulong value) + { + Check (dest, destIdx, 8); + + fixed (byte *target = &dest [destIdx]){ + byte *source = (byte *) &value; + + for (int i = 0; i < 8; i++) + target [i] = source [7-i]; + } + } + + public override void PutBytes (byte [] dest, int destIdx, short value) + { + Check (dest, destIdx, 2); + + fixed (byte *target = &dest [destIdx]){ + byte *source = (byte *) &value; + + for (int i = 0; i < 2; i++) + target [i] = source [1-i]; + } + } + + public override void PutBytes (byte [] dest, int destIdx, ushort value) + { + Check (dest, destIdx, 2); + + fixed (byte *target = &dest [destIdx]){ + byte *source = (byte *) &value; + + for (int i = 0; i < 2; i++) + target [i] = source [1-i]; + } + } + } + +#if MONO_DATACONVERTER_STATIC_METHODS + static unsafe void PutBytesLE (byte *dest, byte *src, int count) + { + int i = 0; + + if (BitConverter.IsLittleEndian){ + for (; i < count; i++) + *dest++ = *src++; + } else { + dest += count; + for (; i < count; i++) + *(--dest) = *src++; + } + } + + static unsafe void PutBytesBE (byte *dest, byte *src, int count) + { + int i = 0; + + if (BitConverter.IsLittleEndian){ + dest += count; + for (; i < count; i++) + *(--dest) = *src++; + } else { + for (; i < count; i++) + *dest++ = *src++; + } + } + + static unsafe void PutBytesNative (byte *dest, byte *src, int count) + { + int i = 0; + + for (; i < count; i++) + dest [i-count] = *src++; + } + + static public unsafe double DoubleFromLE (byte[] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 8) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + double ret; + fixed (byte *src = &data[index]){ + PutBytesLE ((byte *) &ret, src, 8); + } + return ret; + } + + static public unsafe float FloatFromLE (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 4) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + float ret; + fixed (byte *src = &data[index]){ + PutBytesLE ((byte *) &ret, src, 4); + } + return ret; + } + + static public unsafe long Int64FromLE (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 8) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + long ret; + fixed (byte *src = &data[index]){ + PutBytesLE ((byte *) &ret, src, 8); + } + return ret; + } + + static public unsafe ulong UInt64FromLE (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 8) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + ulong ret; + fixed (byte *src = &data[index]){ + PutBytesLE ((byte *) &ret, src, 8); + } + return ret; + } + + static public unsafe int Int32FromLE (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 4) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + int ret; + fixed (byte *src = &data[index]){ + PutBytesLE ((byte *) &ret, src, 4); + } + return ret; + } + + static public unsafe uint UInt32FromLE (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 4) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + uint ret; + fixed (byte *src = &data[index]){ + PutBytesLE ((byte *) &ret, src, 4); + } + return ret; + } + + static public unsafe short Int16FromLE (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 2) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + short ret; + fixed (byte *src = &data[index]){ + PutBytesLE ((byte *) &ret, src, 2); + } + return ret; + } + + static public unsafe ushort UInt16FromLE (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 2) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + ushort ret; + fixed (byte *src = &data[index]){ + PutBytesLE ((byte *) &ret, src, 2); + } + return ret; + } + + static public unsafe double DoubleFromBE (byte[] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 8) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + double ret; + fixed (byte *src = &data[index]){ + PutBytesBE ((byte *) &ret, src, 8); + } + return ret; + } + + static public unsafe float FloatFromBE (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 4) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + float ret; + fixed (byte *src = &data[index]){ + PutBytesBE ((byte *) &ret, src, 4); + } + return ret; + } + + static public unsafe long Int64FromBE (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 8) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + long ret; + fixed (byte *src = &data[index]){ + PutBytesBE ((byte *) &ret, src, 8); + } + return ret; + } + + static public unsafe ulong UInt64FromBE (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 8) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + ulong ret; + fixed (byte *src = &data[index]){ + PutBytesBE ((byte *) &ret, src, 8); + } + return ret; + } + + static public unsafe int Int32FromBE (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 4) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + int ret; + fixed (byte *src = &data[index]){ + PutBytesBE ((byte *) &ret, src, 4); + } + return ret; + } + + static public unsafe uint UInt32FromBE (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 4) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + uint ret; + fixed (byte *src = &data[index]){ + PutBytesBE ((byte *) &ret, src, 4); + } + return ret; + } + + static public unsafe short Int16FromBE (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 2) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + short ret; + fixed (byte *src = &data[index]){ + PutBytesBE ((byte *) &ret, src, 2); + } + return ret; + } + + static public unsafe ushort UInt16FromBE (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 2) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + ushort ret; + fixed (byte *src = &data[index]){ + PutBytesBE ((byte *) &ret, src, 2); + } + return ret; + } + + static public unsafe double DoubleFromNative (byte[] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 8) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + double ret; + fixed (byte *src = &data[index]){ + PutBytesNative ((byte *) &ret, src, 8); + } + return ret; + } + + static public unsafe float FloatFromNative (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 4) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + float ret; + fixed (byte *src = &data[index]){ + PutBytesNative ((byte *) &ret, src, 4); + } + return ret; + } + + static public unsafe long Int64FromNative (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 8) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + long ret; + fixed (byte *src = &data[index]){ + PutBytesNative ((byte *) &ret, src, 8); + } + return ret; + } + + static public unsafe ulong UInt64FromNative (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 8) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + ulong ret; + fixed (byte *src = &data[index]){ + PutBytesNative ((byte *) &ret, src, 8); + } + return ret; + } + + static public unsafe int Int32FromNative (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 4) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + int ret; + fixed (byte *src = &data[index]){ + PutBytesNative ((byte *) &ret, src, 4); + } + return ret; + } + + static public unsafe uint UInt32FromNative (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 4) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + uint ret; + fixed (byte *src = &data[index]){ + PutBytesNative ((byte *) &ret, src, 4); + } + return ret; + } + + static public unsafe short Int16FromNative (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 2) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + short ret; + fixed (byte *src = &data[index]){ + PutBytesNative ((byte *) &ret, src, 2); + } + return ret; + } + + static public unsafe ushort UInt16FromNative (byte [] data, int index) + { + if (data == null) + throw new ArgumentNullException ("data"); + if (data.Length - index < 2) + throw new ArgumentException ("index"); + if (index < 0) + throw new ArgumentException ("index"); + + ushort ret; + fixed (byte *src = &data[index]){ + PutBytesNative ((byte *) &ret, src, 2); + } + return ret; + } + + unsafe static byte[] GetBytesPtr (byte *ptr, int count) + { + byte [] ret = new byte [count]; + + for (int i = 0; i < count; i++) { + ret [i] = ptr [i]; + } + + return ret; + } + + unsafe static byte[] GetBytesSwap (bool swap, byte *ptr, int count) + { + byte [] ret = new byte [count]; + + if (swap){ + int t = count-1; + for (int i = 0; i < count; i++) { + ret [t-i] = ptr [i]; + } + } else { + for (int i = 0; i < count; i++) { + ret [i] = ptr [i]; + } + } + return ret; + } + + unsafe public static byte[] GetBytesNative (bool value) + { + return GetBytesPtr ((byte *) &value, 1); + } + + unsafe public static byte[] GetBytesNative (char value) + { + return GetBytesPtr ((byte *) &value, 2); + } + + unsafe public static byte[] GetBytesNative (short value) + { + return GetBytesPtr ((byte *) &value, 2); + } + + unsafe public static byte[] GetBytesNative (int value) + { + return GetBytesPtr ((byte *) &value, 4); + } + + unsafe public static byte[] GetBytesNative (long value) + { + return GetBytesPtr ((byte *) &value, 8); + } + + [CLSCompliant (false)] + unsafe public static byte[] GetBytesNative (ushort value) + { + return GetBytesPtr ((byte *) &value, 2); + } + + [CLSCompliant (false)] + unsafe public static byte[] GetBytesNative (uint value) + { + return GetBytesPtr ((byte *) &value, 4); + } + + [CLSCompliant (false)] + unsafe public static byte[] GetBytesNative (ulong value) + { + return GetBytesPtr ((byte *) &value, 8); + } + + unsafe public static byte[] GetBytesNative (float value) + { + return GetBytesPtr ((byte *) &value, 4); + } + + unsafe public static byte[] GetBytesNative (double value) + { + return GetBytesPtr ((byte *) &value, 8); + } + + unsafe public static byte[] GetBytesLE (bool value) + { + return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 1); + } + + unsafe public static byte[] GetBytesLE (char value) + { + return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 2); + } + + unsafe public static byte[] GetBytesLE (short value) + { + return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 2); + } + + unsafe public static byte[] GetBytesLE (int value) + { + return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 4); + } + + unsafe public static byte[] GetBytesLE (long value) + { + return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 8); + } + + [CLSCompliant (false)] + unsafe public static byte[] GetBytesLE (ushort value) + { + return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 2); + } + + [CLSCompliant (false)] + unsafe public static byte[] GetBytesLE (uint value) + { + return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 4); + } + + [CLSCompliant (false)] + unsafe public static byte[] GetBytesLE (ulong value) + { + return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 8); + } + + unsafe public static byte[] GetBytesLE (float value) + { + return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 4); + } + + unsafe public static byte[] GetBytesLE (double value) + { + return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 8); + } + + unsafe public static byte[] GetBytesBE (bool value) + { + return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 1); + } + + unsafe public static byte[] GetBytesBE (char value) + { + return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 2); + } + + unsafe public static byte[] GetBytesBE (short value) + { + return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 2); + } + + unsafe public static byte[] GetBytesBE (int value) + { + return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 4); + } + + unsafe public static byte[] GetBytesBE (long value) + { + return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 8); + } + + [CLSCompliant (false)] + unsafe public static byte[] GetBytesBE (ushort value) + { + return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 2); + } + + [CLSCompliant (false)] + unsafe public static byte[] GetBytesBE (uint value) + { + return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 4); + } + + [CLSCompliant (false)] + unsafe public static byte[] GetBytesBE (ulong value) + { + return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 8); + } + + unsafe public static byte[] GetBytesBE (float value) + { + return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 4); + } + + unsafe public static byte[] GetBytesBE (double value) + { + return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 8); + } +#endif + + } +} diff --git a/SharpCompress/Crypto/PBKDF2.cs b/SharpCompress/Crypto/PBKDF2.cs index 7cb772ef..ae7f2c99 100644 --- a/SharpCompress/Crypto/PBKDF2.cs +++ b/SharpCompress/Crypto/PBKDF2.cs @@ -3,6 +3,7 @@ using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Digests; using Org.BouncyCastle.Crypto.Macs; using Org.BouncyCastle.Crypto.Parameters; +using SharpCompress.Converter; namespace SharpCompress.Crypto { @@ -68,7 +69,7 @@ namespace SharpCompress.Crypto private byte[] Hash() { - byte[] array = UIntToOctet(block); + byte[] array = DataConverter.BigEndian.GetBytes(block); ICipherParameters param = new KeyParameter(password); hMac.Init(param); @@ -96,24 +97,6 @@ namespace SharpCompress.Crypto block += 1u; return array3; } - - internal static byte[] UIntToOctet(uint i) - { - byte[] bytes = BitConverter.GetBytes(i); - byte[] result = new[] - { - bytes[3], - bytes[2], - bytes[1], - bytes[0] - }; - if (!BitConverter.IsLittleEndian) - { - return bytes; - } - return result; - } - } } diff --git a/SharpCompress/IO/MarkingBinaryReader.cs b/SharpCompress/IO/MarkingBinaryReader.cs index a9a5d1be..07ddd16e 100644 --- a/SharpCompress/IO/MarkingBinaryReader.cs +++ b/SharpCompress/IO/MarkingBinaryReader.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Linq; +using SharpCompress.Converter; namespace SharpCompress.IO { @@ -36,7 +37,7 @@ namespace SharpCompress.IO public override bool ReadBoolean() { - return BitConverter.ToBoolean(ReadBytes(1), 0); + return ReadBytes(1).Single() != 0; } public override byte ReadByte() @@ -68,39 +69,28 @@ namespace SharpCompress.IO #if !PORTABLE public override decimal ReadDecimal() { - return ByteArrayToDecimal(ReadBytes(16), 0); - } - - private decimal ByteArrayToDecimal(byte[] src, int offset) - { - //http://stackoverflow.com/a/16984356/385387 - var i1 = BitConverter.ToInt32(src, offset); - var i2 = BitConverter.ToInt32(src, offset + 4); - var i3 = BitConverter.ToInt32(src, offset + 8); - var i4 = BitConverter.ToInt32(src, offset + 12); - - return new decimal(new[] { i1, i2, i3, i4 }); + throw new NotSupportedException(); } #endif public override double ReadDouble() { - return BitConverter.ToDouble(ReadBytes(8), 0); + throw new NotSupportedException(); } public override short ReadInt16() { - return BitConverter.ToInt16(ReadBytes(2), 0); + return DataConverter.LittleEndian.GetInt16(ReadBytes(2), 0); } public override int ReadInt32() { - return BitConverter.ToInt32(ReadBytes(4), 0); + return DataConverter.LittleEndian.GetInt32(ReadBytes(4), 0); } public override long ReadInt64() { - return BitConverter.ToInt64(ReadBytes(8), 0); + return DataConverter.LittleEndian.GetInt64(ReadBytes(8), 0); } public override sbyte ReadSByte() @@ -110,7 +100,7 @@ namespace SharpCompress.IO public override float ReadSingle() { - return BitConverter.ToSingle(ReadBytes(4), 0); + throw new NotSupportedException(); } public override string ReadString() @@ -120,17 +110,17 @@ namespace SharpCompress.IO public override ushort ReadUInt16() { - return BitConverter.ToUInt16(ReadBytes(2), 0); + return DataConverter.LittleEndian.GetUInt16(ReadBytes(2), 0); } public override uint ReadUInt32() { - return BitConverter.ToUInt32(ReadBytes(4), 0); + return DataConverter.LittleEndian.GetUInt32(ReadBytes(4), 0); } public override ulong ReadUInt64() { - return BitConverter.ToUInt64(ReadBytes(8), 0); + return DataConverter.LittleEndian.GetUInt64(ReadBytes(8), 0); } } } \ No newline at end of file diff --git a/SharpCompress/SharpCompress.Portable.csproj b/SharpCompress/SharpCompress.Portable.csproj index 49e43055..608308d5 100644 --- a/SharpCompress/SharpCompress.Portable.csproj +++ b/SharpCompress/SharpCompress.Portable.csproj @@ -270,6 +270,7 @@ + diff --git a/SharpCompress/SharpCompress.PortableTest.csproj b/SharpCompress/SharpCompress.PortableTest.csproj index 71281f16..948bc9e9 100644 --- a/SharpCompress/SharpCompress.PortableTest.csproj +++ b/SharpCompress/SharpCompress.PortableTest.csproj @@ -240,6 +240,7 @@ + diff --git a/SharpCompress/SharpCompress.Unsigned.csproj b/SharpCompress/SharpCompress.Unsigned.csproj index bfb80856..58412400 100644 --- a/SharpCompress/SharpCompress.Unsigned.csproj +++ b/SharpCompress/SharpCompress.Unsigned.csproj @@ -244,6 +244,7 @@ + Code diff --git a/SharpCompress/SharpCompress.WindowsStore.csproj b/SharpCompress/SharpCompress.WindowsStore.csproj index b5c5547b..ddd85bb8 100644 --- a/SharpCompress/SharpCompress.WindowsStore.csproj +++ b/SharpCompress/SharpCompress.WindowsStore.csproj @@ -256,6 +256,7 @@ + diff --git a/SharpCompress/SharpCompress.csproj b/SharpCompress/SharpCompress.csproj index fd033f1a..568ba3be 100644 --- a/SharpCompress/SharpCompress.csproj +++ b/SharpCompress/SharpCompress.csproj @@ -244,6 +244,7 @@ + Code diff --git a/SharpCompress/Utility.cs b/SharpCompress/Utility.cs index 6a7c4d72..d6599187 100644 --- a/SharpCompress/Utility.cs +++ b/SharpCompress/Utility.cs @@ -2,9 +2,6 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; -using SharpCompress.Archive; -using SharpCompress.Common; -using SharpCompress.IO; namespace SharpCompress { @@ -29,17 +26,6 @@ namespace SharpCompress return (number >> bits) + (2 << ~bits); } - /// - /// Performs an unsigned bitwise right shift with the specified number - /// - /// Number to operate on - /// Ammount of bits to shift - /// The resulting number from the shift operation - public static int URShift(int number, long bits) - { - return URShift(number, (int)bits); - } - /// /// Performs an unsigned bitwise right shift with the specified number /// @@ -54,17 +40,6 @@ namespace SharpCompress return (number >> bits) + (2L << ~bits); } - /// - /// Performs an unsigned bitwise right shift with the specified number - /// - /// Number to operate on - /// Ammount of bits to shift - /// The resulting number from the shift operation - public static long URShift(long number, long bits) - { - return URShift(number, (int)bits); - } - /// /// Fills the array with an specific value from an specific index to an specific index. /// @@ -120,139 +95,6 @@ namespace SharpCompress } } - /// Read a int value from the byte array at the given position (Big Endian) - /// - /// - /// the array to read from - /// - /// the offset - /// - /// the value - /// - public static int readIntBigEndian(byte[] array, int pos) - { - int temp = 0; - temp |= array[pos] & 0xff; - temp <<= 8; - temp |= array[pos + 1] & 0xff; - temp <<= 8; - temp |= array[pos + 2] & 0xff; - temp <<= 8; - temp |= array[pos + 3] & 0xff; - return temp; - } - - /// Read a short value from the byte array at the given position (little - /// Endian) - /// - /// - /// the array to read from - /// - /// the offset - /// - /// the value - /// - public static short readShortLittleEndian(byte[] array, int pos) - { - return BitConverter.ToInt16(array, pos); - } - - /// Read an int value from the byte array at the given position (little - /// Endian) - /// - /// - /// the array to read from - /// - /// the offset - /// - /// the value - /// - public static int readIntLittleEndian(byte[] array, int pos) - { - return BitConverter.ToInt32(array, pos); - } - - /// Write an int value into the byte array at the given position (Big endian) - /// - /// - /// the array - /// - /// the offset - /// - /// the value to write - /// - public static void writeIntBigEndian(byte[] array, int pos, int value) - { - array[pos] = (byte)((Utility.URShift(value, 24)) & 0xff); - array[pos + 1] = (byte)((Utility.URShift(value, 16)) & 0xff); - array[pos + 2] = (byte)((Utility.URShift(value, 8)) & 0xff); - array[pos + 3] = (byte)((value) & 0xff); - } - - /// Write a short value into the byte array at the given position (little - /// endian) - /// - /// - /// the array - /// - /// the offset - /// - /// the value to write - /// - public static void WriteLittleEndian(byte[] array, int pos, short value) - { - byte[] newBytes = BitConverter.GetBytes(value); - - if (!BitConverter.IsLittleEndian) - Array.Reverse(newBytes); - - Array.Copy(newBytes, 0, array, pos, newBytes.Length); - } - - /// Increment a short value at the specified position by the specified amount - /// (little endian). - /// - public static void incShortLittleEndian(byte[] array, int pos, short incrementValue) - { - short existingValue = BitConverter.ToInt16(array, pos); - existingValue += incrementValue; - WriteLittleEndian(array, pos, existingValue); - //int c = Utility.URShift(((array[pos] & 0xff) + (dv & 0xff)), 8); - //array[pos] = (byte)(array[pos] + (dv & 0xff)); - //if ((c > 0) || ((dv & 0xff00) != 0)) - //{ - // array[pos + 1] = (byte)(array[pos + 1] + ((Utility.URShift(dv, 8)) & 0xff) + c); - //} - } - - /// Write an int value into the byte array at the given position (little - /// endian) - /// - /// - /// the array - /// - /// the offset - /// - /// the value to write - /// - public static void WriteLittleEndian(byte[] array, int pos, int value) - { - byte[] newBytes = BitConverter.GetBytes(value); - - if (!BitConverter.IsLittleEndian) - Array.Reverse(newBytes); - - Array.Copy(newBytes, 0, array, pos, newBytes.Length); - } - - public static void Initialize(this T[] array, Func func) - { - for (int i = 0; i < array.Length; i++) - { - array[i] = func(); - } - } - public static void AddRange(this ICollection destination, IEnumerable source) { foreach (T item in source) @@ -324,18 +166,6 @@ namespace SharpCompress } while (source.Read(buffer, 0, buffer.Length) == buffer.Length); } - - public static byte[] UInt32ToBigEndianBytes(uint x) - { - return new byte[] - { - (byte) ((x >> 24) & 0xff), - (byte) ((x >> 16) & 0xff), - (byte) ((x >> 8) & 0xff), - (byte) (x & 0xff) - }; - } - public static DateTime DosDateToDateTime(UInt16 iDate, UInt16 iTime) { int year = iDate / 512 + 1980; @@ -450,33 +280,6 @@ namespace SharpCompress { Array.Copy(array, 0, destination, index, array.Length); } - - public static long HostToNetworkOrder(long host) - { - return (int)((long)HostToNetworkOrder((int)host) - & unchecked((long)(unchecked((ulong)-1))) << 32 - | ((long)HostToNetworkOrder((int)((int)host >> 32)) & unchecked((long)(unchecked((ulong)-1))))); - } - public static int HostToNetworkOrder(int host) - { - return (int)((int)(HostToNetworkOrder((short)host) & -1) << 16 | (HostToNetworkOrder((short)(host >> 16)) & -1)); - } - public static short HostToNetworkOrder(short host) - { - return (short)((int)(host & 255) << 8 | ((int)host >> 8 & 255)); - } - public static long NetworkToHostOrder(long network) - { - return HostToNetworkOrder(network); - } - public static int NetworkToHostOrder(int network) - { - return HostToNetworkOrder(network); - } - public static short NetworkToHostOrder(short network) - { - return HostToNetworkOrder(network); - } #endif } } \ No newline at end of file diff --git a/SharpCompress/Writer/Zip/ZipCentralDirectoryEntry.cs b/SharpCompress/Writer/Zip/ZipCentralDirectoryEntry.cs index c1a4c1e8..1448d3fd 100644 --- a/SharpCompress/Writer/Zip/ZipCentralDirectoryEntry.cs +++ b/SharpCompress/Writer/Zip/ZipCentralDirectoryEntry.cs @@ -3,6 +3,7 @@ using System.IO; using System.Text; using SharpCompress.Common.Zip; using SharpCompress.Common.Zip.Headers; +using SharpCompress.Converter; namespace SharpCompress.Writer.Zip { @@ -32,23 +33,23 @@ namespace SharpCompress.Writer.Zip flags |= HeaderFlags.Bit1; // eos marker } } - outputStream.Write(BitConverter.GetBytes((ushort) flags), 0, 2); - outputStream.Write(BitConverter.GetBytes((ushort) compression), 0, 2); // zipping method - outputStream.Write(BitConverter.GetBytes(ModificationTime.DateTimeToDosTime()), 0, 4); + outputStream.Write(DataConverter.LittleEndian.GetBytes((ushort) flags), 0, 2); + outputStream.Write(DataConverter.LittleEndian.GetBytes((ushort) compression), 0, 2); // zipping method + outputStream.Write(DataConverter.LittleEndian.GetBytes(ModificationTime.DateTimeToDosTime()), 0, 4); // zipping date and time - outputStream.Write(BitConverter.GetBytes(Crc), 0, 4); // file CRC - outputStream.Write(BitConverter.GetBytes(Compressed), 0, 4); // compressed file size - outputStream.Write(BitConverter.GetBytes(Decompressed), 0, 4); // uncompressed file size - outputStream.Write(BitConverter.GetBytes((ushort) encodedFilename.Length), 0, 2); // Filename in zip - outputStream.Write(BitConverter.GetBytes((ushort) 0), 0, 2); // extra length - outputStream.Write(BitConverter.GetBytes((ushort) encodedComment.Length), 0, 2); + outputStream.Write(DataConverter.LittleEndian.GetBytes(Crc), 0, 4); // file CRC + outputStream.Write(DataConverter.LittleEndian.GetBytes(Compressed), 0, 4); // compressed file size + outputStream.Write(DataConverter.LittleEndian.GetBytes(Decompressed), 0, 4); // uncompressed file size + outputStream.Write(DataConverter.LittleEndian.GetBytes((ushort) encodedFilename.Length), 0, 2); // Filename in zip + outputStream.Write(DataConverter.LittleEndian.GetBytes((ushort) 0), 0, 2); // extra length + outputStream.Write(DataConverter.LittleEndian.GetBytes((ushort) encodedComment.Length), 0, 2); - outputStream.Write(BitConverter.GetBytes((ushort) 0), 0, 2); // disk=0 - outputStream.Write(BitConverter.GetBytes((ushort) 0), 0, 2); // file type: binary - outputStream.Write(BitConverter.GetBytes((ushort) 0), 0, 2); // Internal file attributes - outputStream.Write(BitConverter.GetBytes((ushort) 0x8100), 0, 2); + outputStream.Write(DataConverter.LittleEndian.GetBytes((ushort) 0), 0, 2); // disk=0 + outputStream.Write(DataConverter.LittleEndian.GetBytes((ushort) 0), 0, 2); // file type: binary + outputStream.Write(DataConverter.LittleEndian.GetBytes((ushort) 0), 0, 2); // Internal file attributes + outputStream.Write(DataConverter.LittleEndian.GetBytes((ushort) 0x8100), 0, 2); // External file attributes (normal/readable) - outputStream.Write(BitConverter.GetBytes(HeaderOffset), 0, 4); // Offset of header + outputStream.Write(DataConverter.LittleEndian.GetBytes(HeaderOffset), 0, 4); // Offset of header outputStream.Write(encodedFilename, 0, encodedFilename.Length); outputStream.Write(encodedComment, 0, encodedComment.Length); diff --git a/SharpCompress/Writer/Zip/ZipWriter.cs b/SharpCompress/Writer/Zip/ZipWriter.cs index 4f44fe5d..1831db22 100644 --- a/SharpCompress/Writer/Zip/ZipWriter.cs +++ b/SharpCompress/Writer/Zip/ZipWriter.cs @@ -10,6 +10,7 @@ using SharpCompress.Compressor.BZip2; using SharpCompress.Compressor.Deflate; using SharpCompress.Compressor.LZMA; using SharpCompress.Compressor.PPMd; +using SharpCompress.Converter; using SharpCompress.IO; using DeflateStream = SharpCompress.Compressor.Deflate.DeflateStream; @@ -93,7 +94,7 @@ namespace SharpCompress.Writer.Zip var explicitZipCompressionInfo = compressionInfo != null ? new ZipCompressionInfo(compressionInfo) : this.zipCompressionInfo; byte[] encodedFilename = ArchiveEncoding.Default.GetBytes(filename); - OutputStream.Write(BitConverter.GetBytes(ZipHeaderFactory.ENTRY_HEADER_BYTES), 0, 4); + OutputStream.Write(DataConverter.LittleEndian.GetBytes(ZipHeaderFactory.ENTRY_HEADER_BYTES), 0, 4); if (explicitZipCompressionInfo.Compression == ZipCompressionMethod.Deflate) { OutputStream.Write(new byte[] {20, 0}, 0, 2); //older version which is more compatible @@ -111,14 +112,14 @@ namespace SharpCompress.Writer.Zip flags |= HeaderFlags.Bit1; // eos marker } } - OutputStream.Write(BitConverter.GetBytes((ushort) flags), 0, 2); - OutputStream.Write(BitConverter.GetBytes((ushort)explicitZipCompressionInfo.Compression), 0, 2); // zipping method - OutputStream.Write(BitConverter.GetBytes(modificationTime.DateTimeToDosTime()), 0, 4); + OutputStream.Write(DataConverter.LittleEndian.GetBytes((ushort) flags), 0, 2); + OutputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)explicitZipCompressionInfo.Compression), 0, 2); // zipping method + OutputStream.Write(DataConverter.LittleEndian.GetBytes(modificationTime.DateTimeToDosTime()), 0, 4); // zipping date and time OutputStream.Write(new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 12); // unused CRC, un/compressed size, updated later - OutputStream.Write(BitConverter.GetBytes((ushort) encodedFilename.Length), 0, 2); // filename length - OutputStream.Write(BitConverter.GetBytes((ushort) 0), 0, 2); // extra length + OutputStream.Write(DataConverter.LittleEndian.GetBytes((ushort) encodedFilename.Length), 0, 2); // filename length + OutputStream.Write(DataConverter.LittleEndian.GetBytes((ushort) 0), 0, 2); // extra length OutputStream.Write(encodedFilename, 0, encodedFilename.Length); return 6 + 2 + 2 + 4 + 12 + 2 + 2 + encodedFilename.Length; @@ -126,9 +127,9 @@ namespace SharpCompress.Writer.Zip private void WriteFooter(uint crc, uint compressed, uint uncompressed) { - OutputStream.Write(BitConverter.GetBytes(crc), 0, 4); - OutputStream.Write(BitConverter.GetBytes(compressed), 0, 4); - OutputStream.Write(BitConverter.GetBytes(uncompressed), 0, 4); + OutputStream.Write(DataConverter.LittleEndian.GetBytes(crc), 0, 4); + OutputStream.Write(DataConverter.LittleEndian.GetBytes(compressed), 0, 4); + OutputStream.Write(DataConverter.LittleEndian.GetBytes(uncompressed), 0, 4); } private void WriteEndRecord(uint size) @@ -136,11 +137,11 @@ namespace SharpCompress.Writer.Zip byte[] encodedComment = ArchiveEncoding.Default.GetBytes(zipComment); OutputStream.Write(new byte[] {80, 75, 5, 6, 0, 0, 0, 0}, 0, 8); - OutputStream.Write(BitConverter.GetBytes((ushort) entries.Count), 0, 2); - OutputStream.Write(BitConverter.GetBytes((ushort) entries.Count), 0, 2); - OutputStream.Write(BitConverter.GetBytes(size), 0, 4); - OutputStream.Write(BitConverter.GetBytes((uint) streamPosition), 0, 4); - OutputStream.Write(BitConverter.GetBytes((ushort) encodedComment.Length), 0, 2); + OutputStream.Write(DataConverter.LittleEndian.GetBytes((ushort) entries.Count), 0, 2); + OutputStream.Write(DataConverter.LittleEndian.GetBytes((ushort) entries.Count), 0, 2); + OutputStream.Write(DataConverter.LittleEndian.GetBytes(size), 0, 4); + OutputStream.Write(DataConverter.LittleEndian.GetBytes((uint) streamPosition), 0, 4); + OutputStream.Write(DataConverter.LittleEndian.GetBytes((ushort) encodedComment.Length), 0, 2); OutputStream.Write(encodedComment, 0, encodedComment.Length); } @@ -254,7 +255,7 @@ namespace SharpCompress.Writer.Zip } else { - originalStream.Write(BitConverter.GetBytes(ZipHeaderFactory.POST_DATA_DESCRIPTOR), 0, 4); + originalStream.Write(DataConverter.LittleEndian.GetBytes(ZipHeaderFactory.POST_DATA_DESCRIPTOR), 0, 4); writer.WriteFooter(entry.Crc, counting.Count, decompressed); writer.streamPosition += entry.Compressed + 16; }