VirtualBox

source: vbox/trunk/src/VBox/Main/testcase/tstGuestCtrlParseBuffer.cpp@ 37883

Last change on this file since 37883 was 37883, checked in by vboxsync, 14 years ago

Main: Added testcase for guest control output buffer parsing.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.6 KB
Line 
1/* $Id: tstGuestCtrlParseBuffer.cpp 37883 2011-07-12 09:53:58Z vboxsync $ */
2
3/** @file
4 *
5 * Output stream parsing test cases.
6 */
7
8/*
9 * Copyright (C) 2011 Oracle Corporation
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 */
19
20#include <map>
21
22#include <VBox/com/string.h>
23
24#include <iprt/string.h>
25
26#include <iprt/test.h>
27#include <iprt/stream.h>
28
29using namespace com;
30
31/** @todo Use original source of GuestCtrlImpl.cpp! */
32
33typedef struct VBOXGUESTCTRL_BUFFER_VALUE
34{
35 char *pszValue;
36} VBOXGUESTCTRL_BUFFER_VALUE, *PVBOXGUESTCTRL_BUFFER_VALUE;
37typedef std::map< Utf8Str, VBOXGUESTCTRL_BUFFER_VALUE > GuestBufferMap;
38typedef std::map< Utf8Str, VBOXGUESTCTRL_BUFFER_VALUE >::iterator GuestBufferMapIter;
39typedef std::map< Utf8Str, VBOXGUESTCTRL_BUFFER_VALUE >::const_iterator GuestBufferMapIterConst;
40
41char pszUnterm1[] = { 'a', 's', 'd', 'f' };
42
43static struct
44{
45 const char *pbData;
46 size_t cbData;
47 uint32_t uOffset;
48 uint32_t uMapElements;
49 int iResult;
50} aTests[] =
51{
52 /* Invalid stuff. */
53 { NULL, 0, 0, 0, VERR_INVALID_POINTER },
54 { NULL, 512, 0, 0, VERR_INVALID_POINTER },
55 { "", 0, 0, 0, VERR_INVALID_PARAMETER },
56 { "", 0, 5, 0, VERR_INVALID_PARAMETER },
57 { "", 1, 0, 0, VINF_SUCCESS },
58 { pszUnterm1, 5, 0, 0, VINF_SUCCESS },
59 { "foo=bar", 0, 0, 0, VERR_INVALID_PARAMETER },
60
61 /* Parsing stuff. */
62 { "foo", sizeof("foo"), 0, 0, VINF_SUCCESS },
63 { "foo=", sizeof("foo="), 0, 1, VINF_SUCCESS },
64 { "=bar", sizeof("=bar"), 0, 0, VINF_SUCCESS },
65 { "foo=bar", sizeof("foo=bar"), 0, 1, VINF_SUCCESS },
66 { "foo=bar\0baz=boo", 16, 0, 2, VINF_SUCCESS }
67};
68
69int outputBufferParse(const BYTE *pbData, size_t cbData, uint32_t *puOffset, GuestBufferMap& mapBuf)
70{
71 AssertPtrReturn(pbData, VERR_INVALID_POINTER);
72 AssertReturn(cbData, VERR_INVALID_PARAMETER);
73 AssertPtrReturn(puOffset, VERR_INVALID_POINTER);
74 AssertReturn(*puOffset < cbData, VERR_INVALID_PARAMETER);
75
76 int rc = VINF_SUCCESS;
77
78 size_t uCur = *puOffset;
79 for (uCur = 0; uCur < cbData; uCur++)
80 {
81 const char *pszStart = (char*)&pbData[uCur];
82 const char *pszEnd = pszStart;
83
84 /* Search and of current pair (key=value\0). */
85 while ( *pszEnd != '\0'
86 && ++uCur < cbData)
87 {
88 pszEnd++;
89 }
90
91 size_t uLen = pszEnd - pszStart;
92 if (!uLen)
93 continue;
94
95 const char *pszSep = pszStart;
96 while ( *pszSep != '='
97 && pszSep != pszEnd)
98 {
99 pszSep++;
100 }
101
102 if ( pszSep == pszStart
103 || pszSep == pszEnd)
104 {
105 continue;
106 }
107
108 size_t uKeyLen = pszSep - pszStart;
109 size_t uValLen = pszEnd - (pszSep + 1);
110
111 if (uKeyLen)
112 {
113 Assert(pszSep > pszStart);
114 char *pszKey = (char*)RTMemAllocZ(uKeyLen + 1);
115 if (!pszKey)
116 {
117 rc = VERR_NO_MEMORY;
118 break;
119 }
120 memcpy(pszKey, pszStart, uKeyLen);
121
122 mapBuf[Utf8Str(pszKey)].pszValue = NULL;
123
124 if (uValLen)
125 {
126 Assert(pszEnd > pszSep);
127 char *pszVal = (char*)RTMemAllocZ(uValLen + 1);
128 if (!pszVal)
129 {
130 rc = VERR_NO_MEMORY;
131 break;
132 }
133 memcpy(pszVal, pszSep + 1, uValLen);
134
135 mapBuf[Utf8Str(pszKey)].pszValue = pszVal;
136 }
137
138 RTMemFree(pszKey);
139 }
140 }
141
142 return rc;
143}
144
145int main()
146{
147 RTTEST hTest;
148 int rc = RTTestInitAndCreate("tstParseBuffer", &hTest);
149 if (rc)
150 return rc;
151 RTTestBanner(hTest);
152
153 for (unsigned iTest = 0; iTest < RT_ELEMENTS(aTests); iTest++)
154 {
155 GuestBufferMap map;
156
157 int iResult = outputBufferParse((BYTE*)aTests[iTest].pbData, aTests[iTest].cbData,
158 &aTests[iTest].uOffset, map);
159 if (iResult != aTests[iTest].iResult)
160 {
161 RTTestFailed(hTest, "#%u: Returned %Rrc, expected %Rrc",
162 iTest, iResult, aTests[iTest].iResult);
163 }
164 else if (map.size() != aTests[iTest].uMapElements)
165 {
166 RTTestFailed(hTest, "#%u: Map has %u elements, expected %u",
167 iTest, map.size(), aTests[iTest].uMapElements);
168 }
169
170 if (map.size())
171 RTTestIPrintf(RTTESTLVL_DEBUG, "Output for test #%u\n", iTest);
172 for (GuestBufferMapIter it = map.begin(); it != map.end(); it++)
173 {
174 RTTestIPrintf(RTTESTLVL_DEBUG, "\t%s -> %s\n",
175 it->first.c_str(), it->second.pszValue ? it->second.pszValue : "<undefined>");
176
177 if (it->second.pszValue)
178 RTMemFree(it->second.pszValue);
179 }
180 }
181
182 /*
183 * Summary.
184 */
185 return RTTestSummaryAndDestroy(hTest);
186}
187
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