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(); } }
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); }