StdBuf C4NetpuncherPacketID<TYPE>::PackInto() const { StdBuf buf; auto id = GetID(); buf.New(sizeof(id)); buf.Write(&id, sizeof(id)); return buf; }
StdBuf C4NetpuncherPacketCReq::PackInto() const { StdBuf buf; auto sin6 = static_cast<sockaddr_in6>(addr.AsIPv6()); auto port = addr.GetPort(); buf.New(sizeof(port) + sizeof(sin6.sin6_addr)); size_t offset = 0; buf.Write(&port, sizeof(port), offset); offset += sizeof(port); buf.Write(&sin6.sin6_addr, sizeof(sin6.sin6_addr), offset); static_assert(sizeof(sin6.sin6_addr) == 16, "expected sin6_addr to be 16 bytes"); return buf; }
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; }
bool C4Playback::NextSequentialChunk() { StdBuf BinaryBuf; size_t iRealSize; BinaryBuf.New(4096); // load data until a chunk could be filled for (;;) { iRealSize = 0; playbackFile.Read(BinaryBuf.getMData(), 4096, &iRealSize); if (!iRealSize) return false; BinaryBuf.SetSize(iRealSize); if (!ReadBinary(BinaryBuf)) return false; // okay, at least one chunk has been read! if (chunks.size()) { currChunk = chunks.begin(); return true; } } // playback file reading failed - looks like we're done return false; }
bool C4Playback::StreamToRecord(const char *szStream, StdStrBuf *pRecordFile) { // Load data StdBuf CompressedData; Log("Reading stream..."); if (!CompressedData.LoadFromFile(szStream)) return false; // Decompress unsigned long iStreamSize = CompressedData.getSize() * 5; StdBuf StreamData; StreamData.New(iStreamSize); while (true) { // Initialize stream z_stream strm; ZeroMem(&strm, sizeof strm); strm.next_in = getMBufPtr<BYTE>(CompressedData); strm.avail_in = CompressedData.getSize(); strm.next_out = getMBufPtr<BYTE>(StreamData); strm.avail_out = StreamData.getSize(); // Decompress if (inflateInit(&strm) != Z_OK) return false; int ret = inflate(&strm, Z_FINISH); if (ret == Z_STREAM_END) { inflateEnd(&strm); break; } if (ret != Z_BUF_ERROR) return false; // All input consumed? iStreamSize = strm.total_out; if (strm.avail_in == 0) { Log("Stream data incomplete, using as much data as possible"); break; } // Larger buffer needed StreamData.Grow(CompressedData.getSize()); iStreamSize = StreamData.getSize(); } StreamData.SetSize(iStreamSize); // Parse C4Playback Playback; Playback.ReadBinary(StreamData); LogF("Got %d chunks from stream", Playback.chunks.size()); // Get first chunk, which must contain the initial chunks_t::iterator chunkIter = Playback.chunks.begin(); if (chunkIter == Playback.chunks.end() || chunkIter->Type != RCT_File) return false; // Get initial chunk, go over file name StdBuf InitialData = *chunkIter->pFileData; const char *szInitialFilename = chunkIter->Filename.getData(); // Put to temporary file and unpack char szInitial[_MAX_PATH + 1] = "~initial.tmp"; MakeTempFilename(szInitial); if (!InitialData.SaveToFile(szInitial) || !C4Group_UnpackDirectory(szInitial)) return false; // Load Scenario.txt from Initial C4Group Grp; C4Scenario Initial; if (!Grp.Open(szInitial) || !Initial.Load(Grp) || !Grp.Close()) return false; // Copy original scenario const char *szOrigin = Initial.Head.Origin.getData(); char szRecord[_MAX_PATH + 1]; SCopy(szStream, szRecord, _MAX_PATH); if (GetExtension(szRecord)) *(GetExtension(szRecord) - 1) = 0; SAppend(".c4s", szRecord, _MAX_PATH); LogF("Original scenario is %s, creating %s.", szOrigin, szRecord); if (!C4Group_CopyItem(szOrigin, szRecord, false, false)) return false; // Merge initial if (!Grp.Open(szRecord) || !Grp.Merge(szInitial)) return false; // Process other files in stream chunkIter->Delete(); chunkIter = Playback.chunks.erase(chunkIter); while (chunkIter != Playback.chunks.end()) if (chunkIter->Type == RCT_File) { LogF("Inserting %s...", chunkIter->Filename.getData()); StdStrBuf Temp; Temp.Copy(chunkIter->Filename); MakeTempFilename(&Temp); if (!chunkIter->pFileData->SaveToFile(Temp.getData())) return false; if (!Grp.Move(Temp.getData(), chunkIter->Filename.getData())) return false; chunkIter = Playback.chunks.erase(chunkIter); } else chunkIter++; // Write record data StdBuf RecordData = Playback.ReWriteBinary(); if (!Grp.Add(C4CFN_CtrlRec, RecordData, false, true)) return false; // Done Log("Writing record file..."); Grp.Close(); pRecordFile->Copy(szRecord); return true; }