// Read a single unsigned value from the specified bitstream with a value
    // from 0 to maxcode. If there are exactly a power of two number of possible
    // codes then this will read a fixed number of bits; otherwise it reads the
    // minimum number of bits and then determines whether another bit is needed
    // to define the code.

    internal static long read_code(Bitstream bs, long maxcode)
    {
        int  bitcount = count_bits(maxcode);
        long extras   = (1 << bitcount) - maxcode - 1;
        long code;

        if (bitcount == 0)
        {
            return(0);
        }

        code = BitsUtils.getbits(bitcount - 1, bs);

        code &= (1 << (bitcount - 1)) - 1;

        if (code >= extras)
        {
            code = (code << 1) - extras;

            bs = BitsUtils.getbit(bs);

            if (bs.bitval > 0)
            {
                ++code;
            }
        }

        return(code);
    }
Exemple #2
0
    // Encodes a vector of unsigned integers in a format that can later be
    // decoded as an EncodedUintVector.
    //
    // REQUIRES: T is an unsigned integer type.
    // REQUIRES: 2 <= sizeof(T) <= 8
    // REQUIRES: "encoder" uses the default constructor, so that its buffer
    //           can be enlarged as necessary by calling Ensure(int).
    public static void EncodeUintVector(UInt16[] v, Encoder encoder)
    {
        // The encoding is as follows:
        //
        //   varint64: (v.size() * sizeof(T)) | (len - 1)
        //   array of v.size() elements ["len" bytes each]
        //
        // Note that we don't allow (len == 0) since this would require an extra bit
        // to encode the length.

        UInt16 one_bits = 1;  // Ensures len >= 1.

        foreach (var x in v)
        {
            one_bits |= x;
        }
        int len = (BitsUtils.FindMSBSetNonZero64(one_bits) >> 3) + 1;

        System.Diagnostics.Debug.Assert(len >= 1 && len <= 8);

        // Note that the multiplication is optimized into a bit shift.
        encoder.Ensure(Encoder.kVarintMax64 + v.Length * len);
        UInt64 size_len = ((UInt64)(UInt32)v.Length * sizeof(UInt16)) | (UInt32)(len - 1);

        encoder.PutVarInt64((Int64)size_len);
        foreach (var x in v)
        {
            EncodeUintWithLength(x, len, encoder);
        }
    }
        public override byte[] GetData()
        {
            var data = new byte[527];

            data[0]  = (byte)Command;
            data[1]  = 0;
            data[2]  = 0;
            data[3]  = 0;
            data[4]  = (byte)((int)_operation & 0xFF);
            data[5]  = 0;
            data[6]  = 0;
            data[7]  = 0;
            data[8]  = (byte)(_scope & 0xFF);
            data[9]  = 0;
            data[10] = 0;
            data[11] = 0;
            // length
            data[12] = 0;
            data[13] = 0x10;
            data[14] = 0;
            data[15] = 0;

            foreach (var enableLog in _enabledLogIds)
            {
                var ind = (int)enableLog;
                if (ind > 0)
                {
                    var offset = ind - 0x1000;
                    BitsUtils.SetBitAsBool(data, 16, offset, true);
                }
            }
            return(data);
        }
        private static void ParseSetMask(LogConfigCommandResponse result, byte[] data)
        {
            result.Scope = data[12];
            var numBits    = data[16] + (data[17] << 8);
            var maskLength = (numBits + 7) / 8;

            if (data.Length < maskLength + 16)
            {
                //throw new QcdmManagerException(Strings.QcdmInvalidResponseCommand);
                return;
            }

            var scopeDelta  = result.Scope * 0x1000;
            var enabledLogs = new List <LogId>();

            for (var i = 0; i < numBits; ++i)
            {
                if (BitsUtils.GetBitAsBool(data, 20, i))
                {
                    var v = i + scopeDelta;
                    enabledLogs.Add((LogId)v);
                }
            }

            result.LogIds = enabledLogs.ToArray();
        }
        public static EventMaskSetCommandResponse Parse(byte[] data)
        {
            var result = new EventMaskSetCommandResponse();

            result.CheckResponse(data);
            var status = data[1];

            result.IsError = status != 0;
            if (!result.IsError)
            {
                var numBits    = data[4] + (data[5] << 8);
                var maskLength = (numBits + 7) / 8;
                if (data.Length < maskLength + 6)
                {
                    throw new QcdmManagerException(Strings.QcdmInvalidResponseCommand);
                }

                var enabledEvents = new List <EventId>();
                for (var i = 0; i < numBits; ++i)
                {
                    if (BitsUtils.GetBitAsBool(data, 6, i))
                    {
                        enabledEvents.Add((EventId)i);
                    }
                }

                result.EnabledEvents = enabledEvents.ToArray();
            }

            return(result);
        }
        public static LogConfigCommandResponse Parse(byte[] data)
        {
            var result = new LogConfigCommandResponse();

            result.CheckResponse(data);
            var status = data[8];

            result.IsError   = status != 0;
            result.Operation = (LogConfigOperation)data[4];
            result.Scope     = data[12];
            var numBits    = data[16] + (data[17] << 8);
            var maskLength = (numBits + 7) / 8;

            if (data.Length < (maskLength + 16))
            {
                throw new QcdmManagerException(Strings.QcdmInvalidResponseCommand);
            }

            var enabledLogs = new List <LogId>();

            for (var i = 0; i < numBits; ++i)
            {
                if (BitsUtils.GetBitAsBool(data, 20, i))
                {
                    var v = i + 0x1000;
                    enabledLogs.Add((LogId)v);
                }
            }
            result.EnabledLogs = enabledLogs.ToArray();
            return(result);
        }
