text:
#pragma once
#include <aws/resourcegroupstaggingapi/ResourceGroupsTaggingAPI_EXPORTS.h>
#include <aws/resourcegroupstaggingapi/ResourceGroupsTaggingAPIRequest.h>
#include <aws/core/utils/memory/stl/AWSString.h>
#include <aws/core/utils/memory/stl/AWSVector.h>
#include <aws/resourcegroupstaggingapi/model/TagFilter.h>
#include <utility>

namespace Aws
{
namespace ResourceGroupsTaggingAPI
{
namespace Model
{

  /**
   */
  class AWS_RESOURCEGROUPSTAGGINGAPI_API GetResourcesRequest : public ResourceGroupsTaggingAPIRequest
  {
  public:
    GetResourcesRequest();

    // Service request name is the Operation name which will send this request out,
    // each operation should has unique request name, so that we can get operation's name from this request.
    // Note: this is not true for response, multiple operations may have the same response name,
    // so we can not get operation's name from response.
    inline virtual const char* GetServiceRequestName() const override { return "GetResources"; }

    Aws::String SerializePayload() const override;

    Aws::Http::HeaderValueCollection GetRequestSpecificHeaders() const override;

    /**
     *
Specifies a PaginationToken response value from a previous
     * request to indicate that you want the next page of results. Leave this parameter
     * empty in your initial request.

     */
    inline const Aws::String& GetPaginationToken() const{ return m_paginationToken; }

    /**
     *
Specifies a PaginationToken response value from a previous
     * request to indicate that you want the next page of results. Leave this parameter
     * empty in your initial request.

     */
    inline bool PaginationTokenHasBeenSet() const { return m_paginationTokenHasBeenSet; }

    /**
     *
Specifies a PaginationToken response value from a previous
     * request to indicate that you want the next page of results. Leave this parameter
     * empty in your initial request.

     */
    inline void SetPaginationToken(const Aws::String& value) { m_paginationTokenHasBeenSet = true; m_paginationToken = value; }

    /**
     *
Specifies a PaginationToken response value from a previous
     * request to indicate that you want the next page of results. Leave this parameter
     * empty in your initial request.

     */
    inline void SetPaginationToken(Aws::String&& value) { m_paginationTokenHasBeenSet = true; m_paginationToken = std::move(value); }

    /**
     *
Specifies a PaginationToken response value from a previous
     * request to indicate that you want the next page of results. Leave this parameter
     * empty in your initial request.

     */
    inline void SetPaginationToken(const char* value) { m_paginationTokenHasBeenSet = true; m_paginationToken.assign(value); }

    /**
     *
Specifies a PaginationToken response value from a previous
     * request to indicate that you want the next page of results. Leave this parameter
     * empty in your initial request.

     */
    inline GetResourcesRequest& WithPaginationToken(const Aws::String& value) { SetPaginationToken(value); return *this;}

    /**
     *
Specifies a PaginationToken response value from a previous
     * request to indicate that you want the next page of results. Leave this parameter
     * empty in your initial request.

     */
    inline GetResourcesRequest& WithPaginationToken(Aws::String&& value) { SetPaginationToken(std::move(value)); return *this;}

    /**
     *
Specifies a PaginationToken response value from a previous
     * request to indicate that you want the next page of results. Leave this parameter
     * empty in your initial request.

     */
    inline GetResourcesRequest& WithPaginationToken(const char* value) { SetPaginationToken(value); return *this;}

    /**
     *
Specifies a list of TagFilters (keys and values) to restrict the output to
     * only those resources that have tags with the specified keys and, if included,
     * the specified values. Each TagFilter must contain a key with values
     * optional. A request can include up to 50 keys, and each key can include up to 20
     * values.

Note the following when deciding how to use TagFilters:

     *

If you don't specify a TagFilter, the response
     * includes all resources that are currently tagged or ever had a tag. Resources
     * that currently don't have tags are shown with an empty tag set, like this:
     * "Tags": [].

If you specify more than one filter
     * in a single request, the response returns only those resources that satisfy all
     * filters.

If you specify a filter that contains more than one
     * value for a key, the response returns resources that match any of the
     * specified values for that key.

If you don't specify a value
     * for a key, the response returns all resources that are tagged with that key,
     * with any or no value.

For example, for the following filters:
     * filter1= {keyA,{value1}},
     * filter2={keyB,{value2,value3,value4}}, filter3=
     * {keyC}:

 GetResources({filter1}) returns
     * resources tagged with key1=value1

     * GetResources({filter2}) returns resources tagged with
     * key2=value2 or key2=value3 or key2=value4
     *

 GetResources({filter3}) returns resources
     * tagged with any tag with the key key3, and with any or no value

     *

 GetResources({filter1,filter2,filter3}) returns
     * resources tagged with (key1=value1) and (key2=value2 or key2=value3 or
     * key2=value4) and (key3, any or no value)

     */
    inline const Aws::Vector<TagFilter>& GetTagFilters() const{ return m_tagFilters; }

    /**
     *
Specifies a list of TagFilters (keys and values) to restrict the output to
     * only those resources that have tags with the specified keys and, if included,
     * the specified values. Each TagFilter must contain a key with values
     * optional. A request can include up to 50 keys, and each key can include up to 20
     * values.

Note the following when deciding how to use TagFilters:

     *

If you don't specify a TagFilter, the response
     * includes all resources that are currently tagged or ever had a tag. Resources
     * that currently don't have tags are shown with an empty tag set, like this:
     * "Tags": [].

If you specify more than one filter
     * in a single request, the response returns only those resources that satisfy all
     * filters.

If you specify a filter that contains more than one
     * value for a key, the response returns resources that match any of the
     * specified values for that key.

If you don't specify a value
     * for a key, the response returns all resources that are tagged with that key,
     * with any or no value.

For example, for the following filters:
     * filter1= {keyA,{value1}},
     * filter2={keyB,{value2,value3,value4}}, filter3=
     * {keyC}:

 GetResources({filter1}) returns
     * resources tagged with key1=value1

     * GetResources({filter2}) returns resources tagged with
     * key2=value2 or key2=value3 or key2=value4
     *

 GetResources({filter3}) returns resources
     * tagged with any tag with the key key3, and with any or no value

     *

 GetResources({filter1,filter2,filter3}) returns
     * resources tagged with (key1=value1) and (key2=value2 or key2=value3 or
     * key2=value4) and (key3, any or no value)

     */
    inline bool TagFiltersHasBeenSet() const { return m_tagFiltersHasBeenSet; }

    /**
     *
Specifies a list of TagFilters (keys and values) to restrict the output to
     * only those resources that have tags with the specified keys and, if included,
     * the specified values. Each TagFilter must contain a key with values
     * optional. A request can include up to 50 keys, and each key can include up to 20
     * values.

Note the following when deciding how to use TagFilters:

     *

If you don't specify a TagFilter, the response
     * includes all resources that are currently tagged or ever had a tag. Resources
     * that currently don't have tags are shown with an empty tag set, like this:
     * "Tags": [].

If you specify more than one filter
     * in a single request, the response returns only those resources that satisfy all
     * filters.

If you specify a filter that contains more than one
     * value for a key, the response returns resources that match any of the
     * specified values for that key.

If you don't specify a value
     * for a key, the response returns all resources that are tagged with that key,
     * with any or no value.

For example, for the following filters:
     * filter1= {keyA,{value1}},
     * filter2={keyB,{value2,value3,value4}}, filter3=
     * {keyC}:

 GetResources({filter1}) returns
     * resources tagged with key1=value1

     * GetResources({filter2}) returns resources tagged with
     * key2=value2 or key2=value3 or key2=value4
     *

 GetResources({filter3}) returns resources
     * tagged with any tag with the key key3, and with any or no value

     *

 GetResources({filter1,filter2,filter3}) returns
     * resources tagged with (key1=value1) and (key2=value2 or key2=value3 or
     * key2=value4) and (key3, any or no value)

     */
    inline void SetTagFilters(const Aws::Vector<TagFilter>& value) { m_tagFiltersHasBeenSet = true; m_tagFilters = value; }

    /**
     *
Specifies a list of TagFilters (keys and values) to restrict the output to
     * only those resources that have tags with the specified keys and, if included,
     * the specified values. Each TagFilter must contain a key with values
     * optional. A request can include up to 50 keys, and each key can include up to 20
     * values.

Note the following when deciding how to use TagFilters:

     *

If you don't specify a TagFilter, the response
     * includes all resources that are currently tagged or ever had a tag. Resources
     * that currently don't have tags are shown with an empty tag set, like this:
     * "Tags": [].

If you specify more than one filter
     * in a single request, the response returns only those resources that satisfy all
     * filters.

If you specify a filter that contains more than one
     * value for a key, the response returns resources that match any of the
     * specified values for that key.

If you don't specify a value
     * for a key, the response returns all resources that are tagged with that key,
     * with any or no value.

For example, for the following filters:
     * filter1= {keyA,{value1}},
     * filter2={keyB,{value2,value3,value4}}, filter3=
     * {keyC}:

 GetResources({filter1}) returns
     * resources tagged with key1=value1

     * GetResources({filter2}) returns resources tagged with
     * key2=value2 or key2=value3 or key2=value4
     *

 GetResources({filter3}) returns resources
     * tagged with any tag with the key key3, and with any or no value

     *

 GetResources({filter1,filter2,filter3}) returns
     * resources tagged with (key1=value1) and (key2=value2 or key2=value3 or
     * key2=value4) and (key3, any or no value)

     */
    inline void SetTagFilters(Aws::Vector<TagFilter>&& value) { m_tagFiltersHasBeenSet = true; m_tagFilters = std::move(value); }

    /**
     *
Specifies a list of TagFilters (keys and values) to restrict the output to
     * only those resources that have tags with the specified keys and, if included,
     * the specified values. Each TagFilter must contain a key with values
     * optional. A request can include up to 50 keys, and each key can include up to 20
     * values.

Note the following when deciding how to use TagFilters:

     *

If you don't specify a TagFilter, the response
     * includes all resources that are currently tagged or ever had a tag. Resources
     * that currently don't have tags are shown with an empty tag set, like this:
     * "Tags": [].

If you specify more than one filter
     * in a single request, the response returns only those resources that satisfy all
     * filters.

If you specify a filter that contains more than one
     * value for a key, the response returns resources that match any of the
     * specified values for that key.

If you don't specify a value
     * for a key, the response returns all resources that are tagged with that key,
     * with any or no value.

For example, for the following filters:
     * filter1= {keyA,{value1}},
     * filter2={keyB,{value2,value3,value4}}, filter3=
     * {keyC}:

 GetResources({filter1}) returns
     * resources tagged with key1=value1

     * GetResources({filter2}) returns resources tagged with
     * key2=value2 or key2=value3 or key2=value4
     *

 GetResources({filter3}) returns resources
     * tagged with any tag with the key key3, and with any or no value

     *

 GetResources({filter1,filter2,filter3}) returns
     * resources tagged with (key1=value1) and (key2=value2 or key2=value3 or
     * key2=value4) and (key3, any or no value)

     */
    inline GetResourcesRequest& WithTagFilters(const Aws::Vector<TagFilter>& value) { SetTagFilters(value); return *this;}

