Example #1
0
 public override void SetLength(Int64 value)
 {
     throw new NotSupportedException(SR.GetString("Not supported"));
 }
Example #2
0
        private void CreateTable()
        {
            uint[] codeArray = CalculateHuffmanCode();
            table = new short[1 << tableBits];
#if DEBUG
            //codeArrayDebug = codeArray;
#endif

            // I need to find proof that left and right array will always be
            // enough. I think they are.
            left  = new short[2 * codeLengthArray.Length];
            right = new short[2 * codeLengthArray.Length];
            short avail = (short)codeLengthArray.Length;

            for (int ch = 0; ch < codeLengthArray.Length; ch++)
            {
                // length of this code
                int len = codeLengthArray[ch];
                if (len > 0)
                {
                    // start value (bit reversed)
                    int start = (int)codeArray[ch];

                    if (len <= tableBits)
                    {
                        // If a particular symbol is shorter than nine bits,
                        // then that symbol's translation is duplicated
                        // in all those entries that start with that symbol's bits.
                        // For example, if the symbol is four bits, then it's duplicated
                        // 32 times in a nine-bit table. If a symbol is nine bits long,
                        // it appears in the table once.
                        //
                        // Make sure that in the loop below, code is always
                        // less than table_size.
                        //
                        // On last iteration we store at array index:
                        //    initial_start_at + (locs-1)*increment
                        //  = initial_start_at + locs*increment - increment
                        //  = initial_start_at + (1 << tableBits) - increment
                        //  = initial_start_at + table_size - increment
                        //
                        // Therefore we must ensure:
                        //     initial_start_at + table_size - increment < table_size
                        // or: initial_start_at < increment
                        //
                        int increment = 1 << len;
                        if (start >= increment)
                        {
                            throw new InvalidDataException(SR.GetString(SR.InvalidHuffmanData));
                        }

                        // Note the bits in the table are reverted.
                        int locs = 1 << (tableBits - len);
                        for (int j = 0; j < locs; j++)
                        {
                            table[start] = (short)ch;
                            start       += increment;
                        }
                    }
                    else
                    {
                        // For any code which has length longer than num_elements,
                        // build a binary tree.

                        int overflowBits = len - tableBits;  // the nodes we need to respent the data.
                        int codeBitMask  = 1 << tableBits;   // mask to get current bit (the bits can't fit in the table)

                        // the left, right table is used to repesent the
                        // the rest bits. When we got the first part (number bits.) and look at
                        // tbe table, we will need to follow the tree to find the real character.
                        // This is in place to avoid bloating the table if there are
                        // a few ones with long code.
                        int     index = start & ((1 << tableBits) - 1);
                        short[] array = table;

                        do
                        {
                            short value = array[index];

                            if (value == 0)                   // set up next pointer if this node is not used before.
                            {
                                array[index] = (short)-avail; // use next available slot.
                                value        = (short)-avail;
                                avail++;
                            }

                            if (value > 0)           // prevent an IndexOutOfRangeException from array[index]
                            {
                                throw new InvalidDataException(SR.GetString(SR.InvalidHuffmanData));
                            }

                            Debug.Assert(value < 0, "CreateTable: Only negative numbers are used for tree pointers!");

                            if ((start & codeBitMask) == 0)    // if current bit is 0, go change the left array
                            {
                                array = left;
                            }
                            else                    // if current bit is 1, set value in the right array
                            {
                                array = right;
                            }
                            index = -value;         // go to next node

                            codeBitMask <<= 1;
                            overflowBits--;
                        } while (overflowBits != 0);

                        array[index] = (short)ch;
                    }
                }
            }
        }
Example #3
0
 public override Int64 Seek(Int64 offset, SeekOrigin origin)
 {
     throw new NotSupportedException(SR.GetString("Not supported"));
 }