Exemple #7
0
        public static IHashTrieNode FromBytes(ReadOnlyMemory <byte> bytes)
        {
            if (bytes.Length < 1)
            {
                throw new ArgumentException("Empty bytes to deserialize");
            }
            var type = bytes.Span[0];

            switch (type)
            {
            case 0:
                if (bytes.Length < 1 + 4 + 32)
                {
                    throw new ArgumentException($"Not enough bytes to deserialize: {bytes.Length}");
                }
                var mask = bytes.Slice(1, 4).Span.ToUInt32();
                var len  = (int)BitsUtils.Popcount(mask);
                var hash = bytes.Slice(1 + 4, 32).ToArray();

                ulong[] _children = new ulong[len];
                var     pos       = 32 + 5;

                for (var i = 0; i < len; i++)
                {
                    if (pos >= bytes.Length)
                    {
                        throw new ArgumentException("does not hold all the childen");
                    }
                    byte sz = bytes.Span[pos];

                    if (pos + sz >= bytes.Length)
                    {
                        throw new ArgumentException("not enough bytes to deserialize the children id");
                    }

                    ulong m   = 1;
                    ulong res = 0;
                    for (int j = pos + 1; j <= pos + sz; j++)
                    {
                        res = res + m * bytes.Span[j];
                        m   = m * 256;
                    }
                    _children[i] = res;
                    pos         += sz + 1;
                }
                return(new InternalNode(mask, _children, hash));

            case 1:
                if (bytes.Length < 1 + 32)
                {
                    throw new ArgumentException($"Not enough bytes to deserialize: {bytes.Length}");
                }
                return(new LeafNode(bytes.Slice(1, 32).ToArray(), bytes.Slice(1 + 32).ToArray()));

            default:
                throw new InvalidOperationException($"Type id {type} is not supported");
            }
        }
