VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/rest/RTCRestBinaryString.cpp@ 74117

Last change on this file since 74117 was 74117, checked in by vboxsync, 6 years ago

IPRT/rest: Started implemented more flexible handling of binary uploads and downloads. bugref:9167

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.0 KB
Line 
1/* $Id: RTCRestBinaryString.cpp 74117 2018-09-06 13:30:29Z vboxsync $ */
2/** @file
3 * IPRT - C++ REST, RTCRestBinaryString implementation.
4 */
5
6/*
7 * Copyright (C) 2018 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#define LOG_GROUP RTLOGGROUP_REST
32#include <iprt/cpp/restbinarystring.h>
33
34#include <iprt/assert.h>
35#include <iprt/err.h>
36
37
38
39/** Default constructor. */
40RTCRestBinaryString::RTCRestBinaryString()
41 : RTCRestObjectBase()
42 , m_pbData(NULL)
43 , m_cbData(UINT64_MAX)
44 , m_pvCallbackData(NULL)
45 , m_pfnConsumer(NULL)
46 , m_pfnProducer(NULL)
47 , m_fFreeData(false)
48 , m_strContentType()
49{
50}
51
52
53/**
54 * Destructor.
55 */
56RTCRestBinaryString::~RTCRestBinaryString()
57{
58 if (m_pbData)
59 {
60 if (m_fFreeData)
61 RTMemFree(m_pbData);
62 m_pbData = NULL;
63 }
64 m_fFreeData = false;
65 m_pvCallbackData = NULL;
66 m_pfnProducer = NULL;
67 m_pfnConsumer = NULL;
68}
69
70
71/**
72 * Safe copy assignment method.
73 */
74int RTCRestBinaryString::assignCopy(RTCRestBinaryString const &a_rThat)
75{
76 RT_NOREF(a_rThat);
77 AssertFailedReturn(VERR_NOT_IMPLEMENTED);
78}
79
80
81/*********************************************************************************************************************************
82* Overridden methods *
83*********************************************************************************************************************************/
84
85int RTCRestBinaryString::resetToDefault()
86{
87 AssertFailedReturn(VERR_NOT_IMPLEMENTED);
88}
89
90
91RTCRestOutputBase &RTCRestBinaryString::serializeAsJson(RTCRestOutputBase &a_rDst) const
92{
93 AssertMsgFailed(("We should never get here!\n"));
94 a_rDst.printf("null");
95 return a_rDst;
96}
97
98
99int RTCRestBinaryString::deserializeFromJson(RTCRestJsonCursor const &a_rCursor)
100{
101 return a_rCursor.m_pPrimary->addError(a_rCursor, VERR_NOT_SUPPORTED, "RTCRestBinaryString does not support deserialization!");
102}
103
104
105int RTCRestBinaryString::toString(RTCString *a_pDst, uint32_t a_fFlags /*= kCollectionFormat_Unspecified*/) const
106{
107 RT_NOREF(a_pDst, a_fFlags);
108 AssertFailedReturn(VERR_NOT_SUPPORTED);
109}
110
111
112int RTCRestBinaryString::fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo/*= NULL*/,
113 uint32_t a_fFlags /*= kCollectionFormat_Unspecified*/)
114{
115 RT_NOREF(a_rValue, a_pszName, a_fFlags);
116 AssertFailedReturn(RTErrInfoSet(a_pErrInfo, VERR_NOT_SUPPORTED, "RTCRestBinaryString does not support fromString()!"));
117}
118
119
120RTCRestObjectBase::kTypeClass RTCRestBinaryString::typeClass(void) const
121{
122 return kTypeClass_BinaryString;
123}
124
125
126const char *RTCRestBinaryString::typeName(void) const
127{
128 return "RTCRestBinaryString";
129}
130
131
132/** Factory method. */
133/*static*/ DECLCALLBACK(RTCRestObjectBase *) RTCRestBinaryString::createInstance(void)
134{
135 return new (std::nothrow) RTCRestBinaryString();
136}
137
138
139/*********************************************************************************************************************************
140* Transmit related methods *
141*********************************************************************************************************************************/
142
143int RTCRestBinaryString::xmitPrepare(RTHTTP a_hHttp) const
144{
145 /*
146 * Set the content type if given.
147 */
148 if (m_strContentType.isNotEmpty())
149 {
150 Assert(!RTHttpGetHeader(a_hHttp, RT_STR_TUPLE("Content-Type")));
151 int rc = RTHttpAddHeader(a_hHttp, "Content-Type", m_strContentType.c_str(), m_strContentType.length(),
152 RTHTTPADDHDR_F_BACK);
153 AssertRCReturn(rc, rc);
154 }
155
156 /*
157 * Set the content length if given.
158 */
159 if (m_cbData != UINT64_MAX)
160 {
161 const char *pszContentLength = RTHttpGetHeader(a_hHttp, RT_STR_TUPLE("Content-Length"));
162 AssertMsgReturn(!pszContentLength || RTStrToUInt64(pszContentLength) == m_cbData,
163 ("pszContentLength=%s does not match m_cbData=%RU64\n", pszContentLength, m_cbData),
164 VERR_MISMATCH);
165 if (!pszContentLength)
166 {
167 char szValue[64];
168 ssize_t cchValue = RTStrFormatU64(szValue, sizeof(szValue), m_cbData, 10, 0, 0, 0);
169 int rc = RTHttpAddHeader(a_hHttp, "Content-Length", szValue, cchValue, RTHTTPADDHDR_F_BACK);
170 AssertRCReturn(rc, rc);
171 }
172 }
173
174 /*
175 * Register an upload callback.
176 */
177 AssertReturn(m_pbData != NULL || m_pfnProducer != NULL || m_cbData == 0, VERR_INVALID_STATE);
178
179 int rc = RTHttpSetUploadCallback(a_hHttp, m_cbData, xmitHttpCallback, (RTCRestBinaryString *)this);
180 AssertRCReturn(rc, rc);
181
182 return VINF_SUCCESS;
183}
184
185
186/*static*/ DECLCALLBACK(int)
187RTCRestBinaryString::xmitHttpCallback(RTHTTP hHttp, void *pvBuf, size_t cbBuf,
188 uint64_t offContent, size_t *pcbActual, void *pvUser)
189{
190 RTCRestBinaryString *pThis = (RTCRestBinaryString *)pvUser;
191
192 /*
193 * Call the user upload callback if we've got one.
194 */
195 if (pThis->m_pfnProducer)
196 return pThis->m_pfnProducer(pThis, pvBuf, cbBuf, offContent, pcbActual);
197
198 /*
199 * Feed from the memory buffer.
200 */
201 if (offContent < pThis->m_cbData)
202 {
203 uint64_t const cbLeft = pThis->m_cbData - offContent;
204 size_t const cbToCopy = cbLeft >= cbBuf ? cbBuf : (size_t)cbLeft;
205 memcpy(pvBuf, &pThis->m_pbData[(size_t)offContent], cbToCopy);
206 *pcbActual = cbToCopy;
207 }
208 else
209 *pcbActual = 0;
210
211 RT_NOREF(hHttp);
212 return VINF_SUCCESS;
213}
214
215
216void RTCRestBinaryString::xmitComplete(RTHTTP a_hHttp) const
217{
218 /* Unset the callback. */
219 int rc = RTHttpSetUploadCallback(a_hHttp, m_cbData, NULL, NULL);
220 AssertRC(rc);
221}
222
223
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