mirror of
https://github.com/jlengrand/openapi-generator.git
synced 2026-05-17 00:21:19 +00:00
add cpprest and samples
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
{{#operations}}/*
|
||||
* {{classname}}.h
|
||||
*
|
||||
* {{description}}
|
||||
*/
|
||||
|
||||
#ifndef {{classname}}_H_
|
||||
#define {{classname}}_H_
|
||||
|
||||
{{{defaultInclude}}}
|
||||
#include "ApiClient.h"
|
||||
|
||||
{{#imports}}{{{import}}}
|
||||
{{/imports}}
|
||||
|
||||
{{#apiNamespaceDeclarations}}
|
||||
namespace {{this}} {
|
||||
{{/apiNamespaceDeclarations}}
|
||||
|
||||
using namespace {{modelNamespace}};
|
||||
|
||||
class {{declspec}} {{classname}}
|
||||
{
|
||||
public:
|
||||
{{classname}}( std::shared_ptr<ApiClient> apiClient );
|
||||
virtual ~{{classname}}();
|
||||
{{#operation}}
|
||||
/// <summary>
|
||||
/// {{summary}}
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// {{notes}}
|
||||
/// </remarks>
|
||||
{{#allParams}}/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>{{/allParams}}
|
||||
pplx::task<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}> {{operationId}}({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
|
||||
{{/operation}}
|
||||
|
||||
protected:
|
||||
std::shared_ptr<ApiClient> m_ApiClient;
|
||||
};
|
||||
|
||||
{{#apiNamespaceDeclarations}}
|
||||
}
|
||||
{{/apiNamespaceDeclarations}}
|
||||
|
||||
#endif /* {{classname}}_H_ */
|
||||
|
||||
{{/operations}}
|
||||
@@ -0,0 +1,269 @@
|
||||
{{#operations}}
|
||||
|
||||
#include "{{classname}}.h"
|
||||
#include "IHttpBody.h"
|
||||
#include "JsonBody.h"
|
||||
#include "MultipartFormData.h"
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
|
||||
{{#apiNamespaceDeclarations}}
|
||||
namespace {{this}} {
|
||||
{{/apiNamespaceDeclarations}}
|
||||
|
||||
using namespace {{modelNamespace}};
|
||||
|
||||
{{classname}}::{{classname}}( std::shared_ptr<ApiClient> apiClient )
|
||||
: m_ApiClient(apiClient)
|
||||
{
|
||||
}
|
||||
|
||||
{{classname}}::~{{classname}}()
|
||||
{
|
||||
}
|
||||
|
||||
{{#operation}}
|
||||
pplx::task<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}> {{classname}}::{{operationId}}({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
|
||||
{
|
||||
{{#allParams}}{{#required}}{{^isPrimitiveType}}{{^isContainer}}
|
||||
// verify the required parameter '{{paramName}}' is set
|
||||
if ({{paramName}} == nullptr)
|
||||
{
|
||||
throw ApiException(400, U("Missing required parameter '{{paramName}}' when calling {{classname}}->{{operationId}}"));
|
||||
}
|
||||
{{/isContainer}}{{/isPrimitiveType}}{{/required}}{{/allParams}}
|
||||
|
||||
std::shared_ptr<ApiConfiguration> apiConfiguration( m_ApiClient->getConfiguration() );
|
||||
utility::string_t path = U("{{path}}");
|
||||
{{#pathParams}}boost::replace_all(path, U("{") U("{{baseName}}") U("}"), ApiClient::parameterToString({{{paramName}}}));
|
||||
{{/pathParams}}
|
||||
|
||||
std::map<utility::string_t, utility::string_t> queryParams;
|
||||
std::map<utility::string_t, utility::string_t> headerParams( apiConfiguration->getDefaultHeaders() );
|
||||
std::map<utility::string_t, utility::string_t> formParams;
|
||||
std::map<utility::string_t, std::shared_ptr<HttpContent>> fileParams;
|
||||
|
||||
std::unordered_set<utility::string_t> responseHttpContentTypes;
|
||||
{{#produces}}responseHttpContentTypes.insert( U("{{mediaType}}") );
|
||||
{{/produces}}
|
||||
|
||||
utility::string_t responseHttpContentType;
|
||||
|
||||
// use JSON if possible
|
||||
if ( responseHttpContentTypes.size() == 0 || responseHttpContentTypes.find(U("application/json")) != responseHttpContentTypes.end() )
|
||||
{
|
||||
responseHttpContentType = U("application/json");
|
||||
}
|
||||
// multipart formdata
|
||||
else if( responseHttpContentTypes.find(U("multipart/form-data")) != responseHttpContentTypes.end() )
|
||||
{
|
||||
responseHttpContentType = U("multipart/form-data");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw ApiException(400, U("{{classname}}->{{operationId}} does not produce any supported media type"));
|
||||
}
|
||||
|
||||
headerParams[U("Accept")] = responseHttpContentType;
|
||||
|
||||
std::unordered_set<utility::string_t> consumeHttpContentTypes;
|
||||
{{#consumes}}consumeHttpContentTypes.insert( U("{{mediaType}}") );
|
||||
{{/consumes}}
|
||||
|
||||
{{#allParams}}{{^isBodyParam}}{{^isPrimitiveType}}{{^isContainer}}if ({{paramName}} != nullptr){{/isContainer}}{{/isPrimitiveType}}
|
||||
{
|
||||
{{#isContainer}}{{#isQueryParam}}queryParams[U("{{baseName}}")] = ApiClient::parameterToArrayString<{{items.datatype}}>({{paramName}});
|
||||
{{/isQueryParam}}{{#isHeaderParam}}headerParams[U("{{baseName}}")] = ApiClient::parameterToArrayString<{{items.datatype}}>({{paramName}});
|
||||
{{/isHeaderParam}}{{#isFormParam}}{{^isFile}}formParams[ U("{{baseName}}") ] = ApiClient::parameterToArrayString<{{items.datatype}}>({{paramName}});
|
||||
{{/isFile}}{{/isFormParam}}{{/isContainer}}{{^isContainer}}{{#isQueryParam}}queryParams[U("{{baseName}}")] = ApiClient::parameterToString({{paramName}});
|
||||
{{/isQueryParam}}{{#isHeaderParam}}headerParams[U("{{baseName}}")] = ApiClient::parameterToString({{paramName}});
|
||||
{{/isHeaderParam}}{{#isFormParam}}{{#isFile}}fileParams[ U("{{baseName}}") ] = {{paramName}};
|
||||
{{/isFile}}{{^isFile}}formParams[ U("{{baseName}}") ] = ApiClient::parameterToString({{paramName}});
|
||||
{{/isFile}}{{/isFormParam}}{{/isContainer}}
|
||||
}
|
||||
{{/isBodyParam}}{{/allParams}}
|
||||
|
||||
std::shared_ptr<IHttpBody> httpBody;
|
||||
utility::string_t requestHttpContentType;
|
||||
|
||||
// use JSON if possible
|
||||
if ( consumeHttpContentTypes.size() == 0 || consumeHttpContentTypes.find(U("application/json")) != consumeHttpContentTypes.end() )
|
||||
{
|
||||
requestHttpContentType = U("application/json");
|
||||
|
||||
{{#bodyParam}}
|
||||
web::json::value json;
|
||||
|
||||
{{#isPrimitiveType}} json = ModelBase::toJson({{paramName}});
|
||||
{{/isPrimitiveType}}{{^isPrimitiveType}}{{#isListContainer}}
|
||||
{
|
||||
std::vector<web::json::value> jsonArray;
|
||||
for( auto& item : {{paramName}} )
|
||||
{
|
||||
{{#items.isPrimitiveType}}jsonArray.push_back(ModelBase::toJson(item));
|
||||
{{/items.isPrimitiveType}}{{^items.isPrimitiveType}}{{#items.isString}}jsonArray.push_back(ModelBase::toJson(item));
|
||||
{{/items.isString}}{{^items.isString}}{{#items.isDateTime}}jsonArray.push_back(ModelBase::toJson(item));
|
||||
{{/items.isDateTime}}{{^items.isDateTime}}jsonArray.push_back( item.get() ? item->toJson() : web::json::value::null() );
|
||||
{{/items.isDateTime}}{{/items.isString}}{{/items.isPrimitiveType}}
|
||||
}
|
||||
json = web::json::value::array(jsonArray);
|
||||
}
|
||||
{{/isListContainer}}{{^isListContainer}}json = ModelBase::toJson({{paramName}});
|
||||
{{/isListContainer}}{{/isPrimitiveType}}
|
||||
|
||||
httpBody = std::shared_ptr<IHttpBody>( new JsonBody( json ) );
|
||||
|
||||
{{/bodyParam}}
|
||||
}
|
||||
// multipart formdata
|
||||
else if( consumeHttpContentTypes.find(U("multipart/form-data")) != consumeHttpContentTypes.end() )
|
||||
{
|
||||
requestHttpContentType = U("multipart/form-data");
|
||||
|
||||
{{#bodyParam}}
|
||||
std::shared_ptr<MultipartFormData> multipart(new MultipartFormData);
|
||||
{{#isPrimitiveType}} multipart->add(ModelBase::toHttpContent("{{paramName}}", {{paramName}}));
|
||||
{{/isPrimitiveType}}{{^isPrimitiveType}}{{#isListContainer}}
|
||||
{
|
||||
std::vector<web::json::value> jsonArray;
|
||||
for( auto& item : {{paramName}} )
|
||||
{
|
||||
{{#items.isPrimitiveType}}jsonArray.push_back(ModelBase::toJson(item));
|
||||
{{/items.isPrimitiveType}}{{^items.isPrimitiveType}}{{#items.isString}}jsonArray.push_back(ModelBase::toJson(item));
|
||||
{{/items.isString}}{{^items.isString}}{{#items.isDateTime}}jsonArray.push_back(ModelBase::toJson(item));
|
||||
{{/items.isDateTime}}{{^items.isDateTime}}jsonArray.push_back( item.get() ? item->toJson() : web::json::value::null() );
|
||||
{{/items.isDateTime}}{{/items.isString}}{{/items.isPrimitiveType}}
|
||||
}
|
||||
multipart->add(ModelBase::toHttpContent(U("{{paramName}}"), web::json::value::array(jsonArray), U("application/json")));
|
||||
}
|
||||
{{/isListContainer}}{{^isListContainer}}{{#isString}}multipart->add(ModelBase::toHttpContent(U("{{paramName}}"), {{paramName}}));
|
||||
{{/isString}}{{^isString}}
|
||||
if({{paramName}}.get())
|
||||
{
|
||||
{{paramName}}->toMultipart(multipart, U("{{paramName}}"));
|
||||
}
|
||||
{{/isString}}{{/isListContainer}}{{/isPrimitiveType}}
|
||||
|
||||
httpBody = multipart;
|
||||
requestHttpContentType += U("; boundary=") + multipart->getBoundary();
|
||||
{{/bodyParam}}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw ApiException(415, U("{{classname}}->{{operationId}} does not consume any supported media type"));
|
||||
}
|
||||
|
||||
{{#authMethods}}
|
||||
// authentication ({{name}}) required
|
||||
{{#isApiKey}}
|
||||
{{#isKeyInHeader}}
|
||||
{
|
||||
utility::string_t apiKey = apiConfiguration->getApiKey(U("{{keyParamName}}"));
|
||||
if ( apiKey.size() > 0 )
|
||||
{
|
||||
headerParams[U("{{keyParamName}}")] = apiKey;
|
||||
}
|
||||
}
|
||||
{{/isKeyInHeader}}
|
||||
{{#isKeyInQuery}}
|
||||
{
|
||||
utility::string_t apiKey = apiConfiguration->getApiKey(U("{{keyParamName}}"));
|
||||
if ( apiKey.size() > 0 )
|
||||
{
|
||||
queryParams[U("{{keyParamName}}")] = apiKey;
|
||||
}
|
||||
}
|
||||
{{/isKeyInQuery}}
|
||||
{{/isApiKey}}
|
||||
{{#isBasic}}
|
||||
// Basic authentication is added automatically as part of the http_client_config
|
||||
{{/isBasic}}
|
||||
{{#isOAuth}}
|
||||
// oauth2 authentication is added automatically as part of the http_client_config
|
||||
{{/isOAuth}}
|
||||
{{/authMethods}}
|
||||
|
||||
return m_ApiClient->callApi(path, U("{{httpMethod}}"), queryParams, httpBody, headerParams, formParams, fileParams, requestHttpContentType)
|
||||
.then([=](web::http::http_response response)
|
||||
{
|
||||
// 1xx - informational : OK
|
||||
// 2xx - successful : OK
|
||||
// 3xx - redirection : OK
|
||||
// 4xx - client error : not OK
|
||||
// 5xx - client error : not OK
|
||||
if (response.status_code() >= 400)
|
||||
{
|
||||
throw ApiException(response.status_code()
|
||||
, U("error calling {{operationId}}: ") + response.reason_phrase()
|
||||
, std::make_shared<std::stringstream>(response.extract_utf8string(true).get()));
|
||||
}
|
||||
|
||||
// check response content type
|
||||
if(response.headers().has(U("Content-Type")))
|
||||
{
|
||||
utility::string_t contentType = response.headers()[U("Content-Type")];
|
||||
if( contentType.find(responseHttpContentType) == std::string::npos )
|
||||
{
|
||||
throw ApiException(500
|
||||
, U("error calling {{operationId}}: unexpected response type: ") + contentType
|
||||
, std::make_shared<std::stringstream>(response.extract_utf8string(true).get()));
|
||||
}
|
||||
}
|
||||
|
||||
return response.extract_string();
|
||||
})
|
||||
.then([=](utility::string_t response)
|
||||
{
|
||||
{{^returnType}}return void();
|
||||
{{/returnType}}{{#returnType}}{{#returnContainer}}{{{returnType}}} result;
|
||||
{{/returnContainer}}{{^returnContainer}}{{{returnType}}} result({{{defaultResponse}}});{{/returnContainer}}
|
||||
|
||||
if(responseHttpContentType == U("application/json"))
|
||||
{
|
||||
web::json::value json = web::json::value::parse(response);
|
||||
|
||||
{{#isListContainer}}for( auto& item : json.as_array() )
|
||||
{
|
||||
{{#vendorExtensions.x-codegen-response.items.isPrimitiveType}}result.push_back(ModelBase::{{vendorExtensions.x-codegen-response.items.datatype}}FromJson(item));
|
||||
{{/vendorExtensions.x-codegen-response.items.isPrimitiveType}}{{^vendorExtensions.x-codegen-response.items.isPrimitiveType}}{{#vendorExtensions.x-codegen-response.items.isString}}result.push_back(ModelBase::stringFromJson(item));
|
||||
{{/vendorExtensions.x-codegen-response.items.isString}}{{^vendorExtensions.x-codegen-response.items.isString}}{{{vendorExtensions.x-codegen-response.items.datatype}}} itemObj({{{vendorExtensions.x-codegen-response.items.defaultValue}}});
|
||||
itemObj->fromJson(item);
|
||||
result.push_back(itemObj);
|
||||
{{/vendorExtensions.x-codegen-response.items.isString}}{{/vendorExtensions.x-codegen-response.items.isPrimitiveType}}
|
||||
}
|
||||
{{/isListContainer}}{{^isListContainer}}{{#isMapContainer}}for( auto& item : json.as_object() )
|
||||
{
|
||||
{{#vendorExtensions.x-codegen-response.items.isPrimitiveType}}result[item.first] = ModelBase::{{vendorExtensions.x-codegen-response.items.datatype}}FromJson(item.second);
|
||||
{{/vendorExtensions.x-codegen-response.items.isPrimitiveType}}{{^vendorExtensions.x-codegen-response.items.isPrimitiveType}}{{#vendorExtensions.x-codegen-response.items.isString}}result[item.first] = ModelBase::stringFromJson(item.second);
|
||||
{{/vendorExtensions.x-codegen-response.items.isString}}{{^vendorExtensions.x-codegen-response.items.isString}}{{{vendorExtensions.x-codegen-response.items.datatype}}} itemObj({{{vendorExtensions.x-codegen-response.items.defaultValue}}});
|
||||
itemObj->fromJson(item);
|
||||
result[item.first] = itemObj;
|
||||
{{/vendorExtensions.x-codegen-response.items.isString}}{{/vendorExtensions.x-codegen-response.items.isPrimitiveType}}
|
||||
}
|
||||
{{/isMapContainer}}{{^isMapContainer}}{{#vendorExtensions.x-codegen-response.isPrimitiveType}}result = ModelBase::{{vendorExtensions.x-codegen-response.items.datatype}}FromJson(json);
|
||||
{{/vendorExtensions.x-codegen-response.isPrimitiveType}}{{^vendorExtensions.x-codegen-response.isPrimitiveType}}{{#vendorExtensions.x-codegen-response.isString}}result = ModelBase::stringFromJson(json);
|
||||
{{/vendorExtensions.x-codegen-response.isString}}{{^vendorExtensions.x-codegen-response.isString}}result->fromJson(json);{{/vendorExtensions.x-codegen-response.isString}}{{/vendorExtensions.x-codegen-response.isPrimitiveType}}{{/isMapContainer}}{{/isListContainer}}
|
||||
}
|
||||
// else if(responseHttpContentType == U("multipart/form-data"))
|
||||
// {
|
||||
// TODO multipart response parsing
|
||||
// }
|
||||
else
|
||||
{
|
||||
throw ApiException(500
|
||||
, U("error calling findPetsByStatus: unsupported response type"));
|
||||
}
|
||||
|
||||
return result;
|
||||
{{/returnType}}
|
||||
});
|
||||
}
|
||||
{{/operation}}
|
||||
|
||||
{{#apiNamespaceDeclarations}}
|
||||
}
|
||||
{{/apiNamespaceDeclarations}}
|
||||
|
||||
{{/operations}}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* ApiClient.h
|
||||
*
|
||||
* This is an API client responsible for stating the HTTP calls
|
||||
*/
|
||||
|
||||
#ifndef ApiClient_H_
|
||||
#define ApiClient_H_
|
||||
|
||||
{{{defaultInclude}}}
|
||||
#include "ApiConfiguration.h"
|
||||
#include "ApiException.h"
|
||||
#include "IHttpBody.h"
|
||||
#include "HttpContent.h"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include <cpprest/details/basic_types.h>
|
||||
#include <cpprest/http_client.h>
|
||||
|
||||
{{#apiNamespaceDeclarations}}
|
||||
namespace {{this}} {
|
||||
{{/apiNamespaceDeclarations}}
|
||||
|
||||
using namespace {{modelNamespace}};
|
||||
|
||||
class {{declspec}} ApiClient
|
||||
{
|
||||
public:
|
||||
ApiClient( std::shared_ptr<ApiConfiguration> configuration = nullptr );
|
||||
virtual ~ApiClient();
|
||||
|
||||
std::shared_ptr<ApiConfiguration> getConfiguration() const;
|
||||
void setConfiguration(std::shared_ptr<ApiConfiguration> configuration);
|
||||
|
||||
static utility::string_t parameterToString(utility::string_t value);
|
||||
static utility::string_t parameterToString(int32_t value);
|
||||
static utility::string_t parameterToString(int64_t value);
|
||||
|
||||
template<class T>
|
||||
static utility::string_t parameterToArrayString(std::vector<T> value)
|
||||
{
|
||||
utility::stringstream_t ss;
|
||||
|
||||
for( size_t i = 0; i < value.size(); i++)
|
||||
{
|
||||
if( i > 0) ss << U(", ");
|
||||
ss << ApiClient::parameterToString(value[i]);
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
pplx::task<web::http::http_response> callApi(
|
||||
const utility::string_t& path,
|
||||
const utility::string_t& method,
|
||||
const std::map<utility::string_t, utility::string_t>& queryParams,
|
||||
const std::shared_ptr<IHttpBody> postBody,
|
||||
const std::map<utility::string_t, utility::string_t>& headerParams,
|
||||
const std::map<utility::string_t, utility::string_t>& formParams,
|
||||
const std::map<utility::string_t, std::shared_ptr<HttpContent>>& fileParams,
|
||||
const utility::string_t& contentType
|
||||
) const;
|
||||
|
||||
protected:
|
||||
|
||||
std::shared_ptr<ApiConfiguration> m_Configuration;
|
||||
};
|
||||
|
||||
{{#apiNamespaceDeclarations}}
|
||||
}
|
||||
{{/apiNamespaceDeclarations}}
|
||||
|
||||
#endif /* ApiClient_H_ */
|
||||
@@ -0,0 +1,131 @@
|
||||
#include "ApiClient.h"
|
||||
#include "MultipartFormData.h"
|
||||
#include "ModelBase.h"
|
||||
|
||||
{{#apiNamespaceDeclarations}}
|
||||
namespace {{this}} {
|
||||
{{/apiNamespaceDeclarations}}
|
||||
|
||||
using namespace {{modelNamespace}};
|
||||
|
||||
ApiClient::ApiClient(std::shared_ptr<ApiConfiguration> configuration )
|
||||
: m_Configuration(configuration)
|
||||
{
|
||||
}
|
||||
ApiClient::~ApiClient()
|
||||
{
|
||||
}
|
||||
|
||||
std::shared_ptr<ApiConfiguration> ApiClient::getConfiguration() const
|
||||
{
|
||||
return m_Configuration;
|
||||
}
|
||||
void ApiClient::setConfiguration(std::shared_ptr<ApiConfiguration> configuration)
|
||||
{
|
||||
m_Configuration = configuration;
|
||||
}
|
||||
|
||||
|
||||
utility::string_t ApiClient::parameterToString(utility::string_t value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
utility::string_t ApiClient::parameterToString(int64_t value)
|
||||
{
|
||||
return std::to_wstring(value);
|
||||
}
|
||||
utility::string_t ApiClient::parameterToString(int32_t value)
|
||||
{
|
||||
return std::to_wstring(value);
|
||||
}
|
||||
|
||||
pplx::task<web::http::http_response> ApiClient::callApi(
|
||||
const utility::string_t& path,
|
||||
const utility::string_t& method,
|
||||
const std::map<utility::string_t, utility::string_t>& queryParams,
|
||||
const std::shared_ptr<IHttpBody> postBody,
|
||||
const std::map<utility::string_t, utility::string_t>& headerParams,
|
||||
const std::map<utility::string_t, utility::string_t>& formParams,
|
||||
const std::map<utility::string_t, std::shared_ptr<HttpContent>>& fileParams,
|
||||
const utility::string_t& contentType
|
||||
) const
|
||||
{
|
||||
if (postBody != nullptr && formParams.size() != 0)
|
||||
{
|
||||
throw ApiException(400, U("Cannot have body and form params"));
|
||||
}
|
||||
|
||||
if (postBody != nullptr && fileParams.size() != 0)
|
||||
{
|
||||
throw ApiException(400, U("Cannot have body and file params"));
|
||||
}
|
||||
|
||||
if (fileParams.size() > 0 && contentType != U("multipart/form-data"))
|
||||
{
|
||||
throw ApiException(400, U("Operations with file parameters must be called with multipart/form-data"));
|
||||
}
|
||||
|
||||
web::http::client::http_client client(m_Configuration->getBaseUrl(), m_Configuration->getHttpConfig());
|
||||
|
||||
web::http::http_request request;
|
||||
for ( auto& kvp : headerParams )
|
||||
{
|
||||
request.headers().add(kvp.first, kvp.second);
|
||||
}
|
||||
|
||||
if (fileParams.size() > 0)
|
||||
{
|
||||
MultipartFormData uploadData;
|
||||
for (auto& kvp : formParams)
|
||||
{
|
||||
uploadData.add(ModelBase::toHttpContent(kvp.first, kvp.second));
|
||||
}
|
||||
for (auto& kvp : fileParams)
|
||||
{
|
||||
uploadData.add(ModelBase::toHttpContent(kvp.first, kvp.second));
|
||||
}
|
||||
std::stringstream data;
|
||||
postBody->writeTo(data);
|
||||
auto bodyString = data.str();
|
||||
auto length = bodyString.size();
|
||||
request.set_body(concurrency::streams::bytestream::open_istream(std::move(bodyString)), length, contentType);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (postBody != nullptr)
|
||||
{
|
||||
std::stringstream data;
|
||||
postBody->writeTo(data);
|
||||
auto bodyString = data.str();
|
||||
auto length = bodyString.size();
|
||||
request.set_body(concurrency::streams::bytestream::open_istream(std::move(bodyString)), length, contentType);
|
||||
}
|
||||
else
|
||||
{
|
||||
web::http::uri_builder formData;
|
||||
for (auto& kvp : formParams)
|
||||
{
|
||||
formData.append_query(kvp.first, kvp.second);
|
||||
}
|
||||
request.set_body(formData.query(), U("application/x-www-form-urlencoded"));
|
||||
}
|
||||
}
|
||||
|
||||
web::http::uri_builder builder(path);
|
||||
for (auto& kvp : queryParams)
|
||||
{
|
||||
builder.append_query(kvp.first, kvp.second);
|
||||
}
|
||||
request.set_request_uri(builder.to_uri());
|
||||
request.set_method(method);
|
||||
if ( !request.headers().has( web::http::header_names::user_agent ) )
|
||||
{
|
||||
request.headers().add( web::http::header_names::user_agent, m_Configuration->getUserAgent() );
|
||||
}
|
||||
|
||||
return client.request(request);
|
||||
}
|
||||
|
||||
{{#apiNamespaceDeclarations}}
|
||||
}
|
||||
{{/apiNamespaceDeclarations}}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* ApiConfiguration.h
|
||||
*
|
||||
* This class represents a single item of a multipart-formdata request.
|
||||
*/
|
||||
|
||||
#ifndef ApiConfiguration_H_
|
||||
#define ApiConfiguration_H_
|
||||
|
||||
{{{defaultInclude}}}
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <cpprest/details/basic_types.h>
|
||||
#include <cpprest/http_client.h>
|
||||
{{#apiNamespaceDeclarations}}
|
||||
namespace {{this}} {
|
||||
{{/apiNamespaceDeclarations}}
|
||||
|
||||
class {{declspec}} ApiConfiguration
|
||||
{
|
||||
public:
|
||||
ApiConfiguration();
|
||||
virtual ~ApiConfiguration();
|
||||
|
||||
web::http::client::http_client_config& getHttpConfig();
|
||||
void setHttpConfig( web::http::client::http_client_config& value );
|
||||
|
||||
utility::string_t getBaseUrl() const;
|
||||
void setBaseUrl( const utility::string_t value );
|
||||
|
||||
utility::string_t getUserAgent() const;
|
||||
void setUserAgent( const utility::string_t value );
|
||||
|
||||
std::map<utility::string_t, utility::string_t>& getDefaultHeaders();
|
||||
|
||||
utility::string_t getApiKey( const utility::string_t& prefix) const;
|
||||
void setApiKey( const utility::string_t& prefix, const utility::string_t& apiKey );
|
||||
|
||||
protected:
|
||||
utility::string_t m_BaseUrl;
|
||||
std::map<utility::string_t, utility::string_t> m_DefaultHeaders;
|
||||
std::map<utility::string_t, utility::string_t> m_ApiKeys;
|
||||
web::http::client::http_client_config m_HttpConfig;
|
||||
utility::string_t m_UserAgent;
|
||||
};
|
||||
|
||||
{{#apiNamespaceDeclarations}}
|
||||
}
|
||||
{{/apiNamespaceDeclarations}}
|
||||
#endif /* ApiConfiguration_H_ */
|
||||
@@ -0,0 +1,67 @@
|
||||
#include "ApiConfiguration.h"
|
||||
|
||||
{{#apiNamespaceDeclarations}}
|
||||
namespace {{this}} {
|
||||
{{/apiNamespaceDeclarations}}
|
||||
|
||||
ApiConfiguration::ApiConfiguration()
|
||||
{
|
||||
}
|
||||
|
||||
ApiConfiguration::~ApiConfiguration()
|
||||
{
|
||||
}
|
||||
|
||||
web::http::client::http_client_config& ApiConfiguration::getHttpConfig()
|
||||
{
|
||||
return m_HttpConfig;
|
||||
}
|
||||
|
||||
void ApiConfiguration::setHttpConfig( web::http::client::http_client_config& value )
|
||||
{
|
||||
m_HttpConfig = value;
|
||||
}
|
||||
|
||||
utility::string_t ApiConfiguration::getBaseUrl() const
|
||||
{
|
||||
return m_BaseUrl;
|
||||
}
|
||||
|
||||
void ApiConfiguration::setBaseUrl( const utility::string_t value )
|
||||
{
|
||||
m_BaseUrl = value;
|
||||
}
|
||||
|
||||
utility::string_t ApiConfiguration::getUserAgent() const
|
||||
{
|
||||
return m_UserAgent;
|
||||
}
|
||||
|
||||
void ApiConfiguration::setUserAgent( const utility::string_t value )
|
||||
{
|
||||
m_UserAgent = value;
|
||||
}
|
||||
|
||||
std::map<utility::string_t, utility::string_t>& ApiConfiguration::getDefaultHeaders()
|
||||
{
|
||||
return m_DefaultHeaders;
|
||||
}
|
||||
|
||||
utility::string_t ApiConfiguration::getApiKey( const utility::string_t& prefix) const
|
||||
{
|
||||
auto result = m_ApiKeys.find(prefix);
|
||||
if( result != m_ApiKeys.end() )
|
||||
{
|
||||
return result->second;
|
||||
}
|
||||
return U("");
|
||||
}
|
||||
|
||||
void ApiConfiguration::setApiKey( const utility::string_t& prefix, const utility::string_t& apiKey )
|
||||
{
|
||||
m_ApiKeys[prefix] = apiKey;
|
||||
}
|
||||
|
||||
{{#apiNamespaceDeclarations}}
|
||||
}
|
||||
{{/apiNamespaceDeclarations}}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* ApiException.h
|
||||
*
|
||||
* This is the exception being thrown in case the api call was not successful
|
||||
*/
|
||||
|
||||
#ifndef ApiException_H_
|
||||
#define ApiException_H_
|
||||
|
||||
{{{defaultInclude}}}
|
||||
|
||||
#include <memory>
|
||||
#include <map>
|
||||
|
||||
#include <cpprest/details/basic_types.h>
|
||||
#include <cpprest/http_msg.h>
|
||||
|
||||
|
||||
{{#apiNamespaceDeclarations}}
|
||||
namespace {{this}} {
|
||||
{{/apiNamespaceDeclarations}}
|
||||
|
||||
class {{declspec}} ApiException
|
||||
: public web::http::http_exception
|
||||
{
|
||||
public:
|
||||
ApiException( int errorCode
|
||||
, const utility::string_t& message
|
||||
, std::shared_ptr<std::istream> content = nullptr );
|
||||
ApiException( int errorCode
|
||||
, const utility::string_t& message
|
||||
, std::map<utility::string_t, utility::string_t>& headers
|
||||
, std::shared_ptr<std::istream> content = nullptr );
|
||||
virtual ~ApiException();
|
||||
|
||||
std::map<utility::string_t, utility::string_t>& getHeaders();
|
||||
std::shared_ptr<std::istream> getContent() const;
|
||||
|
||||
protected:
|
||||
std::shared_ptr<std::istream> m_Content;
|
||||
std::map<utility::string_t, utility::string_t> m_Headers;
|
||||
};
|
||||
|
||||
{{#apiNamespaceDeclarations}}
|
||||
}
|
||||
{{/apiNamespaceDeclarations}}
|
||||
|
||||
#endif /* ApiBase_H_ */
|
||||
@@ -0,0 +1,40 @@
|
||||
#include "ApiException.h"
|
||||
|
||||
{{#apiNamespaceDeclarations}}
|
||||
namespace {{this}} {
|
||||
{{/apiNamespaceDeclarations}}
|
||||
|
||||
ApiException::ApiException( int errorCode
|
||||
, const utility::string_t& message
|
||||
, std::shared_ptr<std::istream> content /*= nullptr*/ )
|
||||
: web::http::http_exception( errorCode, message )
|
||||
, m_Content(content)
|
||||
{
|
||||
}
|
||||
ApiException::ApiException( int errorCode
|
||||
, const utility::string_t& message
|
||||
, std::map<utility::string_t, utility::string_t>& headers
|
||||
, std::shared_ptr<std::istream> content /*= nullptr*/ )
|
||||
: web::http::http_exception( errorCode, message )
|
||||
, m_Content(content)
|
||||
, m_Headers(headers)
|
||||
{
|
||||
}
|
||||
|
||||
ApiException::~ApiException()
|
||||
{
|
||||
}
|
||||
|
||||
std::shared_ptr<std::istream> ApiException::getContent() const
|
||||
{
|
||||
return m_Content;
|
||||
}
|
||||
|
||||
std::map<utility::string_t, utility::string_t>& ApiException::getHeaders()
|
||||
{
|
||||
return m_Headers;
|
||||
}
|
||||
|
||||
{{#apiNamespaceDeclarations}}
|
||||
}
|
||||
{{/apiNamespaceDeclarations}}
|
||||
@@ -0,0 +1,51 @@
|
||||
#!/bin/sh
|
||||
# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/
|
||||
#
|
||||
# Usage example: /bin/sh ./git_push.sh wing328 swagger-petstore-cpprest "minor update"
|
||||
|
||||
git_user_id=$1
|
||||
git_repo_id=$2
|
||||
release_note=$3
|
||||
|
||||
if [ "$git_user_id" = "" ]; then
|
||||
git_user_id="{{{gitUserId}}}"
|
||||
echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id"
|
||||
fi
|
||||
|
||||
if [ "$git_repo_id" = "" ]; then
|
||||
git_repo_id="{{{gitRepoId}}}"
|
||||
echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id"
|
||||
fi
|
||||
|
||||
if [ "$release_note" = "" ]; then
|
||||
release_note="{{{releaseNote}}}"
|
||||
echo "[INFO] No command line input provided. Set \$release_note to $release_note"
|
||||
fi
|
||||
|
||||
# Initialize the local directory as a Git repository
|
||||
git init
|
||||
|
||||
# Adds the files in the local repository and stages them for commit.
|
||||
git add .
|
||||
|
||||
# Commits the tracked changes and prepares them to be pushed to a remote repository.
|
||||
git commit -m "$release_note"
|
||||
|
||||
# Sets the new remote
|
||||
git_remote=`git remote`
|
||||
if [ "$git_remote" = "" ]; then # git remote not defined
|
||||
|
||||
if [ "$GIT_TOKEN" = "" ]; then
|
||||
echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git crediential in your environment."
|
||||
git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git
|
||||
else
|
||||
git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
git pull origin master
|
||||
|
||||
# Pushes (Forces) the changes in the local repository up to the remote repository
|
||||
echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git"
|
||||
git push origin master 2>&1 | grep -v 'To https'
|
||||
@@ -0,0 +1,29 @@
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* HttpContent.h
|
||||
*
|
||||
* This class represents a single item of a multipart-formdata request.
|
||||
*/
|
||||
|
||||
#ifndef HttpContent_H_
|
||||
#define HttpContent_H_
|
||||
|
||||
{{{defaultInclude}}}
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <cpprest/details/basic_types.h>
|
||||
|
||||
{{#modelNamespaceDeclarations}}
|
||||
namespace {{this}} {
|
||||
{{/modelNamespaceDeclarations}}
|
||||
|
||||
class {{declspec}} HttpContent
|
||||
{
|
||||
public:
|
||||
HttpContent();
|
||||
virtual ~HttpContent();
|
||||
|
||||
virtual utility::string_t getContentDisposition();
|
||||
virtual void setContentDisposition( const utility::string_t& value );
|
||||
|
||||
virtual utility::string_t getName();
|
||||
virtual void setName( const utility::string_t& value );
|
||||
|
||||
virtual utility::string_t getFileName();
|
||||
virtual void setFileName( const utility::string_t& value );
|
||||
|
||||
virtual utility::string_t getContentType();
|
||||
virtual void setContentType( const utility::string_t& value );
|
||||
|
||||
virtual std::shared_ptr<std::istream> getData();
|
||||
virtual void setData( std::shared_ptr<std::istream> value );
|
||||
|
||||
virtual void writeTo( std::ostream& stream );
|
||||
|
||||
protected:
|
||||
// NOTE: no utility::string_t here because those strings can only contain ascii
|
||||
utility::string_t m_ContentDisposition;
|
||||
utility::string_t m_Name;
|
||||
utility::string_t m_FileName;
|
||||
utility::string_t m_ContentType;
|
||||
std::shared_ptr<std::istream> m_Data;
|
||||
};
|
||||
|
||||
{{#modelNamespaceDeclarations}}
|
||||
}
|
||||
{{/modelNamespaceDeclarations}}
|
||||
|
||||
#endif /* HttpContent_H_ */
|
||||
@@ -0,0 +1,73 @@
|
||||
#include "HttpContent.h"
|
||||
|
||||
{{#modelNamespaceDeclarations}}
|
||||
namespace {{this}} {
|
||||
{{/modelNamespaceDeclarations}}
|
||||
|
||||
HttpContent::HttpContent()
|
||||
{
|
||||
}
|
||||
|
||||
HttpContent::~HttpContent()
|
||||
{
|
||||
}
|
||||
|
||||
utility::string_t HttpContent::getContentDisposition()
|
||||
{
|
||||
return m_ContentDisposition;
|
||||
}
|
||||
|
||||
void HttpContent::setContentDisposition( const utility::string_t & value )
|
||||
{
|
||||
m_ContentDisposition = value;
|
||||
}
|
||||
|
||||
utility::string_t HttpContent::getName()
|
||||
{
|
||||
return m_Name;
|
||||
}
|
||||
|
||||
void HttpContent::setName( const utility::string_t & value )
|
||||
{
|
||||
m_Name = value;
|
||||
}
|
||||
|
||||
utility::string_t HttpContent::getFileName()
|
||||
{
|
||||
return m_FileName;
|
||||
}
|
||||
|
||||
void HttpContent::setFileName( const utility::string_t & value )
|
||||
{
|
||||
m_FileName = value;
|
||||
}
|
||||
|
||||
utility::string_t HttpContent::getContentType()
|
||||
{
|
||||
return m_ContentType;
|
||||
}
|
||||
|
||||
void HttpContent::setContentType( const utility::string_t & value )
|
||||
{
|
||||
m_ContentType = value;
|
||||
}
|
||||
|
||||
std::shared_ptr<std::istream> HttpContent::getData()
|
||||
{
|
||||
return m_Data;
|
||||
}
|
||||
|
||||
void HttpContent::setData( std::shared_ptr<std::istream> value )
|
||||
{
|
||||
m_Data = value;
|
||||
}
|
||||
|
||||
void HttpContent::writeTo( std::ostream& stream )
|
||||
{
|
||||
m_Data->seekg( 0, m_Data->beg );
|
||||
stream << m_Data->rdbuf();
|
||||
}
|
||||
|
||||
{{#modelNamespaceDeclarations}}
|
||||
}
|
||||
{{/modelNamespaceDeclarations}}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* IHttpBody.h
|
||||
*
|
||||
* This is the interface for contents that can be sent to a remote HTTP server.
|
||||
*/
|
||||
|
||||
#ifndef IHttpBody_H_
|
||||
#define IHttpBody_H_
|
||||
|
||||
{{{defaultInclude}}}
|
||||
#include <iostream>
|
||||
|
||||
{{#modelNamespaceDeclarations}}
|
||||
namespace {{this}} {
|
||||
{{/modelNamespaceDeclarations}}
|
||||
|
||||
class {{declspec}} IHttpBody
|
||||
{
|
||||
public:
|
||||
virtual ~IHttpBody() { }
|
||||
|
||||
virtual void writeTo( std::ostream& stream ) = 0;
|
||||
};
|
||||
|
||||
{{#modelNamespaceDeclarations}}
|
||||
}
|
||||
{{/modelNamespaceDeclarations}}
|
||||
|
||||
#endif /* IHttpBody_H_ */
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* JsonBody.h
|
||||
*
|
||||
* This is a JSON http body which can be submitted via http
|
||||
*/
|
||||
|
||||
#ifndef JsonBody_H_
|
||||
#define JsonBody_H_
|
||||
|
||||
{{{defaultInclude}}}
|
||||
#include "IHttpBody.h"
|
||||
|
||||
#include <cpprest/json.h>
|
||||
|
||||
{{#modelNamespaceDeclarations}}
|
||||
namespace {{this}} {
|
||||
{{/modelNamespaceDeclarations}}
|
||||
|
||||
class {{declspec}} JsonBody
|
||||
: public IHttpBody
|
||||
{
|
||||
public:
|
||||
JsonBody( const web::json::value& value );
|
||||
virtual ~JsonBody();
|
||||
|
||||
void writeTo( std::ostream& target ) override;
|
||||
|
||||
protected:
|
||||
web::json::value m_Json;
|
||||
};
|
||||
|
||||
{{#modelNamespaceDeclarations}}
|
||||
}
|
||||
{{/modelNamespaceDeclarations}}
|
||||
|
||||
#endif /* JsonBody_H_ */
|
||||
@@ -0,0 +1,23 @@
|
||||
#include "JsonBody.h"
|
||||
|
||||
{{#modelNamespaceDeclarations}}
|
||||
namespace {{this}} {
|
||||
{{/modelNamespaceDeclarations}}
|
||||
|
||||
JsonBody::JsonBody( const web::json::value& json)
|
||||
: m_Json(json)
|
||||
{
|
||||
}
|
||||
|
||||
JsonBody::~JsonBody()
|
||||
{
|
||||
}
|
||||
|
||||
void JsonBody::writeTo( std::ostream& target )
|
||||
{
|
||||
m_Json.serialize(target);
|
||||
}
|
||||
|
||||
{{#modelNamespaceDeclarations}}
|
||||
}
|
||||
{{/modelNamespaceDeclarations}}
|
||||
@@ -0,0 +1,69 @@
|
||||
{{#models}}{{#model}}/*
|
||||
* {{classname}}.h
|
||||
*
|
||||
* {{description}}
|
||||
*/
|
||||
|
||||
#ifndef {{classname}}_H_
|
||||
#define {{classname}}_H_
|
||||
|
||||
{{{defaultInclude}}}
|
||||
#include "ModelBase.h"
|
||||
|
||||
{{#imports}}{{{this}}}
|
||||
{{/imports}}
|
||||
|
||||
{{#modelNamespaceDeclarations}}
|
||||
namespace {{this}} {
|
||||
{{/modelNamespaceDeclarations}}
|
||||
|
||||
/// <summary>
|
||||
/// {{description}}
|
||||
/// </summary>
|
||||
class {{declspec}} {{classname}}
|
||||
: public ModelBase
|
||||
{
|
||||
public:
|
||||
{{classname}}();
|
||||
virtual ~{{classname}}();
|
||||
|
||||
/////////////////////////////////////////////
|
||||
/// ModelBase overrides
|
||||
|
||||
void validate() override;
|
||||
|
||||
web::json::value toJson() const override;
|
||||
void fromJson(web::json::value& json) override;
|
||||
|
||||
void toMultipart(std::shared_ptr<MultipartFormData> multipart, const utility::string_t& namePrefix) const override;
|
||||
void fromMultiPart(std::shared_ptr<MultipartFormData> multipart, const utility::string_t& namePrefix) override;
|
||||
|
||||
/////////////////////////////////////////////
|
||||
/// {{classname}} members
|
||||
|
||||
{{#vars}}
|
||||
/// <summary>
|
||||
/// {{description}}
|
||||
/// </summary>
|
||||
{{^isNotContainer}}{{{datatype}}}& {{getter}}();
|
||||
{{/isNotContainer}}{{#isNotContainer}}{{{datatype}}} {{getter}}() const;
|
||||
void {{setter}}({{{datatype}}} value);
|
||||
{{/isNotContainer}}{{^required}}bool {{baseName}}IsSet() const;
|
||||
void unset{{name}}();
|
||||
{{/required}}
|
||||
{{/vars}}
|
||||
|
||||
protected:
|
||||
{{#vars}}{{{datatype}}} m_{{name}};
|
||||
{{^required}}bool m_{{name}}IsSet;
|
||||
{{/required}}
|
||||
{{/vars}}
|
||||
};
|
||||
|
||||
{{#modelNamespaceDeclarations}}
|
||||
}
|
||||
{{/modelNamespaceDeclarations}}
|
||||
|
||||
#endif /* {{classname}}_H_ */
|
||||
{{/model}}
|
||||
{{/models}}
|
||||
@@ -0,0 +1,254 @@
|
||||
{{#models}}{{#model}}
|
||||
|
||||
#include "{{classname}}.h"
|
||||
|
||||
{{#modelNamespaceDeclarations}}
|
||||
namespace {{this}} {
|
||||
{{/modelNamespaceDeclarations}}
|
||||
|
||||
{{classname}}::{{classname}}()
|
||||
{
|
||||
{{#vars}}{{#isNotContainer}}{{#isPrimitiveType}}m_{{name}} = {{{defaultValue}}};
|
||||
{{/isPrimitiveType}}{{^isPrimitiveType}}{{#isString}}m_{{name}} = {{{defaultValue}}};
|
||||
{{/isString}}{{#isDateTime}}m_{{name}} = {{{defaultValue}}};
|
||||
{{/isDateTime}}{{/isPrimitiveType}}{{/isNotContainer}}{{^required}}m_{{name}}IsSet = false;
|
||||
{{/required}}{{/vars}}
|
||||
}
|
||||
|
||||
{{classname}}::~{{classname}}()
|
||||
{
|
||||
}
|
||||
|
||||
void {{classname}}::validate()
|
||||
{
|
||||
// TODO: implement validation
|
||||
}
|
||||
|
||||
web::json::value {{classname}}::toJson() const
|
||||
{
|
||||
web::json::value val = web::json::value::object();
|
||||
|
||||
{{#vars}}{{#isPrimitiveType}}{{^required}}if(m_{{name}}IsSet)
|
||||
{
|
||||
val[U("{{baseName}}")] = ModelBase::toJson(m_{{name}});
|
||||
}
|
||||
{{/required}}{{#required}}val[U("{{baseName}}")] = ModelBase::toJson(m_{{name}});
|
||||
{{/required}}{{/isPrimitiveType}}{{^isPrimitiveType}}{{#isListContainer}}{
|
||||
std::vector<web::json::value> jsonArray;
|
||||
for( auto& item : m_{{name}} )
|
||||
{
|
||||
jsonArray.push_back(ModelBase::toJson(item));
|
||||
}
|
||||
{{#required}}val[U("{{baseName}}")] = web::json::value::array(jsonArray);
|
||||
{{/required}}{{^required}}
|
||||
if(jsonArray.size() > 0)
|
||||
{
|
||||
val[U("{{baseName}}")] = web::json::value::array(jsonArray);
|
||||
}
|
||||
{{/required}}
|
||||
}
|
||||
{{/isListContainer}}{{^isListContainer}}{{^required}}if(m_{{name}}IsSet)
|
||||
{
|
||||
val[U("{{baseName}}")] = ModelBase::toJson(m_{{name}});
|
||||
}
|
||||
{{/required}}{{#required}}val[U("{{baseName}}")] = ModelBase::toJson(m_{{name}});
|
||||
{{/required}}{{/isListContainer}}{{/isPrimitiveType}}{{/vars}}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void {{classname}}::fromJson(web::json::value& val)
|
||||
{
|
||||
{{#vars}}{{#isPrimitiveType}}{{^required}}if(val.has_field(U("{{baseName}}")))
|
||||
{
|
||||
{{setter}}(ModelBase::{{baseType}}FromJson(val[U("{{baseName}}")]));
|
||||
}
|
||||
{{/required}}{{#required}}{{setter}}(ModelBase::{{baseType}}FromJson(val[U("{{baseName}}")]));
|
||||
{{/required}}{{/isPrimitiveType}}{{^isPrimitiveType}}{{#isListContainer}}{
|
||||
m_{{name}}.clear();
|
||||
std::vector<web::json::value> jsonArray;
|
||||
{{^required}}if(val.has_field(U("{{baseName}}")))
|
||||
{
|
||||
{{/required}}
|
||||
for( auto& item : val[U("{{baseName}}")].as_array() )
|
||||
{
|
||||
{{#items.isPrimitiveType}}m_{{name}}.push_back(ModelBase::{{baseType}}FromJson(item));
|
||||
{{/items.isPrimitiveType}}{{^items.isPrimitiveType}}{{#items.isString}}m_{{name}}.push_back(ModelBase::stringFromJson(item));
|
||||
{{/items.isString}}{{^items.isString}}{{#items.isDateTime}}m_{{name}}.push_back(ModelBase::dateFromJson(item));
|
||||
{{/items.isDateTime}}{{^items.isDateTime}}
|
||||
if(item.is_null())
|
||||
{
|
||||
m_{{name}}.push_back( {{{items.datatype}}}(nullptr) );
|
||||
}
|
||||
else
|
||||
{
|
||||
{{{items.datatype}}} newItem({{{items.defaultValue}}});
|
||||
newItem->fromJson(item);
|
||||
m_{{name}}.push_back( newItem );
|
||||
}
|
||||
{{/items.isDateTime}}{{/items.isString}}{{/items.isPrimitiveType}}
|
||||
}
|
||||
{{^required}}
|
||||
}
|
||||
{{/required}}
|
||||
}
|
||||
{{/isListContainer}}{{^isListContainer}}{{^required}}if(val.has_field(U("{{baseName}}")))
|
||||
{
|
||||
{{#isString}}{{setter}}(ModelBase::stringFromJson(val[U("{{baseName}}")]));
|
||||
{{/isString}}{{^isString}}{{#isDateTime}}{{setter}}(ModelBase::dateFromJson(val[U("{{baseName}}")]));
|
||||
{{/isDateTime}}{{^isDateTime}}if(!val[U("{{baseName}}")].is_null())
|
||||
{
|
||||
{{{datatype}}} newItem({{{defaultValue}}});
|
||||
newItem->fromJson(val[U("{{baseName}}")]);
|
||||
{{setter}}( newItem );
|
||||
}
|
||||
{{/isDateTime}}{{/isString}}
|
||||
}
|
||||
{{/required}}{{#required}}{{#isString}}{{setter}}(ModelBase::stringFromJson(val[U("{{baseName}}")]));
|
||||
{{/isString}}{{^isString}}{{#isDateTime}}{{setter}}(ModelBase::dateFromJson(val[U("{{baseName}}")]));
|
||||
{{/isDateTime}}{{^isDateTime}}{{#vendorExtensions.x-codegen-file}}{{setter}}(ModelBase::fileFromJson(val[U("{{baseName}}")]));
|
||||
{{/vendorExtensions.x-codegen-file}}{{^vendorExtensions.x-codegen-file}}{{{datatype}}} new{{name}}({{{defaultValue}}});
|
||||
new{{name}}->fromJson(val[U("{{baseName}}")]);
|
||||
{{setter}}( newItem );
|
||||
{{/vendorExtensions.x-codegen-file}}{{/isDateTime}}{{/isString}}{{/required}}{{/isListContainer}}{{/isPrimitiveType}}{{/vars}}
|
||||
}
|
||||
|
||||
void {{classname}}::toMultipart(std::shared_ptr<MultipartFormData> multipart, const utility::string_t& prefix) const
|
||||
{
|
||||
utility::string_t namePrefix = prefix;
|
||||
if(namePrefix.size() > 0 && namePrefix[namePrefix.size() - 1] != U('.'))
|
||||
{
|
||||
namePrefix += U(".");
|
||||
}
|
||||
|
||||
{{#vars}}{{#isPrimitiveType}}{{^required}}if(m_{{name}}IsSet)
|
||||
{
|
||||
multipart->add(ModelBase::toHttpContent(namePrefix + U("{{baseName}}"), m_{{name}}));
|
||||
}
|
||||
{{/required}}{{#required}}multipart->add(ModelBase::toHttpContent(namePrefix + U("{{baseName}}"), m_{{name}}));
|
||||
{{/required}}{{/isPrimitiveType}}{{^isPrimitiveType}}{{#isListContainer}}{
|
||||
std::vector<web::json::value> jsonArray;
|
||||
for( auto& item : m_{{name}} )
|
||||
{
|
||||
jsonArray.push_back(ModelBase::toJson(item));
|
||||
}
|
||||
{{#required}}multipart->add(ModelBase::toHttpContent(namePrefix + U("{{baseName}}"), web::json::value::array(jsonArray), U("application/json")));
|
||||
{{/required}}{{^required}}
|
||||
if(jsonArray.size() > 0)
|
||||
{
|
||||
multipart->add(ModelBase::toHttpContent(namePrefix + U("{{baseName}}"), web::json::value::array(jsonArray), U("application/json")));
|
||||
}
|
||||
{{/required}}
|
||||
}
|
||||
{{/isListContainer}}{{^isListContainer}}{{^required}}if(m_{{name}}IsSet)
|
||||
{
|
||||
{{#isString}}multipart->add(ModelBase::toHttpContent(namePrefix + U("{{baseName}}"), m_{{name}}));
|
||||
{{/isString}}{{^isString}}{{#isDateTime}}multipart->add(ModelBase::toHttpContent(namePrefix + U("{{baseName}}"), m_{{name}}));
|
||||
{{/isDateTime}}{{^isDateTime}}if (m_{{name}}.get())
|
||||
{
|
||||
m_{{name}}->toMultipart(multipart, U("{{baseName}}."));
|
||||
}
|
||||
{{/isDateTime}}{{/isString}}
|
||||
}
|
||||
{{/required}}{{#required}}{{#isString}}multipart->add(ModelBase::toHttpContent(namePrefix + U("{{baseName}}"), m_{{name}}));
|
||||
{{/isString}}{{^isString}}{{#isDateTime}}multipart->add(ModelBase::toHttpContent(namePrefix + U("{{baseName}}"), m_{{name}}));
|
||||
{{/isDateTime}}{{^isDateTime}}{{#vendorExtensions.x-codegen-file}}multipart->add(ModelBase::toHttpContent(namePrefix + U("{{baseName}}"), m_{{name}}));
|
||||
{{/vendorExtensions.x-codegen-file}}{{^vendorExtensions.x-codegen-file}}m_{{name}}->toMultipart(multipart, U("{{baseName}}."));
|
||||
{{/vendorExtensions.x-codegen-file}}{{/isDateTime}}{{/isString}}{{/required}}{{/isListContainer}}{{/isPrimitiveType}}{{/vars}}
|
||||
}
|
||||
|
||||
void {{classname}}::fromMultiPart(std::shared_ptr<MultipartFormData> multipart, const utility::string_t& prefix)
|
||||
{
|
||||
utility::string_t namePrefix = prefix;
|
||||
if(namePrefix.size() > 0 && namePrefix[namePrefix.size() - 1] != U('.'))
|
||||
{
|
||||
namePrefix += U(".");
|
||||
}
|
||||
|
||||
{{#vars}}{{#isPrimitiveType}}{{^required}}if(multipart->hasContent(U("{{baseName}}")))
|
||||
{
|
||||
{{setter}}(ModelBase::{{baseType}}FromHttpContent(multipart->getContent(U("{{baseName}}"))));
|
||||
}
|
||||
{{/required}}{{#required}}{{setter}}(ModelBase::{{baseType}}FromHttpContent(multipart->getContent(U("{{baseName}}"))));
|
||||
{{/required}}{{/isPrimitiveType}}{{^isPrimitiveType}}{{#isListContainer}}{
|
||||
m_{{name}}.clear();
|
||||
{{^required}}if(multipart->hasContent(U("{{baseName}}")))
|
||||
{
|
||||
{{/required}}
|
||||
|
||||
web::json::value jsonArray = web::json::value::parse(ModelBase::stringFromHttpContent(multipart->getContent(U("{{baseName}}"))));
|
||||
for( auto& item : jsonArray.as_array() )
|
||||
{
|
||||
{{#items.isPrimitiveType}}m_{{name}}.push_back(ModelBase::{{baseType}}FromJson(item));
|
||||
{{/items.isPrimitiveType}}{{^items.isPrimitiveType}}{{#items.isString}}m_{{name}}.push_back(ModelBase::stringFromJson(item));
|
||||
{{/items.isString}}{{^items.isString}}{{#items.isDateTime}}m_{{name}}.push_back(ModelBase::dateFromJson(item));
|
||||
{{/items.isDateTime}}{{^items.isDateTime}}
|
||||
if(item.is_null())
|
||||
{
|
||||
m_{{name}}.push_back( {{{items.datatype}}}(nullptr) );
|
||||
}
|
||||
else
|
||||
{
|
||||
{{{items.datatype}}} newItem({{{items.defaultValue}}});
|
||||
newItem->fromJson(item);
|
||||
m_{{name}}.push_back( newItem );
|
||||
}
|
||||
{{/items.isDateTime}}{{/items.isString}}{{/items.isPrimitiveType}}
|
||||
}
|
||||
{{^required}}
|
||||
}
|
||||
{{/required}}
|
||||
}
|
||||
{{/isListContainer}}{{^isListContainer}}{{^required}}if(multipart->hasContent(U("{{baseName}}")))
|
||||
{
|
||||
{{#isString}}{{setter}}(ModelBase::stringFromHttpContent(multipart->getContent(U("{{baseName}}"))));
|
||||
{{/isString}}{{^isString}}{{#isDateTime}}{{setter}}(ModelBase::dateFromHttpContent(multipart->getContent(U("{{baseName}}"))));
|
||||
{{/isDateTime}}{{^isDateTime}}if(multipart->hasContent(U("{{baseName}}")))
|
||||
{
|
||||
{{{datatype}}} newItem({{{defaultValue}}});
|
||||
newItem->fromMultiPart(multipart, U("{{baseName}}."));
|
||||
{{setter}}( newItem );
|
||||
}
|
||||
{{/isDateTime}}{{/isString}}
|
||||
}
|
||||
{{/required}}{{#required}}{{#isString}}{{setter}}(ModelBase::stringFromHttpContent(multipart->getContent(U("{{baseName}}"))));
|
||||
{{/isString}}{{^isString}}{{#isDateTime}}{{setter}}(ModelBase::dateFromHttpContent(multipart->getContent(U("{{baseName}}"))));
|
||||
{{/isDateTime}}{{^isDateTime}}{{#vendorExtensions.x-codegen-file}}{{setter}}(multipart->getContent(U("{{baseName}}")));
|
||||
{{/vendorExtensions.x-codegen-file}}{{^vendorExtensions.x-codegen-file}}{{{datatype}}} new{{name}}({{{defaultValue}}});
|
||||
new{{name}}->fromMultiPart(multipart, U("{{baseName}}."));
|
||||
{{setter}}( new{{name}} );
|
||||
{{/vendorExtensions.x-codegen-file}}{{/isDateTime}}{{/isString}}{{/required}}{{/isListContainer}}{{/isPrimitiveType}}{{/vars}}
|
||||
}
|
||||
|
||||
|
||||
{{#vars}}{{^isNotContainer}}{{{datatype}}}& {{classname}}::{{getter}}()
|
||||
{
|
||||
return m_{{name}};
|
||||
}
|
||||
{{/isNotContainer}}{{#isNotContainer}}{{{datatype}}} {{classname}}::{{getter}}() const
|
||||
{
|
||||
return m_{{name}};
|
||||
}
|
||||
void {{classname}}::{{setter}}({{{datatype}}} value)
|
||||
{
|
||||
m_{{name}} = value;
|
||||
{{^required}}m_{{name}}IsSet = true;{{/required}}
|
||||
}
|
||||
{{/isNotContainer}}
|
||||
{{^required}}bool {{classname}}::{{baseName}}IsSet() const
|
||||
{
|
||||
return m_{{name}}IsSet;
|
||||
}
|
||||
void {{classname}}::unset{{name}}()
|
||||
{
|
||||
m_{{name}}IsSet = false;
|
||||
}
|
||||
{{/required}}
|
||||
{{/vars}}
|
||||
|
||||
{{#modelNamespaceDeclarations}}
|
||||
}
|
||||
{{/modelNamespaceDeclarations}}
|
||||
|
||||
{{/model}}
|
||||
{{/models}}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* ModelBase.h
|
||||
*
|
||||
* This is the base class for all model classes
|
||||
*/
|
||||
|
||||
#ifndef ModelBase_H_
|
||||
#define ModelBase_H_
|
||||
|
||||
{{{defaultInclude}}}
|
||||
#include "HttpContent.h"
|
||||
#include "MultipartFormData.h"
|
||||
|
||||
#include <cpprest/details/basic_types.h>
|
||||
#include <cpprest/json.h>
|
||||
|
||||
{{#modelNamespaceDeclarations}}
|
||||
namespace {{this}} {
|
||||
{{/modelNamespaceDeclarations}}
|
||||
|
||||
class {{declspec}} ModelBase
|
||||
{
|
||||
public:
|
||||
ModelBase();
|
||||
virtual ~ModelBase();
|
||||
|
||||
virtual void validate() = 0;
|
||||
|
||||
virtual web::json::value toJson() const = 0;
|
||||
virtual void fromJson(web::json::value& json) = 0;
|
||||
|
||||
virtual void toMultipart(std::shared_ptr<MultipartFormData> multipart, const utility::string_t& namePrefix) const = 0;
|
||||
virtual void fromMultiPart(std::shared_ptr<MultipartFormData> multipart, const utility::string_t& namePrefix) = 0;
|
||||
|
||||
static web::json::value toJson( const utility::string_t& value );
|
||||
static web::json::value toJson( const utility::datetime& value );
|
||||
static web::json::value toJson( std::shared_ptr<HttpContent> value );
|
||||
static web::json::value toJson( std::shared_ptr<ModelBase> value );
|
||||
static web::json::value toJson( int32_t value );
|
||||
static web::json::value toJson( int64_t value );
|
||||
static web::json::value toJson( double value );
|
||||
|
||||
static int64_t int64_tFromJson(web::json::value& val);
|
||||
static int32_t int32_tFromJson(web::json::value& val);
|
||||
static utility::string_t stringFromJson(web::json::value& val);
|
||||
static utility::datetime dateFromJson(web::json::value& val);
|
||||
static double doubleFromJson(web::json::value& val);
|
||||
static bool boolFromJson(web::json::value& val);
|
||||
static std::shared_ptr<HttpContent> fileFromJson(web::json::value& val);
|
||||
|
||||
static std::shared_ptr<HttpContent> toHttpContent( const utility::string_t& name, const utility::string_t& value, const utility::string_t& contentType = U(""));
|
||||
static std::shared_ptr<HttpContent> toHttpContent( const utility::string_t& name, const utility::datetime& value, const utility::string_t& contentType = U(""));
|
||||
static std::shared_ptr<HttpContent> toHttpContent( const utility::string_t& name, std::shared_ptr<HttpContent> value );
|
||||
static std::shared_ptr<HttpContent> toHttpContent( const utility::string_t& name, const web::json::value& value, const utility::string_t& contentType = U("application/json") );
|
||||
static std::shared_ptr<HttpContent> toHttpContent( const utility::string_t& name, int32_t value, const utility::string_t& contentType = U("") );
|
||||
static std::shared_ptr<HttpContent> toHttpContent( const utility::string_t& name, int64_t value, const utility::string_t& contentType = U("") );
|
||||
static std::shared_ptr<HttpContent> toHttpContent( const utility::string_t& name, double value, const utility::string_t& contentType = U("") );
|
||||
|
||||
static int64_t int64_tFromHttpContent(std::shared_ptr<HttpContent> val);
|
||||
static int32_t int32_tFromHttpContent(std::shared_ptr<HttpContent> val);
|
||||
static utility::string_t stringFromHttpContent(std::shared_ptr<HttpContent> val);
|
||||
static utility::datetime dateFromHttpContent(std::shared_ptr<HttpContent> val);
|
||||
static bool boolFromHttpContent(std::shared_ptr<HttpContent> val);
|
||||
static double doubleFromHttpContent(std::shared_ptr<HttpContent> val);
|
||||
|
||||
|
||||
static utility::string_t toBase64( utility::string_t value );
|
||||
static utility::string_t toBase64( std::shared_ptr<std::istream> value );
|
||||
static std::shared_ptr<std::istream> fromBase64( const utility::string_t& encoded );
|
||||
};
|
||||
|
||||
{{#modelNamespaceDeclarations}}
|
||||
}
|
||||
{{/modelNamespaceDeclarations}}
|
||||
|
||||
#endif /* ModelBase_H_ */
|
||||
@@ -0,0 +1,337 @@
|
||||
#include "ModelBase.h"
|
||||
|
||||
{{#modelNamespaceDeclarations}}
|
||||
namespace {{this}} {
|
||||
{{/modelNamespaceDeclarations}}
|
||||
|
||||
ModelBase::ModelBase()
|
||||
{
|
||||
}
|
||||
ModelBase::~ModelBase()
|
||||
{
|
||||
}
|
||||
|
||||
web::json::value ModelBase::toJson( const utility::string_t& value )
|
||||
{
|
||||
return web::json::value::string(value);
|
||||
}
|
||||
web::json::value ModelBase::toJson( const utility::datetime& value )
|
||||
{
|
||||
return web::json::value::string(value.to_string(utility::datetime::ISO_8601));
|
||||
}
|
||||
web::json::value ModelBase::toJson( int32_t value )
|
||||
{
|
||||
return web::json::value::number(value);
|
||||
}
|
||||
web::json::value ModelBase::toJson( int64_t value )
|
||||
{
|
||||
return web::json::value::number(value);
|
||||
}
|
||||
web::json::value ModelBase::toJson( double value )
|
||||
{
|
||||
return web::json::value::number(value);
|
||||
}
|
||||
|
||||
web::json::value ModelBase::toJson( std::shared_ptr<HttpContent> content )
|
||||
{
|
||||
web::json::value value;
|
||||
value[U("ContentDisposition")] = ModelBase::toJson(content->getContentDisposition());
|
||||
value[U("ContentType")] = ModelBase::toJson(content->getContentType());
|
||||
value[U("FileName")] = ModelBase::toJson(content->getFileName());
|
||||
value[U("InputStream")] = web::json::value::string( ModelBase::toBase64(content->getData()) );
|
||||
return value;
|
||||
}
|
||||
|
||||
std::shared_ptr<HttpContent> ModelBase::fileFromJson(web::json::value& val)
|
||||
{
|
||||
std::shared_ptr<HttpContent> content(new HttpContent);
|
||||
|
||||
if(val.has_field(U("ContentDisposition")))
|
||||
{
|
||||
content->setContentDisposition( ModelBase::stringFromJson(val[U("ContentDisposition")]) );
|
||||
}
|
||||
if(val.has_field(U("ContentType")))
|
||||
{
|
||||
content->setContentType( ModelBase::stringFromJson(val[U("ContentType")]) );
|
||||
}
|
||||
if(val.has_field(U("FileName")))
|
||||
{
|
||||
content->setFileName( ModelBase::stringFromJson(val[U("FileName")]) );
|
||||
}
|
||||
if(val.has_field(U("InputStream")))
|
||||
{
|
||||
content->setData( ModelBase::fromBase64( ModelBase::stringFromJson(val[U("InputStream")]) ) );
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
web::json::value ModelBase::toJson( std::shared_ptr<ModelBase> content )
|
||||
{
|
||||
return content.get() ? content->toJson() : web::json::value::null();
|
||||
}
|
||||
|
||||
std::shared_ptr<HttpContent> ModelBase::toHttpContent( const utility::string_t& name, const utility::string_t& value, const utility::string_t& contentType)
|
||||
{
|
||||
std::shared_ptr<HttpContent> content(new HttpContent);
|
||||
content->setName( name );
|
||||
content->setContentDisposition( U("form-data") );
|
||||
content->setContentType( contentType );
|
||||
content->setData( std::shared_ptr<std::istream>( new std::stringstream( utility::conversions::to_utf8string(value) ) ) );
|
||||
return content;
|
||||
}
|
||||
std::shared_ptr<HttpContent> ModelBase::toHttpContent( const utility::string_t& name, const utility::datetime& value, const utility::string_t& contentType )
|
||||
{
|
||||
std::shared_ptr<HttpContent> content( new HttpContent );
|
||||
content->setName( name );
|
||||
content->setContentDisposition( U("form-data") );
|
||||
content->setContentType( contentType );
|
||||
content->setData( std::shared_ptr<std::istream>( new std::stringstream( utility::conversions::to_utf8string(value.to_string(utility::datetime::ISO_8601) ) ) ) );
|
||||
return content;
|
||||
}
|
||||
std::shared_ptr<HttpContent> ModelBase::toHttpContent( const utility::string_t& name, std::shared_ptr<HttpContent> value )
|
||||
{
|
||||
std::shared_ptr<HttpContent> content( new HttpContent );
|
||||
content->setName( name );
|
||||
content->setContentDisposition( value->getContentDisposition() );
|
||||
content->setContentType( value->getContentType() );
|
||||
content->setData( value->getData() );
|
||||
content->setFileName( value->getFileName() );
|
||||
return content;
|
||||
}
|
||||
std::shared_ptr<HttpContent> ModelBase::toHttpContent( const utility::string_t& name, const web::json::value& value, const utility::string_t& contentType )
|
||||
{
|
||||
std::shared_ptr<HttpContent> content( new HttpContent );
|
||||
content->setName( name );
|
||||
content->setContentDisposition( U("form-data") );
|
||||
content->setContentType( contentType );
|
||||
content->setData( std::shared_ptr<std::istream>( new std::stringstream( utility::conversions::to_utf8string(value.serialize()) ) ) );
|
||||
return content;
|
||||
}
|
||||
std::shared_ptr<HttpContent> ModelBase::toHttpContent( const utility::string_t& name, int32_t value, const utility::string_t& contentType )
|
||||
{
|
||||
std::shared_ptr<HttpContent> content( new HttpContent );
|
||||
content->setName( name );
|
||||
content->setContentDisposition( U("form-data") );
|
||||
content->setContentType( contentType );
|
||||
content->setData( std::shared_ptr<std::istream>( new std::stringstream( std::to_string( value ) ) ) );
|
||||
return content;
|
||||
}
|
||||
std::shared_ptr<HttpContent> ModelBase::toHttpContent( const utility::string_t& name, int64_t value, const utility::string_t& contentType )
|
||||
{
|
||||
std::shared_ptr<HttpContent> content( new HttpContent );
|
||||
content->setName( name );
|
||||
content->setContentDisposition( U("form-data") );
|
||||
content->setContentType( contentType );
|
||||
content->setData( std::shared_ptr<std::istream>( new std::stringstream( std::to_string( value ) ) ) );
|
||||
return content;
|
||||
}
|
||||
std::shared_ptr<HttpContent> ModelBase::toHttpContent( const utility::string_t& name, double value, const utility::string_t& contentType )
|
||||
{
|
||||
std::shared_ptr<HttpContent> content( new HttpContent );
|
||||
content->setName( name );
|
||||
content->setContentDisposition( U("form-data") );
|
||||
content->setContentType( contentType );
|
||||
content->setData( std::shared_ptr<std::istream>( new std::stringstream( std::to_string( value ) ) ) );
|
||||
return content;
|
||||
}
|
||||
|
||||
// base64 encoding/decoding based on : https://en.wikibooks.org/wiki/Algorithm_Implementation/Miscellaneous/Base64#C.2B.2B
|
||||
const static char Base64Chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
const static char Base64PadChar = '=';
|
||||
utility::string_t ModelBase::toBase64( utility::string_t value )
|
||||
{
|
||||
std::shared_ptr<std::istream> source( new std::stringstream( utility::conversions::to_utf8string(value) ) );
|
||||
return ModelBase::toBase64(source);
|
||||
}
|
||||
utility::string_t ModelBase::toBase64( std::shared_ptr<std::istream> value )
|
||||
{
|
||||
value->seekg( 0, value->end );
|
||||
size_t length = value->tellg();
|
||||
value->seekg( 0, value->beg );
|
||||
utility::string_t base64;
|
||||
base64.reserve( ((length / 3) + (length % 3 > 0)) * 4 );
|
||||
char read[3] = { 0 };
|
||||
uint32_t temp;
|
||||
for ( size_t idx = 0; idx < length / 3; idx++ )
|
||||
{
|
||||
value->read( read, 3 );
|
||||
temp = (read[0]) << 16;
|
||||
temp += (read[1]) << 8;
|
||||
temp += (read[2]);
|
||||
base64.append( 1, Base64Chars[(temp & 0x00FC0000) >> 18] );
|
||||
base64.append( 1, Base64Chars[(temp & 0x0003F000) >> 12] );
|
||||
base64.append( 1, Base64Chars[(temp & 0x00000FC0) >> 6] );
|
||||
base64.append( 1, Base64Chars[(temp & 0x0000003F)] );
|
||||
}
|
||||
switch ( length % 3 )
|
||||
{
|
||||
case 1:
|
||||
value->read( read, 1 );
|
||||
temp = read[0] << 16;
|
||||
base64.append( 1, Base64Chars[(temp & 0x00FC0000) >> 18] );
|
||||
base64.append( 1, Base64Chars[(temp & 0x0003F000) >> 12] );
|
||||
base64.append( 2, Base64PadChar );
|
||||
break;
|
||||
case 2:
|
||||
value->read( read, 2 );
|
||||
temp = read[0] << 16;
|
||||
temp += read[1] << 8;
|
||||
base64.append( 1, Base64Chars[(temp & 0x00FC0000) >> 18] );
|
||||
base64.append( 1, Base64Chars[(temp & 0x0003F000) >> 12] );
|
||||
base64.append( 1, Base64Chars[(temp & 0x00000FC0) >> 6] );
|
||||
base64.append( 1, Base64PadChar );
|
||||
break;
|
||||
}
|
||||
return base64;
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<std::istream> ModelBase::fromBase64( const utility::string_t& encoded )
|
||||
{
|
||||
std::shared_ptr<std::stringstream> result(new std::stringstream);
|
||||
|
||||
char outBuf[3] = { 0 };
|
||||
uint32_t temp = 0;
|
||||
|
||||
utility::string_t::const_iterator cursor = encoded.begin();
|
||||
while ( cursor < encoded.end() )
|
||||
{
|
||||
for ( size_t quantumPosition = 0; quantumPosition < 4; quantumPosition++ )
|
||||
{
|
||||
temp <<= 6;
|
||||
if ( *cursor >= 0x41 && *cursor <= 0x5A )
|
||||
{
|
||||
temp |= *cursor - 0x41;
|
||||
}
|
||||
else if ( *cursor >= 0x61 && *cursor <= 0x7A )
|
||||
{
|
||||
temp |= *cursor - 0x47;
|
||||
}
|
||||
else if ( *cursor >= 0x30 && *cursor <= 0x39 )
|
||||
{
|
||||
temp |= *cursor + 0x04;
|
||||
}
|
||||
else if ( *cursor == 0x2B )
|
||||
{
|
||||
temp |= 0x3E; //change to 0x2D for URL alphabet
|
||||
}
|
||||
else if ( *cursor == 0x2F )
|
||||
{
|
||||
temp |= 0x3F; //change to 0x5F for URL alphabet
|
||||
}
|
||||
else if ( *cursor == Base64PadChar ) //pad
|
||||
{
|
||||
switch ( encoded.end() - cursor )
|
||||
{
|
||||
case 1: //One pad character
|
||||
outBuf[0] = (temp >> 16) & 0x000000FF;
|
||||
outBuf[1] = (temp >> 8) & 0x000000FF;
|
||||
result->write( outBuf, 2 );
|
||||
return result;
|
||||
case 2: //Two pad characters
|
||||
outBuf[0] = (temp >> 10) & 0x000000FF;
|
||||
result->write( outBuf, 1 );
|
||||
return result;
|
||||
default:
|
||||
throw web::json::json_exception( U( "Invalid Padding in Base 64!" ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw web::json::json_exception( U( "Non-Valid Character in Base 64!" ) );
|
||||
}
|
||||
++cursor;
|
||||
}
|
||||
|
||||
outBuf[0] = (temp >> 16) & 0x000000FF;
|
||||
outBuf[1] = (temp >> 8) & 0x000000FF;
|
||||
outBuf[2] = (temp) & 0x000000FF;
|
||||
result->write( outBuf, 3 );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int64_t ModelBase::int64_tFromJson(web::json::value& val)
|
||||
{
|
||||
return val.as_number().to_int64();
|
||||
}
|
||||
int32_t ModelBase::int32_tFromJson(web::json::value& val)
|
||||
{
|
||||
return val.as_integer();
|
||||
}
|
||||
utility::string_t ModelBase::stringFromJson(web::json::value& val)
|
||||
{
|
||||
return val.is_string() ? val.as_string() : U("");
|
||||
}
|
||||
|
||||
utility::datetime ModelBase::dateFromJson(web::json::value& val)
|
||||
{
|
||||
return utility::datetime::from_string(val.as_string(), utility::datetime::ISO_8601);
|
||||
}
|
||||
bool ModelBase::boolFromJson(web::json::value& val)
|
||||
{
|
||||
return val.as_bool();
|
||||
}
|
||||
double ModelBase::doubleFromJson(web::json::value& val)
|
||||
{
|
||||
return val.as_double();
|
||||
}
|
||||
|
||||
int64_t ModelBase::int64_tFromHttpContent(std::shared_ptr<HttpContent> val)
|
||||
{
|
||||
utility::string_t str = ModelBase::stringFromHttpContent(val);
|
||||
|
||||
utility::stringstream_t ss(str);
|
||||
int64_t result = 0;
|
||||
ss >> result;
|
||||
return result;
|
||||
}
|
||||
int32_t ModelBase::int32_tFromHttpContent(std::shared_ptr<HttpContent> val)
|
||||
{
|
||||
utility::string_t str = ModelBase::stringFromHttpContent(val);
|
||||
|
||||
utility::stringstream_t ss(str);
|
||||
int32_t result = 0;
|
||||
ss >> result;
|
||||
return result;
|
||||
}
|
||||
utility::string_t ModelBase::stringFromHttpContent(std::shared_ptr<HttpContent> val)
|
||||
{
|
||||
std::shared_ptr<std::istream> data = val->getData();
|
||||
data->seekg( 0, data->beg );
|
||||
|
||||
std::string str((std::istreambuf_iterator<char>(*data.get())),
|
||||
std::istreambuf_iterator<char>());
|
||||
|
||||
return utility::conversions::to_utf16string(str);
|
||||
}
|
||||
utility::datetime ModelBase::dateFromHttpContent(std::shared_ptr<HttpContent> val)
|
||||
{
|
||||
utility::string_t str = ModelBase::stringFromHttpContent(val);
|
||||
return utility::datetime::from_string(str, utility::datetime::ISO_8601);
|
||||
}
|
||||
|
||||
bool ModelBase::boolFromHttpContent(std::shared_ptr<HttpContent> val)
|
||||
{
|
||||
utility::string_t str = ModelBase::stringFromHttpContent(val);
|
||||
|
||||
utility::stringstream_t ss(str);
|
||||
bool result = false;
|
||||
ss >> result;
|
||||
return result;
|
||||
}
|
||||
double ModelBase::doubleFromHttpContent(std::shared_ptr<HttpContent> val)
|
||||
{
|
||||
utility::string_t str = ModelBase::stringFromHttpContent(val);
|
||||
|
||||
utility::stringstream_t ss(str);
|
||||
double result = 0.0;
|
||||
ss >> result;
|
||||
return result;
|
||||
}
|
||||
|
||||
{{#modelNamespaceDeclarations}}
|
||||
}
|
||||
{{/modelNamespaceDeclarations}}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* MultipartFormData.h
|
||||
*
|
||||
* This class represents a container for building a application/x-multipart-formdata requests.
|
||||
*/
|
||||
|
||||
#ifndef MultipartFormData_H_
|
||||
#define MultipartFormData_H_
|
||||
|
||||
{{{defaultInclude}}}
|
||||
#include "IHttpBody.h"
|
||||
#include "HttpContent.h"
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
#include <cpprest/details/basic_types.h>
|
||||
|
||||
|
||||
{{#modelNamespaceDeclarations}}
|
||||
namespace {{this}} {
|
||||
{{/modelNamespaceDeclarations}}
|
||||
|
||||
class {{declspec}} MultipartFormData
|
||||
: public IHttpBody
|
||||
{
|
||||
public:
|
||||
MultipartFormData();
|
||||
MultipartFormData(const utility::string_t& boundary);
|
||||
virtual ~MultipartFormData();
|
||||
|
||||
virtual void add( std::shared_ptr<HttpContent> content );
|
||||
virtual utility::string_t getBoundary();
|
||||
virtual std::shared_ptr<HttpContent> getContent(const utility::string_t& name) const;
|
||||
virtual bool hasContent(const utility::string_t& name) const;
|
||||
virtual void writeTo( std::ostream& target );
|
||||
|
||||
protected:
|
||||
std::vector<std::shared_ptr<HttpContent>> m_Contents;
|
||||
utility::string_t m_Boundary;
|
||||
std::map<utility::string_t, std::shared_ptr<HttpContent>> m_ContentLookup;
|
||||
};
|
||||
|
||||
{{#modelNamespaceDeclarations}}
|
||||
}
|
||||
{{/modelNamespaceDeclarations}}
|
||||
|
||||
#endif /* MultipartFormData_H_ */
|
||||
@@ -0,0 +1,99 @@
|
||||
#include "MultipartFormData.h"
|
||||
#include "ModelBase.h"
|
||||
|
||||
#include <boost/uuid/random_generator.hpp>
|
||||
#include <boost/uuid/uuid_io.hpp>
|
||||
|
||||
{{#modelNamespaceDeclarations}}
|
||||
namespace {{this}} {
|
||||
{{/modelNamespaceDeclarations}}
|
||||
|
||||
MultipartFormData::MultipartFormData()
|
||||
{
|
||||
utility::stringstream_t uuidString;
|
||||
uuidString << boost::uuids::random_generator()();
|
||||
m_Boundary = uuidString.str();
|
||||
}
|
||||
|
||||
MultipartFormData::MultipartFormData(const utility::string_t& boundary)
|
||||
: m_Boundary(boundary)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
MultipartFormData::~MultipartFormData()
|
||||
{
|
||||
}
|
||||
|
||||
utility::string_t MultipartFormData::getBoundary()
|
||||
{
|
||||
return m_Boundary;
|
||||
}
|
||||
|
||||
void MultipartFormData::add( std::shared_ptr<HttpContent> content )
|
||||
{
|
||||
m_Contents.push_back( content );
|
||||
m_ContentLookup[content->getName()] = content;
|
||||
}
|
||||
|
||||
bool MultipartFormData::hasContent(const utility::string_t& name) const
|
||||
{
|
||||
return m_ContentLookup.find(name) != m_ContentLookup.end();
|
||||
}
|
||||
|
||||
std::shared_ptr<HttpContent> MultipartFormData::getContent(const utility::string_t& name) const
|
||||
{
|
||||
auto result = m_ContentLookup.find(name);
|
||||
if(result == m_ContentLookup.end())
|
||||
{
|
||||
return std::shared_ptr<HttpContent>(nullptr);
|
||||
}
|
||||
return result->second;
|
||||
}
|
||||
|
||||
void MultipartFormData::writeTo( std::ostream& target )
|
||||
{
|
||||
for ( size_t i = 0; i < m_Contents.size(); i++ )
|
||||
{
|
||||
std::shared_ptr<HttpContent> content = m_Contents[i];
|
||||
|
||||
// boundary
|
||||
target << "\r\n" << "--" << utility::conversions::to_utf8string( m_Boundary ) << "\r\n";
|
||||
|
||||
// headers
|
||||
target << "Content-Disposition: " << utility::conversions::to_utf8string( content->getContentDisposition() );
|
||||
if ( content->getName().size() > 0 )
|
||||
{
|
||||
target << "; name=\"" << utility::conversions::to_utf8string( content->getName() ) << "\"";
|
||||
}
|
||||
if ( content->getFileName().size() > 0 )
|
||||
{
|
||||
target << "; filename=\"" << utility::conversions::to_utf8string( content->getFileName() ) << "\"";
|
||||
}
|
||||
target << "\r\n";
|
||||
|
||||
if ( content->getContentType().size() > 0 )
|
||||
{
|
||||
target << "Content-Type: " << utility::conversions::to_utf8string( content->getContentType() ) << "\r\n";
|
||||
}
|
||||
|
||||
target << "\r\n";
|
||||
|
||||
// body
|
||||
std::shared_ptr<std::istream> data = content->getData();
|
||||
|
||||
data->seekg( 0, data->end );
|
||||
std::vector<char> dataBytes( data->tellg() );
|
||||
|
||||
data->seekg( 0, data->beg );
|
||||
data->read( &dataBytes[0], dataBytes.size() );
|
||||
|
||||
std::copy( dataBytes.begin(), dataBytes.end(), std::ostreambuf_iterator<char>( target ) );
|
||||
}
|
||||
|
||||
target << "\r\n--" << utility::conversions::to_utf8string( m_Boundary ) << "--\r\n";
|
||||
}
|
||||
|
||||
{{#modelNamespaceDeclarations}}
|
||||
}
|
||||
{{/modelNamespaceDeclarations}}
|
||||
Reference in New Issue
Block a user