Exemple #8
0
    // Return the smallest cell that contains all descendants of this cell whose
    // bounds intersect "rect".  For algorithms that use recursive subdivision
    // to find the cells that intersect a particular object, this method can be
    // used to skip all the initial subdivision steps where only one child needs
    // to be expanded.
    //
    // Note that this method is not the same as returning the smallest cell that
    // contains the intersection of this cell with "rect".  Because of the
    // padding, even if one child completely contains "rect" it is still
    // possible that a neighboring child also intersects "rect".
    //
    // REQUIRES: bound().Intersects(rect)
    public S2CellId ShrinkToFit(R2Rect rect)
    {
        System.Diagnostics.Debug.Assert(Bound.Intersects(rect));

        // Quick rejection test: if "rect" contains the center of this cell along
        // either axis, then no further shrinking is possible.
        int ij_size = S2CellId.SizeIJ(Level);

        if (Level == 0)
        {
            // Fast path (most calls to this function start with a face cell).
            if (rect[0].Contains(0) || rect[1].Contains(0))
            {
                return(Id);
            }
        }
        else
        {
            if (rect[0].Contains(S2.STtoUV(S2.SiTitoST((uint)(2 * ij_lo_[0] + ij_size)))) ||
                rect[1].Contains(S2.STtoUV(S2.SiTitoST((uint)(2 * ij_lo_[1] + ij_size)))))
            {
                return(Id);
            }
        }
        // Otherwise we expand "rect" by the given padding() on all sides and find
        // the range of coordinates that it spans along the i- and j-axes.  We then
        // compute the highest bit position at which the min and max coordinates
        // differ.  This corresponds to the first cell level at which at least two
        // children intersect "rect".

        // Increase the padding to compensate for the error in S2Coords.UVtoST().
        // (The constant below is a provable upper bound on the additional error.)
        R2Rect padded = rect.Expanded(Padding + 1.5 * S2.DoubleEpsilon);
        var    ij_min = new int[2]; // Min i- or j- coordinate spanned by "padded"
        var    ij_xor = new int[2]; // XOR of the min and max i- or j-coordinates

        for (int d = 0; d < 2; ++d)
        {
            ij_min[d] = Math.Max(ij_lo_[d], S2.STtoIJ(S2.UVtoST(padded[d][0])));
            int ij_max = Math.Min(ij_lo_[d] + ij_size - 1,
                                  S2.STtoIJ(S2.UVtoST(padded[d][1])));
            ij_xor[d] = ij_min[d] ^ ij_max;
        }
        // Compute the highest bit position where the two i- or j-endpoints differ,
        // and then choose the cell level that includes both of these endpoints.  So
        // if both pairs of endpoints are equal we choose kMaxLevel; if they differ
        // only at bit 0, we choose (kMaxLevel - 1), and so on.
        var level_msb = ((ij_xor[0] | ij_xor[1]) << 1) + 1;
        var level     = S2.kMaxCellLevel - BitsUtils.FindMSBSetNonZero((uint)level_msb);

        if (level <= Level)
        {
            return(Id);
        }
        return(S2CellId.FromFaceIJ((int)Id.Face(), ij_min[0], ij_min[1]).Parent(level));
    }
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Stream source = null;

            if (FileSelectRadio.IsChecked.GetValueOrDefault())
            {
                source = new FileStream(inputFileName, FileMode.Open, FileAccess.Read);
            }
            else if (BitsSelectRadio.IsChecked.GetValueOrDefault())
            {
                source = new MemoryStream(BitsUtils.ToBinary(BitsTextBox.Text));
            }
            else
            {
                throw new Exception("Source not specified");
            }
            int mode = 0;

            if (DECCRadio.IsChecked.GetValueOrDefault())
            {
                mode = 2;
            }
            else if (SECCRadio.IsChecked.GetValueOrDefault())
            {
                mode = 1;
            }
            else
            {
                throw new Exception("Mode not specified");
            }

            if (FileOutputCheckBox.IsChecked.GetValueOrDefault())
            {
                SaveFileDialog dialog = new SaveFileDialog();
                if (dialog.ShowDialog() == true)
                {
                    using (var fs = new FileStream(dialog.FileName, FileMode.Create, FileAccess.Write))
                    {
                        ECC.Decode(mode, source, fs);
                    }
                }
            }
            else
            {
                OutputText.Document.Blocks.Clear();
                byte[] encoded = Telekom.ECC.Decode(mode, source);
                for (int i = 0; i < encoded.Length; i++)
                {
                    OutputText.AppendText(Convert.ToString(encoded[i], 2).PadLeft(8, '0'));
                }
            }
            source.Close();
        }
Exemple #10
0
    // Computes v^i, where i is a non-negative integer.
    // When T is a floating point type, this has the same semantics as pow(), but
    // is much faster.
    // T can also be any integral type, in which case computations will be
    // performed in the value domain of this integral type, and overflow semantics
    // will be those of T.
    // You can also use any type for which operator*= is defined.
    public static double IPow(double @base, int exp)
    {
        System.Diagnostics.Debug.Assert(exp >= 0);
        var uexp = (UInt32)exp;

        if (uexp < 16)
        {
            var result = ((uexp & 1) != 0) ? @base : 1.0;
            if (uexp >= 2)
            {
                @base *= @base;
                if ((uexp & 2) != 0)
                {
                    result *= @base;
                }
                if (uexp >= 4)
                {
                    @base *= @base;
                    if ((uexp & 4) != 0)
                    {
                        result *= @base;
                    }
                    if (uexp >= 8)
                    {
                        @base  *= @base;
                        result *= @base;
                    }
                }
            }
            return(result);
        }

        {
            var result = @base;
            var count  = 31 ^ BitsUtils.Log2FloorNonZero(uexp);

            uexp <<= count;
            count ^= 31;

            while (count-- > 0)
            {
                uexp  <<= 1;
                result *= result;
                if (uexp >= 0x80000000)
                {
                    result *= @base;
                }
            }

            return(result);
        }
    }
