Snappy.Sharp icon indicating copy to clipboard operation
Snappy.Sharp copied to clipboard

Exception in UnalignedCopy64

Open StefanMenne opened this issue 11 years ago • 2 comments

The following Code results in an Exception during decompression in Utilities.UnalignedCopy64:

byte[] uncompressed = new byte[100]; byte[] compressed = new byte[100];

Snappy.Sharp.SnappyCompressor snappyCompressor = new Snappy.Sharp.SnappyCompressor(); int countBytes = snappyCompressor.Compress( uncompressed, 0, 2, compressed, 0 );

Snappy.Sharp.SnappyDecompressor snappyDecompressor = new Snappy.Sharp.SnappyDecompressor();

// this call works byte[] uncompressed2 = snappyDecompressor.Decompress( compressed, 0, countBytes );

// this call results in an Exception snappyDecompressor.Decompress( compressed, 0, countBytes, uncompressed, 0, 100 );

The Exception occured with the Native-Implementation.

StefanMenne avatar Sep 02 '14 08:09 StefanMenne

I have met a similar problem. It occured when run UnalignedCopy64 function on ARM cpu .See this:How does the ARM Compiler support unaligned accesses?(http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka15414.html)

My Solution is :

        public unsafe static void UnalignedCopy64(byte[] source, int sourceIndex, byte[] dest, int destIndex)
        {
            Debug.Assert(sourceIndex > -1);
            Debug.Assert(destIndex > -1);
            Debug.Assert(sourceIndex + 7 < source.Length);
            Debug.Assert(destIndex + 7 < dest.Length);

#if ARM //any macro you predefine to distinguish with x86 cpu
            for (var i = 0; i < 8; i++)
            {
                dest[destIndex + i] = source[sourceIndex + i];
            }
#else
            fixed (byte* src = &source[sourceIndex], dst = &dest[destIndex])
            {
                *((long*)dst) = *((long*)src);
            }
#endif
        }

        public unsafe static uint GetFourBytes(byte[] source, int index)
        {
            Debug.Assert(index > -1);
            Debug.Assert(index + 3 < source.Length);
#if ARM
            return (uint)source[index] |
                (uint)source[index + 1] << 8 |
                (uint)source[index + 2] << 16 |
                (uint)source[index + 3] << 24;
#else
            fixed (byte* src = &source[index])
            {
                return *((uint*)src);
            }
#endif
        }

        public unsafe static ulong GetEightBytes(byte[] source, int index)
        {
            Debug.Assert(index > -1);
            Debug.Assert(index + 7 < source.Length);
#if ARM
            return (ulong)source[index] |
                    (ulong)source[index + 1] << 8 |
                    (ulong)source[index + 2] << 16 |
                    (ulong)source[index + 3] << 24 |
                    (ulong)source[index + 4] << 32 |
                    (ulong)source[index + 5] << 40 |
                    (ulong)source[index + 6] << 48 |
                    (ulong)source[index + 7] << 56;
#else
            
            fixed (byte* src = &source[index])
            {
                return *((ulong*)src);
            }
#endif

Salty-Sailor avatar Feb 02 '18 06:02 Salty-Sailor

the same issule that I encountered in Unity3D with Android platform

I have met a similar problem. It occured when run UnalignedCopy64 function on ARM cpu .See this:How does the ARM Compiler support unaligned accesses?(http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka15414.html)

My Solution is :

        public unsafe static void UnalignedCopy64(byte[] source, int sourceIndex, byte[] dest, int destIndex)
        {
            Debug.Assert(sourceIndex > -1);
            Debug.Assert(destIndex > -1);
            Debug.Assert(sourceIndex + 7 < source.Length);
            Debug.Assert(destIndex + 7 < dest.Length);

#if ARM //any macro you predefine to distinguish with x86 cpu
            for (var i = 0; i < 8; i++)
            {
                dest[destIndex + i] = source[sourceIndex + i];
            }
#else
            fixed (byte* src = &source[sourceIndex], dst = &dest[destIndex])
            {
                *((long*)dst) = *((long*)src);
            }
#endif
        }

        public unsafe static uint GetFourBytes(byte[] source, int index)
        {
            Debug.Assert(index > -1);
            Debug.Assert(index + 3 < source.Length);
#if ARM
            return (uint)source[index] |
                (uint)source[index + 1] << 8 |
                (uint)source[index + 2] << 16 |
                (uint)source[index + 3] << 24;
#else
            fixed (byte* src = &source[index])
            {
                return *((uint*)src);
            }
#endif
        }

        public unsafe static ulong GetEightBytes(byte[] source, int index)
        {
            Debug.Assert(index > -1);
            Debug.Assert(index + 7 < source.Length);
#if ARM
            return (ulong)source[index] |
                    (ulong)source[index + 1] << 8 |
                    (ulong)source[index + 2] << 16 |
                    (ulong)source[index + 3] << 24 |
                    (ulong)source[index + 4] << 32 |
                    (ulong)source[index + 5] << 40 |
                    (ulong)source[index + 6] << 48 |
                    (ulong)source[index + 7] << 56;
#else
            
            fixed (byte* src = &source[index])
            {
                return *((ulong*)src);
            }
#endif

Useful, THANKYOU

mic89 avatar Sep 21 '18 09:09 mic89