예제 #1
0
        private void GetNextFolderItem(CFolder folder)
        {
            Log.WriteLine("-- GetNextFolderItem --");
            Log.PushIndent();
            try
            {
                int numCoders = ReadNum();
                Log.WriteLine("NumCoders: " + numCoders);

                folder.Coders = new List<CCoderInfo>(numCoders);
                int numInStreams = 0;
                int numOutStreams = 0;
                for (int i = 0; i < numCoders; i++)
                {
                    Log.WriteLine("-- Coder --");
                    Log.PushIndent();
                    try
                    {
                        CCoderInfo coder = new CCoderInfo();
                        folder.Coders.Add(coder);

                        byte mainByte = ReadByte();
                        int idSize = (mainByte & 0xF);
                        byte[] longID = new byte[idSize];
                        ReadBytes(longID, 0, idSize);
                        Log.WriteLine("MethodId: " + String.Join("", Enumerable.Range(0, idSize).Select(x => longID[x].ToString("x2"))));
                        if (idSize > 8)
                            throw new NotSupportedException();
                        ulong id = 0;
                        for (int j = 0; j < idSize; j++)
                            id |= (ulong)longID[idSize - 1 - j] << (8 * j);
                        coder.MethodId = new CMethodId(id);

                        if ((mainByte & 0x10) != 0)
                        {
                            coder.NumInStreams = ReadNum();
                            coder.NumOutStreams = ReadNum();
                            Log.WriteLine("Complex Stream (In: " + coder.NumInStreams + " - Out: " + coder.NumOutStreams + ")");
                        }
                        else
                        {
                            Log.WriteLine("Simple Stream (In: 1 - Out: 1)");
                            coder.NumInStreams = 1;
                            coder.NumOutStreams = 1;
                        }

                        if ((mainByte & 0x20) != 0)
                        {
                            int propsSize = ReadNum();
                            coder.Props = new byte[propsSize];
                            ReadBytes(coder.Props, 0, propsSize);
                            Log.WriteLine("Settings: " + String.Join("", coder.Props.Select(bt => bt.ToString("x2"))));
                        }

                        if ((mainByte & 0x80) != 0)
                            throw new NotSupportedException();

                        numInStreams += coder.NumInStreams;
                        numOutStreams += coder.NumOutStreams;
                    }
                    finally { Log.PopIndent(); }
                }

                int numBindPairs = numOutStreams - 1;
                folder.BindPairs = new List<CBindPair>(numBindPairs);
                Log.WriteLine("BindPairs: " + numBindPairs);
                Log.PushIndent();
                for (int i = 0; i < numBindPairs; i++)
                {
                    CBindPair bp = new CBindPair();
                    bp.InIndex = ReadNum();
                    bp.OutIndex = ReadNum();
                    folder.BindPairs.Add(bp);
                    Log.WriteLine("#" + i + " - In: " + bp.InIndex + " - Out: " + bp.OutIndex);
                }
                Log.PopIndent();

                if (numInStreams < numBindPairs)
                    throw new NotSupportedException();

                int numPackStreams = numInStreams - numBindPairs;
                //folder.PackStreams.Reserve(numPackStreams);
                if (numPackStreams == 1)
                {
                    for (int i = 0; i < numInStreams; i++)
                    {
                        if (folder.FindBindPairForInStream(i) < 0)
                        {
                            Log.WriteLine("Single PackStream: #" + i);
                            folder.PackStreams.Add(i);
                            break;
                        }
                    }

                    if (folder.PackStreams.Count != 1)
                        throw new NotSupportedException();
                }
                else
                {
                    Log.WriteLine("Multiple PackStreams ...");
                    Log.PushIndent();
                    for (int i = 0; i < numPackStreams; i++)
                    {
                        var num = ReadNum();
                        Log.WriteLine("#" + i + " - " + num);
                        folder.PackStreams.Add(num);
                    }
                    Log.PopIndent();
                }
            }
            finally
            {
                Log.PopIndent();
            }
        }
예제 #2
0
        public bool CheckStructure()
        {
            const int kNumCodersMax = 32; // don't change it
            const int kMaskSize     = 32; // it must be >= kNumCodersMax
            const int kNumBindsMax  = 32;

            if (Coders.Count > kNumCodersMax || BindPairs.Count > kNumBindsMax)
            {
                return(false);
            }

            {
                var v = new BitVector(BindPairs.Count + PackStreams.Count);

                for (int i = 0; i < BindPairs.Count; i++)
                {
                    if (v.GetAndSet(BindPairs[i].InIndex))
                    {
                        return(false);
                    }
                }

                for (int i = 0; i < PackStreams.Count; i++)
                {
                    if (v.GetAndSet(PackStreams[i]))
                    {
                        return(false);
                    }
                }
            }

            {
                var v = new BitVector(UnpackSizes.Count);
                for (int i = 0; i < BindPairs.Count; i++)
                {
                    if (v.GetAndSet(BindPairs[i].OutIndex))
                    {
                        return(false);
                    }
                }
            }

            uint[] mask = new uint[kMaskSize];

            {
                List <int> inStreamToCoder  = new List <int>();
                List <int> outStreamToCoder = new List <int>();
                for (int i = 0; i < Coders.Count; i++)
                {
                    CCoderInfo coder = Coders[i];
                    for (int j = 0; j < coder.NumInStreams; j++)
                    {
                        inStreamToCoder.Add(i);
                    }
                    for (int j = 0; j < coder.NumOutStreams; j++)
                    {
                        outStreamToCoder.Add(i);
                    }
                }

                for (int i = 0; i < BindPairs.Count; i++)
                {
                    CBindPair bp = BindPairs[i];
                    mask[inStreamToCoder[bp.InIndex]] |= (1u << outStreamToCoder[bp.OutIndex]);
                }
            }

            for (int i = 0; i < kMaskSize; i++)
            {
                for (int j = 0; j < kMaskSize; j++)
                {
                    if (((1u << j) & mask[i]) != 0)
                    {
                        mask[i] |= mask[j];
                    }
                }
            }

            for (int i = 0; i < kMaskSize; i++)
            {
                if (((1u << i) & mask[i]) != 0)
                {
                    return(false);
                }
            }

            return(true);
        }