scmstream.cpp revision 8014d9e85803119a55d697b5b802d73c011d1f53
326d1845a5ad33574cb834270779589136854527vboxsync * IPRT Testcase / Tool - Source Code Massager Stream Code.
326d1845a5ad33574cb834270779589136854527vboxsync * Copyright (C) 2010-2012 Oracle Corporation
326d1845a5ad33574cb834270779589136854527vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
326d1845a5ad33574cb834270779589136854527vboxsync * available from http://www.virtualbox.org. This file is free software;
326d1845a5ad33574cb834270779589136854527vboxsync * you can redistribute it and/or modify it under the terms of the GNU
326d1845a5ad33574cb834270779589136854527vboxsync * General Public License (GPL) as published by the Free Software
326d1845a5ad33574cb834270779589136854527vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
326d1845a5ad33574cb834270779589136854527vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
326d1845a5ad33574cb834270779589136854527vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
326d1845a5ad33574cb834270779589136854527vboxsync/*******************************************************************************
326d1845a5ad33574cb834270779589136854527vboxsync* Header Files *
326d1845a5ad33574cb834270779589136854527vboxsync*******************************************************************************/
326d1845a5ad33574cb834270779589136854527vboxsync * Initializes the stream structure.
326d1845a5ad33574cb834270779589136854527vboxsync * @param pStream The stream structure.
326d1845a5ad33574cb834270779589136854527vboxsync * @param fWriteOrRead The value of the fWriteOrRead stream member.
326d1845a5ad33574cb834270779589136854527vboxsyncstatic void scmStreamInitInternal(PSCMSTREAM pStream, bool fWriteOrRead)
326d1845a5ad33574cb834270779589136854527vboxsync * Initialize an input stream.
326d1845a5ad33574cb834270779589136854527vboxsync * @returns IPRT status code.
326d1845a5ad33574cb834270779589136854527vboxsync * @param pStream The stream to initialize.
326d1845a5ad33574cb834270779589136854527vboxsync * @param pszFilename The file to take the stream content from.
326d1845a5ad33574cb834270779589136854527vboxsyncint ScmStreamInitForReading(PSCMSTREAM pStream, const char *pszFilename)
326d1845a5ad33574cb834270779589136854527vboxsync scmStreamInitInternal(pStream, false /*fWriteOrRead*/);
326d1845a5ad33574cb834270779589136854527vboxsync int rc = pStream->rc = RTFileReadAll(pszFilename, &pvFile, &cbFile);
326d1845a5ad33574cb834270779589136854527vboxsync * Initialize an output stream.
326d1845a5ad33574cb834270779589136854527vboxsync * @returns IPRT status code
326d1845a5ad33574cb834270779589136854527vboxsync * @param pStream The stream to initialize.
326d1845a5ad33574cb834270779589136854527vboxsync * @param pRelatedStream Pointer to a related stream. NULL is fine.
326d1845a5ad33574cb834270779589136854527vboxsyncint ScmStreamInitForWriting(PSCMSTREAM pStream, PCSCMSTREAM pRelatedStream)
326d1845a5ad33574cb834270779589136854527vboxsync scmStreamInitInternal(pStream, true /*fWriteOrRead*/);
326d1845a5ad33574cb834270779589136854527vboxsync /* allocate stuff */
326d1845a5ad33574cb834270779589136854527vboxsync size_t cLinesEstimate = pRelatedStream && pRelatedStream->fFullyLineated
326d1845a5ad33574cb834270779589136854527vboxsync ? pRelatedStream->cLines + pRelatedStream->cLines / 10
326d1845a5ad33574cb834270779589136854527vboxsync pStream->paLines = (PSCMSTREAMLINE)RTMemAlloc(cLinesEstimate * sizeof(SCMSTREAMLINE));
326d1845a5ad33574cb834270779589136854527vboxsync * Frees the resources associated with the stream.
326d1845a5ad33574cb834270779589136854527vboxsync * Nothing is happens to whatever the stream was initialized from or dumped to.
326d1845a5ad33574cb834270779589136854527vboxsync * @param pStream The stream to delete.
326d1845a5ad33574cb834270779589136854527vboxsync RTFileReadAllFree(pStream->pch, pStream->cbAllocated);
326d1845a5ad33574cb834270779589136854527vboxsync * Get the stream status code.
326d1845a5ad33574cb834270779589136854527vboxsync * @returns IPRT status code.
326d1845a5ad33574cb834270779589136854527vboxsync * @param pStream The stream.
326d1845a5ad33574cb834270779589136854527vboxsync * Grows the buffer of a write stream.
326d1845a5ad33574cb834270779589136854527vboxsync * @returns IPRT status code.
326d1845a5ad33574cb834270779589136854527vboxsync * @param pStream The stream. Must be in write mode.
326d1845a5ad33574cb834270779589136854527vboxsync * @param cbAppending The minimum number of bytes to grow the buffer
326d1845a5ad33574cb834270779589136854527vboxsyncstatic int scmStreamGrowBuffer(PSCMSTREAM pStream, size_t cbAppending)
326d1845a5ad33574cb834270779589136854527vboxsync cbAllocated += RT_MAX(0x1000 + cbAppending, cbAllocated);
326d1845a5ad33574cb834270779589136854527vboxsync pvNew = RTMemDupEx(pStream->pch, pStream->off, cbAllocated - pStream->off);
326d1845a5ad33574cb834270779589136854527vboxsync RTFileReadAllFree(pStream->pch, pStream->cbAllocated);
326d1845a5ad33574cb834270779589136854527vboxsync * Grows the line array of a stream.
326d1845a5ad33574cb834270779589136854527vboxsync * @returns IPRT status code.
326d1845a5ad33574cb834270779589136854527vboxsync * @param pStream The stream.
326d1845a5ad33574cb834270779589136854527vboxsync * @param iMinLine Minimum line number.
326d1845a5ad33574cb834270779589136854527vboxsyncstatic int scmStreamGrowLines(PSCMSTREAM pStream, size_t iMinLine)
326d1845a5ad33574cb834270779589136854527vboxsync cLinesAllocated += RT_MAX(512 + iMinLine, cLinesAllocated);
326d1845a5ad33574cb834270779589136854527vboxsync void *pvNew = RTMemRealloc(pStream->paLines, cLinesAllocated * sizeof(SCMSTREAMLINE));
326d1845a5ad33574cb834270779589136854527vboxsync * Rewinds the stream and sets the mode to read.
326d1845a5ad33574cb834270779589136854527vboxsync * @param pStream The stream.
326d1845a5ad33574cb834270779589136854527vboxsync * Rewinds the stream and sets the mode to write.
326d1845a5ad33574cb834270779589136854527vboxsync * @param pStream The stream.
326d1845a5ad33574cb834270779589136854527vboxsync * Checks if it's a text stream.
326d1845a5ad33574cb834270779589136854527vboxsync * Not 100% proof.
326d1845a5ad33574cb834270779589136854527vboxsync * @returns true if it probably is a text file, false if not.
326d1845a5ad33574cb834270779589136854527vboxsync * @param pStream The stream. Write or read, doesn't matter.
326d1845a5ad33574cb834270779589136854527vboxsync return false;
326d1845a5ad33574cb834270779589136854527vboxsync return false;
326d1845a5ad33574cb834270779589136854527vboxsync return true;
326d1845a5ad33574cb834270779589136854527vboxsync * Performs an integrity check of the stream.
326d1845a5ad33574cb834270779589136854527vboxsync * @returns IPRT status code.
326d1845a5ad33574cb834270779589136854527vboxsync * @param pStream The stream.
326d1845a5ad33574cb834270779589136854527vboxsync * Perform sanity checks.
326d1845a5ad33574cb834270779589136854527vboxsync for (size_t iLine = 0; iLine < pStream->cLines; iLine++)
326d1845a5ad33574cb834270779589136854527vboxsync size_t offEol = pStream->paLines[iLine].off + pStream->paLines[iLine].cch;
326d1845a5ad33574cb834270779589136854527vboxsync AssertReturn(offEol + pStream->paLines[iLine].enmEol <= cbFile, VERR_INTERNAL_ERROR_2);
326d1845a5ad33574cb834270779589136854527vboxsync AssertReturn(pStream->pch[offEol] == '\n', VERR_INTERNAL_ERROR_3);
326d1845a5ad33574cb834270779589136854527vboxsync AssertReturn(pStream->pch[offEol] == '\r', VERR_INTERNAL_ERROR_3);
326d1845a5ad33574cb834270779589136854527vboxsync AssertReturn(pStream->pch[offEol + 1] == '\n', VERR_INTERNAL_ERROR_3);
326d1845a5ad33574cb834270779589136854527vboxsync AssertReturn(iLine + 1 >= pStream->cLines, VERR_INTERNAL_ERROR_4);
326d1845a5ad33574cb834270779589136854527vboxsync AssertReturn(iLine + 1 >= pStream->cLines, VERR_INTERNAL_ERROR_5);
326d1845a5ad33574cb834270779589136854527vboxsync * Writes the stream to a file.
326d1845a5ad33574cb834270779589136854527vboxsync * @returns IPRT status code
326d1845a5ad33574cb834270779589136854527vboxsync * @param pStream The stream.
326d1845a5ad33574cb834270779589136854527vboxsync * @param pszFilenameFmt The filename format string.
326d1845a5ad33574cb834270779589136854527vboxsync * @param ... Format arguments.
326d1845a5ad33574cb834270779589136854527vboxsyncint ScmStreamWriteToFile(PSCMSTREAM pStream, const char *pszFilenameFmt, ...)
326d1845a5ad33574cb834270779589136854527vboxsync * Check that what we're going to write makes sense first.
326d1845a5ad33574cb834270779589136854527vboxsync * Do the actual writing.
326d1845a5ad33574cb834270779589136854527vboxsync rc = RTFileOpenV(&hFile, RTFILE_O_WRITE | RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_WRITE, pszFilenameFmt, va);
326d1845a5ad33574cb834270779589136854527vboxsync rc = RTFileWrite(hFile, pStream->pch, pStream->cb, NULL);
326d1845a5ad33574cb834270779589136854527vboxsync * Writes the stream to standard output.
326d1845a5ad33574cb834270779589136854527vboxsync * @returns IPRT status code
326d1845a5ad33574cb834270779589136854527vboxsync * @param pStream The stream.
326d1845a5ad33574cb834270779589136854527vboxsync * Check that what we're going to write makes sense first.
326d1845a5ad33574cb834270779589136854527vboxsync * Do the actual writing.
326d1845a5ad33574cb834270779589136854527vboxsync rc = RTFileWrite(h.u.hFile, pStream->pch, pStream->cb, NULL);
326d1845a5ad33574cb834270779589136854527vboxsync rc = RTPipeWriteBlocking(h.u.hPipe, pStream->pch, pStream->cb, NULL);
return rc;
return NULL;
return NULL;
return NULL;
cb--;
return pchRet;
return rc;
return VINF_SUCCESS;
if (offRelative >= 0)
offAbsolute = 0;
return rc;
return VINF_SUCCESS;
const char *ScmStreamGetLineByNo(PSCMSTREAM pStream, size_t iLine, size_t *pcchLine, PSCMEOL penmEol)
return NULL;
return NULL;
return NULL;
pStream->off = pStream->paLines[iLine].off + pStream->paLines[iLine].cch + pStream->paLines[iLine].enmEol;
return pchRet;
if ( pszLine
*pcchLine = 0;
return pszLine;
if (pStream->off >= pStream->paLines[iLine].off + pStream->paLines[iLine].cch + pStream->paLines[iLine].enmEol)
return (unsigned)ch;
return (unsigned)ch;
return VERR_EOF;
if (!pchLine)
return cchLine == 0;
return enmEol;
return enmEol;
return rc;
return rc;
return rc;
iLine++;
return VINF_SUCCESS;
return rc;
iLine--;
if (!pchLF)
return rc;
if ( cchLine
cchLine--;
iLine++;
if (!pchLF)
return VINF_SUCCESS;
return VINF_SUCCESS;
char *psz;
if (cch)
return cch;
return cch;
while (cLines-- > 0)
if (!pchLine)
return rc;
return VINF_SUCCESS;
size_t const cchLeft = pStream->paLines[iLine].cch + pStream->paLines[iLine].off - (pStream->off - 1);
return NULL;
char ch;
off++;
return psz;
size_t const cchLeft = pStream->paLines[iLine].cch + pStream->paLines[iLine].off - (pStream->off - 1);
return NULL;
char ch;
off++;
return psz;