* SecondLife.Directory is now properly initialized * Added BitPack class (and unit test) for decoding an arbitrary number of bytes from a byte array git-svn-id: http://libopenmetaverse.googlecode.com/svn/trunk@928 52acb1d6-8a22-11de-b505-999d5b087335
110 lines
3.5 KiB
C#
110 lines
3.5 KiB
C#
/*
|
|
* Copyright (c) 2007, Second Life Reverse Engineering Team
|
|
* All rights reserved.
|
|
*
|
|
* - Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
*
|
|
* - Redistributions of source code must retain the above copyright notice, this
|
|
* list of conditions and the following disclaimer.
|
|
* - Neither the name of the Second Life Reverse Engineering Team nor the names
|
|
* of its contributors may be used to endorse or promote products derived from
|
|
* this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
using System;
|
|
|
|
namespace libsecondlife
|
|
{
|
|
public class BitPack
|
|
{
|
|
private const int MAX_BITS = 8;
|
|
|
|
private byte[] Data;
|
|
private int bytePos;
|
|
private int bitPos;
|
|
|
|
public BitPack(byte[] data, int pos)
|
|
{
|
|
Data = data;
|
|
bytePos = pos;
|
|
}
|
|
|
|
public float UnpackFloat()
|
|
{
|
|
byte[] output = UnpackBitsArray(32);
|
|
|
|
if (!BitConverter.IsLittleEndian) Array.Reverse(output);
|
|
return BitConverter.ToSingle(output, 0);
|
|
}
|
|
|
|
public int UnpackBits(int totalCount)
|
|
{
|
|
byte[] output = UnpackBitsArray(totalCount);
|
|
|
|
if (!BitConverter.IsLittleEndian) Array.Reverse(output);
|
|
return BitConverter.ToInt32(output, 0);
|
|
}
|
|
|
|
private byte[] UnpackBitsArray(int totalCount)
|
|
{
|
|
int count = 0;
|
|
byte[] output = new byte[4];
|
|
int curBytePos = 0;
|
|
int curBitPos = 0;
|
|
|
|
while (totalCount > 0)
|
|
{
|
|
if (totalCount > MAX_BITS)
|
|
{
|
|
count = MAX_BITS;
|
|
totalCount -= MAX_BITS;
|
|
}
|
|
else
|
|
{
|
|
count = totalCount;
|
|
totalCount = 0;
|
|
}
|
|
|
|
while (count > 0)
|
|
{
|
|
// Shift the previous bits
|
|
output[curBytePos] <<= 1;
|
|
|
|
// Grab one bit
|
|
if ((Data[bytePos] & (0x80 >> bitPos++)) != 0)
|
|
++output[curBytePos];
|
|
|
|
--count;
|
|
++curBitPos;
|
|
|
|
if (bitPos >= MAX_BITS)
|
|
{
|
|
bitPos = 0;
|
|
++bytePos;
|
|
}
|
|
if (curBitPos >= MAX_BITS)
|
|
{
|
|
curBitPos = 0;
|
|
++curBytePos;
|
|
}
|
|
}
|
|
}
|
|
|
|
return output;
|
|
}
|
|
}
|
|
}
|