    /**
     *
Specifies a list of TagFilters (keys and values) to restrict the output to
     * only those resources that have tags with the specified keys and, if included,
     * the specified values. Each TagFilter must contain a key with values
     * optional. A request can include up to 50 keys, and each key can include up to 20
     * values.

Note the following when deciding how to use TagFilters:

     *

If you don't specify a TagFilter, the response
     * includes all resources that are currently tagged or ever had a tag. Resources
     * that currently don't have tags are shown with an empty tag set, like this:
     * "Tags": [].

If you specify more than one filter
     * in a single request, the response returns only those resources that satisfy all
     * filters.

If you specify a filter that contains more than one
     * value for a key, the response returns resources that match any of the
     * specified values for that key.

If you don't specify a value
     * for a key, the response returns all resources that are tagged with that key,
     * with any or no value.

For example, for the following filters:
     * filter1= {keyA,{value1}},
     * filter2={keyB,{value2,value3,value4}}, filter3=
     * {keyC}:

 GetResources({filter1}) returns
     * resources tagged with key1=value1

     * GetResources({filter2}) returns resources tagged with
     * key2=value2 or key2=value3 or key2=value4
     *

 GetResources({filter3}) returns resources
     * tagged with any tag with the key key3, and with any or no value

     *

 GetResources({filter1,filter2,filter3}) returns
     * resources tagged with (key1=value1) and (key2=value2 or key2=value3 or
     * key2=value4) and (key3, any or no value)

     */
    inline GetResourcesRequest& WithTagFilters(Aws::Vector<TagFilter>&& value) { SetTagFilters(std::move(value)); return *this;}

    /**
     *
Specifies a list of TagFilters (keys and values) to restrict the output to
     * only those resources that have tags with the specified keys and, if included,
     * the specified values. Each TagFilter must contain a key with values
     * optional. A request can include up to 50 keys, and each key can include up to 20
     * values.

Note the following when deciding how to use TagFilters:

     *

If you don't specify a TagFilter, the response
     * includes all resources that are currently tagged or ever had a tag. Resources
     * that currently don't have tags are shown with an empty tag set, like this:
     * "Tags": [].

If you specify more than one filter
     * in a single request, the response returns only those resources that satisfy all
     * filters.

If you specify a filter that contains more than one
     * value for a key, the response returns resources that match any of the
     * specified values for that key.

If you don't specify a value
     * for a key, the response returns all resources that are tagged with that key,
     * with any or no value.

For example, for the following filters:
     * filter1= {keyA,{value1}},
     * filter2={keyB,{value2,value3,value4}}, filter3=
     * {keyC}:

 GetResources({filter1}) returns
     * resources tagged with key1=value1

     * GetResources({filter2}) returns resources tagged with
     * key2=value2 or key2=value3 or key2=value4
     *

 GetResources({filter3}) returns resources
     * tagged with any tag with the key key3, and with any or no value

     *

 GetResources({filter1,filter2,filter3}) returns
     * resources tagged with (key1=value1) and (key2=value2 or key2=value3 or
     * key2=value4) and (key3, any or no value)

     */
    inline GetResourcesRequest& AddTagFilters(const TagFilter& value) { m_tagFiltersHasBeenSet = true; m_tagFilters.push_back(value); return *this; }

    /**
     *
Specifies a list of TagFilters (keys and values) to restrict the output to
     * only those resources that have tags with the specified keys and, if included,
     * the specified values. Each TagFilter must contain a key with values
     * optional. A request can include up to 50 keys, and each key can include up to 20
     * values.

Note the following when deciding how to use TagFilters:

     *

If you don't specify a TagFilter, the response
     * includes all resources that are currently tagged or ever had a tag. Resources
     * that currently don't have tags are shown with an empty tag set, like this:
     * "Tags": [].

If you specify more than one filter
     * in a single request, the response returns only those resources that satisfy all
     * filters.

If you specify a filter that contains more than one
     * value for a key, the response returns resources that match any of the
     * specified values for that key.

If you don't specify a value
     * for a key, the response returns all resources that are tagged with that key,
     * with any or no value.

For example, for the following filters:
     * filter1= {keyA,{value1}},
     * filter2={keyB,{value2,value3,value4}}, filter3=
     * {keyC}:

 GetResources({filter1}) returns
     * resources tagged with key1=value1

     * GetResources({filter2}) returns resources tagged with
     * key2=value2 or key2=value3 or key2=value4
     *

 GetResources({filter3}) returns resources
     * tagged with any tag with the key key3, and with any or no value

     *

 GetResources({filter1,filter2,filter3}) returns
     * resources tagged with (key1=value1) and (key2=value2 or key2=value3 or
     * key2=value4) and (key3, any or no value)

     */
    inline GetResourcesRequest& AddTagFilters(TagFilter&& value) { m_tagFiltersHasBeenSet = true; m_tagFilters.push_back(std::move(value)); return *this; }

    /**
     *
Specifies the maximum number of results to be returned in each page. A query
     * can return fewer than this maximum, even if there are more results still to
     * return. You should always check the PaginationToken response value
     * to see if there are more results. You can specify a minimum of 1 and a maximum
     * value of 100.

     */
    inline int GetResourcesPerPage() const{ return m_resourcesPerPage; }

    /**
     *
Specifies the maximum number of results to be returned in each page. A query
     * can return fewer than this maximum, even if there are more results still to
     * return. You should always check the PaginationToken response value
     * to see if there are more results. You can specify a minimum of 1 and a maximum
     * value of 100.

     */
    inline bool ResourcesPerPageHasBeenSet() const { return m_resourcesPerPageHasBeenSet; }

    /**
     *
Specifies the maximum number of results to be returned in each page. A query
     * can return fewer than this maximum, even if there are more results still to
     * return. You should always check the PaginationToken response value
     * to see if there are more results. You can specify a minimum of 1 and a maximum
     * value of 100.

     */
    inline void SetResourcesPerPage(int value) { m_resourcesPerPageHasBeenSet = true; m_resourcesPerPage = value; }

    /**
     *
Specifies the maximum number of results to be returned in each page. A query
     * can return fewer than this maximum, even if there are more results still to
     * return. You should always check the PaginationToken response value
     * to see if there are more results. You can specify a minimum of 1 and a maximum
     * value of 100.

     */
    inline GetResourcesRequest& WithResourcesPerPage(int value) { SetResourcesPerPage(value); return *this;}

    /**
     *
Amazon Web Services recommends using ResourcesPerPage instead of
     * this parameter.

A limit that restricts the number of tags (key and value
     * pairs) returned by GetResources in paginated output. A resource
     * with no tags is counted as having one tag (one key and value pair).

     * GetResources does not split a resource and its associated tags
     * across pages. If the specified TagsPerPage would cause such a
     * break, a PaginationToken is returned in place of the affected
     * resource and its tags. Use that token in another request to get the remaining
     * data. For example, if you specify a TagsPerPage of 100
     * and the account has 22 resources with 10 tags each (meaning that each resource
     * has 10 key and value pairs), the output will consist of three pages. The first
     * page displays the first 10 resources, each with its 10 tags. The second page
     * displays the next 10 resources, each with its 10 tags. The third page displays
     * the remaining 2 resources, each with its 10 tags.

You can set
     * TagsPerPage to a minimum of 100 items up to a maximum of 500
     * items.

     */
    inline int GetTagsPerPage() const{ return m_tagsPerPage; }

    /**
     *
Amazon Web Services recommends using ResourcesPerPage instead of
     * this parameter.

A limit that restricts the number of tags (key and value
     * pairs) returned by GetResources in paginated output. A resource
     * with no tags is counted as having one tag (one key and value pair).

     * GetResources does not split a resource and its associated tags
     * across pages. If the specified TagsPerPage would cause such a
     * break, a PaginationToken is returned in place of the affected
     * resource and its tags. Use that token in another request to get the remaining
     * data. For example, if you specify a TagsPerPage of 100
     * and the account has 22 resources with 10 tags each (meaning that each resource
     * has 10 key and value pairs), the output will consist of three pages. The first
     * page displays the first 10 resources, each with its 10 tags. The second page
     * displays the next 10 resources, each with its 10 tags. The third page displays
     * the remaining 2 resources, each with its 10 tags.

You can set
     * TagsPerPage to a minimum of 100 items up to a maximum of 500
     * items.

     */
    inline bool TagsPerPageHasBeenSet() const { return m_tagsPerPageHasBeenSet; }

    /**
     *
Amazon Web Services recommends using ResourcesPerPage instead of
     * this parameter.

A limit that restricts the number of tags (key and value
     * pairs) returned by GetResources in paginated output. A resource
     * with no tags is counted as having one tag (one key and value pair).

     * GetResources does not split a resource and its associated tags
     * across pages. If the specified TagsPerPage would cause such a
     * break, a PaginationToken is returned in place of the affected
     * resource and its tags. Use that token in another request to get the remaining
     * data. For example, if you specify a TagsPerPage of 100
     * and the account has 22 resources with 10 tags each (meaning that each resource
     * has 10 key and value pairs), the output will consist of three pages. The first
     * page displays the first 10 resources, each with its 10 tags. The second page
     * displays the next 10 resources, each with its 10 tags. The third page displays
     * the remaining 2 resources, each with its 10 tags.

You can set
     * TagsPerPage to a minimum of 100 items up to a maximum of 500
     * items.

     */
    inline void SetTagsPerPage(int value) { m_tagsPerPageHasBeenSet = true; m_tagsPerPage = value; }

    /**
     *
Amazon Web Services recommends using ResourcesPerPage instead of
     * this parameter.

A limit that restricts the number of tags (key and value
     * pairs) returned by GetResources in paginated output. A resource
     * with no tags is counted as having one tag (one key and value pair).

     * GetResources does not split a resource and its associated tags
     * across pages. If the specified TagsPerPage would cause such a
     * break, a PaginationToken is returned in place of the affected
     * resource and its tags. Use that token in another request to get the remaining
     * data. For example, if you specify a TagsPerPage of 100
     * and the account has 22 resources with 10 tags each (meaning that each resource
     * has 10 key and value pairs), the output will consist of three pages. The first
     * page displays the first 10 resources, each with its 10 tags. The second page
     * displays the next 10 resources, each with its 10 tags. The third page displays
     * the remaining 2 resources, each with its 10 tags.

You can set
     * TagsPerPage to a minimum of 100 items up to a maximum of 500
     * items.

     */
    inline GetResourcesRequest& WithTagsPerPage(int value) { SetTagsPerPage(value); return *this;}

    /**
     *
Specifies the resource types that you want included in the response. The
     * format of each resource type is service[:resourceType]. For
     * example, specifying a resource type of ec2 returns all Amazon EC2
     * resources (which includes EC2 instances). Specifying a resource type of
     * ec2:instance returns only EC2 instances.

The string for
     * each service name and resource type is the same as that embedded in a resource's
     * Amazon Resource Name (ARN). For the list of services whose resources you can use
     * in this parameter, see Services
     * that support the Resource Groups Tagging API.

You can specify
     * multiple resource types by using an array. The array can include up to 100
     * items. Note that the length constraint requirement applies to each resource type
     * filter. For example, the following string would limit the response to only
     * Amazon EC2 instances, Amazon S3 buckets, or any Audit Manager resource:

     * ec2:instance,s3:bucket,auditmanager

     */
    inline const Aws::Vector<Aws::String>& GetResourceTypeFilters() const{ return m_resourceTypeFilters; }

    /**
     *
Specifies the resource types that you want included in the response. The
     * format of each resource type is service[:resourceType]. For
     * example, specifying a resource type of ec2 returns all Amazon EC2
     * resources (which includes EC2 instances). Specifying a resource type of
     * ec2:instance returns only EC2 instances.

The string for
     * each service name and resource type is the same as that embedded in a resource's
     * Amazon Resource Name (ARN). For the list of services whose resources you can use
     * in this parameter, see Services
     * that support the Resource Groups Tagging API.

You can specify
     * multiple resource types by using an array. The array can include up to 100
     * items. Note that the length constraint requirement applies to each resource type
     * filter. For example, the following string would limit the response to only
     * Amazon EC2 instances, Amazon S3 buckets, or any Audit Manager resource:

     * ec2:instance,s3:bucket,auditmanager

     */
    inline bool ResourceTypeFiltersHasBeenSet() const { return m_resourceTypeFiltersHasBeenSet; }

