BOOL C4Playback::ReadBinary(const StdBuf &Buf) { // sequential reading: Take over rest from last buffer const StdBuf *pUseBuf; uint32_t iFrame = 0; if (fLoadSequential) { sequentialBuffer.Append(Buf); pUseBuf = &sequentialBuffer; iFrame = iLastSequentialFrame; } else pUseBuf = &Buf; // get buffer data size_t iPos = 0; bool fFinished = false; do { // unpack header if (pUseBuf->getSize() - iPos < sizeof(C4RecordChunkHead)) break; const C4RecordChunkHead *pHead = getBufPtr<C4RecordChunkHead>(*pUseBuf, iPos); // get chunk iPos += sizeof(C4RecordChunkHead); StdBuf Chunk = pUseBuf->getPart(iPos, pUseBuf->getSize() - iPos); // Create entry C4RecordChunk c; c.Frame = (iFrame += pHead->iFrm); c.Type = pHead->Type; // Unpack data try { // Initialize compiler StdCompilerBinRead Compiler; Compiler.setInput(Chunk.getRef()); Compiler.Begin(); // Read chunk switch (pHead->Type) { case RCT_Ctrl: Compiler.Value(mkPtrAdaptNoNull(c.pCtrl)); break; case RCT_CtrlPkt: Compiler.Value(mkPtrAdaptNoNull(c.pPkt)); break; case RCT_End: fFinished = true; break; case RCT_File: Compiler.Value(c.Filename); Compiler.Value(mkPtrAdaptNoNull(c.pFileData)); break; default: // debugrec if (pHead->Type >= 0x80) Compiler.Value(mkPtrAdaptNoNull(c.pDbg)); } // Advance over data Compiler.End(); iPos += Compiler.getPosition(); } catch (StdCompiler::EOFException *pEx) { // This is to be expected for sequential reading if (fLoadSequential) { iPos -= sizeof(C4RecordChunkHead); iFrame -= pHead->iFrm; delete pEx; break; } LogF("Record: Binary unpack error: %s", pEx->Msg.getData()); c.Delete(); delete pEx; return FALSE; } catch (StdCompiler::Exception *pEx) { LogF("Record: Binary unpack error: %s", pEx->Msg.getData()); c.Delete(); delete pEx; return FALSE; } // Add to list chunks.push_back(c); c.pPkt = NULL; } while (!fFinished); // erase everything but the trailing part from sequential buffer if (fLoadSequential) { if (iPos >= sequentialBuffer.getSize()) sequentialBuffer.Clear(); else if (iPos) { sequentialBuffer.Move(iPos, sequentialBuffer.getSize() - iPos); sequentialBuffer.Shrink(iPos); } iLastSequentialFrame = iFrame; } return TRUE; }