GuestCtrlIO.cpp revision a7014c99617f226a35a6a46a5b4bddcc6e0c17e0
/* $Id$ */
/** @file
*
* IO helper for IGuest COM class implementations.
*/
/*
* Copyright (C) 2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
/******************************************************************************
* Header Files *
******************************************************************************/
#include "GuestCtrlImplPrivate.h"
#ifdef DEBUG
# include "Logging.h"
#endif /* DEBUG */
/******************************************************************************
* Structures and Typedefs *
******************************************************************************/
/** @todo *NOT* thread safe yet! */
/** @todo Add exception handling for STL stuff! */
{
}
/*
GuestProcessStreamBlock::GuestProcessStreamBlock(const GuestProcessStreamBlock &otherBlock)
{
for (GuestCtrlStreamPairsIter it = otherBlock.m_mapPairs.begin();
it != otherBlock.end(); it++)
{
m_mapPairs[it->first] = new
if (it->second.pszValue)
{
RTMemFree(it->second.pszValue);
it->second.pszValue = NULL;
}
}
}*/
{
Clear();
}
/**
* Destroys the currently stored stream pairs.
*
* @return IPRT status code.
*/
void GuestProcessStreamBlock::Clear()
{
m_mapPairs.clear();
}
#ifdef DEBUG
void GuestProcessStreamBlock::Dump()
{
LogFlowFunc(("Dumping contents of stream block=0x%p (%ld items):\n",
this, m_mapPairs.size()));
{
}
}
#endif
/**
* Returns a 64-bit signed integer of a specified key.
*
* @return IPRT status code. VERR_NOT_FOUND if key was not found.
* @param pszKey Name of key to get the value for.
* @param piVal Pointer to value to return.
*/
{
if (pszValue)
{
return VINF_SUCCESS;
}
return VERR_NOT_FOUND;
}
/**
* Returns a 64-bit integer of a specified key.
*
* @return int64_t Value to return, 0 if not found / on failure.
* @param pszKey Name of key to get the value for.
*/
{
return iVal;
return 0;
}
/**
* Returns the current number of stream pairs.
*
* @return uint32_t Current number of stream pairs.
*/
{
return m_mapPairs.size();
}
/**
* Returns a string value of a specified key.
*
* @return uint32_t Pointer to string to return, NULL if not found / on failure.
* @param pszKey Name of key to get the value for.
*/
{
try
{
}
{
}
return NULL;
}
/**
* Returns a 32-bit unsigned integer of a specified key.
*
* @return IPRT status code. VERR_NOT_FOUND if key was not found.
* @param pszKey Name of key to get the value for.
* @param puVal Pointer to value to return.
*/
{
if (pszValue)
{
return VINF_SUCCESS;
}
return VERR_NOT_FOUND;
}
/**
* Returns a 32-bit unsigned integer of a specified key.
*
* @return uint32_t Value to return, 0 if not found / on failure.
* @param pszKey Name of key to get the value for.
*/
{
return uVal;
return 0;
}
/**
* Sets a value to a key or deletes a key by setting a NULL value.
*
* @return IPRT status code.
* @param pszKey Key name to process.
* @param pszValue Value to set. Set NULL for deleting the key.
*/
{
int rc = VINF_SUCCESS;
try
{
/* Take a shortcut and prevent crashes on some funny versions
* of STL if map is empty initially. */
if (!m_mapPairs.empty())
{
}
if (pszValue)
{
}
}
{
}
return rc;
}
///////////////////////////////////////////////////////////////////////////////
: m_cbAllocated(0),
m_cbSize(0),
m_cbOffset(0),
{
}
{
Destroy();
}
/**
* Adds data to the internal parser buffer. Useful if there
* are multiple rounds of adding data needed.
*
* @return IPRT status code.
* @param pbData Pointer to data to add.
* @param cbData Size (in bytes) of data to add.
*/
{
int rc = VINF_SUCCESS;
/* Rewind the buffer if it's empty. */
if (fAddToSet)
m_cbSize = m_cbOffset = 0;
/* Try and see if we can simply append the data. */
{
}
else
{
/* Move any buffered data to the front. */
if (cbInBuf == 0)
m_cbSize = m_cbOffset = 0;
else if (m_cbOffset) /* Do we have something to move? */
{
m_cbOffset = 0;
}
/* Do we need to grow the buffer? */
{
if (pvNew)
{
}
else
rc = VERR_NO_MEMORY;
}
/* Finally, copy the data. */
if (RT_SUCCESS(rc))
{
{
}
else
}
}
return rc;
}
/**
* Destroys the the internal data buffer.
*/
void GuestProcessStream::Destroy()
{
if (m_pbBuffer)
{
m_pbBuffer = NULL;
}
m_cbAllocated = 0;
m_cbSize = 0;
m_cbOffset = 0;
}
#ifdef DEBUG
{
LogFlowFunc(("Dumping contents of stream=0x%p (cbAlloc=%u, cbSize=%u, cbOff=%u) to %s\n",
int rc = RTFileOpen(&hFile, pszFile, RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_DENY_WRITE);
if (RT_SUCCESS(rc))
{
}
}
#endif
/**
* Returns the current offset of the parser within
* the internal data buffer.
*
* @return uint32_t Parser offset.
*/
{
return m_cbOffset;
}
{
return m_cbSize;
}
/**
* Tries to parse the next upcoming pair block within the internal
* buffer.
*
* Returns VERR_NO_DATA is no data is in internal buffer or buffer has been
* completely parsed already.
*
* Returns VERR_MORE_DATA if current block was parsed (with zero or more pairs
* stored in stream block) but still contains incomplete (unterminated)
* data.
*
* Returns VINF_SUCCESS if current block was parsed until the next upcoming
* block (with zero or more pairs stored in stream block).
*
* @return IPRT status code.
* @param streamBlock Reference to guest stream block to fill.
*
*/
{
if ( !m_pbBuffer
|| !m_cbSize)
{
return VERR_NO_DATA;
}
if (m_cbOffset == m_cbSize)
return VERR_NO_DATA;
int rc = VINF_SUCCESS;
while (*pszStart)
{
{
rc = VERR_MORE_DATA;
break;
}
else
{
if (pszSep)
{
rc = VERR_MORE_DATA;
break;
}
/* Terminate the separator so that we can
* use pszStart as our key from now on. */
*pszSep = '\0';
if (RT_FAILURE(rc))
return rc;
}
/* Next pair. */
}
/* If we did not do any movement but we have stuff left
* in our buffer just skip the current termination so that
* we can try next time. */
if ( !uDistance
&& *pszStart == '\0'
&& m_cbOffset < m_cbSize)
{
uDistance++;
}
m_cbOffset += uDistance;
return rc;
}