Exemple #11
0
        static void Main(string[] args)
        {
            var str   = "1101000110";            // wiadomość do zakodowania (10 bitów)
            var bytes = BitsUtils.ToBinary(str); // konwersja do postaci bitowej

            using MemoryStream ms = new MemoryStream(bytes);
            var       encoded = Telekom.ECC.Encode(1, ms); // Zakodowanie wiadomości do słowa kodowego
            BitVector vector  = new BitVector(encoded);

            vector.SwitchBit(3);                 // zamiana 3 bitu (pierwsze słowo kodowe)
            vector.SwitchBit(12);                // zamiana 12 bitu (drugie słowo kodowe)
            using MemoryStream ms1 = new MemoryStream(encoded);
            var docoded = SingleECC.Decode(ms1); // Odkodowanie słowa kodowego (i korekcja błędów)
        }
Exemple #12
0
        private void OnDirectMessage(object sender, byte[] bytes)
        {
            if ((Guid)sender != opponentGuid)
            {
                return;
            }

            switch (state)
            {
            case GameState.FlippingCoin:
                int opponentPriority = BitsUtils.BytesToInt(bytes);
                if (priority > opponentPriority)
                {
                    state      = GameState.OurTurn;
                    isPlayingX = true;
                    Invoke(new MethodInvoker(() => { labelStatus.Text = "Your turn, it's your day!"; }));
                }
                else if (priority < opponentPriority)
                {
                    state      = GameState.OpponentTurn;
                    isPlayingX = false;

                    Invoke(new MethodInvoker(() =>
                    {
                        labelStatus.Text = "Opponent's turn, better luck next time";
                        SetFieldInteractable(false);
                    }));
                }
                else
                {
                    throw new Exception("Equal priorities :c");
                }

                break;

            case GameState.OpponentTurn:
                byte x = bytes[0];
                byte y = bytes[1];
                state = GameState.OurTurn;
                Invoke(new MethodInvoker(() =>
                {
                    buttons[x, y].Text = !isPlayingX ? "X" : "O";
                    labelStatus.Text   = "Your turn";
                    SetFieldInteractable(true);
                }));
                CheckGameOver();
                break;
            }
        }
        public override byte[] GetData()
        {
            var maskLength = (MaxMaskBitsCount + 7) / 8;
            var data       = new byte[6 + maskLength];

            data[0] = (byte)Command;
            data[1] = 0;
            data[2] = 0;
            data[3] = 0;
            data[4] = (byte)(MaxMaskBitsCount & 0xFF);
            data[5] = (byte)((MaxMaskBitsCount >> 8) & 0xFF);
            foreach (var enableEvent in _enableEvents)
            {
                BitsUtils.SetBitAsBool(data, 6, (int)enableEvent, true);
            }
            return(data);
        }
Exemple #14
0
        private void FormGame_Load(object sender, EventArgs e)
        {
            relay.SendDirectMessage(opponentGuid, BitsUtils.IntToBytes(priority));

            buttons = new Button[tableLayoutPanelGame.ColumnCount, tableLayoutPanelGame.RowCount];

            for (byte y = 0; y < tableLayoutPanelGame.RowCount; y++)
            {
                for (byte x = 0; x < tableLayoutPanelGame.ColumnCount; x++)
                {
                    buttons[x, y] = new Button
                    {
                        Dock = DockStyle.Fill
                    };
                    buttons[x, y].Click += OnClick;

                    tableLayoutPanelGame.Controls.Add(buttons[x, y], x, y);
                }
            }
        }
Exemple #15
0
        public static BitVector operator *(BitMatrix matrix, BitVector vector)
        {
            int len = matrix.M;
            // if(matrix.N != vector.Length)
            //     throw new Exception("Invalid Matrix Size");

            BitVector result = new BitVector(new byte[BitsUtils.GetBytesSize(len)]);

            for (int i = 0; i < len; i++)
            {
                bool res = false;
                for (int j = 0; j < matrix.N; j++)
                {
                    res ^= matrix[i, j] & vector[j];
                }

                result[i] = res;
            }

            return(result);
        }
Exemple #16
0
        private byte[] GetSetMaskData()
        {
            var size       = ((int)_range.Item2 - (int)_range.Item1) / 8 + 16;
            var scopeDelta = _scope * 0x1000;
            var begin      = (int)_range.Item1 < scopeDelta ? _range.Item1 : _range.Item1 - scopeDelta;
            var end        = (int)_range.Item2 < scopeDelta ? _range.Item2 : _range.Item2 - scopeDelta;
            var data       = new byte[size];

            data[0]  = (byte)Command;
            data[1]  = 0;
            data[2]  = 0;
            data[3]  = 0;
            data[4]  = (byte)((int)_operation & 0xFF);
            data[5]  = 0;
            data[6]  = 0;
            data[7]  = 0;
            data[8]  = (byte)(_scope & 0xFF);
            data[9]  = 0;
            data[10] = (byte)((int)begin & 0xFF);
            data[11] = (byte)(((int)begin >> 8) & 0xFF);
            data[12] = (byte)((int)end & 0xFF);
            data[13] = (byte)(((int)end >> 8) & 0xFF);
            data[14] = 0;
            data[15] = 0;

            if (_enabledLogIds.Count > 0)
            {
                for (var id = begin; id <= end; ++id)
                {
                    if (_enabledLogIds.Contains(id + scopeDelta))
                    {
                        BitsUtils.SetBitAsBool(data, 16, (int)id, true);
                    }
                }
            }

            return(data);
        }
