#@ template language="C#" inherits="Generators.BaseGenerator" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#+
protected void GenerateAWSQueryCompatibleBlock()
{
#>
var errorCode = errorResponse.Code;
var errorType = errorResponse.Type;
var queryHeaderKey = Amazon.Util.HeaderKeys.XAmzQueryError;
if (context.ResponseData.IsHeaderPresent(queryHeaderKey))
{
var queryError = context.ResponseData.GetHeaderValue(queryHeaderKey);
if (!string.IsNullOrEmpty(queryError) && queryError.Contains(";"))
{
var queryErrorParts = queryError.Split(';');
if (queryErrorParts.Length == 2)
{
errorCode = queryErrorParts[0];
var errorTypeString = queryErrorParts[1];
if (Enum.IsDefined(typeof(ErrorType), errorTypeString))
{
errorType = (ErrorType) Enum.Parse(typeof(ErrorType), errorTypeString);
}
}
}
}
<#+
}
#>
<#+
protected void AddCommonUsingStatements()
{
#>
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Net;
using System.Text;
using System.Xml.Serialization;
using <#=this.Config.Namespace #>.Model;
using Amazon.Runtime;
using Amazon.Runtime.Internal;
using Amazon.Runtime.Internal.Transform;
using Amazon.Runtime.Internal.Util;
<#+
}
// Set to true when the service model specifies a shape that should be wrapped in a response. ElastiCache CreateCacheCluster is an example of this.
public bool IsWrapped { get; set; }
// set to the name of the member in the base Result class for operations where response data is moved from the result
// class into a structure member. If not set, the response members are assumed to be in the result base class itself.
public string WrappedResultMember { get; set; }
// The operation to unmarshall a response from
public Operation Operation { get; set; }
Shape _structure;
// Set if we are generating what is effectively a void response from an operation - no result class or other
// members were generated
public bool HasSuppressedResult { get; set; }
public string BaseException { get; set; }
// The shape of the response
public Shape Structure
{
get
{
if(this.Operation != null)
{
if(this.Operation.IsResponseWrapped)
return this.Operation.ResponseStructure.Members[0].Shape;
else
return this.Operation.ResponseStructure;
}
return this._structure;
}
set { this._structure = value; }
}
public string UnmarshallerBaseName
{
get
{
if(this.Operation != null)
return this.Operation.Name;
return this.Structure.Name;
}
}
protected void AddResponseSingletonMethod()
{
#>
private static <#=this.UnmarshallerBaseName #>ResponseUnmarshaller _instance = new <#=this.UnmarshallerBaseName #>ResponseUnmarshaller();
internal static <#=this.UnmarshallerBaseName #>ResponseUnmarshaller GetInstance()
{
return _instance;
}
///
/// Gets the singleton.
///
public static <#=this.UnmarshallerBaseName #>ResponseUnmarshaller Instance
{
get
{
return _instance;
}
}
<#+
}
protected void AddStructureSingletonMethod()
{
#>
private static <#=this.UnmarshallerBaseName #>Unmarshaller _instance = new <#=this.UnmarshallerBaseName #>Unmarshaller();
///
/// Gets the singleton.
///
public static <#=this.UnmarshallerBaseName #>Unmarshaller Instance
{
get
{
return _instance;
}
}
<#+
}
// Only applicable for rest-json and rest-xml
// Generates code to parse present header members into the response object
protected void UnmarshallHeaders()
{
if( this.Operation.ResponseHeaderMembers.Count() > 0 )
{
foreach (var member in this.Operation.ResponseHeaderMembers)
{
if (member.Shape.IsMap)
{
#>
//Map of headers with prefix "<#=member.MarshallLocationName#>".
<#+
// Dictionary
if (member.ModelShape.ValueShape.IsString)
{
#>
var headersFor<#=member.PropertyName#> = new Dictionary();
foreach (var name<#=member.PropertyName#> in context.ResponseData.GetHeaderNames())
{
var keyToUse = name<#=member.PropertyName#>;
if("<#=member.MarshallLocationName#>".Length > 0 && keyToUse.StartsWith("<#=member.MarshallLocationName#>")) {
keyToUse = keyToUse.Substring("<#=member.MarshallLocationName#>".Length);
}
if (context.ResponseData.IsHeaderPresent($"<#=member.MarshallLocationName#>{name<#=member.PropertyName#>}"))
{
headersFor<#=member.PropertyName#>.Add(
keyToUse,
context.ResponseData.GetHeaderValue($"<#=member.MarshallLocationName#>{name<#=member.PropertyName#>}")
);
}
}
if(headersFor<#=member.PropertyName#>.Count > 0)
response.<#=member.PropertyName#> = headersFor<#=member.PropertyName#>;
<#+
}
// Dictionary>
else if (member.ModelShape.ValueShape?.ListShape?.IsString == true)
{
#>
var headersFor<#=member.PropertyName#> = new Dictionary>();
foreach (var name<#=member.PropertyName#> in context.ResponseData.GetHeaderNames())
{
var keyToUse = name<#=member.PropertyName#>;
if("<#=member.MarshallLocationName#>".Length > 0 && keyToUse.StartsWith("<#=member.MarshallLocationName#>")) {
keyToUse = keyToUse.Substring("<#=member.MarshallLocationName#>".Length);
}
if (context.ResponseData.IsHeaderPresent($"<#=member.MarshallLocationName#>{name<#=member.PropertyName#>}"))
{
headersFor<#=member.PropertyName#>.Add(
keyToUse,
context.ResponseData.GetHeaderValue($"{nameResponseHeaders}").Split(',').ToList()
);
}
}
if(headersFor<#=member.PropertyName#>.Count > 0)
response.<#=member.PropertyName#> = headersFor<#=member.PropertyName#>;
<#+
}
else
{
throw new InvalidDataException("[{member.ModelName}]: Invalid header map shapes. Header Maps must have a value of either a string or a list of strings: {member.ModelShape.ValueShape.Name}");
}
#>
<#+
continue;
}
#>
if (context.ResponseData.IsHeaderPresent("<#=member.MarshallLocationName#>"))
<#+
if (member.Shape.IsString)
{
if (member.IsJsonValue)
{
#>
{
var headerBytes = Convert.FromBase64String(context.ResponseData.GetHeaderValue("<#=member.MarshallLocationName#>"));
response.<#=member.PropertyName#> = Encoding.UTF8.GetString(headerBytes, 0, headerBytes.Length);
}
<#+
}
else
{
#>
response.<#=member.PropertyName#> = context.ResponseData.GetHeaderValue("<#=member.MarshallLocationName#>");
<#+
}
}
else if (member.Shape.IsMap)
{
#>
//Map of headers with prefix "<#=member.MarshallLocationName#>".
<#+
// Dictionary
if (member.ModelShape.ValueShape.IsString)
{
#>
var headersFor<#=member.PropertyName#> = new Dictionary();
foreach (var name<#=member.PropertyName#> in context.ResponseData.GetHeaderNames())
{
var keyToUse = name<#=member.PropertyName#>;
if("<#=member.MarshallLocationName#>".Length > 0 && keyToUse.StartsWith("<#=member.MarshallLocationName#>")) {
keyToUse = keyToUse.Substring("<#=member.MarshallLocationName#>".Length);
}
if (context.ResponseData.IsHeaderPresent($"<#=member.MarshallLocationName#>{name<#=member.PropertyName#>}"))
{
headersFor<#=member.PropertyName#>.Add(
keyToUse,
context.ResponseData.GetHeaderValue($"<#=member.MarshallLocationName#>{name<#=member.PropertyName#>}")
);
}
}
if(headersFor<#=member.PropertyName#>.Count > 0)
response.<#=member.PropertyName#> = headersFor<#=member.PropertyName#>;
<#+
}
// Dictionary>
else if (member.ModelShape.ValueShape?.ListShape?.IsString == true)
{
#>
var headersFor<#=member.PropertyName#> = new Dictionary>();
foreach (var name<#=member.PropertyName#> in context.ResponseData.GetHeaderNames())
{
var keyToUse = name<#=member.PropertyName#>;
if("<#=member.MarshallLocationName#>".Length > 0 && keyToUse.StartsWith("<#=member.MarshallLocationName#>")) {
keyToUse = keyToUse.Substring("<#=member.MarshallLocationName#>".Length);
}
if (context.ResponseData.IsHeaderPresent($"<#=member.MarshallLocationName#>{name<#=member.PropertyName#>}"))
{
headersFor<#=member.PropertyName#>.Add(
keyToUse,
context.ResponseData.GetHeaderValue($"{nameResponseHeaders}").Split(',').ToList()
);
}
}
if(headersFor<#=member.PropertyName#>.Count > 0)
response.<#=member.PropertyName#> = headersFor<#=member.PropertyName#>;
<#+
}
else
{
throw new InvalidDataException("[{member.ModelName}]: Invalid header map shapes. Header Maps must have a value of either a string or a list of strings: {member.ModelShape.ValueShape.Name}");
}
#>
<#+
}
else if (member.Shape.IsInt)
{
#>
response.<#=member.PropertyName#> = int.Parse(context.ResponseData.GetHeaderValue("<#=member.MarshallLocationName#>"), CultureInfo.InvariantCulture);
<#+
}
else if (member.Shape.IsLong)
{
#>
response.<#=member.PropertyName#> = long.Parse(context.ResponseData.GetHeaderValue("<#=member.MarshallLocationName#>"), CultureInfo.InvariantCulture);
<#+
}
else if (member.Shape.IsDateTime)
{
if( member.TimestampFormat == TimestampFormat.ISO8601 ||
member.TimestampFormat == TimestampFormat.RFC822)
{
#>
response.<#=member.PropertyName#> = DateTime.Parse(context.ResponseData.GetHeaderValue("<#=member.MarshallLocationName#>"), CultureInfo.InvariantCulture);
<#+
}
else if(member.TimestampFormat == TimestampFormat.UnixTimestamp)
{
#>
response.<#=member.PropertyName#> = Amazon.Util.AWSSDKUtils.ConvertFromUnixEpochSeconds(int.Parse(context.ResponseData.GetHeaderValue("<#=member.MarshallLocationName#>"), CultureInfo.InvariantCulture));
<#+
}
else
{
throw new Exception(string.Format("Unable to determine the TimestampFormat for member {0}, type {1}.", member.Shape.Name, member.Shape.Type));
}
}
else
{
throw new Exception("Member " + member.Shape.Name + " cannot be handled because its type, " + member.Shape.Type + ", is not handled. Please update BaseResponseUnmarshaller.tt.");
}
}
}
}
// Generates code to set the status code of the response, example: 404, 200, etc
protected void ProcessStatusCode()
{
if( this.Operation.ResponseStatusCodeMember != null)
{
#>
response.<#=this.Operation.ResponseStatusCodeMember.PropertyName#> = (int)context.ResponseData.StatusCode;
<#+
}
}
#>