forked from loafle/openapi-generator-original
add cpprest and samples
This commit is contained in:
@@ -0,0 +1,382 @@
|
||||
package io.swagger.codegen.languages;
|
||||
|
||||
import io.swagger.codegen.*;
|
||||
import io.swagger.codegen.examples.ExampleGenerator;
|
||||
import io.swagger.models.Model;
|
||||
import io.swagger.models.Operation;
|
||||
import io.swagger.models.Response;
|
||||
import io.swagger.models.Swagger;
|
||||
import io.swagger.models.properties.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.File;
|
||||
|
||||
public class CppRestClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
|
||||
public static final String DECLSPEC = "declspec";
|
||||
public static final String DEFAULT_INCLUDE = "defaultInclude";
|
||||
|
||||
protected String packageVersion = "1.0.0";
|
||||
protected String declspec = "";
|
||||
protected String defaultInclude = "";
|
||||
|
||||
/**
|
||||
* Configures the type of generator.
|
||||
*
|
||||
* @return the CodegenType for this generator
|
||||
* @see io.swagger.codegen.CodegenType
|
||||
*/
|
||||
public CodegenType getTag() {
|
||||
return CodegenType.CLIENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures a friendly name for the generator. This will be used by the
|
||||
* generator to select the library with the -l flag.
|
||||
*
|
||||
* @return the friendly name for the generator
|
||||
*/
|
||||
public String getName() {
|
||||
return "cpprest";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns human-friendly help for the generator. Provide the consumer with
|
||||
* help tips, parameters here
|
||||
*
|
||||
* @return A string value for the help message
|
||||
*/
|
||||
public String getHelp() {
|
||||
return "Generates a C++ API client with C++ REST SDK (https://github.com/Microsoft/cpprestsdk).";
|
||||
}
|
||||
|
||||
public CppRestClientCodegen() {
|
||||
super();
|
||||
|
||||
apiPackage = "io.swagger.client.api";
|
||||
modelPackage = "io.swagger.client.model";
|
||||
|
||||
modelTemplateFiles.put("model-header.mustache", ".h");
|
||||
modelTemplateFiles.put("model-source.mustache", ".cpp");
|
||||
|
||||
apiTemplateFiles.put("api-header.mustache", ".h");
|
||||
apiTemplateFiles.put("api-source.mustache", ".cpp");
|
||||
|
||||
templateDir = "cpprest";
|
||||
|
||||
cliOptions.clear();
|
||||
|
||||
// CLI options
|
||||
addOption(CodegenConstants.MODEL_PACKAGE, "C++ namespace for models (convention: name.space.model).",
|
||||
this.modelPackage);
|
||||
addOption(CodegenConstants.API_PACKAGE, "C++ namespace for apis (convention: name.space.api).",
|
||||
this.apiPackage);
|
||||
addOption(CodegenConstants.PACKAGE_VERSION, "C++ package version.", this.packageVersion);
|
||||
addOption(DECLSPEC, "C++ preprocessor to place before the class name for handling dllexport/dllimport.",
|
||||
this.declspec);
|
||||
addOption(DEFAULT_INCLUDE,
|
||||
"The default include statement that should be placed in all headers for including things like the declspec (convention: #include \"Commons.h\" ",
|
||||
this.defaultInclude);
|
||||
|
||||
reservedWords = new HashSet<String>();
|
||||
|
||||
//supportingFiles.add(new SupportingFile("modelbase-header.mustache", "", "ModelBase.h"));
|
||||
//supportingFiles.add(new SupportingFile("modelbase-source.mustache", "", "ModelBase.cpp"));
|
||||
//supportingFiles.add(new SupportingFile("apibase-header.mustache", "", "ApiBase.h"));
|
||||
//supportingFiles.add(new SupportingFile("apibase-source.mustache", "", "ApiBase.cpp"));
|
||||
supportingFiles.add(new SupportingFile("apiclient-header.mustache", "", "ApiClient.h"));
|
||||
supportingFiles.add(new SupportingFile("apiclient-source.mustache", "", "ApiClient.cpp"));
|
||||
supportingFiles.add(new SupportingFile("apiconfiguration-header.mustache", "", "ApiConfiguration.h"));
|
||||
supportingFiles.add(new SupportingFile("apiconfiguration-source.mustache", "", "ApiConfiguration.cpp"));
|
||||
supportingFiles.add(new SupportingFile("apiexception-header.mustache", "", "ApiException.h"));
|
||||
supportingFiles.add(new SupportingFile("apiexception-source.mustache", "", "ApiException.cpp"));
|
||||
supportingFiles.add(new SupportingFile("ihttpbody-header.mustache", "", "IHttpBody.h"));
|
||||
supportingFiles.add(new SupportingFile("jsonbody-header.mustache", "", "JsonBody.h"));
|
||||
supportingFiles.add(new SupportingFile("jsonbody-source.mustache", "", "JsonBody.cpp"));
|
||||
supportingFiles.add(new SupportingFile("httpcontent-header.mustache", "", "HttpContent.h"));
|
||||
supportingFiles.add(new SupportingFile("httpcontent-source.mustache", "", "HttpContent.cpp"));
|
||||
supportingFiles.add(new SupportingFile("multipart-header.mustache", "", "MultipartFormData.h"));
|
||||
supportingFiles.add(new SupportingFile("multipart-source.mustache", "", "MultipartFormData.cpp"));
|
||||
supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore"));
|
||||
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
|
||||
|
||||
languageSpecificPrimitives = new HashSet<String>(
|
||||
Arrays.asList("int", "char", "bool", "long", "float", "double", "int32_t", "int64_t"));
|
||||
|
||||
typeMapping = new HashMap<String, String>();
|
||||
typeMapping.put("date", "utility::datetime");
|
||||
typeMapping.put("DateTime", "utility::datetime");
|
||||
typeMapping.put("string", "utility::string_t");
|
||||
typeMapping.put("integer", "int32_t");
|
||||
typeMapping.put("long", "int64_t");
|
||||
typeMapping.put("boolean", "bool");
|
||||
typeMapping.put("array", "std::vector");
|
||||
typeMapping.put("map", "std::map");
|
||||
typeMapping.put("file", "HttpContent");
|
||||
typeMapping.put("object", "Object");
|
||||
typeMapping.put("binary", "std::string");
|
||||
|
||||
super.importMapping = new HashMap<String, String>();
|
||||
importMapping.put("std::vector", "#include <vector>");
|
||||
importMapping.put("std::map", "#include <map>");
|
||||
importMapping.put("std::string", "#include <string>");
|
||||
importMapping.put("HttpContent", "#include \"HttpContent.h\"");
|
||||
importMapping.put("Object", "#include \"Object.h\"");
|
||||
importMapping.put("utility::string_t", "#include <cpprest/details/basic_types.h>");
|
||||
importMapping.put("utility::datetime", "#include <cpprest/details/basic_types.h>");
|
||||
}
|
||||
|
||||
protected void addOption(String key, String description, String defaultValue) {
|
||||
CliOption option = new CliOption(key, description);
|
||||
if (defaultValue != null)
|
||||
option.defaultValue(defaultValue);
|
||||
cliOptions.add(option);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processOpts() {
|
||||
super.processOpts();
|
||||
|
||||
if (additionalProperties.containsKey(DECLSPEC)) {
|
||||
declspec = additionalProperties.get(DECLSPEC).toString();
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(DEFAULT_INCLUDE)) {
|
||||
defaultInclude = additionalProperties.get(DEFAULT_INCLUDE).toString();
|
||||
}
|
||||
|
||||
additionalProperties.put("modelNamespaceDeclarations", modelPackage.split("\\."));
|
||||
additionalProperties.put("modelNamespace", modelPackage.replaceAll("\\.", "::"));
|
||||
additionalProperties.put("apiNamespaceDeclarations", apiPackage.split("\\."));
|
||||
additionalProperties.put("apiNamespace", apiPackage.replaceAll("\\.", "::"));
|
||||
additionalProperties.put("declspec", declspec);
|
||||
additionalProperties.put("defaultInclude", defaultInclude);
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes a reserved word as defined in the `reservedWords` array. Handle
|
||||
* escaping those terms here. This logic is only called if a variable
|
||||
* matches the reseved words
|
||||
*
|
||||
* @return the escaped term
|
||||
*/
|
||||
@Override
|
||||
public String escapeReservedWord(String name) {
|
||||
return "_" + name; // add an underscore to the name
|
||||
}
|
||||
|
||||
/**
|
||||
* Location to write model files. You can use the modelPackage() as defined
|
||||
* when the class is instantiated
|
||||
*/
|
||||
public String modelFileFolder() {
|
||||
return outputFolder + "/model";
|
||||
}
|
||||
|
||||
/**
|
||||
* Location to write api files. You can use the apiPackage() as defined when
|
||||
* the class is instantiated
|
||||
*/
|
||||
@Override
|
||||
public String apiFileFolder() {
|
||||
return outputFolder + "/api";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toModelImport(String name) {
|
||||
if (importMapping.containsKey(name)) {
|
||||
return importMapping.get(name);
|
||||
} else {
|
||||
return "#include \"" + name + ".h\"";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodegenModel fromModel(String name, Model model, Map<String, Model> allDefinitions) {
|
||||
CodegenModel codegenModel = super.fromModel(name, model, allDefinitions);
|
||||
|
||||
Set<String> oldImports = codegenModel.imports;
|
||||
codegenModel.imports = new HashSet<String>();
|
||||
for (String imp : oldImports) {
|
||||
String newImp = toModelImport(imp);
|
||||
if (!newImp.isEmpty()) {
|
||||
codegenModel.imports.add(newImp);
|
||||
}
|
||||
}
|
||||
|
||||
return codegenModel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodegenOperation fromOperation(String path, String httpMethod, Operation operation,
|
||||
Map<String, Model> definitions, Swagger swagger) {
|
||||
CodegenOperation op = super.fromOperation(path, httpMethod, operation, definitions, swagger);
|
||||
|
||||
if (operation.getResponses() != null && !operation.getResponses().isEmpty()) {
|
||||
Response methodResponse = findMethodResponse(operation.getResponses());
|
||||
|
||||
if (methodResponse != null) {
|
||||
if (methodResponse.getSchema() != null) {
|
||||
CodegenProperty cm = fromProperty("response", methodResponse.getSchema());
|
||||
op.vendorExtensions.put("x-codegen-response", cm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return op;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessModelProperty(CodegenModel model, CodegenProperty property) {
|
||||
if (isFileProperty(property)) {
|
||||
property.vendorExtensions.put("x-codegen-file", true);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isFileProperty(CodegenProperty property) {
|
||||
return property.baseType.equals("HttpContent");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toModelFilename(String name) {
|
||||
return initialCaps(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toApiFilename(String name) {
|
||||
return initialCaps(name) + "Api";
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional - type declaration. This is a String which is used by the
|
||||
* templates to instantiate your types. There is typically special handling
|
||||
* for different property types
|
||||
*
|
||||
* @return a string value used as the `dataType` field for model templates,
|
||||
* `returnType` for api templates
|
||||
*/
|
||||
@Override
|
||||
public String getTypeDeclaration(Property p) {
|
||||
String swaggerType = getSwaggerType(p);
|
||||
|
||||
if (p instanceof ArrayProperty) {
|
||||
ArrayProperty ap = (ArrayProperty) p;
|
||||
Property inner = ap.getItems();
|
||||
return getSwaggerType(p) + "<" + getTypeDeclaration(inner) + ">";
|
||||
}
|
||||
if (p instanceof MapProperty) {
|
||||
MapProperty mp = (MapProperty) p;
|
||||
Property inner = mp.getAdditionalProperties();
|
||||
return getSwaggerType(p) + "<utility::string_t, " + getTypeDeclaration(inner) + ">";
|
||||
}
|
||||
if (p instanceof StringProperty || p instanceof DateProperty || p instanceof DateTimeProperty
|
||||
|| languageSpecificPrimitives.contains(swaggerType)) {
|
||||
return toModelName(swaggerType);
|
||||
}
|
||||
|
||||
return "std::shared_ptr<" + swaggerType + ">";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toDefaultValue(Property p) {
|
||||
if (p instanceof StringProperty) {
|
||||
return "U(\"\")";
|
||||
} else if (p instanceof BooleanProperty) {
|
||||
return "false";
|
||||
} else if (p instanceof DateProperty) {
|
||||
return "utility::datetime()";
|
||||
} else if (p instanceof DateTimeProperty) {
|
||||
return "utility::datetime()";
|
||||
} else if (p instanceof DoubleProperty) {
|
||||
return "0.0";
|
||||
} else if (p instanceof FloatProperty) {
|
||||
return "0.0f";
|
||||
} else if (p instanceof IntegerProperty) {
|
||||
return "0";
|
||||
} else if (p instanceof LongProperty) {
|
||||
return "0L";
|
||||
} else if (p instanceof DecimalProperty) {
|
||||
return "0.0";
|
||||
} else if (p instanceof MapProperty) {
|
||||
MapProperty ap = (MapProperty) p;
|
||||
String inner = getSwaggerType(ap.getAdditionalProperties());
|
||||
return "std::map<utility::string_t, " + inner + ">()";
|
||||
} else if (p instanceof ArrayProperty) {
|
||||
ArrayProperty ap = (ArrayProperty) p;
|
||||
String inner = getSwaggerType(ap.getItems());
|
||||
if (!languageSpecificPrimitives.contains(inner)) {
|
||||
inner = "std::shared_ptr<" + inner + ">";
|
||||
}
|
||||
return "std::vector<" + inner + ">()";
|
||||
} else if (p instanceof RefProperty) {
|
||||
RefProperty rp = (RefProperty) p;
|
||||
return "new " + toModelName(rp.getSimpleRef()) + "()";
|
||||
}
|
||||
return "nullptr";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessParameter(CodegenParameter parameter) {
|
||||
super.postProcessParameter(parameter);
|
||||
|
||||
boolean isPrimitiveType = parameter.isPrimitiveType == Boolean.TRUE;
|
||||
boolean isListContainer = parameter.isListContainer == Boolean.TRUE;
|
||||
boolean isString = parameter.isString == Boolean.TRUE;
|
||||
|
||||
if (!isPrimitiveType && !isListContainer && !isString && !parameter.dataType.startsWith("std::shared_ptr")) {
|
||||
parameter.dataType = "std::shared_ptr<" + parameter.dataType + ">";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional - swagger type conversion. This is used to map swagger types in
|
||||
* a `Property` into either language specific types via `typeMapping` or
|
||||
* into complex models if there is not a mapping.
|
||||
*
|
||||
* @return a string value of the type or complex model for this property
|
||||
* @see io.swagger.models.properties.Property
|
||||
*/
|
||||
@Override
|
||||
public String getSwaggerType(Property p) {
|
||||
String swaggerType = super.getSwaggerType(p);
|
||||
String type = null;
|
||||
if (typeMapping.containsKey(swaggerType)) {
|
||||
type = typeMapping.get(swaggerType);
|
||||
if (languageSpecificPrimitives.contains(type))
|
||||
return toModelName(type);
|
||||
} else
|
||||
type = swaggerType;
|
||||
return toModelName(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toModelName(String type) {
|
||||
if (typeMapping.keySet().contains(type) || typeMapping.values().contains(type)
|
||||
|| importMapping.values().contains(type) || defaultIncludes.contains(type)
|
||||
|| languageSpecificPrimitives.contains(type)) {
|
||||
return type;
|
||||
} else {
|
||||
return Character.toUpperCase(type.charAt(0)) + type.substring(1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toVarName(String name) {
|
||||
if (typeMapping.keySet().contains(name) || typeMapping.values().contains(name)
|
||||
|| importMapping.values().contains(name) || defaultIncludes.contains(name)
|
||||
|| languageSpecificPrimitives.contains(name)) {
|
||||
return name;
|
||||
}
|
||||
|
||||
if (name.length() > 1) {
|
||||
return Character.toUpperCase(name.charAt(0)) + name.substring(1);
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toApiName(String type) {
|
||||
return Character.toUpperCase(type.charAt(0)) + type.substring(1) + "Api";
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ io.swagger.codegen.languages.AndroidClientCodegen
|
||||
io.swagger.codegen.languages.AspNet5ServerCodegen
|
||||
io.swagger.codegen.languages.AsyncScalaClientCodegen
|
||||
io.swagger.codegen.languages.CSharpClientCodegen
|
||||
io.swagger.codegen.languages.CppRestClientCodegen
|
||||
io.swagger.codegen.languages.DartClientCodegen
|
||||
io.swagger.codegen.languages.FlashClientCodegen
|
||||
io.swagger.codegen.languages.FlaskConnexionCodegen
|
||||
|
||||
@@ -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