    /**
     *
Specifies the resource types that you want included in the response. The
     * format of each resource type is service[:resourceType]. For
     * example, specifying a resource type of ec2 returns all Amazon EC2
     * resources (which includes EC2 instances). Specifying a resource type of
     * ec2:instance returns only EC2 instances.

The string for
     * each service name and resource type is the same as that embedded in a resource's
     * Amazon Resource Name (ARN). For the list of services whose resources you can use
     * in this parameter, see Services
     * that support the Resource Groups Tagging API.

You can specify
     * multiple resource types by using an array. The array can include up to 100
     * items. Note that the length constraint requirement applies to each resource type
     * filter. For example, the following string would limit the response to only
     * Amazon EC2 instances, Amazon S3 buckets, or any Audit Manager resource:

     * ec2:instance,s3:bucket,auditmanager

     */
    inline void SetResourceTypeFilters(const Aws::Vector<Aws::String>& value) { m_resourceTypeFiltersHasBeenSet = true; m_resourceTypeFilters = value; }

    /**
     *
Specifies the resource types that you want included in the response. The
     * format of each resource type is service[:resourceType]. For
     * example, specifying a resource type of ec2 returns all Amazon EC2
     * resources (which includes EC2 instances). Specifying a resource type of
     * ec2:instance returns only EC2 instances.

The string for
     * each service name and resource type is the same as that embedded in a resource's
     * Amazon Resource Name (ARN). For the list of services whose resources you can use
     * in this parameter, see Services
     * that support the Resource Groups Tagging API.

You can specify
     * multiple resource types by using an array. The array can include up to 100
     * items. Note that the length constraint requirement applies to each resource type
     * filter. For example, the following string would limit the response to only
     * Amazon EC2 instances, Amazon S3 buckets, or any Audit Manager resource:

     * ec2:instance,s3:bucket,auditmanager

     */
    inline void SetResourceTypeFilters(Aws::Vector<Aws::String>&& value) { m_resourceTypeFiltersHasBeenSet = true; m_resourceTypeFilters = std::move(value); }

    /**
     *
Specifies the resource types that you want included in the response. The
     * format of each resource type is service[:resourceType]. For
     * example, specifying a resource type of ec2 returns all Amazon EC2
     * resources (which includes EC2 instances). Specifying a resource type of
     * ec2:instance returns only EC2 instances.

The string for
     * each service name and resource type is the same as that embedded in a resource's
     * Amazon Resource Name (ARN). For the list of services whose resources you can use
     * in this parameter, see Services
     * that support the Resource Groups Tagging API.

You can specify
     * multiple resource types by using an array. The array can include up to 100
     * items. Note that the length constraint requirement applies to each resource type
     * filter. For example, the following string would limit the response to only
     * Amazon EC2 instances, Amazon S3 buckets, or any Audit Manager resource:

     * ec2:instance,s3:bucket,auditmanager

     */
    inline GetResourcesRequest& WithResourceTypeFilters(const Aws::Vector<Aws::String>& value) { SetResourceTypeFilters(value); return *this;}

    /**
     *
Specifies the resource types that you want included in the response. The
     * format of each resource type is service[:resourceType]. For
     * example, specifying a resource type of ec2 returns all Amazon EC2
     * resources (which includes EC2 instances). Specifying a resource type of
     * ec2:instance returns only EC2 instances.

The string for
     * each service name and resource type is the same as that embedded in a resource's
     * Amazon Resource Name (ARN). For the list of services whose resources you can use
     * in this parameter, see Services
     * that support the Resource Groups Tagging API.

You can specify
     * multiple resource types by using an array. The array can include up to 100
     * items. Note that the length constraint requirement applies to each resource type
     * filter. For example, the following string would limit the response to only
     * Amazon EC2 instances, Amazon S3 buckets, or any Audit Manager resource:

     * ec2:instance,s3:bucket,auditmanager

     */
    inline GetResourcesRequest& WithResourceTypeFilters(Aws::Vector<Aws::String>&& value) { SetResourceTypeFilters(std::move(value)); return *this;}

    /**
     *
Specifies the resource types that you want included in the response. The
     * format of each resource type is service[:resourceType]. For
     * example, specifying a resource type of ec2 returns all Amazon EC2
     * resources (which includes EC2 instances). Specifying a resource type of
     * ec2:instance returns only EC2 instances.

The string for
     * each service name and resource type is the same as that embedded in a resource's
     * Amazon Resource Name (ARN). For the list of services whose resources you can use
     * in this parameter, see Services
     * that support the Resource Groups Tagging API.

You can specify
     * multiple resource types by using an array. The array can include up to 100
     * items. Note that the length constraint requirement applies to each resource type
     * filter. For example, the following string would limit the response to only
     * Amazon EC2 instances, Amazon S3 buckets, or any Audit Manager resource:

     * ec2:instance,s3:bucket,auditmanager

     */
    inline GetResourcesRequest& AddResourceTypeFilters(const Aws::String& value) { m_resourceTypeFiltersHasBeenSet = true; m_resourceTypeFilters.push_back(value); return *this; }

    /**
     *
Specifies the resource types that you want included in the response. The
     * format of each resource type is service[:resourceType]. For
     * example, specifying a resource type of ec2 returns all Amazon EC2
     * resources (which includes EC2 instances). Specifying a resource type of
     * ec2:instance returns only EC2 instances.

The string for
     * each service name and resource type is the same as that embedded in a resource's
     * Amazon Resource Name (ARN). For the list of services whose resources you can use
     * in this parameter, see Services
     * that support the Resource Groups Tagging API.

You can specify
     * multiple resource types by using an array. The array can include up to 100
     * items. Note that the length constraint requirement applies to each resource type
     * filter. For example, the following string would limit the response to only
     * Amazon EC2 instances, Amazon S3 buckets, or any Audit Manager resource:

     * ec2:instance,s3:bucket,auditmanager

     */
    inline GetResourcesRequest& AddResourceTypeFilters(Aws::String&& value) { m_resourceTypeFiltersHasBeenSet = true; m_resourceTypeFilters.push_back(std::move(value)); return *this; }

    /**
     *
Specifies the resource types that you want included in the response. The
     * format of each resource type is service[:resourceType]. For
     * example, specifying a resource type of ec2 returns all Amazon EC2
     * resources (which includes EC2 instances). Specifying a resource type of
     * ec2:instance returns only EC2 instances.

The string for
     * each service name and resource type is the same as that embedded in a resource's
     * Amazon Resource Name (ARN). For the list of services whose resources you can use
     * in this parameter, see Services
     * that support the Resource Groups Tagging API.

You can specify
     * multiple resource types by using an array. The array can include up to 100
     * items. Note that the length constraint requirement applies to each resource type
     * filter. For example, the following string would limit the response to only
     * Amazon EC2 instances, Amazon S3 buckets, or any Audit Manager resource:

     * ec2:instance,s3:bucket,auditmanager

     */
    inline GetResourcesRequest& AddResourceTypeFilters(const char* value) { m_resourceTypeFiltersHasBeenSet = true; m_resourceTypeFilters.push_back(value); return *this; }

    /**
     *
Specifies whether to include details regarding the compliance with the
     * effective tag policy. Set this to true to determine whether
     * resources are compliant with the tag policy and to get details.

     */
    inline bool GetIncludeComplianceDetails() const{ return m_includeComplianceDetails; }

    /**
     *
Specifies whether to include details regarding the compliance with the
     * effective tag policy. Set this to true to determine whether
     * resources are compliant with the tag policy and to get details.

     */
    inline bool IncludeComplianceDetailsHasBeenSet() const { return m_includeComplianceDetailsHasBeenSet; }

    /**
     *
Specifies whether to include details regarding the compliance with the
     * effective tag policy. Set this to true to determine whether
     * resources are compliant with the tag policy and to get details.

     */
    inline void SetIncludeComplianceDetails(bool value) { m_includeComplianceDetailsHasBeenSet = true; m_includeComplianceDetails = value; }

    /**
     *
Specifies whether to include details regarding the compliance with the
     * effective tag policy. Set this to true to determine whether
     * resources are compliant with the tag policy and to get details.

     */
    inline GetResourcesRequest& WithIncludeComplianceDetails(bool value) { SetIncludeComplianceDetails(value); return *this;}

    /**
     *
Specifies whether to exclude resources that are compliant with the tag
     * policy. Set this to true if you are interested in retrieving
     * information on noncompliant resources only.

You can use this parameter
     * only if the IncludeComplianceDetails parameter is also set to
     * true.

     */
    inline bool GetExcludeCompliantResources() const{ return m_excludeCompliantResources; }

    /**
     *
Specifies whether to exclude resources that are compliant with the tag
     * policy. Set this to true if you are interested in retrieving
     * information on noncompliant resources only.

You can use this parameter
     * only if the IncludeComplianceDetails parameter is also set to
     * true.

     */
    inline bool ExcludeCompliantResourcesHasBeenSet() const { return m_excludeCompliantResourcesHasBeenSet; }

    /**
     *
Specifies whether to exclude resources that are compliant with the tag
     * policy. Set this to true if you are interested in retrieving
     * information on noncompliant resources only.

You can use this parameter
     * only if the IncludeComplianceDetails parameter is also set to
     * true.

     */
    inline void SetExcludeCompliantResources(bool value) { m_excludeCompliantResourcesHasBeenSet = true; m_excludeCompliantResources = value; }

    /**
     *
Specifies whether to exclude resources that are compliant with the tag
     * policy. Set this to true if you are interested in retrieving
     * information on noncompliant resources only.

You can use this parameter
     * only if the IncludeComplianceDetails parameter is also set to
     * true.

     */
    inline GetResourcesRequest& WithExcludeCompliantResources(bool value) { SetExcludeCompliantResources(value); return *this;}

    /**
     *
Specifies a list of ARNs of resources for which you want to retrieve tag
     * data. You can't specify both this parameter and any of the pagination parameters
     * (ResourcesPerPage, TagsPerPage,
     * PaginationToken) in the same request. If you specify both, you get
     * an Invalid Parameter exception.

If a resource specified by
     * this parameter doesn't exist, it doesn't generate an error; it simply isn't
     * included in the response.

An ARN (Amazon Resource Name) uniquely
     * identifies a resource. For more information, see Amazon
     * Resource Names (ARNs) and Amazon Web Services Service Namespaces in the
     * Amazon Web Services General Reference.

     */
    inline const Aws::Vector<Aws::String>& GetResourceARNList() const{ return m_resourceARNList; }

    /**
     *
Specifies a list of ARNs of resources for which you want to retrieve tag
     * data. You can't specify both this parameter and any of the pagination parameters
     * (ResourcesPerPage, TagsPerPage,
     * PaginationToken) in the same request. If you specify both, you get
     * an Invalid Parameter exception.

If a resource specified by
     * this parameter doesn't exist, it doesn't generate an error; it simply isn't
     * included in the response.

An ARN (Amazon Resource Name) uniquely
     * identifies a resource. For more information, see Amazon
     * Resource Names (ARNs) and Amazon Web Services Service Namespaces in the
     * Amazon Web Services General Reference.

     */
    inline bool ResourceARNListHasBeenSet() const { return m_resourceARNListHasBeenSet; }

    /**
     *
Specifies a list of ARNs of resources for which you want to retrieve tag
     * data. You can't specify both this parameter and any of the pagination parameters
     * (ResourcesPerPage, TagsPerPage,
     * PaginationToken) in the same request. If you specify both, you get
     * an Invalid Parameter exception.

If a resource specified by
     * this parameter doesn't exist, it doesn't generate an error; it simply isn't
     * included in the response.

An ARN (Amazon Resource Name) uniquely
     * identifies a resource. For more information, see Amazon
     * Resource Names (ARNs) and Amazon Web Services Service Namespaces in the
     * Amazon Web Services General Reference.

     */
    inline void SetResourceARNList(const Aws::Vector<Aws::String>& value) { m_resourceARNListHasBeenSet = true; m_resourceARNList = value; }

