Beispiel #1
0
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;
}