Exemple #17
0
        public bool Parity()
        {
            var p = RawBytes.Aggregate(0u, (i, b) => i ^ b, x => x);

            return(BitsUtils.Popcount(p) % 2 == 1);
        }
    // Encodes a vector of S2CellIds in a format that can later be decoded as an
    // EncodedS2CellIdVector.  The S2CellIds do not need to be valid.
    //
    // REQUIRES: "encoder" uses the default constructor, so that its buffer
    //           can be enlarged as necessary by calling Ensure(int).
    public static void EncodeS2CellIdVector(List <S2CellId> v, Encoder encoder)
    {
        // v[i] is encoded as (base + (deltas[i] << shift)).
        //
        // "base" consists of 0-7 bytes, and is always shifted so that its bytes are
        // the most-significant bytes of a UInt64.
        //
        // "deltas" is an EncodedUintVector<UInt64>, which means that all deltas
        // have a fixed-length encoding determined by the largest delta.
        //
        // "shift" is in the range 0..56.  The shift value is odd only if all
        // S2CellIds are at the same level, in which case the bit at position
        // (shift - 1) is automatically set to 1 in "base".
        //
        // "base" (3 bits) and "shift" (6 bits) are encoded in either one or two
        // bytes as follows:
        //
        //   - if (shift <= 4 or shift is even), then 1 byte
        //   - otherwise 2 bytes
        //
        // Note that (shift == 1) means that all S2CellIds are leaf cells, and
        // (shift == 2) means that all S2CellIds are at level 29.
        //
        // The full encoded format is as follows:
        //
        //  Byte 0, bits 0-2: base length (0-7 bytes)
        //  Byte 0, bits 3-7: encoded shift (see below)
        //  Byte 1: extended shift code (only needed for odd shifts >= 5)
        //  Followed by 0-7 bytes of "base"
        //  Followed by an EncodedUintVector of deltas.

        UInt64 v_or  = 0;
        UInt64 v_and = ~0UL;
        UInt64 v_min = ~0UL;
        UInt64 v_max = 0;

        foreach (var cellid in v)
        {
            v_or  |= cellid.Id;
            v_and &= cellid.Id;
            v_min  = Math.Min(v_min, cellid.Id);
            v_max  = Math.Max(v_max, cellid.Id);
        }

        // These variables represent the values that will used during encoding.
        UInt64 e_base          = 0; // Base value.
        int    e_base_len      = 0; // Number of bytes to represent "base".
        int    e_shift         = 0; // Delta shift.
        int    e_max_delta_msb = 0; // Bit position of the MSB of the largest delta.

        if (v_or > 0)
        {
            // We only allow even shifts, unless all values have the same low bit (in
            // which case the shift is odd and the preceding bit is implicitly on).
            // There is no point in allowing shifts > 56 since deltas are encoded in
            // at least 1 byte each.
            e_shift = Math.Min(56, BitsUtils.FindLSBSetNonZero64(v_or) & ~1);
            if ((v_and & (1UL << e_shift)) != 0)
            {
                ++e_shift;                                   // All S2CellIds same level.
            }
            // "base" consists of the "base_len" most significant bytes of the minimum
            // S2CellId.  We consider all possible values of "base_len" (0..7) and
            // choose the one that minimizes the total encoding size.
            UInt64 e_bytes = ~0UL;  // Best encoding size so far.
            for (int len = 0; len < 8; ++len)
            {
                // "t_base" is the base value being tested (first "len" bytes of v_min).
                // "t_max_delta_msb" is the most-significant bit position of the largest
                // delta (or zero if there are no deltas, i.e. if v.size() == 0).
                // "t_bytes" is the total size of the variable portion of the encoding.
                UInt64 t_base          = v_min & ~(~0UL >> (8 * len));
                int    t_max_delta_msb = Math.Max(0, BitsUtils.Log2Floor64((v_max - t_base) >> e_shift));
                UInt64 t_bytes         = (ulong)(len + v.Count * ((t_max_delta_msb >> 3) + 1));
                if (t_bytes < e_bytes)
                {
                    e_base          = t_base;
                    e_base_len      = len;
                    e_max_delta_msb = t_max_delta_msb;
                    e_bytes         = t_bytes;
                }
            }

            // It takes one extra byte to encode odd shifts (i.e., the case where all
            // S2CellIds are at the same level), so check whether we can get the same
            // encoding size per delta using an even shift.
            if (((e_shift & 1) != 0) && (e_max_delta_msb & 7) != 7)
            {
                --e_shift;
            }
        }

        System.Diagnostics.Debug.Assert(e_base_len <= 7);
        System.Diagnostics.Debug.Assert(e_shift <= 56);
        encoder.Ensure(2 + e_base_len);

        // As described above, "shift" and "base_len" are encoded in 1 or 2 bytes.
        // "shift_code" is 5 bits:
        //   values <= 28 represent even shifts in the range 0..56
        //   values 29, 30 represent odd shifts 1 and 3
        //   value 31 indicates that the shift is odd and encoded in the next byte
        int shift_code = e_shift >> 1;

        if ((e_shift & 1) != 0)
        {
            shift_code = Math.Min(31, shift_code + 29);
        }
        encoder.Put8((byte)((shift_code << 3) | e_base_len));
        if (shift_code == 31)
        {
            encoder.Put8((byte)(e_shift >> 1));  // Shift is always odd, so 3 bits unused.
        }
        // Encode the "base_len" most-significant bytes of "base".
        UInt64 base_bytes = e_base >> (64 - 8 * Math.Max(1, e_base_len));

        EncodedUintVector.EncodeUintWithLength(base_bytes, e_base_len, encoder);

        // Finally, encode the vector of deltas.
        var deltas = new UInt64[v.Count];

        for (var i = 0; i < v.Count; i++)
        {
            var cellid = v[i];
            deltas[i] = (cellid.Id - e_base) >> e_shift;
        }
        EncodedUintVector.EncodeUintVector(deltas, encoder);
    }