    /**
     *
Specifies a list of ARNs of resources for which you want to retrieve tag
     * data. You can't specify both this parameter and any of the pagination parameters
     * (ResourcesPerPage, TagsPerPage,
     * PaginationToken) in the same request. If you specify both, you get
     * an Invalid Parameter exception.

If a resource specified by
     * this parameter doesn't exist, it doesn't generate an error; it simply isn't
     * included in the response.

An ARN (Amazon Resource Name) uniquely
     * identifies a resource. For more information, see Amazon
     * Resource Names (ARNs) and Amazon Web Services Service Namespaces in the
     * Amazon Web Services General Reference.

     */
    inline void SetResourceARNList(Aws::Vector<Aws::String>&& value) { m_resourceARNListHasBeenSet = true; m_resourceARNList = std::move(value); }

    /**
     *
Specifies a list of ARNs of resources for which you want to retrieve tag
     * data. You can't specify both this parameter and any of the pagination parameters
     * (ResourcesPerPage, TagsPerPage,
     * PaginationToken) in the same request. If you specify both, you get
     * an Invalid Parameter exception.

If a resource specified by
     * this parameter doesn't exist, it doesn't generate an error; it simply isn't
     * included in the response.

An ARN (Amazon Resource Name) uniquely
     * identifies a resource. For more information, see Amazon
     * Resource Names (ARNs) and Amazon Web Services Service Namespaces in the
     * Amazon Web Services General Reference.

     */
    inline GetResourcesRequest& WithResourceARNList(const Aws::Vector<Aws::String>& value) { SetResourceARNList(value); return *this;}

    /**
     *
Specifies a list of ARNs of resources for which you want to retrieve tag
     * data. You can't specify both this parameter and any of the pagination parameters
     * (ResourcesPerPage, TagsPerPage,
     * PaginationToken) in the same request. If you specify both, you get
     * an Invalid Parameter exception.

If a resource specified by
     * this parameter doesn't exist, it doesn't generate an error; it simply isn't
     * included in the response.

An ARN (Amazon Resource Name) uniquely
     * identifies a resource. For more information, see Amazon
     * Resource Names (ARNs) and Amazon Web Services Service Namespaces in the
     * Amazon Web Services General Reference.

     */
    inline GetResourcesRequest& WithResourceARNList(Aws::Vector<Aws::String>&& value) { SetResourceARNList(std::move(value)); return *this;}

    /**
     *
Specifies a list of ARNs of resources for which you want to retrieve tag
     * data. You can't specify both this parameter and any of the pagination parameters
     * (ResourcesPerPage, TagsPerPage,
     * PaginationToken) in the same request. If you specify both, you get
     * an Invalid Parameter exception.

If a resource specified by
     * this parameter doesn't exist, it doesn't generate an error; it simply isn't
     * included in the response.

An ARN (Amazon Resource Name) uniquely
     * identifies a resource. For more information, see Amazon
     * Resource Names (ARNs) and Amazon Web Services Service Namespaces in the
     * Amazon Web Services General Reference.

     */
    inline GetResourcesRequest& AddResourceARNList(const Aws::String& value) { m_resourceARNListHasBeenSet = true; m_resourceARNList.push_back(value); return *this; }

    /**
     *
Specifies a list of ARNs of resources for which you want to retrieve tag
     * data. You can't specify both this parameter and any of the pagination parameters
     * (ResourcesPerPage, TagsPerPage,
     * PaginationToken) in the same request. If you specify both, you get
     * an Invalid Parameter exception.

If a resource specified by
     * this parameter doesn't exist, it doesn't generate an error; it simply isn't
     * included in the response.

An ARN (Amazon Resource Name) uniquely
     * identifies a resource. For more information, see Amazon
     * Resource Names (ARNs) and Amazon Web Services Service Namespaces in the
     * Amazon Web Services General Reference.

     */
    inline GetResourcesRequest& AddResourceARNList(Aws::String&& value) { m_resourceARNListHasBeenSet = true; m_resourceARNList.push_back(std::move(value)); return *this; }

    /**
     *
Specifies a list of ARNs of resources for which you want to retrieve tag
     * data. You can't specify both this parameter and any of the pagination parameters
     * (ResourcesPerPage, TagsPerPage,
     * PaginationToken) in the same request. If you specify both, you get
     * an Invalid Parameter exception.

If a resource specified by
     * this parameter doesn't exist, it doesn't generate an error; it simply isn't
     * included in the response.

An ARN (Amazon Resource Name) uniquely
     * identifies a resource. For more information, see Amazon
     * Resource Names (ARNs) and Amazon Web Services Service Namespaces in the
     * Amazon Web Services General Reference.

     */
    inline GetResourcesRequest& AddResourceARNList(const char* value) { m_resourceARNListHasBeenSet = true; m_resourceARNList.push_back(value); return *this; }

  private:

    Aws::String m_paginationToken;
    bool m_paginationTokenHasBeenSet;

    Aws::Vector<TagFilter> m_tagFilters;
    bool m_tagFiltersHasBeenSet;

    int m_resourcesPerPage;
    bool m_resourcesPerPageHasBeenSet;

    int m_tagsPerPage;
    bool m_tagsPerPageHasBeenSet;

    Aws::Vector<Aws::String> m_resourceTypeFilters;
    bool m_resourceTypeFiltersHasBeenSet;

    bool m_includeComplianceDetails;
    bool m_includeComplianceDetailsHasBeenSet;

    bool m_excludeCompliantResources;
    bool m_excludeCompliantResourcesHasBeenSet;

    Aws::Vector<Aws::String> m_resourceARNList;
    bool m_resourceARNListHasBeenSet;
  };

} // namespace Model
} // namespace ResourceGroupsTaggingAPI
} // namespace Aws


text:
        {% include custom/conditions.html %}

            {{site.sidebar_tagline}}
            {{site.sidebar_version}}

            {% for entry in sidebar %}
            {% for subcategory in entry.subcategories %}
            {% if subcategory.audience contains audience and subcategory.product contains product and subcategory.platform contains platform and subcategory.version contains version and subcategory.output contains "web" %}

{{ subcategory.title }}

                    {% for item in subcategory.items %}
                    {% if item.audience contains audience and item.product contains product and item.platform contains platform and item.version contains version and item.output contains "web" %}
                    {% if item.external_url %}

{{subcategory.title}}

                    {% elsif page.url == item.url %}

{{item.title}}

                    {% else %}

{{item.title}}

                    {% endif %}

                    {% for thirdlevel in item.thirdlevel %}
                    {% if thirdlevel.audience contains audience and thirdlevel.product contains product and thirdlevel.platform contains platform and thirdlevel.version contains version and thirdlevel.output contains "web" %}

{{ thirdlevel.title }}

                            {% for deeplevel in thirdlevel.thirdlevelitems %}
                            {% if deeplevel.audience contains audience and deeplevel.product contains product and deeplevel.platform contains platform and deeplevel.version contains version and deeplevel.output contains "web" %}
                            {% if deeplevel.external_url %}

{{deeplevel.title}}

                            {% elsif page.url == deeplevel.url %}

{{deeplevel.title}}

                            {% else %}

{{deeplevel.title}}

                            {% endif %}

                            {% endif %}
                            {% endfor %}

                    {% endif %}
                    {% endfor %}

                    {% endif %}
                    {% endfor %}

                {% endif %}
                {% endfor %}
                {% endfor %}

			{% include toc.html %}

redpajama_set_name: RedPajamaGithub


text:
#include "sol-interrupt_scheduler_riot.h"
#include "sol-log.h"
#include "sol-mainloop.h"
#include "sol-socket.h"
#include "sol-socket-impl.h"
#include "sol-vector.h"
#include "sol-util-internal.h"

#include "net/gnrc/ipv6.h"
#include "net/gnrc/udp.h"

struct sol_socket_riot {
    struct sol_socket base;

    struct {
        bool (*cb)(void *data, struct sol_socket *s);
        const void *data;
    } read, write;
    struct sol_timeout *write_timeout;
    gnrc_pktsnip_t *curr_pkt;
    gnrc_netreg_entry_t entry;
    gnrc_nettype_t type;
};

static struct sol_ptr_vector ipv6_udp_bound_sockets = SOL_PTR_VECTOR_INIT;

static ssize_t
ipv6_udp_recvmsg(struct sol_socket_riot *s, void *buf, size_t len, struct sol_network_link_addr *cliaddr)
{
    gnrc_pktsnip_t *pkt = s->curr_pkt, *udp, *ipv6;
    ipv6_hdr_t *iphdr;
    udp_hdr_t *udphdr;
    size_t copysize;

    SOL_NULL_CHECK(pkt, -EAGAIN);

    /* When more types of sockets (not just datagram) are accepted,
     * remember to err if !buf && type != DGRAM */
    if (!buf)
        return pkt->size;

    LL_SEARCH_SCALAR(pkt, ipv6, type, GNRC_NETTYPE_IPV6);
    iphdr = ipv6->data;

    LL_SEARCH_SCALAR(pkt, udp, type, GNRC_NETTYPE_UDP);
    udphdr = udp->data;

    cliaddr->family = SOL_NETWORK_FAMILY_INET6;
    memcpy(cliaddr->addr.in6, iphdr->src.u8, sizeof(iphdr->src.u8));
    cliaddr->port = byteorder_ntohs(udphdr->src_port);

    copysize = pkt->size < len ? pkt->size : len;
    memcpy(buf, pkt->data, copysize);

    return copysize;
}

static inline void
riotize_port(uint16_t port, uint8_t buf[2])
{
    buf[0] = (uint8_t)port;
    buf[1] = (uint8_t)(port >> 8);
}

static gnrc_pktsnip_t *
ipv6_udp_sendmsg(struct sol_socket_riot *s, const void *buf, size_t len, const struct sol_network_link_addr *cliaddr)
{
    gnrc_pktsnip_t *payload, *udp, *ipv6;
    ipv6_addr_t addr;
    uint8_t dstport[2], srcport[2];

    riotize_port(cliaddr->port, dstport);
    riotize_port((uint16_t)s->entry.demux_ctx, srcport);

    memcpy(addr.u8, cliaddr->addr.in6, sizeof(addr.u8));

    payload = gnrc_pktbuf_add(NULL, (void *)buf, len, GNRC_NETTYPE_UNDEF);
    SOL_NULL_CHECK(payload, NULL);

    udp = gnrc_udp_hdr_build(payload, srcport, sizeof(srcport), dstport, sizeof(dstport));
    SOL_NULL_CHECK_GOTO(udp, udp_error);

    ipv6 = gnrc_ipv6_hdr_build(udp, NULL, 0, (uint8_t *)&addr, sizeof(addr));
    SOL_NULL_CHECK_GOTO(ipv6, ipv6_error);

    return ipv6;
ipv6_error:
    gnrc_pktbuf_release(udp);
    return NULL;
udp_error:
    gnrc_pktbuf_release(payload);
    return NULL;
}

#define IPV6_MULTICAST_PREFIX_LEN 16

static int
ipv6_udp_join_group(struct sol_socket_riot *s, kernel_pid_t iface, const struct sol_network_link_addr *group)
{
    ipv6_addr_t *addr;

    addr = gnrc_ipv6_netif_add_addr(iface, (ipv6_addr_t *)group->addr.in6,
        IPV6_MULTICAST_PREFIX_LEN, 0);
    SOL_NULL_CHECK(addr, -ENOMEM);

    return 0;
}

static int
udp_bind_cmp_cb(const void *a, const void *b)
{
    const struct sol_socket_riot *s1 = a, *s2 = b;

    return s1->entry.demux_ctx < s2->entry.demux_ctx ? -1 : 1;
}

