StdBuf StdCompilerINIRead::ReadString(size_t iLength, RawCompileType eRawType, bool fAppendNull)
{
	// Excpect valid position
	if (!pPos)
		{ notFound("String"); return StdBuf(); }
	// Skip whitespace
	SkipWhitespace();
	// Escaped? Go over '"'
	if (eRawType == RCT_Escaped && *pPos++ != '"')
		{ notFound("Escaped string"); return StdBuf(); }
	// Create buffer
	StdBuf OutBuf; OutBuf.New(iLength + (fAppendNull ? sizeof('\0') : 0));
	// Read
	char *pOut = getMBufPtr<char>(OutBuf);
	while (iLength && !TestStringEnd(eRawType))
	{
		// Read a character
		if (eRawType == RCT_Escaped)
			*pOut++ = ReadEscapedChar();
		else
			*pOut++ = *pPos++;
		// Count it
		iLength--;
	}
	// Escaped: Go over '"'
	if (eRawType == RCT_Escaped)
	{
		while (*pPos != '"')
		{
			if (!*pPos || *pPos == '\n' || *pPos == '\r')
			{
				Warn("string not terminated!");
				pPos--;
				break;
			}
			pPos++;
		}
		pPos++;
	}
	// Nothing read? Identifiers need to be non-empty
	if (pOut == OutBuf.getData() && (eRawType == RCT_Idtf || eRawType == RCT_ID))
		{ notFound("String"); return StdBuf(); }
	// Append null
	if (fAppendNull)
		*pOut = '\0';
	// Shrink, if less characters were read
	OutBuf.Shrink(iLength);
	// Done
	return OutBuf;
}
Esempio n. 2
0
StdBuf C4Playback::ReWriteBinary() {
  const int OUTPUT_GROW = 16 * 1024;
  StdBuf Output;
  int iPos = 0;
  bool fFinished = false;
  uint32_t iFrame = 0;
  for (chunks_t::const_iterator i = chunks.begin();
       !fFinished && i != chunks.end(); i++) {
    // Check frame difference
    if (i->Frame - iFrame < 0 || i->Frame - iFrame > 0xff)
      LogF(
          "ERROR: Invalid frame difference between chunks (0-255 allowed)! "
          "Data will be invalid!");
    // Pack data
    StdBuf Chunk;
    try {
      switch (i->Type) {
        case RCT_Ctrl:
          Chunk = DecompileToBuf<StdCompilerBinWrite>(*i->pCtrl);
          break;
        case RCT_CtrlPkt:
          Chunk = DecompileToBuf<StdCompilerBinWrite>(*i->pPkt);
          break;
        case RCT_End:
          fFinished = true;
          break;
        default:  // debugrec
          if (i->pDbg) Chunk = DecompileToBuf<StdCompilerBinWrite>(*i->pDbg);
          break;
      }
    } catch (StdCompiler::Exception *pEx) {
      LogF("Record: Binary unpack error: %s", pEx->Msg.getData());
      delete pEx;
      return StdBuf();
    }
    // Grow output
    while (Output.getSize() - iPos <
           sizeof(C4RecordChunkHead) + Chunk.getSize())
      Output.Grow(OUTPUT_GROW);
    // Write header
    C4RecordChunkHead *pHead = getMBufPtr<C4RecordChunkHead>(Output, iPos);
    pHead->Type = i->Type;
    pHead->iFrm = i->Frame - iFrame;
    iPos += sizeof(C4RecordChunkHead);
    iFrame = i->Frame;
    // Write chunk
    Output.Write(Chunk, iPos);
    iPos += Chunk.getSize();
  }
  Output.SetSize(iPos);
  return Output;
}
Esempio n. 3
0
bool C4Record::Rec(int iFrame, const StdBuf &sBuf, C4RecordChunkType eType) {
  // filler chunks (this should never be necessary, though)
  while (iFrame > iLastFrame + 0xff)
    Rec(iLastFrame + 0xff, StdBuf(), RCT_Frame);
  // get frame difference
  uint32_t iFrameDiff = Max<uint32_t>(0, iFrame - iLastFrame);
  iLastFrame += iFrameDiff;
  // create head
  C4RecordChunkHead Head = {static_cast<uint8_t>(iFrameDiff),
                            static_cast<uint8_t>(eType)};
  // pack
  CtrlRec.Write(&Head, sizeof(Head));
  CtrlRec.Write(sBuf.getData(), sBuf.getSize());
#ifdef IMMEDIATEREC
  // immediate rec: always flush
  CtrlRec.Flush();
#endif
  // Stream
  if (fStreaming) Stream(Head, sBuf);
  return true;
}