Exemple #19
0
 public ulong GetChildByHash(byte h)
 {
     return((ChildrenMask & (1u << h)) == 0 ? 0ul : _children[BitsUtils.PositionOf(ChildrenMask, h)]);
 }
Exemple #20
0
        public static IHashTrieNode?ModifyChildren(
            InternalNode node, byte h, ulong value, IEnumerable <byte[]> childrenHashes, byte[]?valueHash
            )
        {
            if (node == null)
            {
                throw new ArgumentNullException(nameof(node));
            }

            var was = node.GetChildByHash(h);

            if (was == value)
            {
                return(node);
            }

            List <byte[]> newHashes;
            var           newNode = new InternalNode();
            var           pos     = (int)BitsUtils.PositionOf(node.ChildrenMask, h);

            if (was == 0)
            {
                if (valueHash is null)
                {
                    throw new ArgumentNullException(nameof(valueHash));
                }
                newNode._children = new ulong[node._children.Length + 1];
                for (var i = 0; i <= node._children.Length; ++i)
                {
                    newNode._children[i] = i < pos ? node._children[i] : (i == pos ? value : node._children[i - 1]);
                }
                newNode.ChildrenMask = node.ChildrenMask | (1u << h);
                newHashes            = childrenHashes.ToList();
                newHashes.Insert(pos, valueHash);
                newNode.UpdateHash(newHashes, GetChildrenLabels(newNode.ChildrenMask));
                return(newNode);
            }

            if (value == 0)
            {
                if (node._children.Length == 1)
                {
                    return(null);
                }
                newNode._children = new ulong[node._children.Length - 1];
                for (var i = 0; i + 1 < node._children.Length; ++i)
                {
                    newNode._children[i] = i < pos ? node._children[i] : node._children[i + 1];
                }
                newNode.ChildrenMask = node.ChildrenMask ^ (1u << h);
                newHashes            = childrenHashes.ToList();
                newHashes.RemoveAt(pos);
                newNode.UpdateHash(newHashes, GetChildrenLabels(newNode.ChildrenMask));
                return(newNode);
            }

            newNode._children      = node._children.ToArray();
            newNode.ChildrenMask   = node.ChildrenMask;
            newNode._children[pos] = value;
            newHashes      = childrenHashes.ToList();
            newHashes[pos] = valueHash ?? throw new ArgumentNullException(nameof(valueHash));
            newNode.UpdateHash(newHashes, GetChildrenLabels(newNode.ChildrenMask));
            return(newNode);
        }
    // Read the next word from the bitstream "wvbits" and return the value. This
    // function can be used for hybrid or lossless streams, but since an
    // optimized version is available for lossless this function would normally
    // be used for hybrid only. If a hybrid lossless stream is being read then
    // the "correction" offset is written at the specified pointer. A return value
    // of WORD_EOF indicates that the end of the bitstream was reached (all 1s) or
    // some other error occurred.

    internal static int get_words(long nsamples, long flags, words_data w, Bitstream bs, int[] buffer, int bufferStartPos)
    {
        entropy_data[] c = w.c;
        int            csamples;
        int            buffer_counter = bufferStartPos;
        int            entidx         = 1;

        if ((flags & (Defines.MONO_FLAG | Defines.FALSE_STEREO)) == 0)
        // if not mono
        {
            nsamples *= 2;
        }
        else
        {
            // it is mono
            entidx = 0;
        }

        for (csamples = 0; csamples < nsamples; ++csamples)
        {
            long ones_count, low, high, mid;

            if ((flags & (Defines.MONO_FLAG | Defines.FALSE_STEREO)) == 0)
            // if not mono
            {
                if (entidx == 1)
                {
                    entidx = 0;
                }
                else
                {
                    entidx = 1;
                }
            }

            if ((w.c[0].median[0] & ~1) == 0 && w.holding_zero == 0 && w.holding_one == 0 && (w.c[1].median[0] & ~1) == 0)
            {
                long mask;
                int  cbits;

                if (w.zeros_acc > 0)
                {
                    --w.zeros_acc;

                    if (w.zeros_acc > 0)
                    {
                        c[entidx].slow_level  -= ((c[entidx].slow_level + SLO) >> SLS);
                        buffer[buffer_counter] = 0;
                        buffer_counter++;
                        continue;
                    }
                }
                else
                {
                    cbits = 0;
                    bs    = BitsUtils.getbit(bs);

                    while (cbits < 33 && bs.bitval > 0)
                    {
                        cbits++;
                        bs = BitsUtils.getbit(bs);
                    }

                    if (cbits == 33)
                    {
                        break;
                    }

                    if (cbits < 2)
                    {
                        w.zeros_acc = cbits;
                    }
                    else
                    {
                        --cbits;

                        for (mask = 1, w.zeros_acc = 0; cbits > 0; mask <<= 1)
                        {
                            bs = BitsUtils.getbit(bs);

                            if (bs.bitval > 0)
                            {
                                w.zeros_acc |= mask;
                            }
                            cbits--;
                        }

                        w.zeros_acc |= mask;
                    }

                    if (w.zeros_acc > 0)
                    {
                        c[entidx].slow_level -= ((c[entidx].slow_level + SLO) >> SLS);
                        w.c[0].median[0]      = 0;
                        w.c[0].median[1]      = 0;
                        w.c[0].median[2]      = 0;
                        w.c[1].median[0]      = 0;
                        w.c[1].median[1]      = 0;
                        w.c[1].median[2]      = 0;

                        buffer[buffer_counter] = 0;
                        buffer_counter++;
                        continue;
                    }
                }
            }

            if (w.holding_zero > 0)
            {
                ones_count = w.holding_zero = 0;
            }
            else
            {
                int next8;
                int uns_buf;

                if (bs.bc < 8)
                {
                    bs.ptr++;
                    bs.buf_index++;

                    if (bs.ptr == bs.end)
                    {
                        bs = BitsUtils.bs_read(bs);
                    }

                    uns_buf = (int)(bs.buf[bs.buf_index] & 0xff);

                    bs.sr = bs.sr | (uns_buf << bs.bc);                     // values in buffer must be unsigned

                    next8 = (int)(bs.sr & 0xff);

                    bs.bc += 8;
                }
                else
                {
                    next8 = (int)(bs.sr & 0xff);
                }

                if (next8 == 0xff)
                {
                    bs.bc  -= 8;
                    bs.sr >>= 8;

                    ones_count = 8;
                    bs         = BitsUtils.getbit(bs);

                    while (ones_count < (LIMIT_ONES + 1) && bs.bitval > 0)
                    {
                        ones_count++;
                        bs = BitsUtils.getbit(bs);
                    }

                    if (ones_count == (LIMIT_ONES + 1))
                    {
                        break;
                    }

                    if (ones_count == LIMIT_ONES)
                    {
                        int mask;
                        int cbits;

                        cbits = 0;
                        bs    = BitsUtils.getbit(bs);

                        while (cbits < 33 && bs.bitval > 0)
                        {
                            cbits++;
                            bs = BitsUtils.getbit(bs);
                        }

                        if (cbits == 33)
                        {
                            break;
                        }

                        if (cbits < 2)
                        {
                            ones_count = cbits;
                        }
                        else
                        {
                            for (mask = 1, ones_count = 0; --cbits > 0; mask <<= 1)
                            {
                                bs = BitsUtils.getbit(bs);

                                if (bs.bitval > 0)
                                {
                                    ones_count |= mask;
                                }
                            }
                            ones_count |= mask;
                        }

                        ones_count += LIMIT_ONES;
                    }
                }
                else
                {
                    bs.bc = (int)(bs.bc - ((ones_count = ones_count_table[next8]) + 1));
                    bs.sr = bs.sr >> (int)(ones_count + 1);                      // needs to be unsigned
                }

                if (w.holding_one > 0)
                {
                    w.holding_one = ones_count & 1;
                    ones_count    = (ones_count >> 1) + 1;
                }
                else
                {
                    w.holding_one = ones_count & 1;
                    ones_count  >>= 1;
                }

                w.holding_zero = (int)(~w.holding_one & 1);
            }

            if ((flags & Defines.HYBRID_FLAG) > 0 && ((flags & (Defines.MONO_FLAG | Defines.FALSE_STEREO)) > 0 || (csamples & 1) == 0))
            {
                w = update_error_limit(w, flags);
            }

            if (ones_count == 0)
            {
                low  = 0;
                high = (((c[entidx].median[0]) >> 4) + 1) - 1;

                // for c# I replace the division by DIV0 with >> 7
                c[entidx].median[0] -= (((c[entidx].median[0] + (DIV0 - 2)) >> 7) * 2);
            }
            else
            {
                low = (((c[entidx].median[0]) >> 4) + 1);

                // for c# I replace the division by DIV0 with >> 7
                c[entidx].median[0] += ((c[entidx].median[0] + DIV0) >> 7) * 5;

                if (ones_count == 1)
                {
                    high = low + (((c[entidx].median[1]) >> 4) + 1) - 1;
                    // for c# I replace the division by DIV1 with >> 6
                    c[entidx].median[1] -= ((c[entidx].median[1] + (DIV1 - 2)) >> 6) * 2;
                }
                else
                {
                    low += (((c[entidx].median[1]) >> 4) + 1);
                    // for c# I replace the division by DIV1 with >> 6
                    c[entidx].median[1] += ((c[entidx].median[1] + DIV1) >> 6) * 5;

                    if (ones_count == 2)
                    {
                        high = low + (((c[entidx].median[2]) >> 4) + 1) - 1;
                        // for c# I replace the division by DIV2 with >> 5
                        c[entidx].median[2] -= ((c[entidx].median[2] + (DIV2 - 2)) >> 5) * 2;
                    }
                    else
                    {
                        low += (ones_count - 2) * (((c[entidx].median[2]) >> 4) + 1);
                        high = low + (((c[entidx].median[2]) >> 4) + 1) - 1;
                        // for c# I replace the division by DIV2 with >> 5
                        c[entidx].median[2] += ((c[entidx].median[2] + DIV2) >> 5) * 5;
                    }
                }
            }

            mid = (high + low + 1) >> 1;

            if (c[entidx].error_limit == 0)
            {
                mid = read_code(bs, high - low);

                mid = mid + low;
            }
            else
            {
                while (high - low > c[entidx].error_limit)
                {
                    bs = BitsUtils.getbit(bs);

                    if (bs.bitval > 0)
                    {
                        mid = (high + (low = mid) + 1) >> 1;
                    }
                    else
                    {
                        mid = ((high = mid - 1) + low + 1) >> 1;
                    }
                }
            }

            bs = BitsUtils.getbit(bs);

            if (bs.bitval > 0)
            {
                buffer[buffer_counter] = (int)~mid;
            }
            else
            {
                buffer[buffer_counter] = (int)mid;
            }

            buffer_counter++;

            if ((flags & Defines.HYBRID_BITRATE) > 0)
            {
                c[entidx].slow_level = c[entidx].slow_level - ((c[entidx].slow_level + SLO) >> SLS) + mylog2(mid);
            }
        }

        w.c = c;

        if ((flags & (Defines.MONO_FLAG | Defines.FALSE_STEREO)) != 0)
        {
            return(csamples);
        }
        else
        {
            return(csamples / 2);
        }
    }
Exemple #22
0
        public bool Parity()
        {
            var p = _signature.ToBytes().Aggregate(0u, (i, b) => i ^ b, x => x);

            return(BitsUtils.Popcount(p) % 2 == 1);
        }