static int
ipv6_udp_bind(struct sol_socket_riot *s, const struct sol_network_link_addr *addr)
{
    struct sol_socket_riot *socket;
    uint32_t first_unused = 1025;
    int ret;
    uint16_t i, port = addr->port;

    SOL_PTR_VECTOR_FOREACH_IDX (&ipv6_udp_bound_sockets, socket, i) {
        if (port && (socket->entry.demux_ctx == (uint32_t)port))
            return -EADDRINUSE;
        if (socket->entry.demux_ctx == first_unused)
            first_unused++;
    }

    s->entry.demux_ctx = port ? port : first_unused;
    ret = sol_ptr_vector_insert_sorted(&ipv6_udp_bound_sockets, s, udp_bind_cmp_cb);
    SOL_INT_CHECK_GOTO(ret, < 0, append_error);

    return 0;
append_error:
    s->entry.demux_ctx = GNRC_NETREG_DEMUX_CTX_ALL;
    return -ENOMEM;
}

static void
ipv6_udp_delete(struct sol_socket_riot *s)
{
    if (s->entry.demux_ctx != GNRC_NETREG_DEMUX_CTX_ALL)
        sol_ptr_vector_remove(&ipv6_udp_bound_sockets, s);
}

static void
socket_udp_recv(struct sol_socket_riot *s, gnrc_pktsnip_t *pkt)
{
    s->curr_pkt = pkt;
    if (s->read.cb)
        s->read.cb((void *)s->read.data, &s->base);
    s->curr_pkt = NULL;
}

static bool
write_timeout_cb(void *data)
{
    struct sol_socket_riot *s = data;

    if (s->write.cb((void *)s->write.data, &s->base))
        return true;

    s->write_timeout = NULL;
    return false;
}

static void
udp_dispatch(gnrc_pktsnip_t *udp, gnrc_pktsnip_t *pkt)
{
    struct sol_socket_riot *s;
    udp_hdr_t *udphdr;
    uint32_t port;
    uint16_t i;

    udphdr = udp->data;
    port = (uint32_t)byteorder_ntohs(udphdr->dst_port);

    SOL_PTR_VECTOR_FOREACH_IDX (&ipv6_udp_bound_sockets, s, i) {
        if (s->entry.demux_ctx == port) {
            socket_udp_recv(s, pkt);
            break;
        }
    }
}

void
sol_network_msg_dispatch(msg_t *msg)
{
    gnrc_pktsnip_t *pkt = (gnrc_pktsnip_t *)msg->content.ptr;
    gnrc_pktsnip_t *udp;

    if (msg->type != GNRC_NETAPI_MSG_TYPE_RCV)
        goto the_end;

    LL_SEARCH_SCALAR(pkt, udp, type, GNRC_NETTYPE_UDP);

    if (udp)
        udp_dispatch(udp, pkt);

the_end:
    gnrc_pktbuf_release(pkt);
}

struct sol_socket *
sol_socket_riot_new(int domain, enum sol_socket_type type, int protocol)
{
    struct sol_socket_riot *socket;

    SOL_INT_CHECK_GOTO(domain, != SOL_NETWORK_FAMILY_INET6, unsupported_family);

    socket = calloc(1, sizeof(*socket));
    SOL_NULL_CHECK_GOTO(socket, socket_error);

    switch (type) {
    case SOL_SOCKET_UDP:
        socket->type = GNRC_NETTYPE_UDP;
        break;
    default:
        SOL_WRN("Unsupported socket type: %d", type);
        goto unsupported_type;
    }

    socket->entry.demux_ctx = GNRC_NETREG_DEMUX_CTX_ALL;
    socket->entry.pid = KERNEL_PID_UNDEF;
    socket->type = GNRC_NETTYPE_UDP;

    return &socket->base;

socket_error:
    errno = ENOMEM;
    return NULL;

unsupported_family:
    errno = EAFNOSUPPORT;
    return NULL;

unsupported_type:
    errno = EPROTOTYPE;
    free(socket);
    return NULL;
}

static void
sol_socket_riot_del(struct sol_socket *s)
{
    struct sol_socket_riot *socket = (struct sol_socket_riot *)s;

    if (socket->entry.pid != KERNEL_PID_UNDEF)
        gnrc_netreg_unregister(socket->type, &socket->entry);
    ipv6_udp_delete(socket);
    free(s);
}

static int
sol_socket_riot_set_on_read(struct sol_socket *s, bool (*cb)(void *data, struct sol_socket *s), const void *data)
{
    struct sol_socket_riot *socket = (struct sol_socket_riot *)s;

    SOL_NULL_CHECK(s, -EINVAL);

    socket->read.cb = cb;
    socket->read.data = data;

    return 0;
}

static int
sol_socket_riot_set_on_write(struct sol_socket *s, bool (*cb)(void *data, struct sol_socket *s), const void *data)
{
    struct sol_socket_riot *socket = (struct sol_socket_riot *)s;

    SOL_NULL_CHECK(socket, -EINVAL);

    if (cb && !socket->write_timeout) {
        socket->write_timeout = sol_timeout_add(0, write_timeout_cb, socket);
        SOL_NULL_CHECK(socket->write_timeout, -ENOMEM);
    } else if (!cb && socket->write_timeout) {
        sol_timeout_del(socket->write_timeout);
        socket->write_timeout = NULL;
    }

    socket->write.cb = cb;
    socket->write.data = data;

    return 0;
}

static ssize_t
sol_socket_riot_recvmsg(struct sol_socket *s, void *buf, size_t len, struct sol_network_link_addr *cliaddr)
{
    struct sol_socket_riot *socket = (struct sol_socket_riot *)s;

    SOL_NULL_CHECK(socket, -EINVAL);

    return ipv6_udp_recvmsg(socket, buf, len, cliaddr);
}

static int
sol_socket_riot_sendmsg(struct sol_socket *s, const void *buf, size_t len, const struct sol_network_link_addr *cliaddr)
{
    struct sol_socket_riot *socket = (struct sol_socket_riot *)s;
    gnrc_netreg_entry_t *sendto;
    gnrc_pktsnip_t *pkt;

    SOL_NULL_CHECK(socket, -EINVAL);

    pkt = ipv6_udp_sendmsg(socket, buf, len, cliaddr);
    SOL_NULL_CHECK(pkt, -ENOMEM);

    sendto = gnrc_netreg_lookup(socket->type, GNRC_NETREG_DEMUX_CTX_ALL);
    gnrc_pktbuf_hold(pkt, gnrc_netreg_num(socket->type, GNRC_NETREG_DEMUX_CTX_ALL) - 1);
    while (sendto != NULL) {
        gnrc_netapi_send(sendto->pid, pkt);
        sendto = gnrc_netreg_getnext(sendto);
    }

    return len;
}

static int
sol_socket_riot_join_group(struct sol_socket *s, int ifindex, const struct sol_network_link_addr *group)
{
    struct sol_socket_riot *socket = (struct sol_socket_riot *)s;

    SOL_NULL_CHECK(socket, -EINVAL);

    return ipv6_udp_join_group(socket, (kernel_pid_t)ifindex, group);
}

static int
sol_socket_riot_bind(struct sol_socket *s, const struct sol_network_link_addr *addr)
{
    struct sol_socket_riot *socket = (struct sol_socket_riot *)s;
    int ret;

    SOL_NULL_CHECK(socket, -EINVAL);

    ret = ipv6_udp_bind(socket, addr);
    SOL_INT_CHECK(ret, < 0, ret);

    socket->entry.pid = sol_interrupt_scheduler_get_pid();
    gnrc_netreg_register(socket->type, &socket->entry);

    return 0;
}

static int
sol_socket_riot_setsockopt(struct sol_socket *socket, enum sol_socket_level level,
    enum sol_socket_option optname, const void *optval, size_t optlen)
{
    SOL_DBG("Not implemented");
    return 0;
}

static int
sol_socket_riot_getsockopt(struct sol_socket *socket, enum sol_socket_level level,
    enum sol_socket_option optname, void *optval, size_t *optlen)
{
    SOL_DBG("Not implemented");
    return 0;
}

const struct sol_socket_impl *
sol_socket_get_impl(void)
{
    static struct sol_socket_impl impl = {
        .bind = sol_socket_riot_bind,
        .join_group = sol_socket_riot_join_group,
        .sendmsg = sol_socket_riot_sendmsg,
        .recvmsg = sol_socket_riot_recvmsg,
        .set_on_write = sol_socket_riot_set_on_write,
        .set_on_read = sol_socket_riot_set_on_read,
        .del = sol_socket_riot_del,
        .new = sol_socket_riot_new,
        .setsockopt = sol_socket_riot_setsockopt,
        .getsockopt = sol_socket_riot_getsockopt
    };

    return &impl;
}


text:
SPEC_BEGIN(YapDatabaseSecondaryIndex_CreationSpec)

describe(@"YapDatabaseSecondaryIndex_Creation", ^{
    __block YapDatabase* database;

    void(^CreateTestRecords)(YapDatabaseConnection*) = ^(YapDatabaseConnection* connection){
        [connection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
            for(int i = 0; i < 10; i++) {
                Person* person = [Person new];
                person.name = [NSString stringWithFormat:@"Person%d", i];
                person.age = 30 + i;
                person.salary = 150 * i;
                [person saveWithTransaction:transaction];
            }
            Company* company = [Company new];
            [company saveWithTransaction:transaction];
        }];
    };

    beforeEach(^{
        database = CreateDatabase();
    });

    afterEach(^{
        CleanupDatabase(database);
        database = nil;
    });

    context(@"indexes", ^{
        __block YapDatabaseConnection* connection;
        __block NSString* ageIndex;
        __block NSString* salaryIndex;
        __block NSString* nameIndex;
        beforeEach(^{
            connection = [database newConnection];
            ageIndex = @"index-age";
            salaryIndex = @"index-salary";
            nameIndex = @"index-name";
            CreateTestRecords(connection);
        });

        context(@"+indexWithClass:properties:", ^{
            __block Person* person;

            it(@"should create index using a property", ^{
                YapDatabaseSecondaryIndex* index = [YapDatabaseSecondaryIndex indexWithClass:[Person class]
                                                                                properties:@{@"age": @(YapDatabaseSecondaryIndexTypeInteger)}];
                [database registerExtension:index withName:ageIndex];

                YapDatabaseSecondaryIndex* index2 = [YapDatabaseSecondaryIndex indexWithClass:[Person class]
                                                                                properties:@{@"name": @(YapDatabaseSecondaryIndexTypeText)}];
                [database registerExtension:index2 withName:nameIndex];

                YapDatabaseSecondaryIndex* index3 = [YapDatabaseSecondaryIndex indexWithClass:[Person class]
                                                                                properties:@{@"salary": @(YapDatabaseSecondaryIndexTypeReal)}];
                [database registerExtension:index3 withName:salaryIndex];

                // find by age
                [connection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
                    YapDatabaseQuery* query = [YapDatabaseQuery queryWithFormat:@"WHERE age = ?", @33];
                    person = [Person findFirstWithIndex:ageIndex query:query transaction:transaction];
                }];

                [[person should] beNonNil];
                [[theValue(person.age) should] equal:theValue(33)];
                [[person.name should] equal:@"Person3"];

                // find by name
                [connection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
                    YapDatabaseQuery* query = [YapDatabaseQuery queryWithFormat:@"WHERE name = ?", @"Person8"];
                    person = [Person findFirstWithIndex:nameIndex query:query transaction:transaction];
                }];
                [[person should] beNonNil];
                [[theValue(person.age) should] equal:theValue(38)];
                [[person.name should] equal:@"Person8"];

                // find by salary
                [connection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
                    YapDatabaseQuery* query = [YapDatabaseQuery queryWithFormat:@"WHERE salary > ?", @1000];
                    person = [Person findFirstWithIndex:salaryIndex query:query transaction:transaction];
                }];

                [[person should] beNonNil];
                [[theValue(person.salary) should] equal:theValue(1050)];
                [[person.name should] equal:@"Person7"];
            });

            it(@"should create index using two property", ^{
                YapDatabaseSecondaryIndex* index = [YapDatabaseSecondaryIndex indexWithClass:[Person class]
                                                                                properties:@{@"age": @(YapDatabaseSecondaryIndexTypeInteger), @"salary": @(YapDatabaseSecondaryIndexTypeReal)}];
                [database registerExtension:index withName:@"age-salary"];

                // find by age
                [connection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
                    YapDatabaseQuery* query = [YapDatabaseQuery queryWithFormat:@"WHERE age > ? and salary > ?", @38, @1000];
                    person = [Person findFirstWithIndex:@"age-salary" query:query transaction:transaction];
                }];

                [[person should] beNonNil];
                [[theValue(person.age) should] equal:theValue(39)];
                [[person.name should] equal:@"Person9"];
            });
        });
    });
});

