VirtualBox

source: vbox/trunk/src/VBox/Main/src-client/GuestCtrlIO.cpp@ 39336

Last change on this file since 39336 was 38439, checked in by vboxsync, 13 years ago

GuestCtrl: Removed dead code.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.4 KB
Line 
1/* $Id: GuestCtrlIO.cpp 38439 2011-08-12 15:29:32Z vboxsync $ */
2/** @file
3 *
4 * IO helper for IGuest COM class implementations.
5 */
6
7/*
8 * Copyright (C) 2011 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19/******************************************************************************
20 * Header Files *
21 ******************************************************************************/
22#include "GuestCtrlImplPrivate.h"
23
24
25/******************************************************************************
26 * Structures and Typedefs *
27 ******************************************************************************/
28
29/** @todo *NOT* thread safe yet! */
30/** @todo Add exception handling for STL stuff! */
31
32GuestProcessStreamBlock::GuestProcessStreamBlock()
33{
34
35}
36
37/*
38GuestProcessStreamBlock::GuestProcessStreamBlock(const GuestProcessStreamBlock &otherBlock)
39{
40 for (GuestCtrlStreamPairsIter it = otherBlock.m_mapPairs.begin();
41 it != otherBlock.end(); it++)
42 {
43 m_mapPairs[it->first] = new
44 if (it->second.pszValue)
45 {
46 RTMemFree(it->second.pszValue);
47 it->second.pszValue = NULL;
48 }
49 }
50}*/
51
52GuestProcessStreamBlock::~GuestProcessStreamBlock()
53{
54 Clear();
55}
56
57/**
58 * Destroys the currently stored stream pairs.
59 *
60 * @return IPRT status code.
61 */
62void GuestProcessStreamBlock::Clear()
63{
64 m_mapPairs.clear();
65}
66
67/**
68 * Returns a 64-bit signed integer of a specified key.
69 *
70 * @return IPRT status code. VERR_NOT_FOUND if key was not found.
71 * @param pszKey Name of key to get the value for.
72 * @param piVal Pointer to value to return.
73 */
74int GuestProcessStreamBlock::GetInt64Ex(const char *pszKey, int64_t *piVal)
75{
76 AssertPtrReturn(pszKey, VERR_INVALID_POINTER);
77 AssertPtrReturn(piVal, VERR_INVALID_POINTER);
78 const char *pszValue = GetString(pszKey);
79 if (pszValue)
80 {
81 *piVal = RTStrToInt64(pszValue);
82 return VINF_SUCCESS;
83 }
84 return VERR_NOT_FOUND;
85}
86
87/**
88 * Returns a 64-bit integer of a specified key.
89 *
90 * @return int64_t Value to return, 0 if not found / on failure.
91 * @param pszKey Name of key to get the value for.
92 */
93int64_t GuestProcessStreamBlock::GetInt64(const char *pszKey)
94{
95 int64_t iVal;
96 if (RT_SUCCESS(GetInt64Ex(pszKey, &iVal)))
97 return iVal;
98 return 0;
99}
100
101/**
102 * Returns the current number of stream pairs.
103 *
104 * @return uint32_t Current number of stream pairs.
105 */
106size_t GuestProcessStreamBlock::GetCount()
107{
108 return m_mapPairs.size();
109}
110
111/**
112 * Returns a string value of a specified key.
113 *
114 * @return uint32_t Pointer to string to return, NULL if not found / on failure.
115 * @param pszKey Name of key to get the value for.
116 */
117const char* GuestProcessStreamBlock::GetString(const char *pszKey)
118{
119 AssertPtrReturn(pszKey, NULL);
120
121 try
122 {
123 GuestCtrlStreamPairMapIterConst itPairs = m_mapPairs.find(Utf8Str(pszKey));
124 if (itPairs != m_mapPairs.end())
125 return itPairs->second.mValue.c_str();
126 }
127 catch (const std::exception &ex)
128 {
129 NOREF(ex);
130 }
131 return NULL;
132}
133
134/**
135 * Returns a 32-bit unsigned integer of a specified key.
136 *
137 * @return IPRT status code. VERR_NOT_FOUND if key was not found.
138 * @param pszKey Name of key to get the value for.
139 * @param puVal Pointer to value to return.
140 */
141int GuestProcessStreamBlock::GetUInt32Ex(const char *pszKey, uint32_t *puVal)
142{
143 AssertPtrReturn(pszKey, VERR_INVALID_POINTER);
144 AssertPtrReturn(puVal, VERR_INVALID_POINTER);
145 const char *pszValue = GetString(pszKey);
146 if (pszValue)
147 {
148 *puVal = RTStrToUInt32(pszValue);
149 return VINF_SUCCESS;
150 }
151 return VERR_NOT_FOUND;
152}
153
154/**
155 * Returns a 32-bit unsigned integer of a specified key.
156 *
157 * @return uint32_t Value to return, 0 if not found / on failure.
158 * @param pszKey Name of key to get the value for.
159 */
160uint32_t GuestProcessStreamBlock::GetUInt32(const char *pszKey)
161{
162 uint32_t uVal;
163 if (RT_SUCCESS(GetUInt32Ex(pszKey, &uVal)))
164 return uVal;
165 return 0;
166}
167
168/**
169 * Sets a value to a key or deletes a key by setting a NULL value.
170 *
171 * @return IPRT status code.
172 * @param pszKey Key name to process.
173 * @param pszValue Value to set. Set NULL for deleting the key.
174 */
175int GuestProcessStreamBlock::SetValue(const char *pszKey, const char *pszValue)
176{
177 AssertPtrReturn(pszKey, VERR_INVALID_POINTER);
178
179 int rc = VINF_SUCCESS;
180 try
181 {
182 Utf8Str Utf8Key(pszKey);
183
184 /* Take a shortcut and prevent crashes on some funny versions
185 * of STL if map is empty initially. */
186 if (!m_mapPairs.empty())
187 {
188 GuestCtrlStreamPairMapIter it = m_mapPairs.find(Utf8Key);
189 if (it != m_mapPairs.end())
190 m_mapPairs.erase(it);
191 }
192
193 if (pszValue)
194 {
195 VBOXGUESTCTRL_STREAMVALUE val(pszValue);
196 m_mapPairs[Utf8Key] = val;
197 }
198 }
199 catch (const std::exception &ex)
200 {
201 NOREF(ex);
202 }
203 return rc;
204}
205
206///////////////////////////////////////////////////////////////////////////////
207
208GuestProcessStream::GuestProcessStream()
209 : m_cbAllocated(0),
210 m_cbSize(0),
211 m_cbOffset(0),
212 m_pbBuffer(NULL)
213{
214
215}
216
217GuestProcessStream::~GuestProcessStream()
218{
219 Destroy();
220}
221
222/**
223 * Adds data to the internal parser buffer. Useful if there
224 * are multiple rounds of adding data needed.
225 *
226 * @return IPRT status code.
227 * @param pbData Pointer to data to add.
228 * @param cbData Size (in bytes) of data to add.
229 */
230int GuestProcessStream::AddData(const BYTE *pbData, size_t cbData)
231{
232 AssertPtrReturn(pbData, VERR_INVALID_POINTER);
233 AssertReturn(cbData, VERR_INVALID_PARAMETER);
234
235 int rc = VINF_SUCCESS;
236
237 /* Rewind the buffer if it's empty. */
238 size_t cbInBuf = m_cbSize - m_cbOffset;
239 bool const fAddToSet = cbInBuf == 0;
240 if (fAddToSet)
241 m_cbSize = m_cbOffset = 0;
242
243 /* Try and see if we can simply append the data. */
244 if (cbData + m_cbSize <= m_cbAllocated)
245 {
246 memcpy(&m_pbBuffer[m_cbSize], pbData, cbData);
247 m_cbSize += cbData;
248 }
249 else
250 {
251 /* Move any buffered data to the front. */
252 cbInBuf = m_cbSize - m_cbOffset;
253 if (cbInBuf == 0)
254 m_cbSize = m_cbOffset = 0;
255 else if (m_cbOffset) /* Do we have something to move? */
256 {
257 memmove(m_pbBuffer, &m_pbBuffer[m_cbOffset], cbInBuf);
258 m_cbSize = cbInBuf;
259 m_cbOffset = 0;
260 }
261
262 /* Do we need to grow the buffer? */
263 if (cbData + m_cbSize > m_cbAllocated)
264 {
265 size_t cbAlloc = m_cbSize + cbData;
266 cbAlloc = RT_ALIGN_Z(cbAlloc, _64K);
267 void *pvNew = RTMemRealloc(m_pbBuffer, cbAlloc);
268 if (pvNew)
269 {
270 m_pbBuffer = (uint8_t *)pvNew;
271 m_cbAllocated = cbAlloc;
272 }
273 else
274 rc = VERR_NO_MEMORY;
275 }
276
277 /* Finally, copy the data. */
278 if (RT_SUCCESS(rc))
279 {
280 if (cbData + m_cbSize <= m_cbAllocated)
281 {
282 memcpy(&m_pbBuffer[m_cbSize], pbData, cbData);
283 m_cbSize += cbData;
284 }
285 else
286 rc = VERR_BUFFER_OVERFLOW;
287 }
288 }
289
290 return rc;
291}
292
293/**
294 * Destroys the the internal data buffer.
295 */
296void GuestProcessStream::Destroy()
297{
298 if (m_pbBuffer)
299 {
300 RTMemFree(m_pbBuffer);
301 m_pbBuffer = NULL;
302 }
303
304 m_cbAllocated = 0;
305 m_cbSize = 0;
306 m_cbOffset = 0;
307}
308
309/**
310 * Returns the current offset of the parser within
311 * the internal data buffer.
312 *
313 * @return uint32_t Parser offset.
314 */
315uint32_t GuestProcessStream::GetOffset()
316{
317 return m_cbOffset;
318}
319
320/**
321 * Tries to parse the next upcoming pair block within the internal
322 * buffer.
323 *
324 * Returns VERR_NO_DATA is no data is in internal buffer or buffer has been
325 * completely parsed already.
326 *
327 * Returns VERR_MORE_DATA if current block was parsed (with zero or more pairs
328 * stored in stream block) but still contains incomplete (unterminated)
329 * data.
330 *
331 * Returns VINF_SUCCESS if current block was parsed until the next upcoming
332 * block (with zero or more pairs stored in stream block).
333 *
334 * @return IPRT status code.
335 * @param streamBlock Reference to guest stream block to fill.
336 *
337 */
338int GuestProcessStream::ParseBlock(GuestProcessStreamBlock &streamBlock)
339{
340 if ( !m_pbBuffer
341 || !m_cbSize)
342 {
343 return VERR_NO_DATA;
344 }
345
346 AssertReturn(m_cbOffset <= m_cbSize, VERR_INVALID_PARAMETER);
347 if (m_cbOffset == m_cbSize)
348 return VERR_NO_DATA;
349
350 int rc = VINF_SUCCESS;
351
352 char *pszOff = (char*)&m_pbBuffer[m_cbOffset];
353 char *pszStart = pszOff;
354 while (*pszStart)
355 {
356 size_t pairLen = strlen(pszStart);
357 if ((pszStart - pszOff) + pairLen + 1 >= m_cbSize)
358 {
359 rc = VERR_MORE_DATA;
360 break;
361 }
362 else
363 {
364 char *pszSep = strchr(pszStart, '=');
365 char *pszVal = NULL;
366 if (pszSep)
367 pszVal = pszSep + 1;
368 if (!pszSep || !pszVal)
369 {
370 rc = VERR_MORE_DATA;
371 break;
372 }
373
374 /* Terminate the separator so that we can
375 * use pszStart as our key from now on. */
376 *pszSep = '\0';
377
378 rc = streamBlock.SetValue(pszStart, pszVal);
379 if (RT_FAILURE(rc))
380 return rc;
381 }
382
383 /* Next pair. */
384 pszStart += pairLen + 1;
385 }
386
387 /* If we did not do any movement but we have stuff left
388 * in our buffer just skip the current termination so that
389 * we can try next time. */
390 uint32_t uDistance = (pszStart - pszOff);
391 if ( !uDistance
392 && *pszStart == '\0'
393 && m_cbOffset < m_cbSize)
394 {
395 uDistance++;
396 }
397 m_cbOffset += uDistance;
398
399 return rc;
400}
401
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette