HRESULT CBlock::Write(IStream* pStream) { HeaderWrite(pStream); TrackNumber.Write(pStream); short t = (short)TimeCode; bswap((BYTE*)&t, 2); pStream->Write(&t, 2, nullptr); BYTE Lacing = 0; BYTE n = (BYTE)BlockData.GetCount(); if (n > 1) { Lacing |= 2; } pStream->Write(&Lacing, 1, nullptr); if (n > 1) { pStream->Write(&n, 1, nullptr); POSITION pos = BlockData.GetHeadPosition(); while (pos) { CBinary* b = BlockData.GetNext(pos); if (pos) { INT_PTR len = b->GetCount(); while (len >= 0) { n = (BYTE)std::min<INT_PTR>(len, 255); pStream->Write(&n, 1, nullptr); len -= 255; } } } } POSITION pos = BlockData.GetHeadPosition(); while (pos) { CBinary* b = BlockData.GetNext(pos); pStream->Write(b->GetData(), (ULONG)b->GetCount(), nullptr); } return S_OK; }
bool TrackEntry::Expand(CBinary& data, UINT64 Scope) { if (ces.ce.IsEmpty()) { return true; } CAtlArray<ContentEncoding*> cearray; POSITION pos = ces.ce.GetHeadPosition(); while (pos) { cearray.Add(ces.ce.GetNext(pos)); } qsort(cearray.GetData(), cearray.GetCount(), sizeof(ContentEncoding*), cesort); for (int i = (int)cearray.GetCount() - 1; i >= 0; i--) { ContentEncoding* ce = cearray[i]; if (!(ce->ContentEncodingScope & Scope)) { continue; } if (ce->ContentEncodingType == ContentEncoding::Compression) { if (!data.Decompress(ce->cc)) { return false; } } else if (ce->ContentEncodingType == ContentEncoding::Encryption) { // TODO return false; } } return true; }
HRESULT CBlock::Write(IStream* pStream) { HeaderWrite(pStream); TrackNumber.Write(pStream); short t = (short)TimeCode; bswap((BYTE*)&t, 2); pStream->Write(&t, 2, NULL); BYTE Lacing = 0; BYTE n = BlockData.GetCount(); if(n > 1) Lacing |= 2; pStream->Write(&Lacing, 1, NULL); if(n > 1) { pStream->Write(&n, 1, NULL); POSITION pos = BlockData.GetHeadPosition(); while(pos) { CBinary* b = BlockData.GetNext(pos); if(pos) { int len = b->GetCount(); while(len >= 0) { n = min(len, 255); pStream->Write(&n, 1, NULL); len -= 255; } } } } POSITION pos = BlockData.GetHeadPosition(); while(pos) { CBinary* b = BlockData.GetNext(pos); pStream->Write(b->GetData(), b->GetCount(), NULL); } return S_OK; }
MatroskaWriter::QWORD CBlock::Size(bool fWithHeader) { MatroskaWriter::QWORD len = 0; len += TrackNumber.Size() + 2 + 1; // TrackNumber + TimeCode + Lacing if(BlockData.GetCount() > 1) { len += 1; // nBlockData POSITION pos = BlockData.GetHeadPosition(); while(pos) { CBinary* b = BlockData.GetNext(pos); if(pos) len += b->GetCount()/255 + 1; } } POSITION pos = BlockData.GetHeadPosition(); while(pos) { CBinary* b = BlockData.GetNext(pos); len += b->GetCount(); } if(fWithHeader) len += HeaderSize(len); return len; }