SPEC_END


text:
package com.vintek.database.model.loan;

import java.io.Serializable;
import javax.persistence.*;
import java.sql.Timestamp;
import java.math.BigDecimal;

/**
 * The persistent class for the LoanDetail database table.
 *
 */
@Entity
public class LoanDetail implements Serializable {
	private static final long serialVersionUID = 1L;

	@Id
	@Column(name="ID")
	private int id;

	@Column(name="ApplicationID")
	private String applicationID;

	@Column(name="Archive")
	private boolean archive;

	@Column(name="ChangeDate")
	private Timestamp changeDate;

	@Column(name="ChangeUser")
	private String changeUser;

	@Column(name="CheckDigitOnly")
	private boolean checkDigitOnly;

	@Column(name="CollateralEntryDate")
	private Timestamp collateralEntryDate;

	@Column(name="CollateralID")
	private int collateralID;

	@Column(name="CollateralStartDate")
	private Timestamp collateralStartDate;

	@Column(name="CollateralType")
	private int collateralType;

	@Column(name="CollateralVINErrorID")
	private int collateralVINErrorID;

	@Column(name="CoOwnerName1")
	private String coOwnerName1;

	@Column(name="CoOwnerName2")
	private String coOwnerName2;

	@Column(name="CoOwnerName3")
	private String coOwnerName3;

	@Column(name="DealerID")
	private String dealerID;

	@Column(name="EntryDate")
	private Timestamp entryDate;

	@Column(name="EntryUser")
	private String entryUser;

	@Column(name="Field1")
	private String field1;

	@Column(name="Field2")
	private String field2;

	@Column(name="Field3")
	private String field3;

	@Column(name="Field4")
	private String field4;

	@Column(name="Field5")
	private String field5;

	@Column(name="Field6")
	private String field6;

	@Column(name="LIENHOLDER")
	private boolean lienholder;

	@Column(name="LoanAmount")
	private BigDecimal loanAmount;

	@Column(name="LoanBalance")
	private BigDecimal loanBalance;

	@Column(name="LoanEnd")
	private Timestamp loanEnd;

	@Column(name="LoanStart")
	private Timestamp loanStart;

	@Column(name="LoanStatus")
	private String loanStatus;

	@Column(name="LoanType")
	private short loanType;

	@Column(name="Make")
	private String make;

	@Column(name="MatchDate")
	private Timestamp matchDate;

	@Column(name="MediaType")
	private short mediaType;

	@Column(name="Mileage")
	private int mileage;

	@Column(name="Model")
	private String model;

	@Column(name="NewOrUsed")
	private short newOrUsed;

	@Column(name="OrganizationID")
	private int organizationID;

	@Column(name="OrgID")
	private String orgID;

	@Column(name="OwnerAddress1")
	private String ownerAddress1;

	@Column(name="OwnerAddress2")
	private String ownerAddress2;

	@Column(name="OwnerCity")
	private String ownerCity;

	@Column(name="OwnerName")
	private String ownerName;

	@Column(name="OwnerState")
	private String ownerState;

	@Column(name="OwnerType")
	private short ownerType;

	@Column(name="OwnerZip")
	private String ownerZip;

	@Column(name="PaperTitleDataPending")
	private boolean paperTitleDataPending;

	@Column(name="PerfectedDate")
	private Timestamp perfectedDate;

	@Column(name="ReverseVIN")
	private String reverseVIN;

	@Column(name="StatusCodeChangeDate")
	private Timestamp statusCodeChangeDate;

	@Column(name="StatusCodeChangeUser")
	private String statusCodeChangeUser;

	@Column(name="TitleID")
	private int titleID;

	@Column(name="VIN")
	private String vin;

	private String VINError;

	@Column(name="Year")
	private String year;

	public LoanDetail() {
	}

	public String getApplicationID() {
		return this.applicationID;
	}

	public void setApplicationID(String applicationID) {
		this.applicationID = applicationID;
	}

	public boolean getArchive() {
		return this.archive;
	}

	public void setArchive(boolean archive) {
		this.archive = archive;
	}

	public Timestamp getChangeDate() {
		return this.changeDate;
	}

	public void setChangeDate(Timestamp changeDate) {
		this.changeDate = changeDate;
	}

	public String getChangeUser() {
		return this.changeUser;
	}

	public void setChangeUser(String changeUser) {
		this.changeUser = changeUser;
	}

	public boolean getCheckDigitOnly() {
		return this.checkDigitOnly;
	}

	public void setCheckDigitOnly(boolean checkDigitOnly) {
		this.checkDigitOnly = checkDigitOnly;
	}

	public Timestamp getCollateralEntryDate() {
		return this.collateralEntryDate;
	}

	public void setCollateralEntryDate(Timestamp collateralEntryDate) {
		this.collateralEntryDate = collateralEntryDate;
	}

	public int getCollateralID() {
		return this.collateralID;
	}

	public void setCollateralID(int collateralID) {
		this.collateralID = collateralID;
	}

	public Timestamp getCollateralStartDate() {
		return this.collateralStartDate;
	}

	public void setCollateralStartDate(Timestamp collateralStartDate) {
		this.collateralStartDate = collateralStartDate;
	}

	public int getCollateralType() {
		return this.collateralType;
	}

	public void setCollateralType(int collateralType) {
		this.collateralType = collateralType;
	}

	public int getCollateralVINErrorID() {
		return this.collateralVINErrorID;
	}

	public void setCollateralVINErrorID(int collateralVINErrorID) {
		this.collateralVINErrorID = collateralVINErrorID;
	}

	public String getCoOwnerName1() {
		return this.coOwnerName1;
	}

	public void setCoOwnerName1(String coOwnerName1) {
		this.coOwnerName1 = coOwnerName1;
	}

	public String getCoOwnerName2() {
		return this.coOwnerName2;
	}

	public void setCoOwnerName2(String coOwnerName2) {
		this.coOwnerName2 = coOwnerName2;
	}

	public String getCoOwnerName3() {
		return this.coOwnerName3;
	}

	public void setCoOwnerName3(String coOwnerName3) {
		this.coOwnerName3 = coOwnerName3;
	}

	public String getDealerID() {
		return this.dealerID;
	}

	public void setDealerID(String dealerID) {
		this.dealerID = dealerID;
	}

	public Timestamp getEntryDate() {
		return this.entryDate;
	}

	public void setEntryDate(Timestamp entryDate) {
		this.entryDate = entryDate;
	}

	public String getEntryUser() {
		return this.entryUser;
	}

	public void setEntryUser(String entryUser) {
		this.entryUser = entryUser;
	}

	public String getField1() {
		return this.field1;
	}

	public void setField1(String field1) {
		this.field1 = field1;
	}

	public String getField2() {
		return this.field2;
	}

	public void setField2(String field2) {
		this.field2 = field2;
	}

	public String getField3() {
		return this.field3;
	}

	public void setField3(String field3) {
		this.field3 = field3;
	}

	public String getField4() {
		return this.field4;
	}

	public void setField4(String field4) {
		this.field4 = field4;
	}

	public String getField5() {
		return this.field5;
	}

	public void setField5(String field5) {
		this.field5 = field5;
	}

	public String getField6() {
		return this.field6;
	}

	public void setField6(String field6) {
		this.field6 = field6;
	}

	public int getId() {
		return this.id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public boolean getLienholder() {
		return this.lienholder;
	}

	public void setLienholder(boolean lienholder) {
		this.lienholder = lienholder;
	}

	public BigDecimal getLoanAmount() {
		return this.loanAmount;
	}

	public void setLoanAmount(BigDecimal loanAmount) {
		this.loanAmount = loanAmount;
	}

	public BigDecimal getLoanBalance() {
		return this.loanBalance;
	}

	public void setLoanBalance(BigDecimal loanBalance) {
		this.loanBalance = loanBalance;
	}

	public Timestamp getLoanEnd() {
		return this.loanEnd;
	}

	public void setLoanEnd(Timestamp loanEnd) {
		this.loanEnd = loanEnd;
	}

	public Timestamp getLoanStart() {
		return this.loanStart;
	}

	public void setLoanStart(Timestamp loanStart) {
		this.loanStart = loanStart;
	}

	public String getLoanStatus() {
		return this.loanStatus;
	}

	public void setLoanStatus(String loanStatus) {
		this.loanStatus = loanStatus;
	}

	public short getLoanType() {
		return this.loanType;
	}

	public void setLoanType(short loanType) {
		this.loanType = loanType;
	}

	public String getMake() {
		return this.make;
	}

	public void setMake(String make) {
		this.make = make;
	}

	public Timestamp getMatchDate() {
		return this.matchDate;
	}

	public void setMatchDate(Timestamp matchDate) {
		this.matchDate = matchDate;
	}

	public short getMediaType() {
		return this.mediaType;
	}

	public void setMediaType(short mediaType) {
		this.mediaType = mediaType;
	}

	public int getMileage() {
		return this.mileage;
	}

	public void setMileage(int mileage) {
		this.mileage = mileage;
	}

	public String getModel() {
		return this.model;
	}

	public void setModel(String model) {
		this.model = model;
	}

	public short getNewOrUsed() {
		return this.newOrUsed;
	}

	public void setNewOrUsed(short newOrUsed) {
		this.newOrUsed = newOrUsed;
	}

	public int getOrganizationID() {
		return this.organizationID;
	}

	public void setOrganizationID(int organizationID) {
		this.organizationID = organizationID;
	}

	public String getOrgID() {
		return this.orgID;
	}

	public void setOrgID(String orgID) {
		this.orgID = orgID;
	}

	public String getOwnerAddress1() {
		return this.ownerAddress1;
	}

	public void setOwnerAddress1(String ownerAddress1) {
		this.ownerAddress1 = ownerAddress1;
	}

	public String getOwnerAddress2() {
		return this.ownerAddress2;
	}

	public void setOwnerAddress2(String ownerAddress2) {
		this.ownerAddress2 = ownerAddress2;
	}

	public String getOwnerCity() {
		return this.ownerCity;
	}

	public void setOwnerCity(String ownerCity) {
		this.ownerCity = ownerCity;
	}

	public String getOwnerName() {
		return this.ownerName;
	}

	public void setOwnerName(String ownerName) {
		this.ownerName = ownerName;
	}

	public String getOwnerState() {
		return this.ownerState;
	}

	public void setOwnerState(String ownerState) {
		this.ownerState = ownerState;
	}

	public short getOwnerType() {
		return this.ownerType;
	}

	public void setOwnerType(short ownerType) {
		this.ownerType = ownerType;
	}

	public String getOwnerZip() {
		return this.ownerZip;
	}

	public void setOwnerZip(String ownerZip) {
		this.ownerZip = ownerZip;
	}

	public boolean getPaperTitleDataPending() {
		return this.paperTitleDataPending;
	}

	public void setPaperTitleDataPending(boolean paperTitleDataPending) {
		this.paperTitleDataPending = paperTitleDataPending;
	}

	public Timestamp getPerfectedDate() {
		return this.perfectedDate;
	}

	public void setPerfectedDate(Timestamp perfectedDate) {
		this.perfectedDate = perfectedDate;
	}

	public String getReverseVIN() {
		return this.reverseVIN;
	}

	public void setReverseVIN(String reverseVIN) {
		this.reverseVIN = reverseVIN;
	}

	public Timestamp getStatusCodeChangeDate() {
		return this.statusCodeChangeDate;
	}

	public void setStatusCodeChangeDate(Timestamp statusCodeChangeDate) {
		this.statusCodeChangeDate = statusCodeChangeDate;
	}

	public String getStatusCodeChangeUser() {
		return this.statusCodeChangeUser;
	}

	public void setStatusCodeChangeUser(String statusCodeChangeUser) {
		this.statusCodeChangeUser = statusCodeChangeUser;
	}

	public int getTitleID() {
		return this.titleID;
	}

	public void setTitleID(int titleID) {
		this.titleID = titleID;
	}

	public String getVin() {
		return this.vin;
	}

	public void setVin(String vin) {
		this.vin = vin;
	}

	public String getVINError() {
		return this.VINError;
	}

	public void setVINError(String VINError) {
		this.VINError = VINError;
	}

	public String getYear() {
		return this.year;
	}

	public void setYear(String year) {
		this.year = year;
	}

}


text:
layout: doc
title: File Structure
searchable: false
---

# File Structure

TBC


text:
 Java app to calculate linear regression parameters, which can easily be deployed to Heroku.

## Running Locally

Make sure you have Java and Maven installed.  Also, install the [Heroku Toolbelt](https://toolbelt.heroku.com/).

```sh
$ git clone https://github.com/fh127/LinearRegressionApp
$ cd LinearRegressionApp
$ mvn clean install
$ heroku login
$ heroku create
$ heroku local web
```

Your app should now be running on local [localhost:5000](http://localhost:5000/).
```
http://localhost:5000/CalculateLinearRegressionExample
```

## Deploying to Heroku

```sh
$ heroku create
$ git push heroku master
$ heroku ps:scale web=1
$ heroku open
```

## Documentation

tener en cuenta
-Tener en cuenta, en algunos equipos puede tener dificultad con los permisos de administrador
```sh
$ sudo su
```

- [Java on Heroku](https://devcenter.heroku.com/categories/java)


text:
<!doctype html>

		<meta charset="utf-8">

		<title>Object-Oriented CoffeeScript</title>

		<meta name="description" content="A framework for easily creating beautiful presentations using HTML">
		<meta name="author" content="Hakim El Hattab">

		<meta name="apple-mobile-web-app-capable" content="yes" />
		<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />

		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

		<link rel="stylesheet" href="css/reveal.min.css">
		<link rel="stylesheet" href="css/theme/default.css" id="theme">

		<link rel="stylesheet" href="lib/css/zenburn.css">

Object-Oriented CoffeeScript

						Richard Clayton - DevOps/Fullstack Engineer

Goals

Discuss Object-Oriented Programming (OOP) in JavaScript.

Demonstrate how CoffeeScript provides a simpler OOP model for JavaScript.

What this talk is not about

A debate about the merits of functional or object-oriented programming.

Advocation of CoffeeScript over JavaScript.

Use whatever makes you feel most productive.

About Me

Chief Software Engineer, Berico Technologies

Hobbies:

Software (truly blessed to do what I love!)

Traveling, especially to historic locales.

Boogie Boarding

Remodeling my house

Whiskey, especially Scotch and Bourbon.

Married with two precocious daughters (3 and 5)...

Programming Paradigms

								A programming paradigm is a fundamental style of computer programming, a way of building the structure and elements of computer programs.

								http://en.wikipedia.org/wiki/Programming_paradigm

Six Fundamental Paradigms

Imperative

Declaritve

Functional

Object-Oriented

Logic

Symbolic

							http://en.wikipedia.org/wiki/Programming_paradigm

JavaScript is a hybrid

Imperative

Functional

Object-Oriented

							http://en.wikipedia.org/wiki/Comparison_of_multi-paradigm_programming_languages

Imperative
explicit statements that change a program state

Programmers describe how to do something:

document.getElementById("caption").style.width = '300px';

Instead of describing the end state (declarative):

My Caption

							http://en.wikipedia.org/wiki/Comparison_of_multi-paradigm_programming_languages

Functional
uses evaluation of mathematical functions
and avoids state and mutable data

Behavior is described as functions:

function square(x){ return x * x; }

State passed into the function remains unchanged:

var x = 5;
var y = square(x);
console.log(x); // 5
console.log(y); // 25

							http://en.wikipedia.org/wiki/Comparison_of_multi-paradigm_programming_languages

Object-Oriented
uses data structures consisting of
data fields and methods together

Behavior is defined on the container:

var Car = function(){
 var speed = 0;
 this.accelerate = function(mph){
  speed += mph;
 };
};

Behavior of the container modifies state:

var car = new Car();
car.accelerate(10); // 10mph
car.accelerate(15); // 25mph

							http://en.wikipedia.org/wiki/Comparison_of_multi-paradigm_programming_languages

Object-Oriented JavaScript
Confusing, underused, and underappreciated.

What's Confusing about OO.js?

No class declaration syntax.

Unfamiliar inheritance model.

Limited encapsulation.

No class declaration syntax

Class/Type declaration is simply assigning properties and functions on another function (which is also strangely an object)!

var Car = function(gasAmount){
 // This is the constructor!
 this.speed = 0; // Public property
 this.gas = (gasAmount > 10.5)? 10.5 : gasAmount;
 // Public method
 this.fillTank = function(gasAmount){
  if ((this.gas + gasAmount) >= 10.5){ this.gas = 10.5; }
  else { this.gas += gasAmount; }
 }
};
//Public method
Car.prototype.move = function(){
 if (this.gas > 0){ this.gas -= 0.1; this.speed++; }
};

Unfamiliar inheritance model.

Prototypical Inheritance

Objects inherit directly from other objects.

Members are "resolved" through a prototype chain.

var Car = function(){
 console.log("Vroom!");
 this.speed = 0;
};

Car.prototype.move = function(){ console.log("Moving"); };

var Honda = function(){
 Car.call(this); // Call the Parent Contructor
 console.log("Gas efficient, Vroom!");
};

Honda.prototype = Object.create(Car.prototype);

var civic = new Honda();
civic.move(); // Resolved to Car

Limited encapsulation

Member visibility is a real problem in JavaScript, since there is no real concept of private or protected state.

var Clazz = function(){
 // Crockford calls these 'private', I call them 'hidden'.
 var hidden = true;
 // Can access variables in the constructor.
 // Crockford calls this a "privileged method"
 var modifyInternal = function(value){ hidden = value; }
 // Public variable
 this.publicVar = 10;
 // 'Public-privileged' method since it has access to
 // variables defined within the constructor.
 this.publicMethod = function(){}
}
// Public method attached to the prototype.
Clazz.prototype.move = function(){
 // Has no access to variables defined within the constructor
};

						Douglas Crockford would disagree with me to some extent. You can see a more indepth article about member visibility here: http://www.crockford.com/javascript/private.html

So how do we make OOP in JavaScript more approachable?

CoffeeScript!

is a little language that compiles into JavaScript.

								Underneath that awkward Java-esque patina, JavaScript has always had a gorgeous heart.

								CoffeeScript is an attempt to expose the good parts of JavaScript in a simple way.

							http://coffeescript.org/

Object-Oriented CoffeeScript

Instead of repetitively attaching functions to a prototype, CoffeeScript provides a basic class structure that allows you to name your class, set the superclass, assign prototypal properties, and define the constructor, in a single assignable expression.

						http://coffeescript.org/#classes

Class Declaration

class Car
 speed: 0
 move: (mph) -> @speed += mph

						Note: @ is a shortcut for this; you are free to keep using this if you want.

var Car;

Car = (function() {
 function Car() {}

 Car.prototype.speed = 0;

 Car.prototype.move = function(mph) {
  return this.speed += mph;
 };

 return Car;
})();

Constructors

class Car
 constructor: (name) ->
  console.log "Created car named '#{name}'"

var Car;

Car = (function() {
 function Car(name) {
  console.log("Created car named '" + name + "'");
 }

 return Car;
})();

Automatic Property Declaration

class Car
 constructor: (@name, @mpg) ->
  console.log "Created car named '#{@name}' with #{@mpg} mpgs."

var Car;

Car = (function() {
  function Car(name, mpg) {
   this.name = name;
   this.mpg = mpg;
   console.log("Created car named '" + this.name
	  + "' with " + this.mpg + " mpgs.");
 }

 return Car;

})();

Member visibility

class Clazz
 hiddenVar = 10
 publicVar: 10
 hiddenMethod = -> console.log "Hidden!"
 publicMethod: -> console.log "Public!"

var Clazz;

Clazz = (function() {
 var hiddenMethod, hiddenVar;
 function Clazz() {}
 hiddenVar = 10;
 Clazz.prototype.publicVar = 10;
 hiddenMethod = function() {
  return console.log("Hidden!");
 };
 Clazz.prototype.publicMethod = function() {
  return console.log("Public!");
 };
 return Clazz;
})();

          Caution!  There are no 'private' variables in JavaScript, simply those not in scope.
Hidden variables are actually global to all instances of the type for which they are defined!!!!

Class properties and methods

class Clazz
 @CLASS_PROPERTY = 123
 @CLASS_METHOD = -> console.log Clazz.CLASS_PROPERTY

Clazz.CLASS_METHOD()

var Clazz;

Clazz = (function() {
 function Clazz() {}

 Clazz.CLASS_PROPERTY = 123;

 Clazz.CLASS_METHOD = function() {
  return console.log(Clazz.CLASS_PROPERTY);
 };

 return Clazz;

})();

Clazz.CLASS_METHOD();

Inheritance

class Human
 hitPoints = 10
 receiveDamage: (dmg) ->
  hitPoints -= dmg

class Knight extends Human
 attack: (human) ->
  human.receiveDamage 15

serf = new Human
knight1 = new Knight
knight2 = new Knight

knight1.attack serf
knight2.attack knight1

Inheritance, cont.

var Human, Knight, knight1, knight2, serf,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) {
 for (var key in parent) {
  if (__hasProp.call(parent, key)) child[key] = parent[key];
 }
 function ctor() { this.constructor = child; }
 ctor.prototype = parent.prototype;
 child.prototype = new ctor();
 child.__super__ = parent.prototype; return child;
};

					Great discussion of what __extends does here:
http://hangar.runway7.net/coffeescript/class-model

Inheritance, cont.

Human = (function() {
 var hitPoints;
 function Human() {}
  hitPoints = 10;
  Human.prototype.receiveDamage = function(dmg) {
  return hitPoints -= dmg;
 };
 return Human;
})();

Inheritance, cont.

Knight = (function(_super) {
 __extends(Knight, _super);
 function Knight() {
  return Knight.__super__.constructor.apply(this, arguments);
 }
 Knight.prototype.attack = function(human) {
  return human.receiveDamage(15);
 };
 return Knight;
})(Human);

serf = new Human;
knight1 = new Knight;
knight2 = new Knight;

knight1.attack(serf);
knight2.attack(knight1);

Calling the Parent's Constructor

class Car
 constructor: (@topSpeed, @mpg) ->

class Honda extends Car
 constructor: (topSpeed, mpg, @color) ->
  super topSpeed, mpg

Car = (function() {
 function Car(topSpeed, mpg) {
  this.topSpeed = topSpeed;
  this.mpg = mpg;
 }
 return Car;
})();

Honda = (function(_super) {
 __extends(Honda, _super);
 function Honda(topSpeed, mpg, color) {
  this.color = color;
  Honda.__super__.constructor.call(this, topSpeed, mpg);
 }
 return Honda;
})(Car);

Calling Methods on Super Type

class Car
 speed: 10
 move: (mph) ->
  @speed += mph
 getSpeed: -> @speed

class Honda extends Car
 move: (mph) ->
  console.log "This little Honda's movin'!"
  super mph

Honda = (function(_super) {
 __extends(Honda, _super);

 function Honda() {
  return Honda.__super__.constructor.apply(this, arguments);
 }

 Honda.prototype.move = function(mph) {
  console.log("This little Honda's movin'!");
  return Honda.__super__.move.call(this, mph);
 };

 return Honda;
})(Car);

Protypical Assignment

class Car
 speed: 10
 move: (mph) ->
  @speed += mph

Car::getSpeed -> @speed

var Car;

Car = (function() {
 function Car() {}
 Car.prototype.speed = 10;
 Car.prototype.move = function(mph) {
  return this.speed += mph;
 };
 return Car;
})();

Car.prototype.getSpeed(function() {
 return this.speed;
});

Function Binding

Losing closure-scope sucks and is especially
 problematic when using classes:

class TextDestroyerOfDoom
 message: "Your text was destroyed!"
 destroyText: (i, element) ->
  $(element).text @message

destroyer = new TextDestroyerOfDoom()

$("div").each destroyer.destroyText

This code does not work!

this has been overridden by jQuery to the

current DOM element in the iteration,

meaning @message is undefined.

Fat Arrow =>

Binds the execution of the member method to the object instance, preserving the scope of this.

class TextDestroyerOfDoom
message: "Your text was destroyed!"
destroyText: (i, element) =>
	$(element).text @message

destroyer = new TextDestroyerOfDoom()

$("div").each destroyer.destroyText

Fat Arrow, Behind the Scenes

var TextDestroyerOfDoom, destroyer,
 __bind = function(fn, me){
  return function(){ return fn.apply(me, arguments); }; };

TextDestroyerOfDoom = (function() {
 function TextDestroyerOfDoom() {
  this.destroyText = __bind(this.destroyText, this);
 }

 TextDestroyerOfDoom.prototype.message = "Your text was destroyed!";

 TextDestroyerOfDoom.prototype.destroyText = function(i, element) {
  return $(element).text(this.message);
 };

 return TextDestroyerOfDoom;
})();

Conclusion

CoffeeScript makes OOP in JavaScript...

Understandable

Easier

Enjoyable

Thank You!

Contact Me

rlc.blacksun@gmail.com

@richardclayton

http://rclayton.silvrback.com

http://www.gettingcirrius.com

github.com/rclayton,
							github.com/berico-rclayton


text:
package com.amazonaws.services.elasticsearch.model.transform;

import java.util.Map;

import javax.annotation.Generated;

import com.amazonaws.SdkClientException;
import com.amazonaws.services.elasticsearch.model.*;

import com.amazonaws.protocol.*;
import com.amazonaws.annotation.SdkInternalApi;

/**
 * ElasticsearchDomainStatusMarshaller
 */
@Generated("com.amazonaws:aws-java-sdk-code-generator")
@SdkInternalApi
public class ElasticsearchDomainStatusMarshaller {

    private static final MarshallingInfo<String> DOMAINID_BINDING = MarshallingInfo.builder(MarshallingType.STRING).marshallLocation(MarshallLocation.PAYLOAD)
            .marshallLocationName("DomainId").build();
    private static final MarshallingInfo<String> DOMAINNAME_BINDING = MarshallingInfo.builder(MarshallingType.STRING)
            .marshallLocation(MarshallLocation.PAYLOAD).marshallLocationName("DomainName").build();
    private static final MarshallingInfo<String> ARN_BINDING = MarshallingInfo.builder(MarshallingType.STRING).marshallLocation(MarshallLocation.PAYLOAD)
            .marshallLocationName("ARN").build();
    private static final MarshallingInfo<Boolean> CREATED_BINDING = MarshallingInfo.builder(MarshallingType.BOOLEAN).marshallLocation(MarshallLocation.PAYLOAD)
            .marshallLocationName("Created").build();
    private static final MarshallingInfo<Boolean> DELETED_BINDING = MarshallingInfo.builder(MarshallingType.BOOLEAN).marshallLocation(MarshallLocation.PAYLOAD)
            .marshallLocationName("Deleted").build();
    private static final MarshallingInfo<String> ENDPOINT_BINDING = MarshallingInfo.builder(MarshallingType.STRING).marshallLocation(MarshallLocation.PAYLOAD)
            .marshallLocationName("Endpoint").build();
    private static final MarshallingInfo<Map> ENDPOINTS_BINDING = MarshallingInfo.builder(MarshallingType.MAP).marshallLocation(MarshallLocation.PAYLOAD)
            .marshallLocationName("Endpoints").build();
    private static final MarshallingInfo<Boolean> PROCESSING_BINDING = MarshallingInfo.builder(MarshallingType.BOOLEAN)
            .marshallLocation(MarshallLocation.PAYLOAD).marshallLocationName("Processing").build();
    private static final MarshallingInfo<Boolean> UPGRADEPROCESSING_BINDING = MarshallingInfo.builder(MarshallingType.BOOLEAN)
            .marshallLocation(MarshallLocation.PAYLOAD).marshallLocationName("UpgradeProcessing").build();
    private static final MarshallingInfo<String> ELASTICSEARCHVERSION_BINDING = MarshallingInfo.builder(MarshallingType.STRING)
            .marshallLocation(MarshallLocation.PAYLOAD).marshallLocationName("ElasticsearchVersion").build();
    private static final MarshallingInfo<StructuredPojo> ELASTICSEARCHCLUSTERCONFIG_BINDING = MarshallingInfo.builder(MarshallingType.STRUCTURED)
            .marshallLocation(MarshallLocation.PAYLOAD).marshallLocationName("ElasticsearchClusterConfig").build();
    private static final MarshallingInfo<StructuredPojo> EBSOPTIONS_BINDING = MarshallingInfo.builder(MarshallingType.STRUCTURED)
            .marshallLocation(MarshallLocation.PAYLOAD).marshallLocationName("EBSOptions").build();
    private static final MarshallingInfo<String> ACCESSPOLICIES_BINDING = MarshallingInfo.builder(MarshallingType.STRING)
            .marshallLocation(MarshallLocation.PAYLOAD).marshallLocationName("AccessPolicies").build();
    private static final MarshallingInfo<StructuredPojo> SNAPSHOTOPTIONS_BINDING = MarshallingInfo.builder(MarshallingType.STRUCTURED)
            .marshallLocation(MarshallLocation.PAYLOAD).marshallLocationName("SnapshotOptions").build();
    private static final MarshallingInfo<StructuredPojo> VPCOPTIONS_BINDING = MarshallingInfo.builder(MarshallingType.STRUCTURED)
            .marshallLocation(MarshallLocation.PAYLOAD).marshallLocationName("VPCOptions").build();
    private static final MarshallingInfo<StructuredPojo> COGNITOOPTIONS_BINDING = MarshallingInfo.builder(MarshallingType.STRUCTURED)
            .marshallLocation(MarshallLocation.PAYLOAD).marshallLocationName("CognitoOptions").build();
    private static final MarshallingInfo<StructuredPojo> ENCRYPTIONATRESTOPTIONS_BINDING = MarshallingInfo.builder(MarshallingType.STRUCTURED)
            .marshallLocation(MarshallLocation.PAYLOAD).marshallLocationName("EncryptionAtRestOptions").build();
    private static final MarshallingInfo<StructuredPojo> NODETONODEENCRYPTIONOPTIONS_BINDING = MarshallingInfo.builder(MarshallingType.STRUCTURED)
            .marshallLocation(MarshallLocation.PAYLOAD).marshallLocationName("NodeToNodeEncryptionOptions").build();
    private static final MarshallingInfo<Map> ADVANCEDOPTIONS_BINDING = MarshallingInfo.builder(MarshallingType.MAP).marshallLocation(MarshallLocation.PAYLOAD)
            .marshallLocationName("AdvancedOptions").build();
    private static final MarshallingInfo<Map> LOGPUBLISHINGOPTIONS_BINDING = MarshallingInfo.builder(MarshallingType.MAP)
            .marshallLocation(MarshallLocation.PAYLOAD).marshallLocationName("LogPublishingOptions").build();
    private static final MarshallingInfo<StructuredPojo> SERVICESOFTWAREOPTIONS_BINDING = MarshallingInfo.builder(MarshallingType.STRUCTURED)
            .marshallLocation(MarshallLocation.PAYLOAD).marshallLocationName("ServiceSoftwareOptions").build();

    private static final ElasticsearchDomainStatusMarshaller instance = new ElasticsearchDomainStatusMarshaller();

    public static ElasticsearchDomainStatusMarshaller getInstance() {
        return instance;
    }

    /**
     * Marshall the given parameter object.
     */
    public void marshall(ElasticsearchDomainStatus elasticsearchDomainStatus, ProtocolMarshaller protocolMarshaller) {

        if (elasticsearchDomainStatus == null) {
            throw new SdkClientException("Invalid argument passed to marshall(...)");
        }

        try {
            protocolMarshaller.marshall(elasticsearchDomainStatus.getDomainId(), DOMAINID_BINDING);
            protocolMarshaller.marshall(elasticsearchDomainStatus.getDomainName(), DOMAINNAME_BINDING);
            protocolMarshaller.marshall(elasticsearchDomainStatus.getARN(), ARN_BINDING);
            protocolMarshaller.marshall(elasticsearchDomainStatus.getCreated(), CREATED_BINDING);
            protocolMarshaller.marshall(elasticsearchDomainStatus.getDeleted(), DELETED_BINDING);
            protocolMarshaller.marshall(elasticsearchDomainStatus.getEndpoint(), ENDPOINT_BINDING);
            protocolMarshaller.marshall(elasticsearchDomainStatus.getEndpoints(), ENDPOINTS_BINDING);
            protocolMarshaller.marshall(elasticsearchDomainStatus.getProcessing(), PROCESSING_BINDING);
            protocolMarshaller.marshall(elasticsearchDomainStatus.getUpgradeProcessing(), UPGRADEPROCESSING_BINDING);
            protocolMarshaller.marshall(elasticsearchDomainStatus.getElasticsearchVersion(), ELASTICSEARCHVERSION_BINDING);
            protocolMarshaller.marshall(elasticsearchDomainStatus.getElasticsearchClusterConfig(), ELASTICSEARCHCLUSTERCONFIG_BINDING);
            protocolMarshaller.marshall(elasticsearchDomainStatus.getEBSOptions(), EBSOPTIONS_BINDING);
            protocolMarshaller.marshall(elasticsearchDomainStatus.getAccessPolicies(), ACCESSPOLICIES_BINDING);
            protocolMarshaller.marshall(elasticsearchDomainStatus.getSnapshotOptions(), SNAPSHOTOPTIONS_BINDING);
            protocolMarshaller.marshall(elasticsearchDomainStatus.getVPCOptions(), VPCOPTIONS_BINDING);
            protocolMarshaller.marshall(elasticsearchDomainStatus.getCognitoOptions(), COGNITOOPTIONS_BINDING);
            protocolMarshaller.marshall(elasticsearchDomainStatus.getEncryptionAtRestOptions(), ENCRYPTIONATRESTOPTIONS_BINDING);
            protocolMarshaller.marshall(elasticsearchDomainStatus.getNodeToNodeEncryptionOptions(), NODETONODEENCRYPTIONOPTIONS_BINDING);
            protocolMarshaller.marshall(elasticsearchDomainStatus.getAdvancedOptions(), ADVANCEDOPTIONS_BINDING);
            protocolMarshaller.marshall(elasticsearchDomainStatus.getLogPublishingOptions(), LOGPUBLISHINGOPTIONS_BINDING);
            protocolMarshaller.marshall(elasticsearchDomainStatus.getServiceSoftwareOptions(), SERVICESOFTWAREOPTIONS_BINDING);
        } catch (Exception e) {
            throw new SdkClientException("Unable to marshall request to JSON: " + e.getMessage(), e);
        }
    }

}