From b70563673ca893154b26d301327b941ee2d19c7c Mon Sep 17 00:00:00 2001 From: Victor Vazquez Date: Sat, 18 Jun 2022 01:48:18 +0000 Subject: [PATCH] changes --- sdk/template/azure-template/CMakeLists.txt | 58 +- .../inc/azure/storage/blobs/rest_client.hpp | 3932 ++++++++++ .../inc/azure/template/template_client.hpp | 4 +- .../azure-template/src/rest_client.cpp | 6804 +++++++++++++++++ .../azure-template/src/template_client.cpp | 14 +- sdk/template/azure-template/vcpkg.json | 3 + 6 files changed, 10752 insertions(+), 63 deletions(-) create mode 100644 sdk/template/azure-template/inc/azure/storage/blobs/rest_client.hpp create mode 100644 sdk/template/azure-template/src/rest_client.cpp diff --git a/sdk/template/azure-template/CMakeLists.txt b/sdk/template/azure-template/CMakeLists.txt index 7d4d3126a..f9f7df4e8 100644 --- a/sdk/template/azure-template/CMakeLists.txt +++ b/sdk/template/azure-template/CMakeLists.txt @@ -9,51 +9,28 @@ az_vcpkg_integrate() cmake_minimum_required (VERSION 3.13) project(azure-template LANGUAGES CXX) -include(AzureTransportAdapters) -include(AzureBuildTargetForCI) -include(AzureVersion) -include(AzureCodeCoverage) -include(AzureDoxygen) -include(AzureGlobalCompileOptions) -include(AzureConfigRTTI) - set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED True) set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) -include(AzureVersion) -include(AzureCodeCoverage) -include(AzureTransportAdapters) -include(AzureDoxygen) -include(AzureGlobalCompileOptions) -include(AzureConfigRTTI) -include(AzureBuildTargetForCI) -# Add create_map_file function -include(CreateMapFile) - - -if(NOT AZ_ALL_LIBRARIES) - find_package(azure-core-cpp "1.2.0" CONFIG QUIET) - if(NOT azure-core-cpp_FOUND) - find_package(azure-core-cpp "1.2.0" REQUIRED) - endif() -endif() +find_package(azure-storage-common-cpp REQUIRED) set( AZURE_TEMPLATE_HEADER inc/azure/template/dll_import_export.hpp inc/azure/template/template_client.hpp inc/azure/template.hpp + inc/azure/storage/blobs/rest_client.hpp ) set( AZURE_TEMPLATE_SOURCE src/private/package_version.hpp src/template_client.cpp + src/rest_client.cpp ) add_library(azure-template ${AZURE_TEMPLATE_HEADER} ${AZURE_TEMPLATE_SOURCE}) -create_per_service_target_build(template azure-template) target_include_directories( azure-template @@ -62,35 +39,8 @@ target_include_directories( $ ) -target_link_libraries(azure-template PUBLIC Azure::azure-core) +target_link_libraries(azure-template PUBLIC Azure::azure-core Azure::azure-storage-common) # make sure that users can consume the project as a library. add_library(Azure::azure-template ALIAS azure-template) -# coverage. Has no effect if BUILD_CODE_COVERAGE is OFF -create_code_coverage(template azure-template azure-template-test "tests?/*;samples?/*") - -get_az_version("${CMAKE_CURRENT_SOURCE_DIR}/src/private/package_version.hpp") -generate_documentation(azure-template ${AZ_LIBRARY_VERSION}) - -az_vcpkg_export( - azure-template - TEMPLATE - "azure/template/dll_import_export.hpp" - ) - -az_rtti_setup( - azure-template - TEMPLATE - "azure/template/rtti.hpp" -) - -if(BUILD_TESTING) - if (NOT AZ_ALL_LIBRARIES OR FETCH_SOURCE_DEPS) - include(AddGoogleTest) - enable_testing () - endif() - - # tests - add_subdirectory(test) -endif() diff --git a/sdk/template/azure-template/inc/azure/storage/blobs/rest_client.hpp b/sdk/template/azure-template/inc/azure/storage/blobs/rest_client.hpp new file mode 100644 index 000000000..cf6c87a23 --- /dev/null +++ b/sdk/template/azure-template/inc/azure/storage/blobs/rest_client.hpp @@ -0,0 +1,3932 @@ + +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// +// Code generated by Microsoft (R) AutoRest C++ Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "azure/template/dll_import_export.hpp" +#include + +namespace Azure { +namespace Storage { +namespace Blobs { +namespace _detail { +/** + * The version used for the operations to Azure storage services. + */ +constexpr static const char *ApiVersion = "2020-08-04"; +} // namespace _detail +namespace Models { +/** + * @brief The algorithm used to produce the encryption key hash. Currently, the + * only accepted value is "AES256". Must be provided if the x-ms-encryption-key + * header is provided. + */ +class EncryptionAlgorithmType final { +public: + EncryptionAlgorithmType() = default; + explicit EncryptionAlgorithmType(std::string value) + : m_value(std::move(value)) {} + bool operator==(const EncryptionAlgorithmType &other) const { + return m_value == other.m_value; + } + bool operator!=(const EncryptionAlgorithmType &other) const { + return !(*this == other); + } + const std::string &ToString() const { return m_value; } + AZ_TEMPLATE_DLLEXPORT const static EncryptionAlgorithmType Aes256; + +private: + std::string m_value; +}; +/** + * @brief Extensible enum used to specify how the service should look for a + * block ID. + */ +class BlockType final { +public: + BlockType() = default; + explicit BlockType(std::string value) : m_value(std::move(value)) {} + bool operator==(const BlockType &other) const { + return m_value == other.m_value; + } + bool operator!=(const BlockType &other) const { return !(*this == other); } + const std::string &ToString() const { return m_value; } + AZ_TEMPLATE_DLLEXPORT const static BlockType Committed; + AZ_TEMPLATE_DLLEXPORT const static BlockType Uncommitted; + AZ_TEMPLATE_DLLEXPORT const static BlockType Latest; + +private: + std::string m_value; +}; +/** + * @brief The retention policy which determines how long the associated data + * should persist. + */ +struct RetentionPolicy final { + /** + * Indicates whether a retention policy is enabled for the storage service. + */ + bool IsEnabled = bool(); + /** + * Indicates the number of days that metrics or logging or soft-deleted data + * should be retained. All data older than this value will be deleted. + */ + Nullable Days; +}; +/** + * @brief Azure Analytics Logging settings. + */ +struct AnalyticsLogging final { + /** + * The version of Storage Analytics to configure. + */ + std::string Version; + /** + * Indicates whether all delete requests should be logged. + */ + bool Delete = bool(); + /** + * Indicates whether all read requests should be logged. + */ + bool Read = bool(); + /** + * Indicates whether all write requests should be logged. + */ + bool Write = bool(); + /** + * The retention policy which determines how long the associated data should + * persist. + */ + Models::RetentionPolicy RetentionPolicy; +}; +/** + * @brief A summary of request statistics grouped by API in hour or minute + * aggregates for blobs. + */ +struct Metrics final { + /** + * The version of Storage Analytics to configure. + */ + std::string Version; + /** + * Indicates whether metrics are enabled for the Blob service. + */ + bool IsEnabled = bool(); + /** + * Indicates whether metrics should generate summary statistics for called API + * operations. + */ + Nullable IncludeApis; + /** + * The retention policy which determines how long the associated data should + * persist. + */ + Models::RetentionPolicy RetentionPolicy; +}; +/** + * @brief CORS is an HTTP feature that enables a web application running under + * one domain to access resources in another domain. Web browsers implement a + * security restriction known as same-origin policy that prevents a web page + * from calling APIs in a different domain; CORS provides a secure way to allow + * one domain (the origin domain) to call APIs in another domain. + */ +struct CorsRule final { + /** + * The origin domains that are permitted to make a request against the storage + * service via CORS. The origin domain is the domain from which the request + * originates. Note that the origin must be an exact case-sensitive match with + * the origin that the user age sends to the service. You can also use the + * wildcard character '*' to allow all origin domains to make requests via + * CORS. + */ + std::string AllowedOrigins; + /** + * The methods (HTTP request verbs) that the origin domain may use for a CORS + * request. (comma separated). + */ + std::string AllowedMethods; + /** + * The request headers that the origin domain may specify on the CORS request. + */ + std::string AllowedHeaders; + /** + * The response headers that may be sent in the response to the CORS request + * and exposed by the browser to the request issuer. + */ + std::string ExposedHeaders; + /** + * The maximum amount time that a browser should cache the preflight OPTIONS + * request. + */ + int32_t MaxAgeInSeconds = int32_t(); +}; +/** + * @brief The properties that enable an account to host a static website. + */ +struct StaticWebsite final { + /** + * Indicates whether this account is hosting a static website. + */ + bool IsEnabled = bool(); + /** + * The default name of the index page under each directory. + */ + Nullable IndexDocument; + /** + * The absolute path of the custom 404 page. + */ + Nullable ErrorDocument404Path; + /** + * Absolute path of the default index page. + */ + Nullable DefaultIndexDocumentPath; +}; +/** + * @brief Response type for + * #Azure::Storage::Blobs::ServiceClient::SetProperties. + */ +struct SetServicePropertiesResult final {}; +/** + * @brief Storage Service Properties. + */ +struct BlobServiceProperties final { + /** + * Azure Analytics Logging settings. + */ + AnalyticsLogging Logging; + /** + * A summary of request statistics grouped by API in hour or minute aggregates + * for blobs. + */ + Metrics HourMetrics; + /** + * A summary of request statistics grouped by API in hour or minute aggregates + * for blobs. + */ + Metrics MinuteMetrics; + /** + * The set of CORS rules. + */ + std::vector Cors; + /** + * The default version to use for requests to the Blob service if an incoming + * request's version is not specified. Possible values include version + * 2008-10-27 and all more recent versions. + */ + Nullable DefaultServiceVersion; + /** + * The retention policy which determines how long the associated data should + * persist. + */ + RetentionPolicy DeleteRetentionPolicy; + /** + * The properties that enable an account to host a static website. + */ + Models::StaticWebsite StaticWebsite; +}; +/** + * @brief The status of the secondary location. + */ +class GeoReplicationStatus final { +public: + GeoReplicationStatus() = default; + explicit GeoReplicationStatus(std::string value) + : m_value(std::move(value)) {} + bool operator==(const GeoReplicationStatus &other) const { + return m_value == other.m_value; + } + bool operator!=(const GeoReplicationStatus &other) const { + return !(*this == other); + } + const std::string &ToString() const { return m_value; } + AZ_TEMPLATE_DLLEXPORT const static GeoReplicationStatus Live; + AZ_TEMPLATE_DLLEXPORT const static GeoReplicationStatus Bootstrap; + AZ_TEMPLATE_DLLEXPORT const static GeoReplicationStatus Unavailable; + +private: + std::string m_value; +}; +/** + * @brief Geo-Replication information for the Secondary Storage Service. + */ +struct GeoReplication final { + /** + * The status of the secondary location. + */ + GeoReplicationStatus Status; + /** + * A GMT date/time value, to the second. All primary writes preceding this + * value are guaranteed to be available for read operations at the secondary. + * Primary writes after this point in time may or may not be available for + * reads. + */ + Nullable LastSyncedOn; +}; +/** + * @brief Stats for the storage service. + */ +struct ServiceStatistics final { + /** + * Geo-Replication information for the Secondary Storage Service. + */ + Models::GeoReplication GeoReplication; +}; +/** + * @brief The current lease status of the blob. + */ +class LeaseStatus final { +public: + LeaseStatus() = default; + explicit LeaseStatus(std::string value) : m_value(std::move(value)) {} + bool operator==(const LeaseStatus &other) const { + return m_value == other.m_value; + } + bool operator!=(const LeaseStatus &other) const { return !(*this == other); } + const std::string &ToString() const { return m_value; } + AZ_TEMPLATE_DLLEXPORT const static LeaseStatus Locked; + AZ_TEMPLATE_DLLEXPORT const static LeaseStatus Unlocked; + +private: + std::string m_value; +}; +/** + * @brief The current lease state of the blob. + */ +class LeaseState final { +public: + LeaseState() = default; + explicit LeaseState(std::string value) : m_value(std::move(value)) {} + bool operator==(const LeaseState &other) const { + return m_value == other.m_value; + } + bool operator!=(const LeaseState &other) const { return !(*this == other); } + const std::string &ToString() const { return m_value; } + AZ_TEMPLATE_DLLEXPORT const static LeaseState Available; + AZ_TEMPLATE_DLLEXPORT const static LeaseState Leased; + AZ_TEMPLATE_DLLEXPORT const static LeaseState Expired; + AZ_TEMPLATE_DLLEXPORT const static LeaseState Breaking; + AZ_TEMPLATE_DLLEXPORT const static LeaseState Broken; + +private: + std::string m_value; +}; +/** + * @brief When a blob is leased, specifies whether the lease is of infinite or + * fixed duration. + */ +class LeaseDurationType final { +public: + LeaseDurationType() = default; + explicit LeaseDurationType(std::string value) : m_value(std::move(value)) {} + bool operator==(const LeaseDurationType &other) const { + return m_value == other.m_value; + } + bool operator!=(const LeaseDurationType &other) const { + return !(*this == other); + } + const std::string &ToString() const { return m_value; } + AZ_TEMPLATE_DLLEXPORT const static LeaseDurationType Infinite; + AZ_TEMPLATE_DLLEXPORT const static LeaseDurationType Fixed; + +private: + std::string m_value; +}; +/** + * @brief Specifies whether data in the container may be accessed publicly and + * the level of access. + */ +class PublicAccessType final { +public: + PublicAccessType() = default; + explicit PublicAccessType(std::string value) : m_value(std::move(value)) {} + bool operator==(const PublicAccessType &other) const { + return m_value == other.m_value; + } + bool operator!=(const PublicAccessType &other) const { + return !(*this == other); + } + const std::string &ToString() const { return m_value; } + AZ_TEMPLATE_DLLEXPORT const static PublicAccessType BlobContainer; + AZ_TEMPLATE_DLLEXPORT const static PublicAccessType Blob; + AZ_TEMPLATE_DLLEXPORT const static PublicAccessType None; + +private: + std::string m_value; +}; +/** + * @brief Properties of a container. + */ +struct BlobContainerItemDetails final { + /** + * Returns the date and time the container was last modified. Any operation + * that modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * The current lease status of the blob. + */ + Models::LeaseStatus LeaseStatus; + /** + * The current lease state of the blob. + */ + Models::LeaseState LeaseState; + /** + * When a blob is leased, specifies whether the lease is of infinite or fixed + * duration. + */ + Nullable LeaseDuration; + /** + * Specifies whether data in the container may be accessed publicly and the + * level of access. + */ + PublicAccessType AccessType; + /** + * Indicates whether the container has an immutability policy set on it. + */ + bool HasImmutabilityPolicy = bool(); + /** + * Indicates whether the container has a legal hold. + */ + bool HasLegalHold = bool(); + /** + * The default encryption scope for the container. + */ + std::string DefaultEncryptionScope = "$account-encryption-key"; + /** + * Indicates whether the container's default encryption scope can be + * overriden. + */ + bool PreventEncryptionScopeOverride = false; + /** + * Data and time at which this container was deleted. Only valid when this + * container was deleted. + */ + Nullable DeletedOn; + /** + * Remaining days before this container will be permanantely deleted. Only + * valid when this container was deleted. + */ + Nullable RemainingRetentionDays; + /** + * A set of name-value pairs associated with this blob or blob container. + */ + std::map + Metadata; + /** + * Indicates if version level worm is enabled on this container. + */ + bool HasImmutableStorageWithVersioning = false; +}; +/** + * @brief An Azure Storage container. + */ +struct BlobContainerItem final { + /** + * Blob container name. + */ + std::string Name; + /** + * Indicates whether this container was deleted. + */ + bool IsDeleted = bool(); + /** + * Version ID of a deleted container. + */ + Nullable VersionId; + /** + * Properties of a container. + */ + BlobContainerItemDetails Details; +}; +/** + * @brief Include this parameter to specify that the container's metadata be + * returned as part of the response body. + */ +enum class ListBlobContainersIncludeFlags { + None = 0, + Metadata = 1, + Deleted = 2, +}; +inline ListBlobContainersIncludeFlags +operator|(ListBlobContainersIncludeFlags lhs, + ListBlobContainersIncludeFlags rhs) { + using type = std::underlying_type_t; + return static_cast(static_cast(lhs) | + static_cast(rhs)); +} +inline ListBlobContainersIncludeFlags & +operator|=(ListBlobContainersIncludeFlags &lhs, + ListBlobContainersIncludeFlags rhs) { + lhs = lhs | rhs; + return lhs; +} +inline ListBlobContainersIncludeFlags +operator&(ListBlobContainersIncludeFlags lhs, + ListBlobContainersIncludeFlags rhs) { + using type = std::underlying_type_t; + return static_cast(static_cast(lhs) & + static_cast(rhs)); +} +inline ListBlobContainersIncludeFlags & +operator&=(ListBlobContainersIncludeFlags &lhs, + ListBlobContainersIncludeFlags rhs) { + lhs = lhs & rhs; + return lhs; +} +namespace _detail { +/** + * @brief An enumeration of containers. + */ +struct ListBlobContainersResult final { + std::string ServiceEndpoint; + std::string Prefix; + Nullable ContinuationToken; + /** + * Array of BlobContainerItem. + */ + std::vector Items; +}; +/** + * @brief Key information. + */ +struct KeyInfo final { + /** + * The date-time the key is active in ISO 8601 UTC time. + */ + std::string Start; + /** + * The date-time the key expires in ISO 8601 UTC time. + */ + std::string Expiry; +}; +} // namespace _detail +/** + * @brief A user delegation key. + */ +struct UserDelegationKey final { + /** + * The Azure Active Directory object ID in GUID format. + */ + std::string SignedObjectId; + /** + * The Azure Active Directory tenant ID in GUID format. + */ + std::string SignedTenantId; + /** + * The date-time the key is active. + */ + DateTime SignedStartsOn; + /** + * The date-time the key expires. + */ + DateTime SignedExpiresOn; + /** + * Abbreviation of the Azure Storage service that accepts the key. + */ + std::string SignedService; + /** + * The service version that created the key. + */ + std::string SignedVersion; + /** + * The key as a base64 string. + */ + std::string Value; +}; +/** + * @brief Identifies the sku name of the account. + */ +class SkuName final { +public: + SkuName() = default; + explicit SkuName(std::string value) : m_value(std::move(value)) {} + bool operator==(const SkuName &other) const { + return m_value == other.m_value; + } + bool operator!=(const SkuName &other) const { return !(*this == other); } + const std::string &ToString() const { return m_value; } + AZ_TEMPLATE_DLLEXPORT const static SkuName StandardLrs; + AZ_TEMPLATE_DLLEXPORT const static SkuName StandardGrs; + AZ_TEMPLATE_DLLEXPORT const static SkuName StandardRagrs; + AZ_TEMPLATE_DLLEXPORT const static SkuName StandardZrs; + AZ_TEMPLATE_DLLEXPORT const static SkuName PremiumLrs; + AZ_TEMPLATE_DLLEXPORT const static SkuName PremiumZrs; + AZ_TEMPLATE_DLLEXPORT const static SkuName StandardGzrs; + AZ_TEMPLATE_DLLEXPORT const static SkuName StandardRagzrs; + +private: + std::string m_value; +}; +/** + * @brief Identifies the account kind. + */ +class AccountKind final { +public: + AccountKind() = default; + explicit AccountKind(std::string value) : m_value(std::move(value)) {} + bool operator==(const AccountKind &other) const { + return m_value == other.m_value; + } + bool operator!=(const AccountKind &other) const { return !(*this == other); } + const std::string &ToString() const { return m_value; } + AZ_TEMPLATE_DLLEXPORT const static AccountKind Storage; + AZ_TEMPLATE_DLLEXPORT const static AccountKind BlobStorage; + AZ_TEMPLATE_DLLEXPORT const static AccountKind StorageV2; + AZ_TEMPLATE_DLLEXPORT const static AccountKind FileStorage; + AZ_TEMPLATE_DLLEXPORT const static AccountKind BlockBlobStorage; + +private: + std::string m_value; +}; +/** + * @brief Response type for + * #Azure::Storage::Blobs::ServiceClient::GetAccountInfo. + */ +struct AccountInfo final { + /** + * Identifies the sku name of the account. + */ + Models::SkuName SkuName; + /** + * Identifies the account kind. + */ + Models::AccountKind AccountKind; + /** + * Version 2019-07-07 and newer. Indicates if the account has a hierarchical + * namespace enabled. + */ + bool IsHierarchicalNamespaceEnabled = bool(); +}; +/** + * @brief Blob info from a Filter Blobs API call. + */ +struct TaggedBlobItem final { + /** + * Blob name. + */ + std::string BlobName; + /** + * Blob container name. + */ + std::string BlobContainerName; + /** + * User-defined tags for this blob. + */ + std::map Tags; +}; +namespace _detail { +/** + * @brief The result of a Filter Blobs API call. + */ +struct FindBlobsByTagsResult final { + std::string ServiceEndpoint; + /** + * Array of TaggedBlobItem. + */ + std::vector Items; + Nullable ContinuationToken; +}; +} // namespace _detail +/** + * @brief Response type for #Azure::Storage::Blobs::BlobContainerClient::Create. + */ +struct CreateBlobContainerResult final { + /** + * Indicates if the container was successfully created by this operation. + */ + bool Created = true; + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the container was last modified. Any operation + * that modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; +}; +/** + * @brief Response type for + * #Azure::Storage::Blobs::BlobContainerClient::GetProperties. + */ +struct BlobContainerProperties final { + /** + * A set of name-value pair associated with this blob container. + */ + std::map + Metadata; + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the container was last modified. Any operation + * that modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; + /** + * When a blob is leased, specifies whether the lease is of infinite or fixed + * duration. + */ + Nullable LeaseDuration; + /** + * Lease state of the blob. + */ + Models::LeaseState LeaseState; + /** + * The current lease status of the blob. + */ + Models::LeaseStatus LeaseStatus; + /** + * Indicated whether data in the container may be accessed publicly and the + * level of access. + */ + PublicAccessType AccessType = PublicAccessType::None; + /** + * Indicates whether the container has an immutability policy set on it. + */ + bool HasImmutabilityPolicy = bool(); + /** + * Indicates whether the container has a legal hold. + */ + bool HasLegalHold = bool(); + /** + * The default encryption scope for the container. + */ + std::string DefaultEncryptionScope = "$account-encryption-key"; + /** + * Indicates whether the container's default encryption scope can be + * overriden. + */ + bool PreventEncryptionScopeOverride = false; + /** + * Indicates whether version level worm is enabled on a container. + */ + bool HasImmutableStorageWithVersioning = false; +}; +/** + * @brief Response type for #Azure::Storage::Blobs::BlobContainerClient::Delete. + */ +struct DeleteBlobContainerResult final { + /** + * Indicates if the container was successfully deleted by this operation. + */ + bool Deleted = true; +}; +/** + * @brief Response type for + * #Azure::Storage::Blobs::BlobContainerClient::SetMetadata. + */ +struct SetBlobContainerMetadataResult final { + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the container was last modified. Any operation + * that modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; +}; +/** + * @brief Signed identifier. + */ +struct SignedIdentifier final { + /** + * A unique id. + */ + std::string Id; + /** + * The date-time the policy is active. + */ + Nullable StartsOn; + /** + * The date-time the policy expires. + */ + Nullable ExpiresOn; + /** + * The permissions for the acl policy. + */ + std::string Permissions; +}; +/** + * @brief Response type for + * #Azure::Storage::Blobs::BlobContainerClient::GetAccessPolicy. + */ +struct BlobContainerAccessPolicy final { + /** + * A collection of signed identifiers. + */ + std::vector SignedIdentifiers; + /** + * Indicated whether data in the container may be accessed publicly and the + * level of access. + */ + PublicAccessType AccessType = PublicAccessType::None; +}; +/** + * @brief Response type for + * #Azure::Storage::Blobs::BlobContainerClient::SetAccessPolicy. + */ +struct SetBlobContainerAccessPolicyResult final { + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the container was last modified. Any operation + * that modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; +}; +namespace _detail { +/** + * @brief Response type for + * #Azure::Storage::Blobs::BlobContainerClient::Undelete. + */ +struct UndeleteBlobContainerResult final {}; +/** + * @brief Response type for #Azure::Storage::Blobs::BlobContainerClient::Rename. + */ +struct RenameBlobContainerResult final {}; +/** + * @brief Response type for + * #Azure::Storage::Blobs::BlobContainerClient::AcquireLease. + */ +struct AcquireBlobContainerLeaseResult final { + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the container was last modified. Any operation + * that modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; + /** + * Uniquely identifies a container's lease. + */ + std::string LeaseId; +}; +/** + * @brief Response type for + * #Azure::Storage::Blobs::BlobContainerClient::ReleaseLease. + */ +struct ReleaseBlobContainerLeaseResult final { + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the container was last modified. Any operation + * that modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; +}; +/** + * @brief Response type for + * #Azure::Storage::Blobs::BlobContainerClient::RenewLease. + */ +struct RenewBlobContainerLeaseResult final { + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the container was last modified. Any operation + * that modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; + /** + * Uniquely identifies a container's lease. + */ + std::string LeaseId; +}; +/** + * @brief Response type for + * #Azure::Storage::Blobs::BlobContainerClient::BreakLease. + */ +struct BreakBlobContainerLeaseResult final { + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the container was last modified. Any operation + * that modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; + /** + * Approximate time remaining in the lease period, in seconds. + */ + int32_t LeaseTime = int32_t(); +}; +/** + * @brief Response type for + * #Azure::Storage::Blobs::BlobContainerClient::ChangeLease. + */ +struct ChangeBlobContainerLeaseResult final { + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the container was last modified. Any operation + * that modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; + /** + * Uniquely identifies a container's lease. + */ + std::string LeaseId; +}; +} // namespace _detail +/** + * @brief Status of the copy operation. + */ +class CopyStatus final { +public: + CopyStatus() = default; + explicit CopyStatus(std::string value) : m_value(std::move(value)) {} + bool operator==(const CopyStatus &other) const { + return m_value == other.m_value; + } + bool operator!=(const CopyStatus &other) const { return !(*this == other); } + const std::string &ToString() const { return m_value; } + AZ_TEMPLATE_DLLEXPORT const static CopyStatus Pending; + AZ_TEMPLATE_DLLEXPORT const static CopyStatus Success; + AZ_TEMPLATE_DLLEXPORT const static CopyStatus Aborted; + AZ_TEMPLATE_DLLEXPORT const static CopyStatus Failed; + +private: + std::string m_value; +}; +/** + * @brief Optional. Indicates the tier to be set on the blob. + */ +class AccessTier final { +public: + AccessTier() = default; + explicit AccessTier(std::string value) : m_value(std::move(value)) {} + bool operator==(const AccessTier &other) const { + return m_value == other.m_value; + } + bool operator!=(const AccessTier &other) const { return !(*this == other); } + const std::string &ToString() const { return m_value; } + AZ_TEMPLATE_DLLEXPORT const static AccessTier P1; + AZ_TEMPLATE_DLLEXPORT const static AccessTier P2; + AZ_TEMPLATE_DLLEXPORT const static AccessTier P3; + AZ_TEMPLATE_DLLEXPORT const static AccessTier P4; + AZ_TEMPLATE_DLLEXPORT const static AccessTier P6; + AZ_TEMPLATE_DLLEXPORT const static AccessTier P10; + AZ_TEMPLATE_DLLEXPORT const static AccessTier P15; + AZ_TEMPLATE_DLLEXPORT const static AccessTier P20; + AZ_TEMPLATE_DLLEXPORT const static AccessTier P30; + AZ_TEMPLATE_DLLEXPORT const static AccessTier P40; + AZ_TEMPLATE_DLLEXPORT const static AccessTier P50; + AZ_TEMPLATE_DLLEXPORT const static AccessTier P60; + AZ_TEMPLATE_DLLEXPORT const static AccessTier P70; + AZ_TEMPLATE_DLLEXPORT const static AccessTier P80; + AZ_TEMPLATE_DLLEXPORT const static AccessTier Hot; + AZ_TEMPLATE_DLLEXPORT const static AccessTier Cool; + AZ_TEMPLATE_DLLEXPORT const static AccessTier Archive; + +private: + std::string m_value; +}; +/** + * @brief For blob storage LRS accounts, valid values are + * rehydrate-pending-to-hot/rehydrate-pending-to-cool. If the blob is being + * rehydrated and is not complete then this value indicates that rehydrate is + * pending and also tells the destination tier. + */ +class ArchiveStatus final { +public: + ArchiveStatus() = default; + explicit ArchiveStatus(std::string value) : m_value(std::move(value)) {} + bool operator==(const ArchiveStatus &other) const { + return m_value == other.m_value; + } + bool operator!=(const ArchiveStatus &other) const { + return !(*this == other); + } + const std::string &ToString() const { return m_value; } + AZ_TEMPLATE_DLLEXPORT const static ArchiveStatus RehydratePendingToHot; + AZ_TEMPLATE_DLLEXPORT const static ArchiveStatus RehydratePendingToCool; + +private: + std::string m_value; +}; +/** + * @brief Optional: Indicates the priority with which to rehydrate an archived + * blob. + */ +class RehydratePriority final { +public: + RehydratePriority() = default; + explicit RehydratePriority(std::string value) : m_value(std::move(value)) {} + bool operator==(const RehydratePriority &other) const { + return m_value == other.m_value; + } + bool operator!=(const RehydratePriority &other) const { + return !(*this == other); + } + const std::string &ToString() const { return m_value; } + AZ_TEMPLATE_DLLEXPORT const static RehydratePriority High; + AZ_TEMPLATE_DLLEXPORT const static RehydratePriority Standard; + +private: + std::string m_value; +}; +/** + * @brief Standard HTTP properties supported by containers and blobs. + */ +struct BlobHttpHeaders final { + /** + * MIME content type of the blob. + */ + std::string ContentType; + /** + * Specifies which content encodings have been applied to the blob. + */ + std::string ContentEncoding; + /** + * Specifies the natural languages used by this blob. + */ + std::string ContentLanguage; + /** + * Hash of the blob content. + */ + Storage::ContentHash ContentHash; + /** + * Conveys additional information about how to process the resource payload, + * and also can be used to attach additional metadata. + */ + std::string ContentDisposition; + /** + * Specifies directives for caching mechanisms. + */ + std::string CacheControl; +}; +/** + * @brief The replication status of blob with the given policy and rule + * identifiers. + */ +class ObjectReplicationStatus final { +public: + ObjectReplicationStatus() = default; + explicit ObjectReplicationStatus(std::string value) + : m_value(std::move(value)) {} + bool operator==(const ObjectReplicationStatus &other) const { + return m_value == other.m_value; + } + bool operator!=(const ObjectReplicationStatus &other) const { + return !(*this == other); + } + const std::string &ToString() const { return m_value; } + AZ_TEMPLATE_DLLEXPORT const static ObjectReplicationStatus Complete; + AZ_TEMPLATE_DLLEXPORT const static ObjectReplicationStatus Failed; + +private: + std::string m_value; +}; +/** + * @brief Contains the object replication rule ID and replication status of a + * blob. + */ +struct ObjectReplicationRule final { + /** + * Object replication rule ID. + */ + std::string RuleId; + /** + * Object replication status. + */ + ObjectReplicationStatus ReplicationStatus; +}; +/** + * @brief Contains object replication policy ID and the respective list of + * #ObjectReplicationRule s. This is used when retrieving the object replication + * properties on the source blob. + */ +struct ObjectReplicationPolicy final { + /** + * Object replication policy ID. + */ + std::string PolicyId; + /** + * The Rule IDs and respective replication status that are under the policy + * ID. + */ + std::vector Rules; +}; +/** + * @brief Specifies the immutability policy mode to set on the blob. + */ +class BlobImmutabilityPolicyMode final { +public: + BlobImmutabilityPolicyMode() = default; + explicit BlobImmutabilityPolicyMode(std::string value) + : m_value(std::move(value)) {} + bool operator==(const BlobImmutabilityPolicyMode &other) const { + return m_value == other.m_value; + } + bool operator!=(const BlobImmutabilityPolicyMode &other) const { + return !(*this == other); + } + const std::string &ToString() const { return m_value; } + AZ_TEMPLATE_DLLEXPORT const static BlobImmutabilityPolicyMode Unlocked; + AZ_TEMPLATE_DLLEXPORT const static BlobImmutabilityPolicyMode Locked; + +private: + std::string m_value; +}; +/** + * @brief Immutability policy associated with the blob. + */ +struct BlobImmutabilityPolicy final { + /** + * The date until which the blob can be protected from being modified or + * deleted. + */ + DateTime ExpiresOn; + /** + * Specifies the immutability policy mode set on the blob. + */ + BlobImmutabilityPolicyMode PolicyMode; +}; +/** + * @brief Properties of a blob. + */ +struct BlobItemDetails final { + /** + * The date and time at which the blob was created. + */ + DateTime CreatedOn; + /** + * The date and time the blob was last modified. + */ + DateTime LastModified; + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * The current sequence number for a page blob. + */ + Nullable SequenceNumber; + /** + * The current lease status of the blob. + */ + Models::LeaseStatus LeaseStatus; + /** + * The current lease state of the blob. + */ + Models::LeaseState LeaseState; + /** + * When a blob is leased, specifies whether the lease is of infinite or fixed + * duration. + */ + Nullable LeaseDuration; + /** + * String identifier for this copy operation. Use with Get Blob Properties to + * check the status of this copy operation, or pass to Abort Copy Blob to + * abort a pending copy. + */ + Nullable CopyId; + /** + * Status of the copy operation. + */ + Nullable CopyStatus; + /** + * URL up to 2 KB in length that specifies the source blob or file used in the + * last attempted Copy Blob operation where this blob was the destination + * blob. This header does not appear if this blob has never been the + * destination in a Copy Blob operation, or if this blob has been modified + * after a concluded Copy Blob operation using Set Blob Properties, Put Blob, + * or Put Block List. + */ + Nullable CopySource; + /** + * Contains the number of bytes copied and the total bytes in the source in + * the last attempted Copy Blob operation where this blob was the destination + * blob. Can show between 0 and Content-Length bytes copied. This header does + * not appear if this blob has never been the destination in a Copy Blob + * operation, or if this blob has been modified after a concluded Copy Blob + * operation using Set Blob Properties, Put Blob, or Put Block List. + */ + Nullable CopyProgress; + /** + * Conclusion time of the last attempted Copy Blob operation where this blob + * was the destination blob. This value can specify the time of a completed, + * aborted, or failed copy attempt. This header does not appear if a copy is + * pending, if this blob has never been the destination in a Copy Blob + * operation, or if this blob has been modified after a concluded Copy Blob + * operation using Set Blob Properties, Put Blob, or Put Block List. + */ + Nullable CopyCompletedOn; + /** + * Only appears when x-ms-copy-status is failed or pending. Describes the + * cause of the last fatal or non-fatal copy operation failure. This header + * does not appear if this blob has never been the destination in a Copy Blob + * operation, or if this blob has been modified after a concluded Copy Blob + * operation using Set Blob Properties, Put Blob, or Put Block List. + */ + Nullable CopyStatusDescription; + /** + * The value of this header is set to true if the blob data and application + * metadata are completely encrypted using the specified algorithm. Otherwise, + * the value is set to false (when the blob is unencrypted, or if only parts + * of the blob/application metadata are encrypted). + */ + bool IsServerEncrypted = bool(); + /** + * Included if the blob is incremental copy blob. + */ + Nullable IsIncrementalCopy; + /** + * Included if the blob is incremental copy blob or incremental copy snapshot, + * if x-ms-copy-status is success. Snapshot time of the last successful + * incremental copy snapshot for this blob. + */ + Nullable IncrementalCopyDestinationSnapshot; + /** + * Data and time at which this blob was deleted. Only valid when this blob was + * deleted. + */ + Nullable DeletedOn; + /** + * Remaining days before this blob will be permanantely deleted. Only valid + * when this blob was deleted. + */ + Nullable RemainingRetentionDays; + /** + * The tier of page blob on a premium storage account or tier of block blob on + * blob storage or general purpose v2 account. + */ + Nullable AccessTier; + /** + * True if the access tier is not explicitly set on the blob. + */ + Nullable IsAccessTierInferred; + /** + * For blob storage LRS accounts, valid values are + * rehydrate-pending-to-hot/rehydrate-pending-to-cool. If the blob is being + * rehydrated and is not complete then this value indicates that rehydrate is + * pending and also tells the destination tier. + */ + Nullable ArchiveStatus; + /** + * SHA-256 hash of the encryption key. + */ + Nullable> EncryptionKeySha256; + /** + * The name of the encryption scope under which the blob is encrypted. + */ + Nullable EncryptionScope; + /** + * The time the tier was changed on the object. This is only returned if the + * tier on the block blob was ever set. + */ + Nullable AccessTierChangedOn; + /** + * The time this blob will expire. + */ + Nullable ExpiresOn; + /** + * If this blob has been sealed. + */ + Nullable IsSealed; + /** + * If an object is in rehydrate pending state then this header is returned + * with priority of rehydrate. Valid values are High and Standard. + */ + Nullable RehydratePriority; + /** + * UTC date/time value generated by the service that indicates the time at + * which the blob was last read or written to. + */ + Nullable LastAccessedOn; + /** + * Indicates whether the blob has a legal hold. + */ + bool HasLegalHold = false; + /** + * Standard HTTP properties supported by containers and blobs. + */ + BlobHttpHeaders HttpHeaders; + /** + * A set of name-value pairs associated with this blob or blob container. + */ + std::map + Metadata; + /** + * User-defined tags for this blob. + */ + std::map Tags; + /** + * Array of ObjectReplicationPolicy. + */ + std::vector ObjectReplicationSourceProperties; + /** + * Immutability policy associated with the blob. + */ + Nullable ImmutabilityPolicy; +}; +/** + * @brief Type of the blob. + */ +class BlobType final { +public: + BlobType() = default; + explicit BlobType(std::string value) : m_value(std::move(value)) {} + bool operator==(const BlobType &other) const { + return m_value == other.m_value; + } + bool operator!=(const BlobType &other) const { return !(*this == other); } + const std::string &ToString() const { return m_value; } + AZ_TEMPLATE_DLLEXPORT const static BlobType BlockBlob; + AZ_TEMPLATE_DLLEXPORT const static BlobType PageBlob; + AZ_TEMPLATE_DLLEXPORT const static BlobType AppendBlob; + +private: + std::string m_value; +}; +/** + * @brief An Azure Storage blob. + */ +struct BlobItem final { + /** + * Blob name. + */ + std::string Name; + /** + * Indicates whether this blob was deleted. + */ + bool IsDeleted = bool(); + /** + * A string value that uniquely identifies a blob snapshot. + */ + std::string Snapshot; + /** + * A string value that uniquely identifies a blob version. + */ + Nullable VersionId; + /** + * Indicates if this is the current version of the blob. + */ + Nullable IsCurrentVersion; + /** + * Properties of a blob. + */ + BlobItemDetails Details; + /** + * Size in bytes. + */ + int64_t BlobSize = int64_t(); + /** + * Type of the blob. + */ + Models::BlobType BlobType; +}; +/** + * @brief Include this parameter to specify one or more datasets to include in + * the response. + */ +enum class ListBlobsIncludeFlags { + None = 0, + Copy = 1, + Deleted = 2, + Metadata = 4, + Snapshots = 8, + UncomittedBlobs = 16, + Versions = 32, + Tags = 64, + ImmutabilityPolicy = 128, + LegalHold = 256, +}; +inline ListBlobsIncludeFlags operator|(ListBlobsIncludeFlags lhs, + ListBlobsIncludeFlags rhs) { + using type = std::underlying_type_t; + return static_cast(static_cast(lhs) | + static_cast(rhs)); +} +inline ListBlobsIncludeFlags &operator|=(ListBlobsIncludeFlags &lhs, + ListBlobsIncludeFlags rhs) { + lhs = lhs | rhs; + return lhs; +} +inline ListBlobsIncludeFlags operator&(ListBlobsIncludeFlags lhs, + ListBlobsIncludeFlags rhs) { + using type = std::underlying_type_t; + return static_cast(static_cast(lhs) & + static_cast(rhs)); +} +inline ListBlobsIncludeFlags &operator&=(ListBlobsIncludeFlags &lhs, + ListBlobsIncludeFlags rhs) { + lhs = lhs & rhs; + return lhs; +} +namespace _detail { +/** + * @brief An enumeration of blobs. + */ +struct ListBlobsResult final { + std::string ServiceEndpoint; + std::string BlobContainerName; + std::string Prefix; + Nullable ContinuationToken; + /** + * Array of BlobItem. + */ + std::vector Items; +}; +/** + * @brief An enumeration of blobs. + */ +struct ListBlobsByHierarchyResult final { + std::string ServiceEndpoint; + std::string BlobContainerName; + std::string Prefix; + std::string Delimiter; + Nullable ContinuationToken; + /** + * Array of BlobItem. + */ + std::vector Items; + /** + * Array of ListBlobsHierarchySegmentResponseBlobPrefixesItem. + */ + std::vector BlobPrefixes; +}; +} // namespace _detail +/** + * @brief Detailed information of the downloaded blob. + */ +struct DownloadBlobDetails final { + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the container was last modified. Any operation + * that modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; + /** + * The date and time at which the blob was created. + */ + DateTime CreatedOn; + /** + * The time this blob will expire. + */ + Nullable ExpiresOn; + /** + * UTC date/time value generated by the service that indicates the time at + * which the blob was last read or written to. + */ + Nullable LastAccessedOn; + /** + * Standard HTTP properties supported by containers and blobs. + */ + BlobHttpHeaders HttpHeaders; + /** + * A set of name-value pairs associated with this blob or blob container. + */ + std::map + Metadata; + /** + * The current sequence number for a page blob. + */ + Nullable SequenceNumber; + /** + * The number of committed blocks present in the blob. + */ + Nullable CommittedBlockCount; + /** + * If the blob has been sealed. This value is null for block blobs or page + * blobs. + */ + Nullable IsSealed; + /** + * When a blob is leased, specifies whether the lease is of infinite or fixed + * duration. + */ + Nullable LeaseDuration; + /** + * The current lease state of the blob. + */ + Nullable LeaseState; + /** + * The current lease status of the blob. + */ + Nullable LeaseStatus; + /** + * True if the blob data and metadata are completely encrypted using the + * specified algorithm. Otherwise, the value is set to false (when the blob is + * unencrypted, or if only parts of the blob/application metadata are + * encrypted). + */ + bool IsServerEncrypted = bool(); + /** + * SHA-256 hash of the encryption key used to encrypt the blob data and + * metadata. + */ + Nullable> EncryptionKeySha256; + /** + * Name of the encryption scope used to encrypt the blob data and metadata. + */ + Nullable EncryptionScope; + /** + * Only valid when Object Replication is enabled and current blob is the + * destination. + */ + Nullable ObjectReplicationDestinationPolicyId; + /** + * Only valid when Object Replication is enabled and current blob is the + * source. + */ + std::vector ObjectReplicationSourceProperties; + /** + * The number of tags associated with the blob. + */ + Nullable TagCount; + /** + * String identifier for this copy operation. Use with Get Blob Properties to + * check the status of this copy operation, or pass to Abort Copy Blob to + * abort a pending copy. + */ + Nullable CopyId; + /** + * URL up to 2 KB in length that specifies the source blob or file used in the + * last attempted Copy Blob operation where this blob was the destination + * blob. This header does not appear if this blob has never been the + * destination in a Copy Blob operation, or if this blob has been modified + * after a concluded Copy Blob operation using Set Blob Properties, Put Blob, + * or Put Block List. + */ + Nullable CopySource; + /** + * Status of the copy operation. + */ + Nullable CopyStatus; + /** + * Only appears when x-ms-copy-status is failed or pending. Describes the + * cause of the last fatal or non-fatal copy operation failure. This header + * does not appear if this blob has never been the destination in a Copy Blob + * operation, or if this blob has been modified after a concluded Copy Blob + * operation using Set Blob Properties, Put Blob, or Put Block List. + */ + Nullable CopyStatusDescription; + /** + * Contains the number of bytes copied and the total bytes in the source in + * the last attempted Copy Blob operation where this blob was the destination + * blob. Can show between 0 and Content-Length bytes copied. This header does + * not appear if this blob has never been the destination in a Copy Blob + * operation, or if this blob has been modified after a concluded Copy Blob + * operation using Set Blob Properties, Put Blob, or Put Block List. + */ + Nullable CopyProgress; + /** + * Conclusion time of the last attempted Copy Blob operation where this blob + * was the destination blob. This value can specify the time of a completed, + * aborted, or failed copy attempt. This header does not appear if a copy is + * pending, if this blob has never been the destination in a Copy Blob + * operation, or if this blob has been modified after a concluded Copy Blob + * operation using Set Blob Properties, Put Blob, or Put Block List. + */ + Nullable CopyCompletedOn; + /** + * A string value returned by the service that uniquely identifies the blob + * version. + */ + Nullable VersionId; + /** + * Indicates whether version of this blob is the current version. + */ + Nullable IsCurrentVersion; + /** + * Immutability policy associated with the blob. + */ + Nullable ImmutabilityPolicy; + /** + * Indicates whether the blob has a legal hold. + */ + bool HasLegalHold = false; +}; +/** + * @brief Response type for #Azure::Storage::Blobs::BlobClient::Download. + */ +struct DownloadBlobResult final { + /** + * Detailed information of the downloaded blob. + */ + DownloadBlobDetails Details; + /** + * Size of the blob in bytes. + */ + int64_t BlobSize = int64_t(); + /** + * Indicates the range of bytes returned. + */ + Core::Http::HttpRange ContentRange; + /** + * CRC64 or MD5 hash for the downloaded range of data. + */ + Nullable TransactionalContentHash; + /** + * Content of the blob or blob range. + */ + std::unique_ptr BodyStream; + /** + * The blob's type. + */ + Models::BlobType BlobType; +}; +/** + * @brief Response type for #Azure::Storage::Blobs::BlobClient::GetProperties. + */ +struct BlobProperties final { + /** + * Array of ObjectReplicationPolicy. + */ + std::vector ObjectReplicationSourceProperties; + /** + * Immutability policy associated with the blob. + */ + Nullable ImmutabilityPolicy; + /** + * Standard HTTP properties supported by containers and blobs. + */ + BlobHttpHeaders HttpHeaders; + /** + * Returns the date and time the blob was last modified. Any operation that + * modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; + /** + * Returns the date and time the blob was created. + */ + DateTime CreatedOn; + /** + * A set of name-value pair associated with this blob. + */ + std::map + Metadata; + /** + * Optional. Only valid when Object Replication is enabled for the storage + * container and on the destination blob of the replication. + */ + Nullable ObjectReplicationDestinationPolicyId; + /** + * The blob's type. + */ + Models::BlobType BlobType; + /** + * Conclusion time of the last attempted Copy Blob operation where this blob + * was the destination blob. This value can specify the time of a completed, + * aborted, or failed copy attempt. This header does not appear if a copy is + * pending, if this blob has never been the destination in a Copy Blob + * operation, or if this blob has been modified after a concluded Copy Blob + * operation using Set Blob Properties, Put Blob, or Put Block List. + */ + Nullable CopyCompletedOn; + /** + * Only appears when x-ms-copy-status is failed or pending. Describes the + * cause of the last fatal or non-fatal copy operation failure. This header + * does not appear if this blob has never been the destination in a Copy Blob + * operation, or if this blob has been modified after a concluded Copy Blob + * operation using Set Blob Properties, Put Blob, or Put Block List. + */ + Nullable CopyStatusDescription; + /** + * String identifier for this copy operation. Use with Get Blob Properties to + * check the status of this copy operation, or pass to Abort Copy Blob to + * abort a pending copy. + */ + Nullable CopyId; + /** + * Contains the number of bytes copied and the total bytes in the source in + * the last attempted Copy Blob operation where this blob was the destination + * blob. Can show between 0 and Content-Length bytes copied. This header does + * not appear if this blob has never been the destination in a Copy Blob + * operation, or if this blob has been modified after a concluded Copy Blob + * operation using Set Blob Properties, Put Blob, or Put Block List. + */ + Nullable CopyProgress; + /** + * URL up to 2 KB in length that specifies the source blob or file used in the + * last attempted Copy Blob operation where this blob was the destination + * blob. This header does not appear if this blob has never been the + * destination in a Copy Blob operation, or if this blob has been modified + * after a concluded Copy Blob operation using Set Blob Properties, Put Blob, + * or Put Block List. + */ + Nullable CopySource; + /** + * State of the copy operation identified by x-ms-copy-id. + */ + Nullable CopyStatus; + /** + * Included if the blob is incremental copy blob. + */ + Nullable IsIncrementalCopy; + /** + * Included if the blob is incremental copy blob or incremental copy snapshot, + * if x-ms-copy-status is success. Snapshot time of the last successful + * incremental copy snapshot for this blob. + */ + Nullable IncrementalCopyDestinationSnapshot; + /** + * When a blob is leased, specifies whether the lease is of infinite or fixed + * duration. + */ + Nullable LeaseDuration; + /** + * Lease state of the blob. + */ + Nullable LeaseState; + /** + * The current lease status of the blob. + */ + Nullable LeaseStatus; + /** + * Size of the blob in bytes. + */ + int64_t BlobSize = int64_t(); + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * The current sequence number for a page blob. This header is not returned + * for block blobs or append blobs. + */ + Nullable SequenceNumber; + /** + * The number of committed blocks present in the blob. This header is returned + * only for append blobs. + */ + Nullable CommittedBlockCount; + /** + * The value of this header is set to true if the blob data and application + * metadata are completely encrypted using the specified algorithm. Otherwise, + * the value is set to false (when the blob is unencrypted, or if only parts + * of the blob/application metadata are encrypted). + */ + bool IsServerEncrypted = bool(); + /** + * The SHA-256 hash of the encryption key used to encrypt the metadata. This + * header is only returned when the metadata was encrypted with a + * customer-provided key. + */ + Nullable> EncryptionKeySha256; + /** + * Returns the name of the encryption scope used to encrypt the blob contents + * and application metadata. Note that the absence of this header implies use + * of the default account encryption scope. + */ + Nullable EncryptionScope; + /** + * The tier of page blob on a premium storage account or tier of block blob on + * blob storage LRS accounts. For a list of allowed premium page blob tiers, + * see + * https://docs.microsoft.com/en-us/azure/virtual-machines/windows/premium-storage#features. + * For blob storage LRS accounts, valid values are Hot/Cool/Archive. + */ + Nullable AccessTier; + /** + * For page blobs on a premium storage account only. If the access tier is not + * explicitly set on the blob, the tier is inferred based on its content + * length and this header will be returned with true value. + */ + Nullable IsAccessTierInferred; + /** + * For blob storage LRS accounts, valid values are + * rehydrate-pending-to-hot/rehydrate-pending-to-cool. If the blob is being + * rehydrated and is not complete then this header is returned indicating that + * rehydrate is pending and also tells the destination tier. + */ + Nullable ArchiveStatus; + /** + * The time the tier was changed on the object. This is only returned if the + * tier on the block blob was ever set. + */ + Nullable AccessTierChangedOn; + /** + * A DateTime value returned by the service that uniquely identifies the blob. + * The value of this header indicates the blob version, and may be used in + * subsequent requests to access this version of the blob. + */ + Nullable VersionId; + /** + * The value of this header indicates whether version of this blob is a + * current version, see also x-ms-version-id header. + */ + Nullable IsCurrentVersion; + /** + * The number of tags associated with the blob. + */ + Nullable TagCount; + /** + * The time this blob will expire. + */ + Nullable ExpiresOn; + /** + * If this blob has been sealed. + */ + Nullable IsSealed; + /** + * If an object is in rehydrate pending state then this header is returned + * with priority of rehydrate. Valid values are High and Standard. + */ + Nullable RehydratePriority; + /** + * UTC date/time value generated by the service that indicates the time at + * which the blob was last read or written to. + */ + Nullable LastAccessedOn; + /** + * Indicates if a legal hold is present on the blob. + */ + bool HasLegalHold = false; +}; +/** + * @brief Required if the blob has associated snapshots. Specify one of the + * following two options: include: Delete the base blob and all of its + * snapshots. only: Delete only the blob's snapshots and not the blob itself. + */ +class DeleteSnapshotsOption final { +public: + DeleteSnapshotsOption() = default; + explicit DeleteSnapshotsOption(std::string value) + : m_value(std::move(value)) {} + bool operator==(const DeleteSnapshotsOption &other) const { + return m_value == other.m_value; + } + bool operator!=(const DeleteSnapshotsOption &other) const { + return !(*this == other); + } + const std::string &ToString() const { return m_value; } + AZ_TEMPLATE_DLLEXPORT const static DeleteSnapshotsOption + IncludeSnapshots; + AZ_TEMPLATE_DLLEXPORT const static DeleteSnapshotsOption OnlySnapshots; + +private: + std::string m_value; +}; +/** + * @brief Response type for #Azure::Storage::Blobs::BlobClient::Delete. + */ +struct DeleteBlobResult final { + /** + * Indicates if the blob was successfully created by this operation. + */ + bool Deleted = true; +}; +/** + * @brief Response type for #Azure::Storage::Blobs::BlobClient::Undelete. + */ +struct UndeleteBlobResult final {}; +/** + * @brief Required. Indicates mode of the expiry time. + */ +class ScheduleBlobExpiryOriginType final { +public: + ScheduleBlobExpiryOriginType() = default; + explicit ScheduleBlobExpiryOriginType(std::string value) + : m_value(std::move(value)) {} + bool operator==(const ScheduleBlobExpiryOriginType &other) const { + return m_value == other.m_value; + } + bool operator!=(const ScheduleBlobExpiryOriginType &other) const { + return !(*this == other); + } + const std::string &ToString() const { return m_value; } + AZ_TEMPLATE_DLLEXPORT const static ScheduleBlobExpiryOriginType + NeverExpire; + AZ_TEMPLATE_DLLEXPORT const static ScheduleBlobExpiryOriginType + RelativeToCreation; + AZ_TEMPLATE_DLLEXPORT const static ScheduleBlobExpiryOriginType + RelativeToNow; + AZ_TEMPLATE_DLLEXPORT const static ScheduleBlobExpiryOriginType Absolute; + +private: + std::string m_value; +}; +/** + * @brief Response type for #Azure::Storage::Blobs::BlobClient::SetExpiry. + */ +struct SetBlobExpiryResult final { + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the container was last modified. Any operation + * that modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; +}; +/** + * @brief Response type for #Azure::Storage::Blobs::BlobClient::SetHttpHeaders. + */ +struct SetBlobHttpHeadersResult final { + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the container was last modified. Any operation + * that modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; + /** + * The current sequence number for a page blob. This header is not returned + * for block blobs or append blobs. + */ + Nullable SequenceNumber; +}; +/** + * @brief Response type for + * #Azure::Storage::Blobs::BlobClient::SetImmutabilityPolicy. + */ +struct SetBlobImmutabilityPolicyResult final { + /** + * Immutability policy associated with the blob. + */ + BlobImmutabilityPolicy ImmutabilityPolicy; +}; +/** + * @brief Response type for + * #Azure::Storage::Blobs::BlobClient::DeleteImmutabilityPolicy. + */ +struct DeleteBlobImmutabilityPolicyResult final {}; +/** + * @brief Response type for #Azure::Storage::Blobs::BlobClient::SetLegalHold. + */ +struct SetBlobLegalHoldResult final { + /** + * Indicates if the blob has a legal hold. + */ + bool HasLegalHold = bool(); +}; +/** + * @brief Response type for #Azure::Storage::Blobs::BlobClient::SetMetadata. + */ +struct SetBlobMetadataResult final { + /** + * The field is deprecated and is always null. Use GetProperties() instead to + * check sequence number for a page blob. + */ + Nullable SequenceNumber; + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the container was last modified. Any operation + * that modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; + /** + * A DateTime value returned by the service that uniquely identifies the blob. + * The value of this header indicates the blob version, and may be used in + * subsequent requests to access this version of the blob. + */ + Nullable VersionId; + /** + * The value of this header is set to true if the contents of the request are + * successfully encrypted using the specified algorithm, and false otherwise. + */ + bool IsServerEncrypted = bool(); + /** + * The SHA-256 hash of the encryption key used to encrypt the metadata. This + * header is only returned when the metadata was encrypted with a + * customer-provided key. + */ + Nullable> EncryptionKeySha256; + /** + * Returns the name of the encryption scope used to encrypt the blob contents + * and application metadata. Note that the absence of this header implies use + * of the default account encryption scope. + */ + Nullable EncryptionScope; +}; +namespace _detail { +/** + * @brief Response type for #Azure::Storage::Blobs::BlobClient::AcquireLease. + */ +struct AcquireBlobLeaseResult final { + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the blob was last modified. Any operation that + * modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; + /** + * Uniquely identifies a blobs's lease. + */ + std::string LeaseId; +}; +/** + * @brief Response type for #Azure::Storage::Blobs::BlobClient::ReleaseLease. + */ +struct ReleaseBlobLeaseResult final { + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the blob was last modified. Any operation that + * modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; +}; +/** + * @brief Response type for #Azure::Storage::Blobs::BlobClient::RenewLease. + */ +struct RenewBlobLeaseResult final { + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the blob was last modified. Any operation that + * modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; + /** + * Uniquely identifies a blobs's lease. + */ + std::string LeaseId; +}; +/** + * @brief Response type for #Azure::Storage::Blobs::BlobClient::ChangeLease. + */ +struct ChangeBlobLeaseResult final { + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the blob was last modified. Any operation that + * modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; + /** + * Uniquely identifies a blobs's lease. + */ + std::string LeaseId; +}; +/** + * @brief Response type for #Azure::Storage::Blobs::BlobClient::BreakLease. + */ +struct BreakBlobLeaseResult final { + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the blob was last modified. Any operation that + * modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; + /** + * Approximate time remaining in the lease period, in seconds. + */ + int32_t LeaseTime = int32_t(); +}; +} // namespace _detail +/** + * @brief Response type for #Azure::Storage::Blobs::BlobClient::CreateSnapshot. + */ +struct CreateBlobSnapshotResult final { + /** + * The field is deprecated and is always null. Use GetProperties() instead to + * get SHA256 of the encryption key. + */ + Nullable> EncryptionKeySha256; + /** + * The field is deprecated and is always null. Use GetProperties() instead to + * check the encryption scope. + */ + Nullable EncryptionScope; + /** + * Uniquely identifies the snapshot and indicates the snapshot version. It may + * be used in subsequent requests to access the snapshot. + */ + std::string Snapshot; + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the container was last modified. Any operation + * that modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; + /** + * A DateTime value returned by the service that uniquely identifies the blob. + * The value of this header indicates the blob version, and may be used in + * subsequent requests to access this version of the blob. + */ + Nullable VersionId; + /** + * True if the contents of the request are successfully encrypted using the + * specified algorithm, and false otherwise. For a snapshot request, this + * header is set to true when metadata was provided in the request and + * encrypted with a customer-provided key. + */ + bool IsServerEncrypted = bool(); +}; +namespace _detail { +/** + * @brief Response type for + * #Azure::Storage::Blobs::BlobClient::StartCopyFromUri. + */ +struct StartBlobCopyFromUriResult final { + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the container was last modified. Any operation + * that modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; + /** + * A DateTime value returned by the service that uniquely identifies the blob. + * The value of this header indicates the blob version, and may be used in + * subsequent requests to access this version of the blob. + */ + Nullable VersionId; + /** + * String identifier for this copy operation. Use with Get Blob Properties to + * check the status of this copy operation, or pass to Abort Copy Blob to + * abort a pending copy. + */ + std::string CopyId; + /** + * State of the copy operation identified by x-ms-copy-id. + */ + Models::CopyStatus CopyStatus; +}; +} // namespace _detail +/** + * @brief Response type for #Azure::Storage::Blobs::BlobClient::CopyFromUri. + */ +struct CopyBlobFromUriResult final { + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the container was last modified. Any operation + * that modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; + /** + * A DateTime value returned by the service that uniquely identifies the blob. + * The value of this header indicates the blob version, and may be used in + * subsequent requests to access this version of the blob. + */ + Nullable VersionId; + /** + * String identifier for this copy operation. + */ + std::string CopyId; + /** + * State of the copy operation identified by x-ms-copy-id. + */ + Models::CopyStatus CopyStatus; + /** + * This response header is returned so that the client can check for the + * integrity of the copied content. This header is only returned if the source + * content MD5 was specified. + */ + Nullable TransactionalContentHash; +}; +/** + * @brief Response type for + * #Azure::Storage::Blobs::BlobClient::AbortCopyFromUri. + */ +struct AbortBlobCopyFromUriResult final {}; +/** + * @brief Response type for #Azure::Storage::Blobs::BlobClient::SetTier. + */ +struct SetBlobAccessTierResult final {}; +/** + * @brief Response type for #Azure::Storage::Blobs::BlobClient::SetTags. + */ +struct SetBlobTagsResult final {}; +/** + * @brief Response type for #Azure::Storage::Blobs::PageBlobClient::Create. + */ +struct CreatePageBlobResult final { + /** + * Indicates if the page blob was successfully created by this operation. + */ + bool Created = true; + /** + * The field is deprecated and is always null. Use GetProperties() instead to + * check sequence number for a page blob. + */ + Nullable SequenceNumber; + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the container was last modified. Any operation + * that modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; + /** + * A DateTime value returned by the service that uniquely identifies the blob. + * The value of this header indicates the blob version, and may be used in + * subsequent requests to access this version of the blob. + */ + Nullable VersionId; + /** + * The value of this header is set to true if the contents of the request are + * successfully encrypted using the specified algorithm, and false otherwise. + */ + bool IsServerEncrypted = bool(); + /** + * The SHA-256 hash of the encryption key used to encrypt the blob. This + * header is only returned when the blob was encrypted with a + * customer-provided key. + */ + Nullable> EncryptionKeySha256; + /** + * Returns the name of the encryption scope used to encrypt the blob contents + * and application metadata. Note that the absence of this header implies use + * of the default account encryption scope. + */ + Nullable EncryptionScope; +}; +/** + * @brief Response type for #Azure::Storage::Blobs::PageBlobClient::UploadPages. + */ +struct UploadPagesResult final { + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the container was last modified. Any operation + * that modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; + /** + * If the blob has an MD5 hash and this operation is to read the full blob, + * this response header is returned so that the client can check for message + * content integrity. + */ + Nullable TransactionalContentHash; + /** + * The current sequence number for the page blob. + */ + int64_t SequenceNumber = int64_t(); + /** + * The value of this header is set to true if the contents of the request are + * successfully encrypted using the specified algorithm, and false otherwise. + */ + bool IsServerEncrypted = bool(); + /** + * The SHA-256 hash of the encryption key used to encrypt the pages. This + * header is only returned when the pages were encrypted with a + * customer-provided key. + */ + Nullable> EncryptionKeySha256; + /** + * Returns the name of the encryption scope used to encrypt the blob contents + * and application metadata. Note that the absence of this header implies use + * of the default account encryption scope. + */ + Nullable EncryptionScope; +}; +/** + * @brief Response type for #Azure::Storage::Blobs::PageBlobClient::ClearPages. + */ +struct ClearPagesResult final { + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the container was last modified. Any operation + * that modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; + /** + * The current sequence number for the page blob. + */ + int64_t SequenceNumber = int64_t(); +}; +/** + * @brief Response type for + * #Azure::Storage::Blobs::PageBlobClient::UploadPagesFromUri. + */ +struct UploadPagesFromUriResult final { + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the container was last modified. Any operation + * that modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; + /** + * If the blob has an MD5 hash and this operation is to read the full blob, + * this response header is returned so that the client can check for message + * content integrity. + */ + Nullable TransactionalContentHash; + /** + * The current sequence number for the page blob. + */ + int64_t SequenceNumber = int64_t(); + /** + * The value of this header is set to true if the contents of the request are + * successfully encrypted using the specified algorithm, and false otherwise. + */ + bool IsServerEncrypted = bool(); + /** + * The SHA-256 hash of the encryption key used to encrypt the blob. This + * header is only returned when the blob was encrypted with a + * customer-provided key. + */ + Nullable> EncryptionKeySha256; + /** + * Returns the name of the encryption scope used to encrypt the blob contents + * and application metadata. Note that the absence of this header implies use + * of the default account encryption scope. + */ + Nullable EncryptionScope; +}; +namespace _detail { +/** + * @brief Response type for + * #Azure::Storage::Blobs::PageBlobClient::GetPageRanges. + */ +struct GetPageRangesResult final { + Azure::ETag ETag; + DateTime LastModified; + /** + * Size of the blob in bytes. + */ + int64_t BlobSize = int64_t(); + /** + * Array of PageRange. + */ + std::vector PageRanges; + /** + * Array of ClearRange. + */ + std::vector ClearRanges; +}; +/** + * @brief Response type for + * #Azure::Storage::Blobs::PageBlobClient::GetPageRangesDiff. + */ +struct GetPageRangesDiffResult final { + Azure::ETag ETag; + DateTime LastModified; + /** + * Size of the blob in bytes. + */ + int64_t BlobSize = int64_t(); + /** + * Array of PageRange. + */ + std::vector PageRanges; + /** + * Array of ClearRange. + */ + std::vector ClearRanges; +}; +} // namespace _detail +/** + * @brief Response type for #Azure::Storage::Blobs::PageBlobClient::Resize. + */ +struct ResizePageBlobResult final { + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the container was last modified. Any operation + * that modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; + /** + * The current sequence number for a page blob. This header is not returned + * for block blobs or append blobs. + */ + int64_t SequenceNumber = int64_t(); +}; +/** + * @brief Required if the x-ms-blob-sequence-number header is set for the + * request. This property applies to page blobs only. This property indicates + * how the service should modify the blob's sequence number. + */ +class SequenceNumberAction final { +public: + SequenceNumberAction() = default; + explicit SequenceNumberAction(std::string value) + : m_value(std::move(value)) {} + bool operator==(const SequenceNumberAction &other) const { + return m_value == other.m_value; + } + bool operator!=(const SequenceNumberAction &other) const { + return !(*this == other); + } + const std::string &ToString() const { return m_value; } + AZ_TEMPLATE_DLLEXPORT const static SequenceNumberAction Max; + AZ_TEMPLATE_DLLEXPORT const static SequenceNumberAction Update; + AZ_TEMPLATE_DLLEXPORT const static SequenceNumberAction Increment; + +private: + std::string m_value; +}; +/** + * @brief Response type for + * #Azure::Storage::Blobs::PageBlobClient::UpdateSequenceNumber. + */ +struct UpdateSequenceNumberResult final { + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the container was last modified. Any operation + * that modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; + /** + * The current sequence number for a page blob. This header is not returned + * for block blobs or append blobs. + */ + int64_t SequenceNumber = int64_t(); +}; +namespace _detail { +/** + * @brief Response type for + * #Azure::Storage::Blobs::PageBlobClient::StartCopyIncremental. + */ +struct StartBlobCopyIncrementalResult final { + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the container was last modified. Any operation + * that modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; + /** + * String identifier for this copy operation. Use with Get Blob Properties to + * check the status of this copy operation, or pass to Abort Copy Blob to + * abort a pending copy. + */ + std::string CopyId; + /** + * State of the copy operation identified by x-ms-copy-id. + */ + Models::CopyStatus CopyStatus; + /** + * A DateTime value returned by the service that uniquely identifies the blob. + * The value of this header indicates the blob version, and may be used in + * subsequent requests to access this version of the blob. + */ + Nullable VersionId; +}; +} // namespace _detail +/** + * @brief Response type for #Azure::Storage::Blobs::AppendBlobClient::Create. + */ +struct CreateAppendBlobResult final { + /** + * Indicates if the append blob was successfully created by this operation. + */ + bool Created = true; + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the container was last modified. Any operation + * that modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; + /** + * A DateTime value returned by the service that uniquely identifies the blob. + * The value of this header indicates the blob version, and may be used in + * subsequent requests to access this version of the blob. + */ + Nullable VersionId; + /** + * The value of this header is set to true if the contents of the request are + * successfully encrypted using the specified algorithm, and false otherwise. + */ + bool IsServerEncrypted = bool(); + /** + * The SHA-256 hash of the encryption key used to encrypt the blob. This + * header is only returned when the blob was encrypted with a + * customer-provided key. + */ + Nullable> EncryptionKeySha256; + /** + * Returns the name of the encryption scope used to encrypt the blob contents + * and application metadata. Note that the absence of this header implies use + * of the default account encryption scope. + */ + Nullable EncryptionScope; +}; +/** + * @brief Response type for + * #Azure::Storage::Blobs::AppendBlobClient::AppendBlock. + */ +struct AppendBlockResult final { + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the container was last modified. Any operation + * that modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; + /** + * If the blob has an MD5 hash and this operation is to read the full blob, + * this response header is returned so that the client can check for message + * content integrity. + */ + Nullable TransactionalContentHash; + /** + * This response header is returned only for append operations. It returns the + * offset at which the block was committed, in bytes. + */ + int64_t AppendOffset = int64_t(); + /** + * The number of committed blocks present in the blob. This header is returned + * only for append blobs. + */ + int32_t CommittedBlockCount = int32_t(); + /** + * The value of this header is set to true if the contents of the request are + * successfully encrypted using the specified algorithm, and false otherwise. + */ + bool IsServerEncrypted = bool(); + /** + * The SHA-256 hash of the encryption key used to encrypt the block. This + * header is only returned when the block was encrypted with a + * customer-provided key. + */ + Nullable> EncryptionKeySha256; + /** + * Returns the name of the encryption scope used to encrypt the blob contents + * and application metadata. Note that the absence of this header implies use + * of the default account encryption scope. + */ + Nullable EncryptionScope; +}; +/** + * @brief Response type for + * #Azure::Storage::Blobs::AppendBlobClient::AppendBlockFromUri. + */ +struct AppendBlockFromUriResult final { + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the container was last modified. Any operation + * that modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; + /** + * If the blob has an MD5 hash and this operation is to read the full blob, + * this response header is returned so that the client can check for message + * content integrity. + */ + Nullable TransactionalContentHash; + /** + * This response header is returned only for append operations. It returns the + * offset at which the block was committed, in bytes. + */ + int64_t AppendOffset = int64_t(); + /** + * The number of committed blocks present in the blob. This header is returned + * only for append blobs. + */ + int32_t CommittedBlockCount = int32_t(); + /** + * The SHA-256 hash of the encryption key used to encrypt the block. This + * header is only returned when the block was encrypted with a + * customer-provided key. + */ + Nullable> EncryptionKeySha256; + /** + * Returns the name of the encryption scope used to encrypt the blob contents + * and application metadata. Note that the absence of this header implies use + * of the default account encryption scope. + */ + Nullable EncryptionScope; + /** + * The value of this header is set to true if the contents of the request are + * successfully encrypted using the specified algorithm, and false otherwise. + */ + bool IsServerEncrypted = bool(); +}; +/** + * @brief Response type for #Azure::Storage::Blobs::AppendBlobClient::Seal. + */ +struct SealAppendBlobResult final { + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the container was last modified. Any operation + * that modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; + /** + * If this blob has been sealed. + */ + bool IsSealed = bool(); +}; +/** + * @brief Response type for #Azure::Storage::Blobs::BlockBlobClient::Upload. + */ +struct UploadBlockBlobResult final { + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the container was last modified. Any operation + * that modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; + /** + * If the blob has an MD5 hash and this operation is to read the full blob, + * this response header is returned so that the client can check for message + * content integrity. + */ + Nullable TransactionalContentHash; + /** + * A DateTime value returned by the service that uniquely identifies the blob. + * The value of this header indicates the blob version, and may be used in + * subsequent requests to access this version of the blob. + */ + Nullable VersionId; + /** + * The value of this header is set to true if the contents of the request are + * successfully encrypted using the specified algorithm, and false otherwise. + */ + bool IsServerEncrypted = bool(); + /** + * The SHA-256 hash of the encryption key used to encrypt the blob. This + * header is only returned when the blob was encrypted with a + * customer-provided key. + */ + Nullable> EncryptionKeySha256; + /** + * Returns the name of the encryption scope used to encrypt the blob contents + * and application metadata. Note that the absence of this header implies use + * of the default account encryption scope. + */ + Nullable EncryptionScope; +}; +/** + * @brief Response type for + * #Azure::Storage::Blobs::BlockBlobClient::UploadFromUri. + */ +struct UploadBlockBlobFromUriResult final { + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the container was last modified. Any operation + * that modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; + /** + * If the blob has an MD5 hash and this operation is to read the full blob, + * this response header is returned so that the client can check for message + * content integrity. + */ + Nullable TransactionalContentHash; + /** + * A DateTime value returned by the service that uniquely identifies the blob. + * The value of this header indicates the blob version, and may be used in + * subsequent requests to access this version of the blob. + */ + Nullable VersionId; + /** + * The value of this header is set to true if the contents of the request are + * successfully encrypted using the specified algorithm, and false otherwise. + */ + bool IsServerEncrypted = bool(); + /** + * The SHA-256 hash of the encryption key used to encrypt the blob. This + * header is only returned when the blob was encrypted with a + * customer-provided key. + */ + Nullable> EncryptionKeySha256; + /** + * Returns the name of the encryption scope used to encrypt the blob contents + * and application metadata. Note that the absence of this header implies use + * of the default account encryption scope. + */ + Nullable EncryptionScope; +}; +/** + * @brief Response type for #Azure::Storage::Blobs::BlockBlobClient::StageBlock. + */ +struct StageBlockResult final { + /** + * This header is returned so that the client can check for message content + * integrity. The value of this header is computed by the Blob service; it is + * not necessarily the same value specified in the request headers. + */ + Nullable TransactionalContentHash; + /** + * The value of this header is set to true if the contents of the request are + * successfully encrypted using the specified algorithm, and false otherwise. + */ + bool IsServerEncrypted = bool(); + /** + * The SHA-256 hash of the encryption key used to encrypt the block. This + * header is only returned when the block was encrypted with a + * customer-provided key. + */ + Nullable> EncryptionKeySha256; + /** + * Returns the name of the encryption scope used to encrypt the blob contents + * and application metadata. Note that the absence of this header implies use + * of the default account encryption scope. + */ + Nullable EncryptionScope; +}; +/** + * @brief Response type for + * #Azure::Storage::Blobs::BlockBlobClient::StageBlockFromUri. + */ +struct StageBlockFromUriResult final { + /** + * This header is returned so that the client can check for message content + * integrity. The value of this header is computed by the Blob service; it is + * not necessarily the same value specified in the request headers. + */ + Nullable TransactionalContentHash; + /** + * The value of this header is set to true if the contents of the request are + * successfully encrypted using the specified algorithm, and false otherwise. + */ + bool IsServerEncrypted = bool(); + /** + * The SHA-256 hash of the encryption key used to encrypt the block. This + * header is only returned when the block was encrypted with a + * customer-provided key. + */ + Nullable> EncryptionKeySha256; + /** + * Returns the name of the encryption scope used to encrypt the blob contents + * and application metadata. Note that the absence of this header implies use + * of the default account encryption scope. + */ + Nullable EncryptionScope; +}; +namespace _detail { +struct BlockLookupList final { + /** + * Array of BlockLookupListCommittedItem. + */ + std::vector Committed; + /** + * Array of BlockLookupListUncommittedItem. + */ + std::vector Uncommitted; + /** + * Array of BlockLookupListLatestItem. + */ + std::vector Latest; +}; +} // namespace _detail +/** + * @brief Response type for + * #Azure::Storage::Blobs::BlockBlobClient::CommitBlockList. + */ +struct CommitBlockListResult final { + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the container was last modified. Any operation + * that modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; + /** + * This header is returned so that the client can check for message content + * integrity. This header refers to the content of the request, meaning, in + * this case, the list of blocks, and not the content of the blob itself. + */ + Nullable TransactionalContentHash; + /** + * A DateTime value returned by the service that uniquely identifies the blob. + * The value of this header indicates the blob version, and may be used in + * subsequent requests to access this version of the blob. + */ + Nullable VersionId; + /** + * The value of this header is set to true if the contents of the request are + * successfully encrypted using the specified algorithm, and false otherwise. + */ + bool IsServerEncrypted = bool(); + /** + * The SHA-256 hash of the encryption key used to encrypt the blob. This + * header is only returned when the blob was encrypted with a + * customer-provided key. + */ + Nullable> EncryptionKeySha256; + /** + * Returns the name of the encryption scope used to encrypt the blob contents + * and application metadata. Note that the absence of this header implies use + * of the default account encryption scope. + */ + Nullable EncryptionScope; +}; +/** + * @brief Represents a single block in a block blob. It describes the block's + * ID and size. + */ +struct BlobBlock final { + /** + * The base64 encoded block ID. + */ + std::string Name; + /** + * The block size in bytes. + */ + int64_t Size = int64_t(); +}; +/** + * @brief Specifies whether to return the list of committed blocks, the list of + * uncommitted blocks, or both lists together. + */ +class BlockListType final { +public: + BlockListType() = default; + explicit BlockListType(std::string value) : m_value(std::move(value)) {} + bool operator==(const BlockListType &other) const { + return m_value == other.m_value; + } + bool operator!=(const BlockListType &other) const { + return !(*this == other); + } + const std::string &ToString() const { return m_value; } + AZ_TEMPLATE_DLLEXPORT const static BlockListType Committed; + AZ_TEMPLATE_DLLEXPORT const static BlockListType Uncommitted; + AZ_TEMPLATE_DLLEXPORT const static BlockListType All; + +private: + std::string m_value; +}; +/** + * @brief Response type for + * #Azure::Storage::Blobs::BlockBlobClient::GetBlockList. + */ +struct GetBlockListResult final { + /** + * The ETag contains a value that you can use to perform operations + * conditionally. If the request version is 2011-08-18 or newer, the ETag + * value will be in quotes. + */ + Azure::ETag ETag; + /** + * Returns the date and time the container was last modified. Any operation + * that modifies the blob, including an update of the blob's metadata or + * properties, changes the last-modified time of the blob. + */ + DateTime LastModified; + /** + * Size of the blob in bytes. + */ + int64_t BlobSize = 0; + /** + * List of committed blocks. + */ + std::vector CommittedBlocks; + /** + * List of uncommitted blocks. + */ + std::vector UncommittedBlocks; +}; +} // namespace Models +namespace _detail { +class ServiceClient final { +public: + struct SetServicePropertiesOptions final { + Models::BlobServiceProperties BlobServiceProperties; + }; + static Response SetProperties( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const SetServicePropertiesOptions &options, const Core::Context &context); + struct GetServicePropertiesOptions final {}; + static Response GetProperties( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const GetServicePropertiesOptions &options, const Core::Context &context); + struct GetServiceStatisticsOptions final {}; + static Response GetStatistics( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const GetServiceStatisticsOptions &options, const Core::Context &context); + struct ListServiceBlobContainersOptions final { + Nullable Prefix; + Nullable Marker; + Nullable MaxResults; + Nullable Include; + }; + static Response + ListBlobContainers(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const ListServiceBlobContainersOptions &options, + const Core::Context &context); + struct GetServiceUserDelegationKeyOptions final { + Models::_detail::KeyInfo KeyInfo; + }; + static Response + GetUserDelegationKey(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const GetServiceUserDelegationKeyOptions &options, + const Core::Context &context); + struct GetServiceAccountInfoOptions final {}; + static Response + GetAccountInfo(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const GetServiceAccountInfoOptions &options, + const Core::Context &context); + struct FindServiceBlobsByTagsOptions final { + Nullable Where; + Nullable Marker; + Nullable MaxResults; + }; + static Response + FindBlobsByTags(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const FindServiceBlobsByTagsOptions &options, + const Core::Context &context); +}; +class BlobContainerClient final { +public: + struct CreateBlobContainerOptions final { + std::map Metadata; + Models::PublicAccessType Access; + Nullable DefaultEncryptionScope; + Nullable PreventEncryptionScopeOverride; + }; + static Response + Create(Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const CreateBlobContainerOptions &options, + const Core::Context &context); + struct GetBlobContainerPropertiesOptions final { + Nullable LeaseId; + }; + static Response + GetProperties(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const GetBlobContainerPropertiesOptions &options, + const Core::Context &context); + struct DeleteBlobContainerOptions final { + Nullable LeaseId; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + }; + static Response + Delete(Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const DeleteBlobContainerOptions &options, + const Core::Context &context); + struct SetBlobContainerMetadataOptions final { + Nullable LeaseId; + std::map Metadata; + Nullable IfModifiedSince; + }; + static Response + SetMetadata(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const SetBlobContainerMetadataOptions &options, + const Core::Context &context); + struct GetBlobContainerAccessPolicyOptions final { + Nullable LeaseId; + }; + static Response + GetAccessPolicy(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const GetBlobContainerAccessPolicyOptions &options, + const Core::Context &context); + struct SetBlobContainerAccessPolicyOptions final { + std::vector ContainerAcl; + Nullable LeaseId; + Models::PublicAccessType Access; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + }; + static Response + SetAccessPolicy(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const SetBlobContainerAccessPolicyOptions &options, + const Core::Context &context); + struct UndeleteBlobContainerOptions final { + Nullable DeletedContainerName; + Nullable DeletedContainerVersion; + }; + static Response + Undelete(Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const UndeleteBlobContainerOptions &options, + const Core::Context &context); + struct RenameBlobContainerOptions final { + std::string SourceContainerName; + Nullable SourceLeaseId; + }; + static Response + Rename(Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const RenameBlobContainerOptions &options, + const Core::Context &context); + struct AcquireBlobContainerLeaseOptions final { + Nullable Duration; + Nullable ProposedLeaseId; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + }; + static Response + AcquireLease(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const AcquireBlobContainerLeaseOptions &options, + const Core::Context &context); + struct ReleaseBlobContainerLeaseOptions final { + std::string LeaseId; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + }; + static Response + ReleaseLease(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const ReleaseBlobContainerLeaseOptions &options, + const Core::Context &context); + struct RenewBlobContainerLeaseOptions final { + std::string LeaseId; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + }; + static Response + RenewLease(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const RenewBlobContainerLeaseOptions &options, + const Core::Context &context); + struct BreakBlobContainerLeaseOptions final { + Nullable BreakPeriod; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + }; + static Response + BreakLease(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const BreakBlobContainerLeaseOptions &options, + const Core::Context &context); + struct ChangeBlobContainerLeaseOptions final { + std::string LeaseId; + std::string ProposedLeaseId; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + }; + static Response + ChangeLease(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const ChangeBlobContainerLeaseOptions &options, + const Core::Context &context); + struct ListBlobContainerBlobsOptions final { + Nullable Prefix; + Nullable Marker; + Nullable MaxResults; + Nullable Include; + }; + static Response + ListBlobs(Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const ListBlobContainerBlobsOptions &options, + const Core::Context &context); + struct ListBlobContainerBlobsByHierarchyOptions final { + Nullable Prefix; + std::string Delimiter; + Nullable Marker; + Nullable MaxResults; + Nullable Include; + }; + static Response + ListBlobsByHierarchy(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const ListBlobContainerBlobsByHierarchyOptions &options, + const Core::Context &context); +}; +class BlobClient final { +public: + struct DownloadBlobOptions final { + Nullable Snapshot; + Nullable VersionId; + Nullable Range; + Nullable LeaseId; + Nullable RangeGetContentMD5; + Nullable RangeGetContentCRC64; + Nullable EncryptionKey; + Nullable> EncryptionKeySha256; + Nullable EncryptionAlgorithm; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + ETag IfMatch; + ETag IfNoneMatch; + Nullable IfTags; + }; + static Response + Download(Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const DownloadBlobOptions &options, const Core::Context &context); + struct GetBlobPropertiesOptions final { + Nullable Snapshot; + Nullable VersionId; + Nullable LeaseId; + Nullable EncryptionKey; + Nullable> EncryptionKeySha256; + Nullable EncryptionAlgorithm; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + ETag IfMatch; + ETag IfNoneMatch; + Nullable IfTags; + }; + static Response + GetProperties(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, const GetBlobPropertiesOptions &options, + const Core::Context &context); + struct DeleteBlobOptions final { + Nullable Snapshot; + Nullable VersionId; + Nullable LeaseId; + Nullable DeleteSnapshots; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + ETag IfMatch; + ETag IfNoneMatch; + Nullable IfTags; + }; + static Response + Delete(Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const DeleteBlobOptions &options, const Core::Context &context); + struct UndeleteBlobOptions final {}; + static Response + Undelete(Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const UndeleteBlobOptions &options, const Core::Context &context); + struct SetBlobExpiryOptions final { + Models::ScheduleBlobExpiryOriginType ExpiryOptions; + Nullable ExpiresOn; + }; + static Response + SetExpiry(Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const SetBlobExpiryOptions &options, const Core::Context &context); + struct SetBlobHttpHeadersOptions final { + std::string BlobCacheControl; + std::string BlobContentType; + std::vector BlobContentMD5; + std::string BlobContentEncoding; + std::string BlobContentLanguage; + Nullable LeaseId; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + ETag IfMatch; + ETag IfNoneMatch; + Nullable IfTags; + std::string BlobContentDisposition; + }; + static Response + SetHttpHeaders(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, const SetBlobHttpHeadersOptions &options, + const Core::Context &context); + struct SetBlobImmutabilityPolicyOptions final { + Nullable IfUnmodifiedSince; + Nullable ImmutabilityPolicyExpiry; + Nullable ImmutabilityPolicyMode; + }; + static Response + SetImmutabilityPolicy(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const SetBlobImmutabilityPolicyOptions &options, + const Core::Context &context); + struct DeleteBlobImmutabilityPolicyOptions final {}; + static Response + DeleteImmutabilityPolicy(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const DeleteBlobImmutabilityPolicyOptions &options, + const Core::Context &context); + struct SetBlobLegalHoldOptions final { + bool LegalHold = bool(); + }; + static Response + SetLegalHold(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, const SetBlobLegalHoldOptions &options, + const Core::Context &context); + struct SetBlobMetadataOptions final { + std::map Metadata; + Nullable LeaseId; + Nullable EncryptionKey; + Nullable> EncryptionKeySha256; + Nullable EncryptionAlgorithm; + Nullable EncryptionScope; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + ETag IfMatch; + ETag IfNoneMatch; + Nullable IfTags; + }; + static Response + SetMetadata(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, const SetBlobMetadataOptions &options, + const Core::Context &context); + struct AcquireBlobLeaseOptions final { + Nullable Duration; + Nullable ProposedLeaseId; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + ETag IfMatch; + ETag IfNoneMatch; + Nullable IfTags; + }; + static Response + AcquireLease(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, const AcquireBlobLeaseOptions &options, + const Core::Context &context); + struct ReleaseBlobLeaseOptions final { + std::string LeaseId; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + ETag IfMatch; + ETag IfNoneMatch; + Nullable IfTags; + }; + static Response + ReleaseLease(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, const ReleaseBlobLeaseOptions &options, + const Core::Context &context); + struct RenewBlobLeaseOptions final { + std::string LeaseId; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + ETag IfMatch; + ETag IfNoneMatch; + Nullable IfTags; + }; + static Response + RenewLease(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, const RenewBlobLeaseOptions &options, + const Core::Context &context); + struct ChangeBlobLeaseOptions final { + std::string LeaseId; + std::string ProposedLeaseId; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + ETag IfMatch; + ETag IfNoneMatch; + Nullable IfTags; + }; + static Response + ChangeLease(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, const ChangeBlobLeaseOptions &options, + const Core::Context &context); + struct BreakBlobLeaseOptions final { + Nullable BreakPeriod; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + ETag IfMatch; + ETag IfNoneMatch; + Nullable IfTags; + }; + static Response + BreakLease(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, const BreakBlobLeaseOptions &options, + const Core::Context &context); + struct CreateBlobSnapshotOptions final { + std::map Metadata; + Nullable EncryptionKey; + Nullable> EncryptionKeySha256; + Nullable EncryptionAlgorithm; + Nullable EncryptionScope; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + ETag IfMatch; + ETag IfNoneMatch; + Nullable IfTags; + Nullable LeaseId; + }; + static Response + CreateSnapshot(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, const CreateBlobSnapshotOptions &options, + const Core::Context &context); + struct StartBlobCopyFromUriOptions final { + Nullable SourceLeaseId; + std::map Metadata; + Nullable Tier; + Nullable RehydratePriority; + Nullable SourceIfModifiedSince; + Nullable SourceIfUnmodifiedSince; + ETag SourceIfMatch; + ETag SourceIfNoneMatch; + Nullable SourceIfTags; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + ETag IfMatch; + ETag IfNoneMatch; + Nullable IfTags; + std::string CopySource; + Nullable LeaseId; + Nullable BlobTagsString; + Nullable SealBlob; + Nullable ImmutabilityPolicyExpiry; + Nullable ImmutabilityPolicyMode; + Nullable LegalHold; + }; + static Response StartCopyFromUri( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const StartBlobCopyFromUriOptions &options, const Core::Context &context); + struct CopyBlobFromUriOptions final { + std::map Metadata; + Nullable Tier; + Nullable SourceIfModifiedSince; + Nullable SourceIfUnmodifiedSince; + ETag SourceIfMatch; + ETag SourceIfNoneMatch; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + ETag IfMatch; + ETag IfNoneMatch; + Nullable IfTags; + std::string CopySource; + Nullable LeaseId; + Nullable> SourceContentMD5; + Nullable BlobTagsString; + Nullable ImmutabilityPolicyExpiry; + Nullable ImmutabilityPolicyMode; + Nullable LegalHold; + Nullable> SourceContentcrc64; + }; + static Response + CopyFromUri(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, const CopyBlobFromUriOptions &options, + const Core::Context &context); + struct AbortBlobCopyFromUriOptions final { + std::string CopyId; + Nullable LeaseId; + }; + static Response AbortCopyFromUri( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const AbortBlobCopyFromUriOptions &options, const Core::Context &context); + struct SetBlobTierOptions final { + Nullable Snapshot; + Nullable VersionId; + Models::AccessTier Tier; + Nullable RehydratePriority; + Nullable LeaseId; + Nullable IfTags; + }; + static Response + SetTier(Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const SetBlobTierOptions &options, const Core::Context &context); + struct GetBlobTagsOptions final { + Nullable Snapshot; + Nullable VersionId; + Nullable IfTags; + Nullable LeaseId; + }; + static Response> + GetTags(Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const GetBlobTagsOptions &options, const Core::Context &context); + struct SetBlobTagsOptions final { + std::map Tags; + Nullable VersionId; + Nullable> TransactionalContentMD5; + Nullable> TransactionalContentCrc64; + Nullable IfTags; + Nullable LeaseId; + }; + static Response + SetTags(Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const SetBlobTagsOptions &options, const Core::Context &context); +}; +class PageBlobClient final { +public: + struct CreatePageBlobOptions final { + Nullable Tier; + std::string BlobContentType; + std::string BlobContentEncoding; + std::string BlobContentLanguage; + std::vector BlobContentMD5; + std::string BlobCacheControl; + std::map Metadata; + Nullable LeaseId; + std::string BlobContentDisposition; + Nullable EncryptionKey; + Nullable> EncryptionKeySha256; + Nullable EncryptionAlgorithm; + Nullable EncryptionScope; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + ETag IfMatch; + ETag IfNoneMatch; + Nullable IfTags; + int64_t BlobContentLength = int64_t(); + Nullable BlobSequenceNumber; + Nullable BlobTagsString; + Nullable ImmutabilityPolicyExpiry; + Nullable ImmutabilityPolicyMode; + Nullable LegalHold; + }; + static Response + Create(Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const CreatePageBlobOptions &options, const Core::Context &context); + struct UploadPageBlobPagesOptions final { + Nullable> TransactionalContentMD5; + Nullable> TransactionalContentCrc64; + Nullable Range; + Nullable LeaseId; + Nullable EncryptionKey; + Nullable> EncryptionKeySha256; + Nullable EncryptionAlgorithm; + Nullable EncryptionScope; + Nullable IfSequenceNumberLessThanOrEqualTo; + Nullable IfSequenceNumberLessThan; + Nullable IfSequenceNumberEqualTo; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + ETag IfMatch; + ETag IfNoneMatch; + Nullable IfTags; + }; + static Response + UploadPages(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, Core::IO::BodyStream &requestBody, + const UploadPageBlobPagesOptions &options, + const Core::Context &context); + struct ClearPageBlobPagesOptions final { + Nullable Range; + Nullable LeaseId; + Nullable EncryptionKey; + Nullable> EncryptionKeySha256; + Nullable EncryptionAlgorithm; + Nullable EncryptionScope; + Nullable IfSequenceNumberLessThanOrEqualTo; + Nullable IfSequenceNumberLessThan; + Nullable IfSequenceNumberEqualTo; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + ETag IfMatch; + ETag IfNoneMatch; + Nullable IfTags; + }; + static Response + ClearPages(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, const ClearPageBlobPagesOptions &options, + const Core::Context &context); + struct UploadPageBlobPagesFromUriOptions final { + std::string SourceUrl; + std::string SourceRange; + Nullable> SourceContentMD5; + Nullable> SourceContentcrc64; + std::string Range; + Nullable EncryptionKey; + Nullable> EncryptionKeySha256; + Nullable EncryptionAlgorithm; + Nullable EncryptionScope; + Nullable LeaseId; + Nullable IfSequenceNumberLessThanOrEqualTo; + Nullable IfSequenceNumberLessThan; + Nullable IfSequenceNumberEqualTo; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + ETag IfMatch; + ETag IfNoneMatch; + Nullable IfTags; + Nullable SourceIfModifiedSince; + Nullable SourceIfUnmodifiedSince; + ETag SourceIfMatch; + ETag SourceIfNoneMatch; + }; + static Response + UploadPagesFromUri(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const UploadPageBlobPagesFromUriOptions &options, + const Core::Context &context); + struct GetPageBlobPageRangesOptions final { + Nullable Snapshot; + Nullable Range; + Nullable LeaseId; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + ETag IfMatch; + ETag IfNoneMatch; + Nullable IfTags; + }; + static Response + GetPageRanges(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const GetPageBlobPageRangesOptions &options, + const Core::Context &context); + struct GetPageBlobPageRangesDiffOptions final { + Nullable Snapshot; + Nullable Prevsnapshot; + Nullable PrevSnapshotUrl; + Nullable Range; + Nullable LeaseId; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + ETag IfMatch; + ETag IfNoneMatch; + Nullable IfTags; + }; + static Response + GetPageRangesDiff(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const GetPageBlobPageRangesDiffOptions &options, + const Core::Context &context); + struct ResizePageBlobOptions final { + Nullable LeaseId; + Nullable EncryptionKey; + Nullable> EncryptionKeySha256; + Nullable EncryptionAlgorithm; + Nullable EncryptionScope; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + ETag IfMatch; + ETag IfNoneMatch; + Nullable IfTags; + int64_t BlobContentLength = int64_t(); + }; + static Response + Resize(Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const ResizePageBlobOptions &options, const Core::Context &context); + struct UpdatePageBlobSequenceNumberOptions final { + Nullable LeaseId; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + ETag IfMatch; + ETag IfNoneMatch; + Nullable IfTags; + Models::SequenceNumberAction SequenceNumberAction; + Nullable BlobSequenceNumber; + }; + static Response + UpdateSequenceNumber(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const UpdatePageBlobSequenceNumberOptions &options, + const Core::Context &context); + struct StartPageBlobCopyIncrementalOptions final { + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + ETag IfMatch; + ETag IfNoneMatch; + Nullable IfTags; + std::string CopySource; + }; + static Response + StartCopyIncremental(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const StartPageBlobCopyIncrementalOptions &options, + const Core::Context &context); +}; +class AppendBlobClient final { +public: + struct CreateAppendBlobOptions final { + std::string BlobContentType; + std::string BlobContentEncoding; + std::string BlobContentLanguage; + std::vector BlobContentMD5; + std::string BlobCacheControl; + std::map Metadata; + Nullable LeaseId; + std::string BlobContentDisposition; + Nullable EncryptionKey; + Nullable> EncryptionKeySha256; + Nullable EncryptionAlgorithm; + Nullable EncryptionScope; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + ETag IfMatch; + ETag IfNoneMatch; + Nullable IfTags; + Nullable BlobTagsString; + Nullable ImmutabilityPolicyExpiry; + Nullable ImmutabilityPolicyMode; + Nullable LegalHold; + }; + static Response + Create(Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const CreateAppendBlobOptions &options, const Core::Context &context); + struct AppendAppendBlobBlockOptions final { + Nullable> TransactionalContentMD5; + Nullable> TransactionalContentCrc64; + Nullable LeaseId; + Nullable MaxSize; + Nullable AppendPosition; + Nullable EncryptionKey; + Nullable> EncryptionKeySha256; + Nullable EncryptionAlgorithm; + Nullable EncryptionScope; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + ETag IfMatch; + ETag IfNoneMatch; + Nullable IfTags; + }; + static Response + AppendBlock(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, Core::IO::BodyStream &requestBody, + const AppendAppendBlobBlockOptions &options, + const Core::Context &context); + struct AppendAppendBlobBlockFromUriOptions final { + std::string SourceUrl; + Nullable SourceRange; + Nullable> SourceContentMD5; + Nullable> SourceContentcrc64; + Nullable> TransactionalContentMD5; + Nullable EncryptionKey; + Nullable> EncryptionKeySha256; + Nullable EncryptionAlgorithm; + Nullable EncryptionScope; + Nullable LeaseId; + Nullable MaxSize; + Nullable AppendPosition; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + ETag IfMatch; + ETag IfNoneMatch; + Nullable IfTags; + Nullable SourceIfModifiedSince; + Nullable SourceIfUnmodifiedSince; + ETag SourceIfMatch; + ETag SourceIfNoneMatch; + }; + static Response + AppendBlockFromUri(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const AppendAppendBlobBlockFromUriOptions &options, + const Core::Context &context); + struct SealAppendBlobOptions final { + Nullable LeaseId; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + ETag IfMatch; + ETag IfNoneMatch; + Nullable AppendPosition; + }; + static Response + Seal(Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const SealAppendBlobOptions &options, const Core::Context &context); +}; +class BlockBlobClient final { +public: + struct UploadBlockBlobOptions final { + Nullable> TransactionalContentMD5; + std::string BlobContentType; + std::string BlobContentEncoding; + std::string BlobContentLanguage; + std::vector BlobContentMD5; + std::string BlobCacheControl; + std::map Metadata; + Nullable LeaseId; + std::string BlobContentDisposition; + Nullable EncryptionKey; + Nullable> EncryptionKeySha256; + Nullable EncryptionAlgorithm; + Nullable EncryptionScope; + Nullable Tier; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + ETag IfMatch; + ETag IfNoneMatch; + Nullable IfTags; + Nullable BlobTagsString; + Nullable ImmutabilityPolicyExpiry; + Nullable ImmutabilityPolicyMode; + Nullable LegalHold; + Nullable> TransactionalContentCrc64; + }; + static Response + Upload(Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + Core::IO::BodyStream &requestBody, + const UploadBlockBlobOptions &options, const Core::Context &context); + struct UploadBlockBlobFromUriOptions final { + std::string BlobContentType; + std::string BlobContentEncoding; + std::string BlobContentLanguage; + std::vector BlobContentMD5; + std::string BlobCacheControl; + std::map Metadata; + Nullable LeaseId; + std::string BlobContentDisposition; + Nullable EncryptionKey; + Nullable> EncryptionKeySha256; + Nullable EncryptionAlgorithm; + Nullable EncryptionScope; + Nullable Tier; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + ETag IfMatch; + ETag IfNoneMatch; + Nullable IfTags; + Nullable SourceIfModifiedSince; + Nullable SourceIfUnmodifiedSince; + ETag SourceIfMatch; + ETag SourceIfNoneMatch; + Nullable SourceIfTags; + Nullable> SourceContentMD5; + Nullable BlobTagsString; + std::string CopySource; + Nullable CopySourceBlobProperties; + Nullable> SourceContentcrc64; + }; + static Response + UploadFromUri(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const UploadBlockBlobFromUriOptions &options, + const Core::Context &context); + struct StageBlockBlobBlockOptions final { + std::string BlockId; + Nullable> TransactionalContentMD5; + Nullable> TransactionalContentCrc64; + Nullable LeaseId; + Nullable EncryptionKey; + Nullable> EncryptionKeySha256; + Nullable EncryptionAlgorithm; + Nullable EncryptionScope; + }; + static Response + StageBlock(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, Core::IO::BodyStream &requestBody, + const StageBlockBlobBlockOptions &options, + const Core::Context &context); + struct StageBlockBlobBlockFromUriOptions final { + std::string BlockId; + std::string SourceUrl; + Nullable SourceRange; + Nullable> SourceContentMD5; + Nullable> SourceContentcrc64; + Nullable EncryptionKey; + Nullable> EncryptionKeySha256; + Nullable EncryptionAlgorithm; + Nullable EncryptionScope; + Nullable LeaseId; + Nullable SourceIfModifiedSince; + Nullable SourceIfUnmodifiedSince; + ETag SourceIfMatch; + ETag SourceIfNoneMatch; + }; + static Response + StageBlockFromUri(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const StageBlockBlobBlockFromUriOptions &options, + const Core::Context &context); + struct CommitBlockBlobBlockListOptions final { + Models::_detail::BlockLookupList Blocks; + std::string BlobCacheControl; + std::string BlobContentType; + std::string BlobContentEncoding; + std::string BlobContentLanguage; + std::vector BlobContentMD5; + Nullable> TransactionalContentMD5; + Nullable> TransactionalContentCrc64; + std::map Metadata; + Nullable LeaseId; + std::string BlobContentDisposition; + Nullable EncryptionKey; + Nullable> EncryptionKeySha256; + Nullable EncryptionAlgorithm; + Nullable EncryptionScope; + Nullable Tier; + Nullable IfModifiedSince; + Nullable IfUnmodifiedSince; + ETag IfMatch; + ETag IfNoneMatch; + Nullable IfTags; + Nullable BlobTagsString; + Nullable ImmutabilityPolicyExpiry; + Nullable ImmutabilityPolicyMode; + Nullable LegalHold; + }; + static Response + CommitBlockList(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const CommitBlockBlobBlockListOptions &options, + const Core::Context &context); + struct GetBlockBlobBlockListOptions final { + Nullable Snapshot; + Models::BlockListType ListType; + Nullable LeaseId; + Nullable IfTags; + }; + static Response + GetBlockList(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const GetBlockBlobBlockListOptions &options, + const Core::Context &context); +}; +} // namespace _detail +} // namespace Blobs +} // namespace Storage +} // namespace Azure \ No newline at end of file diff --git a/sdk/template/azure-template/inc/azure/template/template_client.hpp b/sdk/template/azure-template/inc/azure/template/template_client.hpp index 6ee21c0f3..f371b26fe 100644 --- a/sdk/template/azure-template/inc/azure/template/template_client.hpp +++ b/sdk/template/azure-template/inc/azure/template/template_client.hpp @@ -4,7 +4,7 @@ #pragma once #include -#include +// #include #include namespace Azure { namespace Template { @@ -19,7 +19,7 @@ namespace Azure { namespace Template { int GetValue(int key, Azure::Core::Context const& context = Azure::Core::Context{}) const; private: - Azure::Core::Tracing::_internal::TracingContextFactory m_tracingFactory; + //Azure::Core::Tracing::_internal::TracingContextFactory m_tracingFactory; }; }} // namespace Azure::Template diff --git a/sdk/template/azure-template/src/rest_client.cpp b/sdk/template/azure-template/src/rest_client.cpp new file mode 100644 index 000000000..776a2a11f --- /dev/null +++ b/sdk/template/azure-template/src/rest_client.cpp @@ -0,0 +1,6804 @@ + +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// +// Code generated by Microsoft (R) AutoRest C++ Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { +std::string ListBlobContainersIncludeFlagsToString( + const Azure::Storage::Blobs::Models::ListBlobContainersIncludeFlags &val) { + const Azure::Storage::Blobs::Models::ListBlobContainersIncludeFlags + valueList[] = { + Azure::Storage::Blobs::Models::ListBlobContainersIncludeFlags:: + Metadata, + Azure::Storage::Blobs::Models::ListBlobContainersIncludeFlags:: + Deleted, + }; + const char *stringList[] = { + "metadata", + "deleted", + }; + std::string ret; + for (size_t i = 0; i < 2; ++i) { + if ((val & valueList[i]) == valueList[i]) { + if (!ret.empty()) { + ret += ","; + } + ret += stringList[i]; + } + } + return ret; +} +std::string ListBlobsIncludeFlagsToString( + const Azure::Storage::Blobs::Models::ListBlobsIncludeFlags &val) { + const Azure::Storage::Blobs::Models::ListBlobsIncludeFlags valueList[] = { + Azure::Storage::Blobs::Models::ListBlobsIncludeFlags::Copy, + Azure::Storage::Blobs::Models::ListBlobsIncludeFlags::Deleted, + Azure::Storage::Blobs::Models::ListBlobsIncludeFlags::Metadata, + Azure::Storage::Blobs::Models::ListBlobsIncludeFlags::Snapshots, + Azure::Storage::Blobs::Models::ListBlobsIncludeFlags::UncomittedBlobs, + Azure::Storage::Blobs::Models::ListBlobsIncludeFlags::Versions, + Azure::Storage::Blobs::Models::ListBlobsIncludeFlags::Tags, + Azure::Storage::Blobs::Models::ListBlobsIncludeFlags::ImmutabilityPolicy, + Azure::Storage::Blobs::Models::ListBlobsIncludeFlags::LegalHold, + }; + const char *stringList[] = { + "copy", + "deleted", + "metadata", + "snapshots", + "uncommittedblobs", + "versions", + "tags", + "immutabilitypolicy", + "legalhold", + }; + std::string ret; + for (size_t i = 0; i < 9; ++i) { + if ((val & valueList[i]) == valueList[i]) { + if (!ret.empty()) { + ret += ","; + } + ret += stringList[i]; + } + } + return ret; +} +} // namespace +namespace Azure { +namespace Storage { +namespace Blobs { +namespace Models { +const EncryptionAlgorithmType EncryptionAlgorithmType::Aes256("AES256"); +const BlockType BlockType::Committed("Committed"); +const BlockType BlockType::Uncommitted("Uncommitted"); +const BlockType BlockType::Latest("Latest"); +const GeoReplicationStatus GeoReplicationStatus::Live("live"); +const GeoReplicationStatus GeoReplicationStatus::Bootstrap("bootstrap"); +const GeoReplicationStatus GeoReplicationStatus::Unavailable("unavailable"); +const LeaseStatus LeaseStatus::Locked("locked"); +const LeaseStatus LeaseStatus::Unlocked("unlocked"); +const LeaseState LeaseState::Available("available"); +const LeaseState LeaseState::Leased("leased"); +const LeaseState LeaseState::Expired("expired"); +const LeaseState LeaseState::Breaking("breaking"); +const LeaseState LeaseState::Broken("broken"); +const LeaseDurationType LeaseDurationType::Infinite("infinite"); +const LeaseDurationType LeaseDurationType::Fixed("fixed"); +const PublicAccessType PublicAccessType::BlobContainer("container"); +const PublicAccessType PublicAccessType::Blob("blob"); +const PublicAccessType PublicAccessType::None(""); +const SkuName SkuName::StandardLrs("Standard_LRS"); +const SkuName SkuName::StandardGrs("Standard_GRS"); +const SkuName SkuName::StandardRagrs("Standard_RAGRS"); +const SkuName SkuName::StandardZrs("Standard_ZRS"); +const SkuName SkuName::PremiumLrs("Premium_LRS"); +const SkuName SkuName::PremiumZrs("Premium_ZRS"); +const SkuName SkuName::StandardGzrs("Standard_GZRS"); +const SkuName SkuName::StandardRagzrs("Standard_RAGZRS"); +const AccountKind AccountKind::Storage("Storage"); +const AccountKind AccountKind::BlobStorage("BlobStorage"); +const AccountKind AccountKind::StorageV2("StorageV2"); +const AccountKind AccountKind::FileStorage("FileStorage"); +const AccountKind AccountKind::BlockBlobStorage("BlockBlobStorage"); +const CopyStatus CopyStatus::Pending("pending"); +const CopyStatus CopyStatus::Success("success"); +const CopyStatus CopyStatus::Aborted("aborted"); +const CopyStatus CopyStatus::Failed("failed"); +const AccessTier AccessTier::P1("P1"); +const AccessTier AccessTier::P2("P2"); +const AccessTier AccessTier::P3("P3"); +const AccessTier AccessTier::P4("P4"); +const AccessTier AccessTier::P6("P6"); +const AccessTier AccessTier::P10("P10"); +const AccessTier AccessTier::P15("P15"); +const AccessTier AccessTier::P20("P20"); +const AccessTier AccessTier::P30("P30"); +const AccessTier AccessTier::P40("P40"); +const AccessTier AccessTier::P50("P50"); +const AccessTier AccessTier::P60("P60"); +const AccessTier AccessTier::P70("P70"); +const AccessTier AccessTier::P80("P80"); +const AccessTier AccessTier::Hot("Hot"); +const AccessTier AccessTier::Cool("Cool"); +const AccessTier AccessTier::Archive("Archive"); +const ArchiveStatus + ArchiveStatus::RehydratePendingToHot("rehydrate-pending-to-hot"); +const ArchiveStatus + ArchiveStatus::RehydratePendingToCool("rehydrate-pending-to-cool"); +const RehydratePriority RehydratePriority::High("High"); +const RehydratePriority RehydratePriority::Standard("Standard"); +const ObjectReplicationStatus ObjectReplicationStatus::Complete("complete"); +const ObjectReplicationStatus ObjectReplicationStatus::Failed("failed"); +const BlobImmutabilityPolicyMode + BlobImmutabilityPolicyMode::Unlocked("unlocked"); +const BlobImmutabilityPolicyMode BlobImmutabilityPolicyMode::Locked("locked"); +const BlobType BlobType::BlockBlob("BlockBlob"); +const BlobType BlobType::PageBlob("PageBlob"); +const BlobType BlobType::AppendBlob("AppendBlob"); +const DeleteSnapshotsOption DeleteSnapshotsOption::IncludeSnapshots("include"); +const DeleteSnapshotsOption DeleteSnapshotsOption::OnlySnapshots("only"); +const ScheduleBlobExpiryOriginType + ScheduleBlobExpiryOriginType::NeverExpire("NeverExpire"); +const ScheduleBlobExpiryOriginType + ScheduleBlobExpiryOriginType::RelativeToCreation("RelativeToCreation"); +const ScheduleBlobExpiryOriginType + ScheduleBlobExpiryOriginType::RelativeToNow("RelativeToNow"); +const ScheduleBlobExpiryOriginType + ScheduleBlobExpiryOriginType::Absolute("Absolute"); +const SequenceNumberAction SequenceNumberAction::Max("max"); +const SequenceNumberAction SequenceNumberAction::Update("update"); +const SequenceNumberAction SequenceNumberAction::Increment("increment"); +const BlockListType BlockListType::Committed("committed"); +const BlockListType BlockListType::Uncommitted("uncommitted"); +const BlockListType BlockListType::All("all"); +} // namespace Models +namespace _detail { +Response ServiceClient::SetProperties( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const SetServicePropertiesOptions &options, const Core::Context &context) { + std::string xmlBody; + { + _internal::XmlWriter writer; + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, + "StorageServiceProperties"}); + writer.Write( + _internal::XmlNode{_internal::XmlNodeType::StartTag, "Logging"}); + writer.Write( + _internal::XmlNode{_internal::XmlNodeType::StartTag, "Version", + options.BlobServiceProperties.Logging.Version}); + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::StartTag, "Delete", + options.BlobServiceProperties.Logging.Delete ? "true" : "false"}); + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::StartTag, "Read", + options.BlobServiceProperties.Logging.Read ? "true" : "false"}); + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::StartTag, "Write", + options.BlobServiceProperties.Logging.Write ? "true" : "false"}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, + "RetentionPolicy"}); + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::StartTag, "Enabled", + options.BlobServiceProperties.Logging.RetentionPolicy.IsEnabled + ? "true" + : "false"}); + if (options.BlobServiceProperties.Logging.RetentionPolicy.Days.HasValue()) { + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::StartTag, "Days", + std::to_string(options.BlobServiceProperties.Logging.RetentionPolicy + .Days.Value())}); + } + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write( + _internal::XmlNode{_internal::XmlNodeType::StartTag, "HourMetrics"}); + writer.Write( + _internal::XmlNode{_internal::XmlNodeType::StartTag, "Version", + options.BlobServiceProperties.HourMetrics.Version}); + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::StartTag, "Enabled", + options.BlobServiceProperties.HourMetrics.IsEnabled ? "true" + : "false"}); + if (options.BlobServiceProperties.HourMetrics.IncludeApis.HasValue()) { + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::StartTag, "IncludeAPIs", + options.BlobServiceProperties.HourMetrics.IncludeApis.Value() + ? "true" + : "false"}); + } + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, + "RetentionPolicy"}); + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::StartTag, "Enabled", + options.BlobServiceProperties.HourMetrics.RetentionPolicy.IsEnabled + ? "true" + : "false"}); + if (options.BlobServiceProperties.HourMetrics.RetentionPolicy.Days + .HasValue()) { + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::StartTag, "Days", + std::to_string(options.BlobServiceProperties.HourMetrics + .RetentionPolicy.Days.Value())}); + } + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write( + _internal::XmlNode{_internal::XmlNodeType::StartTag, "MinuteMetrics"}); + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::StartTag, "Version", + options.BlobServiceProperties.MinuteMetrics.Version}); + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::StartTag, "Enabled", + options.BlobServiceProperties.MinuteMetrics.IsEnabled ? "true" + : "false"}); + if (options.BlobServiceProperties.MinuteMetrics.IncludeApis.HasValue()) { + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::StartTag, "IncludeAPIs", + options.BlobServiceProperties.MinuteMetrics.IncludeApis.Value() + ? "true" + : "false"}); + } + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, + "RetentionPolicy"}); + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::StartTag, "Enabled", + options.BlobServiceProperties.MinuteMetrics.RetentionPolicy.IsEnabled + ? "true" + : "false"}); + if (options.BlobServiceProperties.MinuteMetrics.RetentionPolicy.Days + .HasValue()) { + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::StartTag, "Days", + std::to_string(options.BlobServiceProperties.MinuteMetrics + .RetentionPolicy.Days.Value())}); + } + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "Cors"}); + for (const auto &i1 : options.BlobServiceProperties.Cors) { + writer.Write( + _internal::XmlNode{_internal::XmlNodeType::StartTag, "CorsRule"}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, + "AllowedOrigins", i1.AllowedOrigins}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, + "AllowedMethods", i1.AllowedMethods}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, + "AllowedHeaders", i1.AllowedHeaders}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, + "ExposedHeaders", i1.ExposedHeaders}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, + "MaxAgeInSeconds", + std::to_string(i1.MaxAgeInSeconds)}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + } + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + if (options.BlobServiceProperties.DefaultServiceVersion.HasValue()) { + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::StartTag, "DefaultServiceVersion", + options.BlobServiceProperties.DefaultServiceVersion.Value()}); + } + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, + "DeleteRetentionPolicy"}); + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::StartTag, "Enabled", + options.BlobServiceProperties.DeleteRetentionPolicy.IsEnabled + ? "true" + : "false"}); + if (options.BlobServiceProperties.DeleteRetentionPolicy.Days.HasValue()) { + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::StartTag, "Days", + std::to_string(options.BlobServiceProperties.DeleteRetentionPolicy + .Days.Value())}); + } + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write( + _internal::XmlNode{_internal::XmlNodeType::StartTag, "StaticWebsite"}); + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::StartTag, "Enabled", + options.BlobServiceProperties.StaticWebsite.IsEnabled ? "true" + : "false"}); + if (options.BlobServiceProperties.StaticWebsite.IndexDocument.HasValue()) { + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::StartTag, "IndexDocument", + options.BlobServiceProperties.StaticWebsite.IndexDocument.Value()}); + } + if (options.BlobServiceProperties.StaticWebsite.ErrorDocument404Path + .HasValue()) { + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::StartTag, "ErrorDocument404Path", + options.BlobServiceProperties.StaticWebsite.ErrorDocument404Path + .Value()}); + } + if (options.BlobServiceProperties.StaticWebsite.DefaultIndexDocumentPath + .HasValue()) { + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::StartTag, "DefaultIndexDocumentPath", + options.BlobServiceProperties.StaticWebsite.DefaultIndexDocumentPath + .Value()}); + } + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::End}); + xmlBody = writer.GetDocument(); + } + Core::IO::MemoryBodyStream requestBody( + reinterpret_cast(xmlBody.data()), xmlBody.length()); + auto request = + Core::Http::Request(Core::Http::HttpMethod::Put, url, &requestBody); + request.SetHeader("Content-Type", "application/xml; charset=UTF-8"); + request.SetHeader("Content-Length", std::to_string(requestBody.Length())); + request.GetUrl().AppendQueryParameter("restype", "service"); + request.GetUrl().AppendQueryParameter("comp", "properties"); + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Accepted) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::SetServicePropertiesResult response; + return Response(std::move(response), + std::move(pRawResponse)); +} +Response ServiceClient::GetProperties( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const GetServicePropertiesOptions &options, const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url); + request.GetUrl().AppendQueryParameter("restype", "service"); + request.GetUrl().AppendQueryParameter("comp", "properties"); + request.SetHeader("x-ms-version", "2020-08-04"); + (void)options; + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::BlobServiceProperties response; + { + const auto &responseBody = pRawResponse->GetBody(); + _internal::XmlReader reader( + reinterpret_cast(responseBody.data()), + responseBody.size()); + enum class XmlTagEnum { + kUnknown, + kStorageServiceProperties, + kLogging, + kVersion, + kDelete, + kRead, + kWrite, + kRetentionPolicy, + kEnabled, + kDays, + kHourMetrics, + kIncludeAPIs, + kMinuteMetrics, + kCors, + kCorsRule, + kAllowedOrigins, + kAllowedMethods, + kAllowedHeaders, + kExposedHeaders, + kMaxAgeInSeconds, + kDefaultServiceVersion, + kDeleteRetentionPolicy, + kStaticWebsite, + kIndexDocument, + kErrorDocument404Path, + kDefaultIndexDocumentPath, + }; + const std::unordered_map XmlTagEnumMap{ + {"StorageServiceProperties", XmlTagEnum::kStorageServiceProperties}, + {"Logging", XmlTagEnum::kLogging}, + {"Version", XmlTagEnum::kVersion}, + {"Delete", XmlTagEnum::kDelete}, + {"Read", XmlTagEnum::kRead}, + {"Write", XmlTagEnum::kWrite}, + {"RetentionPolicy", XmlTagEnum::kRetentionPolicy}, + {"Enabled", XmlTagEnum::kEnabled}, + {"Days", XmlTagEnum::kDays}, + {"HourMetrics", XmlTagEnum::kHourMetrics}, + {"IncludeAPIs", XmlTagEnum::kIncludeAPIs}, + {"MinuteMetrics", XmlTagEnum::kMinuteMetrics}, + {"Cors", XmlTagEnum::kCors}, + {"CorsRule", XmlTagEnum::kCorsRule}, + {"AllowedOrigins", XmlTagEnum::kAllowedOrigins}, + {"AllowedMethods", XmlTagEnum::kAllowedMethods}, + {"AllowedHeaders", XmlTagEnum::kAllowedHeaders}, + {"ExposedHeaders", XmlTagEnum::kExposedHeaders}, + {"MaxAgeInSeconds", XmlTagEnum::kMaxAgeInSeconds}, + {"DefaultServiceVersion", XmlTagEnum::kDefaultServiceVersion}, + {"DeleteRetentionPolicy", XmlTagEnum::kDeleteRetentionPolicy}, + {"StaticWebsite", XmlTagEnum::kStaticWebsite}, + {"IndexDocument", XmlTagEnum::kIndexDocument}, + {"ErrorDocument404Path", XmlTagEnum::kErrorDocument404Path}, + {"DefaultIndexDocumentPath", XmlTagEnum::kDefaultIndexDocumentPath}, + }; + std::vector xmlPath; + Models::CorsRule vectorElement1; + while (true) { + auto node = reader.Read(); + if (node.Type == _internal::XmlNodeType::End) { + break; + } else if (node.Type == _internal::XmlNodeType::StartTag) { + auto ite = XmlTagEnumMap.find(node.Name); + xmlPath.push_back(ite == XmlTagEnumMap.end() ? XmlTagEnum::kUnknown + : ite->second); + + } else if (node.Type == _internal::XmlNodeType::Text) { + if (xmlPath.size() == 3 && + xmlPath[0] == XmlTagEnum::kStorageServiceProperties && + xmlPath[1] == XmlTagEnum::kLogging && + xmlPath[2] == XmlTagEnum::kVersion) { + response.Logging.Version = node.Value; + } else if (xmlPath.size() == 3 && + xmlPath[0] == XmlTagEnum::kStorageServiceProperties && + xmlPath[1] == XmlTagEnum::kLogging && + xmlPath[2] == XmlTagEnum::kDelete) { + response.Logging.Delete = node.Value == std::string("true"); + } else if (xmlPath.size() == 3 && + xmlPath[0] == XmlTagEnum::kStorageServiceProperties && + xmlPath[1] == XmlTagEnum::kLogging && + xmlPath[2] == XmlTagEnum::kRead) { + response.Logging.Read = node.Value == std::string("true"); + } else if (xmlPath.size() == 3 && + xmlPath[0] == XmlTagEnum::kStorageServiceProperties && + xmlPath[1] == XmlTagEnum::kLogging && + xmlPath[2] == XmlTagEnum::kWrite) { + response.Logging.Write = node.Value == std::string("true"); + } else if (xmlPath.size() == 4 && + xmlPath[0] == XmlTagEnum::kStorageServiceProperties && + xmlPath[1] == XmlTagEnum::kLogging && + xmlPath[2] == XmlTagEnum::kRetentionPolicy && + xmlPath[3] == XmlTagEnum::kEnabled) { + response.Logging.RetentionPolicy.IsEnabled = + node.Value == std::string("true"); + } else if (xmlPath.size() == 4 && + xmlPath[0] == XmlTagEnum::kStorageServiceProperties && + xmlPath[1] == XmlTagEnum::kLogging && + xmlPath[2] == XmlTagEnum::kRetentionPolicy && + xmlPath[3] == XmlTagEnum::kDays) { + response.Logging.RetentionPolicy.Days = std::stoi(node.Value); + } else if (xmlPath.size() == 3 && + xmlPath[0] == XmlTagEnum::kStorageServiceProperties && + xmlPath[1] == XmlTagEnum::kHourMetrics && + xmlPath[2] == XmlTagEnum::kVersion) { + response.HourMetrics.Version = node.Value; + } else if (xmlPath.size() == 3 && + xmlPath[0] == XmlTagEnum::kStorageServiceProperties && + xmlPath[1] == XmlTagEnum::kHourMetrics && + xmlPath[2] == XmlTagEnum::kEnabled) { + response.HourMetrics.IsEnabled = node.Value == std::string("true"); + } else if (xmlPath.size() == 3 && + xmlPath[0] == XmlTagEnum::kStorageServiceProperties && + xmlPath[1] == XmlTagEnum::kHourMetrics && + xmlPath[2] == XmlTagEnum::kIncludeAPIs) { + response.HourMetrics.IncludeApis = node.Value == std::string("true"); + } else if (xmlPath.size() == 4 && + xmlPath[0] == XmlTagEnum::kStorageServiceProperties && + xmlPath[1] == XmlTagEnum::kHourMetrics && + xmlPath[2] == XmlTagEnum::kRetentionPolicy && + xmlPath[3] == XmlTagEnum::kEnabled) { + response.HourMetrics.RetentionPolicy.IsEnabled = + node.Value == std::string("true"); + } else if (xmlPath.size() == 4 && + xmlPath[0] == XmlTagEnum::kStorageServiceProperties && + xmlPath[1] == XmlTagEnum::kHourMetrics && + xmlPath[2] == XmlTagEnum::kRetentionPolicy && + xmlPath[3] == XmlTagEnum::kDays) { + response.HourMetrics.RetentionPolicy.Days = std::stoi(node.Value); + } else if (xmlPath.size() == 3 && + xmlPath[0] == XmlTagEnum::kStorageServiceProperties && + xmlPath[1] == XmlTagEnum::kMinuteMetrics && + xmlPath[2] == XmlTagEnum::kVersion) { + response.MinuteMetrics.Version = node.Value; + } else if (xmlPath.size() == 3 && + xmlPath[0] == XmlTagEnum::kStorageServiceProperties && + xmlPath[1] == XmlTagEnum::kMinuteMetrics && + xmlPath[2] == XmlTagEnum::kEnabled) { + response.MinuteMetrics.IsEnabled = node.Value == std::string("true"); + } else if (xmlPath.size() == 3 && + xmlPath[0] == XmlTagEnum::kStorageServiceProperties && + xmlPath[1] == XmlTagEnum::kMinuteMetrics && + xmlPath[2] == XmlTagEnum::kIncludeAPIs) { + response.MinuteMetrics.IncludeApis = + node.Value == std::string("true"); + } else if (xmlPath.size() == 4 && + xmlPath[0] == XmlTagEnum::kStorageServiceProperties && + xmlPath[1] == XmlTagEnum::kMinuteMetrics && + xmlPath[2] == XmlTagEnum::kRetentionPolicy && + xmlPath[3] == XmlTagEnum::kEnabled) { + response.MinuteMetrics.RetentionPolicy.IsEnabled = + node.Value == std::string("true"); + } else if (xmlPath.size() == 4 && + xmlPath[0] == XmlTagEnum::kStorageServiceProperties && + xmlPath[1] == XmlTagEnum::kMinuteMetrics && + xmlPath[2] == XmlTagEnum::kRetentionPolicy && + xmlPath[3] == XmlTagEnum::kDays) { + response.MinuteMetrics.RetentionPolicy.Days = std::stoi(node.Value); + } else if (xmlPath.size() == 4 && + xmlPath[0] == XmlTagEnum::kStorageServiceProperties && + xmlPath[1] == XmlTagEnum::kCors && + xmlPath[2] == XmlTagEnum::kCorsRule && + xmlPath[3] == XmlTagEnum::kAllowedOrigins) { + vectorElement1.AllowedOrigins = node.Value; + } else if (xmlPath.size() == 4 && + xmlPath[0] == XmlTagEnum::kStorageServiceProperties && + xmlPath[1] == XmlTagEnum::kCors && + xmlPath[2] == XmlTagEnum::kCorsRule && + xmlPath[3] == XmlTagEnum::kAllowedMethods) { + vectorElement1.AllowedMethods = node.Value; + } else if (xmlPath.size() == 4 && + xmlPath[0] == XmlTagEnum::kStorageServiceProperties && + xmlPath[1] == XmlTagEnum::kCors && + xmlPath[2] == XmlTagEnum::kCorsRule && + xmlPath[3] == XmlTagEnum::kAllowedHeaders) { + vectorElement1.AllowedHeaders = node.Value; + } else if (xmlPath.size() == 4 && + xmlPath[0] == XmlTagEnum::kStorageServiceProperties && + xmlPath[1] == XmlTagEnum::kCors && + xmlPath[2] == XmlTagEnum::kCorsRule && + xmlPath[3] == XmlTagEnum::kExposedHeaders) { + vectorElement1.ExposedHeaders = node.Value; + } else if (xmlPath.size() == 4 && + xmlPath[0] == XmlTagEnum::kStorageServiceProperties && + xmlPath[1] == XmlTagEnum::kCors && + xmlPath[2] == XmlTagEnum::kCorsRule && + xmlPath[3] == XmlTagEnum::kMaxAgeInSeconds) { + vectorElement1.MaxAgeInSeconds = std::stoi(node.Value); + } else if (xmlPath.size() == 2 && + xmlPath[0] == XmlTagEnum::kStorageServiceProperties && + xmlPath[1] == XmlTagEnum::kDefaultServiceVersion) { + response.DefaultServiceVersion = node.Value; + } else if (xmlPath.size() == 3 && + xmlPath[0] == XmlTagEnum::kStorageServiceProperties && + xmlPath[1] == XmlTagEnum::kDeleteRetentionPolicy && + xmlPath[2] == XmlTagEnum::kEnabled) { + response.DeleteRetentionPolicy.IsEnabled = + node.Value == std::string("true"); + } else if (xmlPath.size() == 3 && + xmlPath[0] == XmlTagEnum::kStorageServiceProperties && + xmlPath[1] == XmlTagEnum::kDeleteRetentionPolicy && + xmlPath[2] == XmlTagEnum::kDays) { + response.DeleteRetentionPolicy.Days = std::stoi(node.Value); + } else if (xmlPath.size() == 3 && + xmlPath[0] == XmlTagEnum::kStorageServiceProperties && + xmlPath[1] == XmlTagEnum::kStaticWebsite && + xmlPath[2] == XmlTagEnum::kEnabled) { + response.StaticWebsite.IsEnabled = node.Value == std::string("true"); + } else if (xmlPath.size() == 3 && + xmlPath[0] == XmlTagEnum::kStorageServiceProperties && + xmlPath[1] == XmlTagEnum::kStaticWebsite && + xmlPath[2] == XmlTagEnum::kIndexDocument) { + response.StaticWebsite.IndexDocument = node.Value; + } else if (xmlPath.size() == 3 && + xmlPath[0] == XmlTagEnum::kStorageServiceProperties && + xmlPath[1] == XmlTagEnum::kStaticWebsite && + xmlPath[2] == XmlTagEnum::kErrorDocument404Path) { + response.StaticWebsite.ErrorDocument404Path = node.Value; + } else if (xmlPath.size() == 3 && + xmlPath[0] == XmlTagEnum::kStorageServiceProperties && + xmlPath[1] == XmlTagEnum::kStaticWebsite && + xmlPath[2] == XmlTagEnum::kDefaultIndexDocumentPath) { + response.StaticWebsite.DefaultIndexDocumentPath = node.Value; + } + } else if (node.Type == _internal::XmlNodeType::Attribute) { + + } else if (node.Type == _internal::XmlNodeType::EndTag) { + if (xmlPath.size() == 3 && + xmlPath[0] == XmlTagEnum::kStorageServiceProperties && + xmlPath[1] == XmlTagEnum::kCors && + xmlPath[2] == XmlTagEnum::kCorsRule) { + response.Cors.push_back(std::move(vectorElement1)); + vectorElement1 = Models::CorsRule(); + } + xmlPath.pop_back(); + } + } + } + return Response(std::move(response), + std::move(pRawResponse)); +} +Response ServiceClient::GetStatistics( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const GetServiceStatisticsOptions &options, const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url); + request.GetUrl().AppendQueryParameter("restype", "service"); + request.GetUrl().AppendQueryParameter("comp", "stats"); + request.SetHeader("x-ms-version", "2020-08-04"); + (void)options; + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::ServiceStatistics response; + { + const auto &responseBody = pRawResponse->GetBody(); + _internal::XmlReader reader( + reinterpret_cast(responseBody.data()), + responseBody.size()); + enum class XmlTagEnum { + kUnknown, + kStorageServiceStats, + kGeoReplication, + kStatus, + kLastSyncTime, + }; + const std::unordered_map XmlTagEnumMap{ + {"StorageServiceStats", XmlTagEnum::kStorageServiceStats}, + {"GeoReplication", XmlTagEnum::kGeoReplication}, + {"Status", XmlTagEnum::kStatus}, + {"LastSyncTime", XmlTagEnum::kLastSyncTime}, + }; + std::vector xmlPath; + + while (true) { + auto node = reader.Read(); + if (node.Type == _internal::XmlNodeType::End) { + break; + } else if (node.Type == _internal::XmlNodeType::StartTag) { + auto ite = XmlTagEnumMap.find(node.Name); + xmlPath.push_back(ite == XmlTagEnumMap.end() ? XmlTagEnum::kUnknown + : ite->second); + + } else if (node.Type == _internal::XmlNodeType::Text) { + if (xmlPath.size() == 3 && + xmlPath[0] == XmlTagEnum::kStorageServiceStats && + xmlPath[1] == XmlTagEnum::kGeoReplication && + xmlPath[2] == XmlTagEnum::kStatus) { + response.GeoReplication.Status = + Models::GeoReplicationStatus(node.Value); + } else if (xmlPath.size() == 3 && + xmlPath[0] == XmlTagEnum::kStorageServiceStats && + xmlPath[1] == XmlTagEnum::kGeoReplication && + xmlPath[2] == XmlTagEnum::kLastSyncTime) { + response.GeoReplication.LastSyncedOn = + DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } + } else if (node.Type == _internal::XmlNodeType::Attribute) { + + } else if (node.Type == _internal::XmlNodeType::EndTag) { + + xmlPath.pop_back(); + } + } + } + return Response(std::move(response), + std::move(pRawResponse)); +} +Response +ServiceClient::ListBlobContainers( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const ListServiceBlobContainersOptions &options, + const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url); + request.GetUrl().AppendQueryParameter("comp", "list"); + if (options.Prefix.HasValue() && !options.Prefix.Value().empty()) { + request.GetUrl().AppendQueryParameter( + "prefix", _internal::UrlEncodeQueryParameter(options.Prefix.Value())); + } + if (options.Marker.HasValue() && !options.Marker.Value().empty()) { + request.GetUrl().AppendQueryParameter( + "marker", _internal::UrlEncodeQueryParameter(options.Marker.Value())); + } + if (options.MaxResults.HasValue()) { + request.GetUrl().AppendQueryParameter( + "maxresults", std::to_string(options.MaxResults.Value())); + } + if (options.Include.HasValue() && + !ListBlobContainersIncludeFlagsToString(options.Include.Value()) + .empty()) { + request.GetUrl().AppendQueryParameter( + "include", + _internal::UrlEncodeQueryParameter( + ListBlobContainersIncludeFlagsToString(options.Include.Value()))); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::_detail::ListBlobContainersResult response; + { + const auto &responseBody = pRawResponse->GetBody(); + _internal::XmlReader reader( + reinterpret_cast(responseBody.data()), + responseBody.size()); + enum class XmlTagEnum { + kUnknown, + kEnumerationResults, + kPrefix, + kNextMarker, + kContainers, + kContainer, + kName, + kDeleted, + kVersion, + kProperties, + kLastModified, + kEtag, + kLeaseStatus, + kLeaseState, + kLeaseDuration, + kPublicAccess, + kHasImmutabilityPolicy, + kHasLegalHold, + kDefaultEncryptionScope, + kDenyEncryptionScopeOverride, + kDeletedTime, + kRemainingRetentionDays, + kMetadata, + kImmutableStorageWithVersioningEnabled, + }; + const std::unordered_map XmlTagEnumMap{ + {"EnumerationResults", XmlTagEnum::kEnumerationResults}, + {"Prefix", XmlTagEnum::kPrefix}, + {"NextMarker", XmlTagEnum::kNextMarker}, + {"Containers", XmlTagEnum::kContainers}, + {"Container", XmlTagEnum::kContainer}, + {"Name", XmlTagEnum::kName}, + {"Deleted", XmlTagEnum::kDeleted}, + {"Version", XmlTagEnum::kVersion}, + {"Properties", XmlTagEnum::kProperties}, + {"Last-Modified", XmlTagEnum::kLastModified}, + {"Etag", XmlTagEnum::kEtag}, + {"LeaseStatus", XmlTagEnum::kLeaseStatus}, + {"LeaseState", XmlTagEnum::kLeaseState}, + {"LeaseDuration", XmlTagEnum::kLeaseDuration}, + {"PublicAccess", XmlTagEnum::kPublicAccess}, + {"HasImmutabilityPolicy", XmlTagEnum::kHasImmutabilityPolicy}, + {"HasLegalHold", XmlTagEnum::kHasLegalHold}, + {"DefaultEncryptionScope", XmlTagEnum::kDefaultEncryptionScope}, + {"DenyEncryptionScopeOverride", + XmlTagEnum::kDenyEncryptionScopeOverride}, + {"DeletedTime", XmlTagEnum::kDeletedTime}, + {"RemainingRetentionDays", XmlTagEnum::kRemainingRetentionDays}, + {"Metadata", XmlTagEnum::kMetadata}, + {"ImmutableStorageWithVersioningEnabled", + XmlTagEnum::kImmutableStorageWithVersioningEnabled}, + }; + std::vector xmlPath; + Models::BlobContainerItem vectorElement1; + std::string mapKey2; + std::string mapValue3; + while (true) { + auto node = reader.Read(); + if (node.Type == _internal::XmlNodeType::End) { + break; + } else if (node.Type == _internal::XmlNodeType::StartTag) { + auto ite = XmlTagEnumMap.find(node.Name); + xmlPath.push_back(ite == XmlTagEnumMap.end() ? XmlTagEnum::kUnknown + : ite->second); + if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kContainers && + xmlPath[2] == XmlTagEnum::kContainer && + xmlPath[3] == XmlTagEnum::kMetadata) { + mapKey2 = node.Name; + } + } else if (node.Type == _internal::XmlNodeType::Text) { + if (xmlPath.size() == 2 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kPrefix) { + response.Prefix = node.Value; + } else if (xmlPath.size() == 2 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kNextMarker) { + response.ContinuationToken = node.Value; + } else if (xmlPath.size() == 4 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kContainers && + xmlPath[2] == XmlTagEnum::kContainer && + xmlPath[3] == XmlTagEnum::kName) { + vectorElement1.Name = node.Value; + } else if (xmlPath.size() == 4 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kContainers && + xmlPath[2] == XmlTagEnum::kContainer && + xmlPath[3] == XmlTagEnum::kDeleted) { + vectorElement1.IsDeleted = node.Value == std::string("true"); + } else if (xmlPath.size() == 4 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kContainers && + xmlPath[2] == XmlTagEnum::kContainer && + xmlPath[3] == XmlTagEnum::kVersion) { + vectorElement1.VersionId = node.Value; + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kContainers && + xmlPath[2] == XmlTagEnum::kContainer && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kLastModified) { + vectorElement1.Details.LastModified = + DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kContainers && + xmlPath[2] == XmlTagEnum::kContainer && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kEtag) { + vectorElement1.Details.ETag = ETag(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kContainers && + xmlPath[2] == XmlTagEnum::kContainer && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kLeaseStatus) { + vectorElement1.Details.LeaseStatus = Models::LeaseStatus(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kContainers && + xmlPath[2] == XmlTagEnum::kContainer && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kLeaseState) { + vectorElement1.Details.LeaseState = Models::LeaseState(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kContainers && + xmlPath[2] == XmlTagEnum::kContainer && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kLeaseDuration) { + vectorElement1.Details.LeaseDuration = + Models::LeaseDurationType(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kContainers && + xmlPath[2] == XmlTagEnum::kContainer && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kPublicAccess) { + vectorElement1.Details.AccessType = + Models::PublicAccessType(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kContainers && + xmlPath[2] == XmlTagEnum::kContainer && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kHasImmutabilityPolicy) { + vectorElement1.Details.HasImmutabilityPolicy = + node.Value == std::string("true"); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kContainers && + xmlPath[2] == XmlTagEnum::kContainer && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kHasLegalHold) { + vectorElement1.Details.HasLegalHold = + node.Value == std::string("true"); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kContainers && + xmlPath[2] == XmlTagEnum::kContainer && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kDefaultEncryptionScope) { + vectorElement1.Details.DefaultEncryptionScope = node.Value; + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kContainers && + xmlPath[2] == XmlTagEnum::kContainer && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kDenyEncryptionScopeOverride) { + vectorElement1.Details.PreventEncryptionScopeOverride = + node.Value == std::string("true"); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kContainers && + xmlPath[2] == XmlTagEnum::kContainer && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kDeletedTime) { + vectorElement1.Details.DeletedOn = + DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kContainers && + xmlPath[2] == XmlTagEnum::kContainer && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kRemainingRetentionDays) { + vectorElement1.Details.RemainingRetentionDays = std::stoi(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kContainers && + xmlPath[2] == XmlTagEnum::kContainer && + xmlPath[3] == XmlTagEnum::kMetadata) { + mapValue3 = node.Value; + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kContainers && + xmlPath[2] == XmlTagEnum::kContainer && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == + XmlTagEnum::kImmutableStorageWithVersioningEnabled) { + vectorElement1.Details.HasImmutableStorageWithVersioning = + node.Value == std::string("true"); + } + } else if (node.Type == _internal::XmlNodeType::Attribute) { + if (xmlPath.size() == 1 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + node.Name == "ServiceEndpoint") { + response.ServiceEndpoint = node.Value; + } + } else if (node.Type == _internal::XmlNodeType::EndTag) { + if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kContainers && + xmlPath[2] == XmlTagEnum::kContainer && + xmlPath[3] == XmlTagEnum::kMetadata) { + vectorElement1.Details.Metadata[std::move(mapKey2)] = + std::move(mapValue3); + } else if (xmlPath.size() == 3 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kContainers && + xmlPath[2] == XmlTagEnum::kContainer) { + response.Items.push_back(std::move(vectorElement1)); + vectorElement1 = Models::BlobContainerItem(); + } + xmlPath.pop_back(); + } + } + } + return Response( + std::move(response), std::move(pRawResponse)); +} +Response ServiceClient::GetUserDelegationKey( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const GetServiceUserDelegationKeyOptions &options, + const Core::Context &context) { + std::string xmlBody; + { + _internal::XmlWriter writer; + writer.Write( + _internal::XmlNode{_internal::XmlNodeType::StartTag, "KeyInfo"}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "Start", + options.KeyInfo.Start}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "Expiry", + options.KeyInfo.Expiry}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::End}); + xmlBody = writer.GetDocument(); + } + Core::IO::MemoryBodyStream requestBody( + reinterpret_cast(xmlBody.data()), xmlBody.length()); + auto request = + Core::Http::Request(Core::Http::HttpMethod::Post, url, &requestBody); + request.SetHeader("Content-Type", "application/xml; charset=UTF-8"); + request.SetHeader("Content-Length", std::to_string(requestBody.Length())); + request.GetUrl().AppendQueryParameter("restype", "service"); + request.GetUrl().AppendQueryParameter("comp", "userdelegationkey"); + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::UserDelegationKey response; + { + const auto &responseBody = pRawResponse->GetBody(); + _internal::XmlReader reader( + reinterpret_cast(responseBody.data()), + responseBody.size()); + enum class XmlTagEnum { + kUnknown, + kUserDelegationKey, + kSignedOid, + kSignedTid, + kSignedStart, + kSignedExpiry, + kSignedService, + kSignedVersion, + kValue, + }; + const std::unordered_map XmlTagEnumMap{ + {"UserDelegationKey", XmlTagEnum::kUserDelegationKey}, + {"SignedOid", XmlTagEnum::kSignedOid}, + {"SignedTid", XmlTagEnum::kSignedTid}, + {"SignedStart", XmlTagEnum::kSignedStart}, + {"SignedExpiry", XmlTagEnum::kSignedExpiry}, + {"SignedService", XmlTagEnum::kSignedService}, + {"SignedVersion", XmlTagEnum::kSignedVersion}, + {"Value", XmlTagEnum::kValue}, + }; + std::vector xmlPath; + + while (true) { + auto node = reader.Read(); + if (node.Type == _internal::XmlNodeType::End) { + break; + } else if (node.Type == _internal::XmlNodeType::StartTag) { + auto ite = XmlTagEnumMap.find(node.Name); + xmlPath.push_back(ite == XmlTagEnumMap.end() ? XmlTagEnum::kUnknown + : ite->second); + + } else if (node.Type == _internal::XmlNodeType::Text) { + if (xmlPath.size() == 2 && + xmlPath[0] == XmlTagEnum::kUserDelegationKey && + xmlPath[1] == XmlTagEnum::kSignedOid) { + response.SignedObjectId = node.Value; + } else if (xmlPath.size() == 2 && + xmlPath[0] == XmlTagEnum::kUserDelegationKey && + xmlPath[1] == XmlTagEnum::kSignedTid) { + response.SignedTenantId = node.Value; + } else if (xmlPath.size() == 2 && + xmlPath[0] == XmlTagEnum::kUserDelegationKey && + xmlPath[1] == XmlTagEnum::kSignedStart) { + response.SignedStartsOn = + DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc3339); + } else if (xmlPath.size() == 2 && + xmlPath[0] == XmlTagEnum::kUserDelegationKey && + xmlPath[1] == XmlTagEnum::kSignedExpiry) { + response.SignedExpiresOn = + DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc3339); + } else if (xmlPath.size() == 2 && + xmlPath[0] == XmlTagEnum::kUserDelegationKey && + xmlPath[1] == XmlTagEnum::kSignedService) { + response.SignedService = node.Value; + } else if (xmlPath.size() == 2 && + xmlPath[0] == XmlTagEnum::kUserDelegationKey && + xmlPath[1] == XmlTagEnum::kSignedVersion) { + response.SignedVersion = node.Value; + } else if (xmlPath.size() == 2 && + xmlPath[0] == XmlTagEnum::kUserDelegationKey && + xmlPath[1] == XmlTagEnum::kValue) { + response.Value = node.Value; + } + } else if (node.Type == _internal::XmlNodeType::Attribute) { + + } else if (node.Type == _internal::XmlNodeType::EndTag) { + + xmlPath.pop_back(); + } + } + } + return Response(std::move(response), + std::move(pRawResponse)); +} +Response ServiceClient::GetAccountInfo( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const GetServiceAccountInfoOptions &options, const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url); + request.GetUrl().AppendQueryParameter("restype", "account"); + request.GetUrl().AppendQueryParameter("comp", "properties"); + request.SetHeader("x-ms-version", "2020-08-04"); + (void)options; + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::AccountInfo response; + response.SkuName = + Models::SkuName(pRawResponse->GetHeaders().at("x-ms-sku-name")); + response.AccountKind = + Models::AccountKind(pRawResponse->GetHeaders().at("x-ms-account-kind")); + response.IsHierarchicalNamespaceEnabled = + pRawResponse->GetHeaders().at("x-ms-is-hns-enabled") == + std::string("true"); + return Response(std::move(response), + std::move(pRawResponse)); +} +Response +ServiceClient::FindBlobsByTags(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const FindServiceBlobsByTagsOptions &options, + const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url); + request.GetUrl().AppendQueryParameter("comp", "blobs"); + request.SetHeader("x-ms-version", "2020-08-04"); + if (options.Where.HasValue() && !options.Where.Value().empty()) { + request.GetUrl().AppendQueryParameter( + "where", _internal::UrlEncodeQueryParameter(options.Where.Value())); + } + if (options.Marker.HasValue() && !options.Marker.Value().empty()) { + request.GetUrl().AppendQueryParameter( + "marker", _internal::UrlEncodeQueryParameter(options.Marker.Value())); + } + if (options.MaxResults.HasValue()) { + request.GetUrl().AppendQueryParameter( + "maxresults", std::to_string(options.MaxResults.Value())); + } + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::_detail::FindBlobsByTagsResult response; + { + const auto &responseBody = pRawResponse->GetBody(); + _internal::XmlReader reader( + reinterpret_cast(responseBody.data()), + responseBody.size()); + enum class XmlTagEnum { + kUnknown, + kEnumerationResults, + kBlobs, + kBlob, + kName, + kContainerName, + kTags, + kTagSet, + kTag, + kKey, + kValue, + kNextMarker, + }; + const std::unordered_map XmlTagEnumMap{ + {"EnumerationResults", XmlTagEnum::kEnumerationResults}, + {"Blobs", XmlTagEnum::kBlobs}, + {"Blob", XmlTagEnum::kBlob}, + {"Name", XmlTagEnum::kName}, + {"ContainerName", XmlTagEnum::kContainerName}, + {"Tags", XmlTagEnum::kTags}, + {"TagSet", XmlTagEnum::kTagSet}, + {"Tag", XmlTagEnum::kTag}, + {"Key", XmlTagEnum::kKey}, + {"Value", XmlTagEnum::kValue}, + {"NextMarker", XmlTagEnum::kNextMarker}, + }; + std::vector xmlPath; + Models::TaggedBlobItem vectorElement1; + std::string mapKey2; + std::string mapValue3; + while (true) { + auto node = reader.Read(); + if (node.Type == _internal::XmlNodeType::End) { + break; + } else if (node.Type == _internal::XmlNodeType::StartTag) { + auto ite = XmlTagEnumMap.find(node.Name); + xmlPath.push_back(ite == XmlTagEnumMap.end() ? XmlTagEnum::kUnknown + : ite->second); + + } else if (node.Type == _internal::XmlNodeType::Text) { + if (xmlPath.size() == 4 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kName) { + vectorElement1.BlobName = node.Value; + } else if (xmlPath.size() == 4 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kContainerName) { + vectorElement1.BlobContainerName = node.Value; + } else if (xmlPath.size() == 7 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kTags && + xmlPath[4] == XmlTagEnum::kTagSet && + xmlPath[5] == XmlTagEnum::kTag && + xmlPath[6] == XmlTagEnum::kKey) { + mapKey2 = node.Value; + } else if (xmlPath.size() == 7 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kTags && + xmlPath[4] == XmlTagEnum::kTagSet && + xmlPath[5] == XmlTagEnum::kTag && + xmlPath[6] == XmlTagEnum::kValue) { + mapValue3 = node.Value; + } else if (xmlPath.size() == 2 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kNextMarker) { + response.ContinuationToken = node.Value; + } + } else if (node.Type == _internal::XmlNodeType::Attribute) { + if (xmlPath.size() == 1 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + node.Name == "ServiceEndpoint") { + response.ServiceEndpoint = node.Value; + } + } else if (node.Type == _internal::XmlNodeType::EndTag) { + if (xmlPath.size() == 7 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kTags && + xmlPath[4] == XmlTagEnum::kTagSet && + xmlPath[5] == XmlTagEnum::kTag && + xmlPath[6] == XmlTagEnum::kValue) { + vectorElement1.Tags[std::move(mapKey2)] = std::move(mapValue3); + } else if (xmlPath.size() == 3 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob) { + response.Items.push_back(std::move(vectorElement1)); + vectorElement1 = Models::TaggedBlobItem(); + } + xmlPath.pop_back(); + } + } + } + return Response( + std::move(response), std::move(pRawResponse)); +} +Response BlobContainerClient::Create( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const CreateBlobContainerOptions &options, const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.GetUrl().AppendQueryParameter("restype", "container"); + for (const auto &p : options.Metadata) { + request.SetHeader("x-ms-meta-" + p.first, p.second); + } + if (!options.Access.ToString().empty()) { + request.SetHeader("x-ms-blob-public-access", options.Access.ToString()); + } + request.SetHeader("x-ms-version", "2020-08-04"); + if (options.DefaultEncryptionScope.HasValue() && + !options.DefaultEncryptionScope.Value().empty()) { + request.SetHeader("x-ms-default-encryption-scope", + options.DefaultEncryptionScope.Value()); + } + if (options.PreventEncryptionScopeOverride.HasValue()) { + request.SetHeader("x-ms-deny-encryption-scope-override", + options.PreventEncryptionScopeOverride.Value() ? "true" + : "false"); + } + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Created) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::CreateBlobContainerResult response; + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + return Response(std::move(response), + std::move(pRawResponse)); +} +Response BlobContainerClient::GetProperties( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const GetBlobContainerPropertiesOptions &options, + const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url); + request.GetUrl().AppendQueryParameter("restype", "container"); + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::BlobContainerProperties response; + for (auto i = pRawResponse->GetHeaders().lower_bound("x-ms-meta-"); + i != pRawResponse->GetHeaders().end() && + i->first.substr(0, 10) == "x-ms-meta-"; + ++i) { + response.Metadata.emplace(i->first.substr(10), i->second); + } + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + if (pRawResponse->GetHeaders().count("x-ms-lease-duration") != 0) { + response.LeaseDuration = Models::LeaseDurationType( + pRawResponse->GetHeaders().at("x-ms-lease-duration")); + } + response.LeaseState = + Models::LeaseState(pRawResponse->GetHeaders().at("x-ms-lease-state")); + response.LeaseStatus = + Models::LeaseStatus(pRawResponse->GetHeaders().at("x-ms-lease-status")); + if (pRawResponse->GetHeaders().count("x-ms-blob-public-access") != 0) { + response.AccessType = Models::PublicAccessType( + pRawResponse->GetHeaders().at("x-ms-blob-public-access")); + } + response.HasImmutabilityPolicy = + pRawResponse->GetHeaders().at("x-ms-has-immutability-policy") == + std::string("true"); + response.HasLegalHold = pRawResponse->GetHeaders().at( + "x-ms-has-legal-hold") == std::string("true"); + if (pRawResponse->GetHeaders().count("x-ms-default-encryption-scope") != 0) { + response.DefaultEncryptionScope = + pRawResponse->GetHeaders().at("x-ms-default-encryption-scope"); + } + if (pRawResponse->GetHeaders().count("x-ms-deny-encryption-scope-override") != + 0) { + response.PreventEncryptionScopeOverride = + pRawResponse->GetHeaders().at("x-ms-deny-encryption-scope-override") == + std::string("true"); + } + if (pRawResponse->GetHeaders().count( + "x-ms-immutable-storage-with-versioning-enabled") != 0) { + response.HasImmutableStorageWithVersioning = + pRawResponse->GetHeaders().at( + "x-ms-immutable-storage-with-versioning-enabled") == + std::string("true"); + } + return Response(std::move(response), + std::move(pRawResponse)); +} +Response BlobContainerClient::Delete( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const DeleteBlobContainerOptions &options, const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Delete, url); + request.GetUrl().AppendQueryParameter("restype", "container"); + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Accepted) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::DeleteBlobContainerResult response; + return Response(std::move(response), + std::move(pRawResponse)); +} +Response +BlobContainerClient::SetMetadata(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const SetBlobContainerMetadataOptions &options, + const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.GetUrl().AppendQueryParameter("restype", "container"); + request.GetUrl().AppendQueryParameter("comp", "metadata"); + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + for (const auto &p : options.Metadata) { + request.SetHeader("x-ms-meta-" + p.first, p.second); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::SetBlobContainerMetadataResult response; + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + return Response( + std::move(response), std::move(pRawResponse)); +} +Response +BlobContainerClient::GetAccessPolicy( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const GetBlobContainerAccessPolicyOptions &options, + const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url); + request.GetUrl().AppendQueryParameter("restype", "container"); + request.GetUrl().AppendQueryParameter("comp", "acl"); + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::BlobContainerAccessPolicy response; + { + const auto &responseBody = pRawResponse->GetBody(); + _internal::XmlReader reader( + reinterpret_cast(responseBody.data()), + responseBody.size()); + enum class XmlTagEnum { + kUnknown, + kSignedIdentifiers, + kSignedIdentifier, + kId, + kAccessPolicy, + kStart, + kExpiry, + kPermission, + }; + const std::unordered_map XmlTagEnumMap{ + {"SignedIdentifiers", XmlTagEnum::kSignedIdentifiers}, + {"SignedIdentifier", XmlTagEnum::kSignedIdentifier}, + {"Id", XmlTagEnum::kId}, + {"AccessPolicy", XmlTagEnum::kAccessPolicy}, + {"Start", XmlTagEnum::kStart}, + {"Expiry", XmlTagEnum::kExpiry}, + {"Permission", XmlTagEnum::kPermission}, + }; + std::vector xmlPath; + Models::SignedIdentifier vectorElement1; + while (true) { + auto node = reader.Read(); + if (node.Type == _internal::XmlNodeType::End) { + break; + } else if (node.Type == _internal::XmlNodeType::StartTag) { + auto ite = XmlTagEnumMap.find(node.Name); + xmlPath.push_back(ite == XmlTagEnumMap.end() ? XmlTagEnum::kUnknown + : ite->second); + + } else if (node.Type == _internal::XmlNodeType::Text) { + if (xmlPath.size() == 3 && + xmlPath[0] == XmlTagEnum::kSignedIdentifiers && + xmlPath[1] == XmlTagEnum::kSignedIdentifier && + xmlPath[2] == XmlTagEnum::kId) { + vectorElement1.Id = node.Value; + } else if (xmlPath.size() == 4 && + xmlPath[0] == XmlTagEnum::kSignedIdentifiers && + xmlPath[1] == XmlTagEnum::kSignedIdentifier && + xmlPath[2] == XmlTagEnum::kAccessPolicy && + xmlPath[3] == XmlTagEnum::kStart) { + vectorElement1.StartsOn = + DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc3339); + } else if (xmlPath.size() == 4 && + xmlPath[0] == XmlTagEnum::kSignedIdentifiers && + xmlPath[1] == XmlTagEnum::kSignedIdentifier && + xmlPath[2] == XmlTagEnum::kAccessPolicy && + xmlPath[3] == XmlTagEnum::kExpiry) { + vectorElement1.ExpiresOn = + DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc3339); + } else if (xmlPath.size() == 4 && + xmlPath[0] == XmlTagEnum::kSignedIdentifiers && + xmlPath[1] == XmlTagEnum::kSignedIdentifier && + xmlPath[2] == XmlTagEnum::kAccessPolicy && + xmlPath[3] == XmlTagEnum::kPermission) { + vectorElement1.Permissions = node.Value; + } + } else if (node.Type == _internal::XmlNodeType::Attribute) { + + } else if (node.Type == _internal::XmlNodeType::EndTag) { + if (xmlPath.size() == 2 && + xmlPath[0] == XmlTagEnum::kSignedIdentifiers && + xmlPath[1] == XmlTagEnum::kSignedIdentifier) { + response.SignedIdentifiers.push_back(std::move(vectorElement1)); + vectorElement1 = Models::SignedIdentifier(); + } + xmlPath.pop_back(); + } + } + } + if (pRawResponse->GetHeaders().count("x-ms-blob-public-access") != 0) { + response.AccessType = Models::PublicAccessType( + pRawResponse->GetHeaders().at("x-ms-blob-public-access")); + } + return Response(std::move(response), + std::move(pRawResponse)); +} +Response +BlobContainerClient::SetAccessPolicy( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const SetBlobContainerAccessPolicyOptions &options, + const Core::Context &context) { + std::string xmlBody; + { + _internal::XmlWriter writer; + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, + "SignedIdentifiers"}); + for (const auto &i1 : options.ContainerAcl) { + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, + "SignedIdentifier"}); + writer.Write( + _internal::XmlNode{_internal::XmlNodeType::StartTag, "Id", i1.Id}); + writer.Write( + _internal::XmlNode{_internal::XmlNodeType::StartTag, "AccessPolicy"}); + if (i1.StartsOn.HasValue()) { + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::StartTag, "Start", + i1.StartsOn.Value().ToString( + Azure::DateTime::DateFormat::Rfc3339, + Azure::DateTime::TimeFractionFormat::AllDigits)}); + } + if (i1.ExpiresOn.HasValue()) { + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::StartTag, "Expiry", + i1.ExpiresOn.Value().ToString( + Azure::DateTime::DateFormat::Rfc3339, + Azure::DateTime::TimeFractionFormat::AllDigits)}); + } + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, + "Permission", i1.Permissions}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + } + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::End}); + xmlBody = writer.GetDocument(); + } + Core::IO::MemoryBodyStream requestBody( + reinterpret_cast(xmlBody.data()), xmlBody.length()); + auto request = + Core::Http::Request(Core::Http::HttpMethod::Put, url, &requestBody); + request.SetHeader("Content-Type", "application/xml; charset=UTF-8"); + request.SetHeader("Content-Length", std::to_string(requestBody.Length())); + request.GetUrl().AppendQueryParameter("restype", "container"); + request.GetUrl().AppendQueryParameter("comp", "acl"); + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + if (!options.Access.ToString().empty()) { + request.SetHeader("x-ms-blob-public-access", options.Access.ToString()); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::SetBlobContainerAccessPolicyResult response; + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + return Response( + std::move(response), std::move(pRawResponse)); +} +Response +BlobContainerClient::Undelete(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const UndeleteBlobContainerOptions &options, + const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.GetUrl().AppendQueryParameter("restype", "container"); + request.GetUrl().AppendQueryParameter("comp", "undelete"); + request.SetHeader("x-ms-version", "2020-08-04"); + if (options.DeletedContainerName.HasValue() && + !options.DeletedContainerName.Value().empty()) { + request.SetHeader("x-ms-deleted-container-name", + options.DeletedContainerName.Value()); + } + if (options.DeletedContainerVersion.HasValue() && + !options.DeletedContainerVersion.Value().empty()) { + request.SetHeader("x-ms-deleted-container-version", + options.DeletedContainerVersion.Value()); + } + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Created) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::_detail::UndeleteBlobContainerResult response; + return Response( + std::move(response), std::move(pRawResponse)); +} +Response +BlobContainerClient::Rename(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const RenameBlobContainerOptions &options, + const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.GetUrl().AppendQueryParameter("restype", "container"); + request.GetUrl().AppendQueryParameter("comp", "rename"); + request.SetHeader("x-ms-version", "2020-08-04"); + if (!options.SourceContainerName.empty()) { + request.SetHeader("x-ms-source-container-name", + options.SourceContainerName); + } + if (options.SourceLeaseId.HasValue() && + !options.SourceLeaseId.Value().empty()) { + request.SetHeader("x-ms-source-lease-id", options.SourceLeaseId.Value()); + } + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::_detail::RenameBlobContainerResult response; + return Response( + std::move(response), std::move(pRawResponse)); +} +Response +BlobContainerClient::AcquireLease( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const AcquireBlobContainerLeaseOptions &options, + const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.GetUrl().AppendQueryParameter("comp", "lease"); + request.GetUrl().AppendQueryParameter("restype", "container"); + request.SetHeader("x-ms-lease-action", "acquire"); + if (options.Duration.HasValue()) { + request.SetHeader("x-ms-lease-duration", + std::to_string(options.Duration.Value())); + } + if (options.ProposedLeaseId.HasValue() && + !options.ProposedLeaseId.Value().empty()) { + request.SetHeader("x-ms-proposed-lease-id", + options.ProposedLeaseId.Value()); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Created) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::_detail::AcquireBlobContainerLeaseResult response; + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + response.LeaseId = pRawResponse->GetHeaders().at("x-ms-lease-id"); + return Response( + std::move(response), std::move(pRawResponse)); +} +Response +BlobContainerClient::ReleaseLease( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const ReleaseBlobContainerLeaseOptions &options, + const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.GetUrl().AppendQueryParameter("comp", "lease"); + request.GetUrl().AppendQueryParameter("restype", "container"); + request.SetHeader("x-ms-lease-action", "release"); + if (!options.LeaseId.empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::_detail::ReleaseBlobContainerLeaseResult response; + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + return Response( + std::move(response), std::move(pRawResponse)); +} +Response +BlobContainerClient::RenewLease(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const RenewBlobContainerLeaseOptions &options, + const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.GetUrl().AppendQueryParameter("comp", "lease"); + request.GetUrl().AppendQueryParameter("restype", "container"); + request.SetHeader("x-ms-lease-action", "renew"); + if (!options.LeaseId.empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::_detail::RenewBlobContainerLeaseResult response; + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + response.LeaseId = pRawResponse->GetHeaders().at("x-ms-lease-id"); + return Response( + std::move(response), std::move(pRawResponse)); +} +Response +BlobContainerClient::BreakLease(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const BreakBlobContainerLeaseOptions &options, + const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.GetUrl().AppendQueryParameter("comp", "lease"); + request.GetUrl().AppendQueryParameter("restype", "container"); + request.SetHeader("x-ms-lease-action", "break"); + if (options.BreakPeriod.HasValue()) { + request.SetHeader("x-ms-lease-break-period", + std::to_string(options.BreakPeriod.Value())); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Accepted) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::_detail::BreakBlobContainerLeaseResult response; + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + response.LeaseTime = + std::stoi(pRawResponse->GetHeaders().at("x-ms-lease-time")); + return Response( + std::move(response), std::move(pRawResponse)); +} +Response +BlobContainerClient::ChangeLease(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const ChangeBlobContainerLeaseOptions &options, + const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.GetUrl().AppendQueryParameter("comp", "lease"); + request.GetUrl().AppendQueryParameter("restype", "container"); + request.SetHeader("x-ms-lease-action", "change"); + if (!options.LeaseId.empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId); + } + if (!options.ProposedLeaseId.empty()) { + request.SetHeader("x-ms-proposed-lease-id", options.ProposedLeaseId); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::_detail::ChangeBlobContainerLeaseResult response; + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + response.LeaseId = pRawResponse->GetHeaders().at("x-ms-lease-id"); + return Response( + std::move(response), std::move(pRawResponse)); +} +Response +BlobContainerClient::ListBlobs(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const ListBlobContainerBlobsOptions &options, + const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url); + request.GetUrl().AppendQueryParameter("restype", "container"); + request.GetUrl().AppendQueryParameter("comp", "list"); + if (options.Prefix.HasValue() && !options.Prefix.Value().empty()) { + request.GetUrl().AppendQueryParameter( + "prefix", _internal::UrlEncodeQueryParameter(options.Prefix.Value())); + } + if (options.Marker.HasValue() && !options.Marker.Value().empty()) { + request.GetUrl().AppendQueryParameter( + "marker", _internal::UrlEncodeQueryParameter(options.Marker.Value())); + } + if (options.MaxResults.HasValue()) { + request.GetUrl().AppendQueryParameter( + "maxresults", std::to_string(options.MaxResults.Value())); + } + if (options.Include.HasValue() && + !ListBlobsIncludeFlagsToString(options.Include.Value()).empty()) { + request.GetUrl().AppendQueryParameter( + "include", _internal::UrlEncodeQueryParameter( + ListBlobsIncludeFlagsToString(options.Include.Value()))); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::_detail::ListBlobsResult response; + { + const auto &responseBody = pRawResponse->GetBody(); + _internal::XmlReader reader( + reinterpret_cast(responseBody.data()), + responseBody.size()); + enum class XmlTagEnum { + kUnknown, + kEnumerationResults, + kPrefix, + kNextMarker, + kBlobs, + kBlob, + kName, + kDeleted, + kSnapshot, + kVersionId, + kIsCurrentVersion, + kProperties, + kCreationTime, + kLastModified, + kEtag, + kXMsBlobSequenceNumber, + kLeaseStatus, + kLeaseState, + kLeaseDuration, + kCopyId, + kCopyStatus, + kCopySource, + kCopyProgress, + kCopyCompletionTime, + kCopyStatusDescription, + kServerEncrypted, + kIncrementalCopy, + kCopyDestinationSnapshot, + kDeletedTime, + kRemainingRetentionDays, + kAccessTier, + kAccessTierInferred, + kArchiveStatus, + kCustomerProvidedKeySha256, + kEncryptionScope, + kAccessTierChangeTime, + kExpiryTime, + kSealed, + kRehydratePriority, + kLastAccessTime, + kLegalHold, + kContentType, + kContentEncoding, + kContentLanguage, + kContentMD5, + kContentDisposition, + kCacheControl, + kMetadata, + kTags, + kTagSet, + kTag, + kKey, + kValue, + kOrMetadata, + kImmutabilityPolicyUntilDate, + kImmutabilityPolicyMode, + kContentLength, + kBlobType, + }; + const std::unordered_map XmlTagEnumMap{ + {"EnumerationResults", XmlTagEnum::kEnumerationResults}, + {"Prefix", XmlTagEnum::kPrefix}, + {"NextMarker", XmlTagEnum::kNextMarker}, + {"Blobs", XmlTagEnum::kBlobs}, + {"Blob", XmlTagEnum::kBlob}, + {"Name", XmlTagEnum::kName}, + {"Deleted", XmlTagEnum::kDeleted}, + {"Snapshot", XmlTagEnum::kSnapshot}, + {"VersionId", XmlTagEnum::kVersionId}, + {"IsCurrentVersion", XmlTagEnum::kIsCurrentVersion}, + {"Properties", XmlTagEnum::kProperties}, + {"Creation-Time", XmlTagEnum::kCreationTime}, + {"Last-Modified", XmlTagEnum::kLastModified}, + {"Etag", XmlTagEnum::kEtag}, + {"x-ms-blob-sequence-number", XmlTagEnum::kXMsBlobSequenceNumber}, + {"LeaseStatus", XmlTagEnum::kLeaseStatus}, + {"LeaseState", XmlTagEnum::kLeaseState}, + {"LeaseDuration", XmlTagEnum::kLeaseDuration}, + {"CopyId", XmlTagEnum::kCopyId}, + {"CopyStatus", XmlTagEnum::kCopyStatus}, + {"CopySource", XmlTagEnum::kCopySource}, + {"CopyProgress", XmlTagEnum::kCopyProgress}, + {"CopyCompletionTime", XmlTagEnum::kCopyCompletionTime}, + {"CopyStatusDescription", XmlTagEnum::kCopyStatusDescription}, + {"ServerEncrypted", XmlTagEnum::kServerEncrypted}, + {"IncrementalCopy", XmlTagEnum::kIncrementalCopy}, + {"CopyDestinationSnapshot", XmlTagEnum::kCopyDestinationSnapshot}, + {"DeletedTime", XmlTagEnum::kDeletedTime}, + {"RemainingRetentionDays", XmlTagEnum::kRemainingRetentionDays}, + {"AccessTier", XmlTagEnum::kAccessTier}, + {"AccessTierInferred", XmlTagEnum::kAccessTierInferred}, + {"ArchiveStatus", XmlTagEnum::kArchiveStatus}, + {"CustomerProvidedKeySha256", XmlTagEnum::kCustomerProvidedKeySha256}, + {"EncryptionScope", XmlTagEnum::kEncryptionScope}, + {"AccessTierChangeTime", XmlTagEnum::kAccessTierChangeTime}, + {"Expiry-Time", XmlTagEnum::kExpiryTime}, + {"Sealed", XmlTagEnum::kSealed}, + {"RehydratePriority", XmlTagEnum::kRehydratePriority}, + {"LastAccessTime", XmlTagEnum::kLastAccessTime}, + {"LegalHold", XmlTagEnum::kLegalHold}, + {"Content-Type", XmlTagEnum::kContentType}, + {"Content-Encoding", XmlTagEnum::kContentEncoding}, + {"Content-Language", XmlTagEnum::kContentLanguage}, + {"Content-MD5", XmlTagEnum::kContentMD5}, + {"Content-Disposition", XmlTagEnum::kContentDisposition}, + {"Cache-Control", XmlTagEnum::kCacheControl}, + {"Metadata", XmlTagEnum::kMetadata}, + {"Tags", XmlTagEnum::kTags}, + {"TagSet", XmlTagEnum::kTagSet}, + {"Tag", XmlTagEnum::kTag}, + {"Key", XmlTagEnum::kKey}, + {"Value", XmlTagEnum::kValue}, + {"OrMetadata", XmlTagEnum::kOrMetadata}, + {"ImmutabilityPolicyUntilDate", + XmlTagEnum::kImmutabilityPolicyUntilDate}, + {"ImmutabilityPolicyMode", XmlTagEnum::kImmutabilityPolicyMode}, + {"Content-Length", XmlTagEnum::kContentLength}, + {"BlobType", XmlTagEnum::kBlobType}, + }; + std::vector xmlPath; + Models::BlobItem vectorElement1; + std::string mapKey2; + std::string mapValue3; + std::string mapKey4; + std::string mapValue5; + Models::ObjectReplicationPolicy vectorElement6; + Models::ObjectReplicationRule vectorElement7; + while (true) { + auto node = reader.Read(); + if (node.Type == _internal::XmlNodeType::End) { + break; + } else if (node.Type == _internal::XmlNodeType::StartTag) { + auto ite = XmlTagEnumMap.find(node.Name); + xmlPath.push_back(ite == XmlTagEnumMap.end() ? XmlTagEnum::kUnknown + : ite->second); + if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kMetadata) { + mapKey2 = node.Name; + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kOrMetadata) { + vectorElement6.PolicyId = node.Name; + vectorElement7.RuleId = node.Name; + } else if (((xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kImmutabilityPolicyUntilDate) || + (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kImmutabilityPolicyMode)) && + !vectorElement1.Details.ImmutabilityPolicy.HasValue()) { + vectorElement1.Details.ImmutabilityPolicy = + Models::BlobImmutabilityPolicy(); + } + } else if (node.Type == _internal::XmlNodeType::Text) { + if (xmlPath.size() == 2 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kPrefix) { + response.Prefix = node.Value; + } else if (xmlPath.size() == 2 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kNextMarker) { + response.ContinuationToken = node.Value; + } else if (xmlPath.size() == 4 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kName) { + vectorElement1.Name = node.Value; + } else if (xmlPath.size() == 4 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kDeleted) { + vectorElement1.IsDeleted = node.Value == std::string("true"); + } else if (xmlPath.size() == 4 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kSnapshot) { + vectorElement1.Snapshot = node.Value; + } else if (xmlPath.size() == 4 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kVersionId) { + vectorElement1.VersionId = node.Value; + } else if (xmlPath.size() == 4 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kIsCurrentVersion) { + vectorElement1.IsCurrentVersion = node.Value == std::string("true"); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kCreationTime) { + vectorElement1.Details.CreatedOn = + DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kLastModified) { + vectorElement1.Details.LastModified = + DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kEtag) { + vectorElement1.Details.ETag = ETag(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kXMsBlobSequenceNumber) { + vectorElement1.Details.SequenceNumber = std::stoll(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kLeaseStatus) { + vectorElement1.Details.LeaseStatus = Models::LeaseStatus(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kLeaseState) { + vectorElement1.Details.LeaseState = Models::LeaseState(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kLeaseDuration) { + vectorElement1.Details.LeaseDuration = + Models::LeaseDurationType(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kCopyId) { + vectorElement1.Details.CopyId = node.Value; + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kCopyStatus) { + vectorElement1.Details.CopyStatus = Models::CopyStatus(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kCopySource) { + vectorElement1.Details.CopySource = node.Value; + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kCopyProgress) { + vectorElement1.Details.CopyProgress = node.Value; + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kCopyCompletionTime) { + vectorElement1.Details.CopyCompletedOn = + DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kCopyStatusDescription) { + vectorElement1.Details.CopyStatusDescription = node.Value; + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kServerEncrypted) { + vectorElement1.Details.IsServerEncrypted = + node.Value == std::string("true"); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kIncrementalCopy) { + vectorElement1.Details.IsIncrementalCopy = + node.Value == std::string("true"); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kCopyDestinationSnapshot) { + vectorElement1.Details.IncrementalCopyDestinationSnapshot = + node.Value; + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kDeletedTime) { + vectorElement1.Details.DeletedOn = + DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kRemainingRetentionDays) { + vectorElement1.Details.RemainingRetentionDays = std::stoi(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kAccessTier) { + vectorElement1.Details.AccessTier = Models::AccessTier(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kAccessTierInferred) { + vectorElement1.Details.IsAccessTierInferred = + node.Value == std::string("true"); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kArchiveStatus) { + vectorElement1.Details.ArchiveStatus = + Models::ArchiveStatus(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kCustomerProvidedKeySha256) { + vectorElement1.Details.EncryptionKeySha256 = + Core::Convert::Base64Decode(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kEncryptionScope) { + vectorElement1.Details.EncryptionScope = node.Value; + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kAccessTierChangeTime) { + vectorElement1.Details.AccessTierChangedOn = + DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kExpiryTime) { + vectorElement1.Details.ExpiresOn = + DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kSealed) { + vectorElement1.Details.IsSealed = node.Value == std::string("true"); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kRehydratePriority) { + vectorElement1.Details.RehydratePriority = + Models::RehydratePriority(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kLastAccessTime) { + vectorElement1.Details.LastAccessedOn = + DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kLegalHold) { + vectorElement1.Details.HasLegalHold = + node.Value == std::string("true"); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kContentType) { + vectorElement1.Details.HttpHeaders.ContentType = node.Value; + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kContentEncoding) { + vectorElement1.Details.HttpHeaders.ContentEncoding = node.Value; + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kContentLanguage) { + vectorElement1.Details.HttpHeaders.ContentLanguage = node.Value; + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kContentMD5) { + vectorElement1.Details.HttpHeaders.ContentHash.Value = + Core::Convert::Base64Decode(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kContentDisposition) { + vectorElement1.Details.HttpHeaders.ContentDisposition = node.Value; + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kCacheControl) { + vectorElement1.Details.HttpHeaders.CacheControl = node.Value; + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kMetadata) { + mapValue3 = node.Value; + } else if (xmlPath.size() == 7 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kTags && + xmlPath[4] == XmlTagEnum::kTagSet && + xmlPath[5] == XmlTagEnum::kTag && + xmlPath[6] == XmlTagEnum::kKey) { + mapKey4 = node.Value; + } else if (xmlPath.size() == 7 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kTags && + xmlPath[4] == XmlTagEnum::kTagSet && + xmlPath[5] == XmlTagEnum::kTag && + xmlPath[6] == XmlTagEnum::kValue) { + mapValue5 = node.Value; + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kOrMetadata) { + vectorElement7.ReplicationStatus = + Models::ObjectReplicationStatus(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kImmutabilityPolicyUntilDate) { + vectorElement1.Details.ImmutabilityPolicy.Value().ExpiresOn = + DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kImmutabilityPolicyMode) { + vectorElement1.Details.ImmutabilityPolicy.Value().PolicyMode = + Models::BlobImmutabilityPolicyMode(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kContentLength) { + vectorElement1.BlobSize = std::stoll(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kBlobType) { + vectorElement1.BlobType = Models::BlobType(node.Value); + } + } else if (node.Type == _internal::XmlNodeType::Attribute) { + if (xmlPath.size() == 1 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + node.Name == "ServiceEndpoint") { + response.ServiceEndpoint = node.Value; + } else if (xmlPath.size() == 1 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + node.Name == "ContainerName") { + response.BlobContainerName = node.Value; + } + } else if (node.Type == _internal::XmlNodeType::EndTag) { + if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kMetadata) { + vectorElement1.Details.Metadata[std::move(mapKey2)] = + std::move(mapValue3); + } else if (xmlPath.size() == 7 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kTags && + xmlPath[4] == XmlTagEnum::kTagSet && + xmlPath[5] == XmlTagEnum::kTag && + xmlPath[6] == XmlTagEnum::kValue) { + vectorElement1.Details.Tags[std::move(mapKey4)] = + std::move(mapValue5); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kOrMetadata) { + vectorElement6.Rules.push_back(std::move(vectorElement7)); + vectorElement7 = Models::ObjectReplicationRule(); + vectorElement1.Details.ObjectReplicationSourceProperties.push_back( + std::move(vectorElement6)); + vectorElement6 = Models::ObjectReplicationPolicy(); + } else if (xmlPath.size() == 3 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob) { + response.Items.push_back(std::move(vectorElement1)); + vectorElement1 = Models::BlobItem(); + } + xmlPath.pop_back(); + } + } + } + return Response(std::move(response), + std::move(pRawResponse)); +} +Response +BlobContainerClient::ListBlobsByHierarchy( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const ListBlobContainerBlobsByHierarchyOptions &options, + const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url); + request.GetUrl().AppendQueryParameter("restype", "container"); + request.GetUrl().AppendQueryParameter("comp", "list"); + if (options.Prefix.HasValue() && !options.Prefix.Value().empty()) { + request.GetUrl().AppendQueryParameter( + "prefix", _internal::UrlEncodeQueryParameter(options.Prefix.Value())); + } + if (!options.Delimiter.empty()) { + request.GetUrl().AppendQueryParameter( + "delimiter", _internal::UrlEncodeQueryParameter(options.Delimiter)); + } + if (options.Marker.HasValue() && !options.Marker.Value().empty()) { + request.GetUrl().AppendQueryParameter( + "marker", _internal::UrlEncodeQueryParameter(options.Marker.Value())); + } + if (options.MaxResults.HasValue()) { + request.GetUrl().AppendQueryParameter( + "maxresults", std::to_string(options.MaxResults.Value())); + } + if (options.Include.HasValue() && + !ListBlobsIncludeFlagsToString(options.Include.Value()).empty()) { + request.GetUrl().AppendQueryParameter( + "include", _internal::UrlEncodeQueryParameter( + ListBlobsIncludeFlagsToString(options.Include.Value()))); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::_detail::ListBlobsByHierarchyResult response; + { + const auto &responseBody = pRawResponse->GetBody(); + _internal::XmlReader reader( + reinterpret_cast(responseBody.data()), + responseBody.size()); + enum class XmlTagEnum { + kUnknown, + kEnumerationResults, + kPrefix, + kDelimiter, + kNextMarker, + kBlobs, + kBlob, + kName, + kDeleted, + kSnapshot, + kVersionId, + kIsCurrentVersion, + kProperties, + kCreationTime, + kLastModified, + kEtag, + kXMsBlobSequenceNumber, + kLeaseStatus, + kLeaseState, + kLeaseDuration, + kCopyId, + kCopyStatus, + kCopySource, + kCopyProgress, + kCopyCompletionTime, + kCopyStatusDescription, + kServerEncrypted, + kIncrementalCopy, + kCopyDestinationSnapshot, + kDeletedTime, + kRemainingRetentionDays, + kAccessTier, + kAccessTierInferred, + kArchiveStatus, + kCustomerProvidedKeySha256, + kEncryptionScope, + kAccessTierChangeTime, + kExpiryTime, + kSealed, + kRehydratePriority, + kLastAccessTime, + kLegalHold, + kContentType, + kContentEncoding, + kContentLanguage, + kContentMD5, + kContentDisposition, + kCacheControl, + kMetadata, + kTags, + kTagSet, + kTag, + kKey, + kValue, + kOrMetadata, + kImmutabilityPolicyUntilDate, + kImmutabilityPolicyMode, + kContentLength, + kBlobType, + kBlobPrefix, + }; + const std::unordered_map XmlTagEnumMap{ + {"EnumerationResults", XmlTagEnum::kEnumerationResults}, + {"Prefix", XmlTagEnum::kPrefix}, + {"Delimiter", XmlTagEnum::kDelimiter}, + {"NextMarker", XmlTagEnum::kNextMarker}, + {"Blobs", XmlTagEnum::kBlobs}, + {"Blob", XmlTagEnum::kBlob}, + {"Name", XmlTagEnum::kName}, + {"Deleted", XmlTagEnum::kDeleted}, + {"Snapshot", XmlTagEnum::kSnapshot}, + {"VersionId", XmlTagEnum::kVersionId}, + {"IsCurrentVersion", XmlTagEnum::kIsCurrentVersion}, + {"Properties", XmlTagEnum::kProperties}, + {"Creation-Time", XmlTagEnum::kCreationTime}, + {"Last-Modified", XmlTagEnum::kLastModified}, + {"Etag", XmlTagEnum::kEtag}, + {"x-ms-blob-sequence-number", XmlTagEnum::kXMsBlobSequenceNumber}, + {"LeaseStatus", XmlTagEnum::kLeaseStatus}, + {"LeaseState", XmlTagEnum::kLeaseState}, + {"LeaseDuration", XmlTagEnum::kLeaseDuration}, + {"CopyId", XmlTagEnum::kCopyId}, + {"CopyStatus", XmlTagEnum::kCopyStatus}, + {"CopySource", XmlTagEnum::kCopySource}, + {"CopyProgress", XmlTagEnum::kCopyProgress}, + {"CopyCompletionTime", XmlTagEnum::kCopyCompletionTime}, + {"CopyStatusDescription", XmlTagEnum::kCopyStatusDescription}, + {"ServerEncrypted", XmlTagEnum::kServerEncrypted}, + {"IncrementalCopy", XmlTagEnum::kIncrementalCopy}, + {"CopyDestinationSnapshot", XmlTagEnum::kCopyDestinationSnapshot}, + {"DeletedTime", XmlTagEnum::kDeletedTime}, + {"RemainingRetentionDays", XmlTagEnum::kRemainingRetentionDays}, + {"AccessTier", XmlTagEnum::kAccessTier}, + {"AccessTierInferred", XmlTagEnum::kAccessTierInferred}, + {"ArchiveStatus", XmlTagEnum::kArchiveStatus}, + {"CustomerProvidedKeySha256", XmlTagEnum::kCustomerProvidedKeySha256}, + {"EncryptionScope", XmlTagEnum::kEncryptionScope}, + {"AccessTierChangeTime", XmlTagEnum::kAccessTierChangeTime}, + {"Expiry-Time", XmlTagEnum::kExpiryTime}, + {"Sealed", XmlTagEnum::kSealed}, + {"RehydratePriority", XmlTagEnum::kRehydratePriority}, + {"LastAccessTime", XmlTagEnum::kLastAccessTime}, + {"LegalHold", XmlTagEnum::kLegalHold}, + {"Content-Type", XmlTagEnum::kContentType}, + {"Content-Encoding", XmlTagEnum::kContentEncoding}, + {"Content-Language", XmlTagEnum::kContentLanguage}, + {"Content-MD5", XmlTagEnum::kContentMD5}, + {"Content-Disposition", XmlTagEnum::kContentDisposition}, + {"Cache-Control", XmlTagEnum::kCacheControl}, + {"Metadata", XmlTagEnum::kMetadata}, + {"Tags", XmlTagEnum::kTags}, + {"TagSet", XmlTagEnum::kTagSet}, + {"Tag", XmlTagEnum::kTag}, + {"Key", XmlTagEnum::kKey}, + {"Value", XmlTagEnum::kValue}, + {"OrMetadata", XmlTagEnum::kOrMetadata}, + {"ImmutabilityPolicyUntilDate", + XmlTagEnum::kImmutabilityPolicyUntilDate}, + {"ImmutabilityPolicyMode", XmlTagEnum::kImmutabilityPolicyMode}, + {"Content-Length", XmlTagEnum::kContentLength}, + {"BlobType", XmlTagEnum::kBlobType}, + {"BlobPrefix", XmlTagEnum::kBlobPrefix}, + }; + std::vector xmlPath; + Models::BlobItem vectorElement1; + std::string mapKey2; + std::string mapValue3; + std::string mapKey4; + std::string mapValue5; + Models::ObjectReplicationPolicy vectorElement6; + Models::ObjectReplicationRule vectorElement7; + std::string vectorElement8; + while (true) { + auto node = reader.Read(); + if (node.Type == _internal::XmlNodeType::End) { + break; + } else if (node.Type == _internal::XmlNodeType::StartTag) { + auto ite = XmlTagEnumMap.find(node.Name); + xmlPath.push_back(ite == XmlTagEnumMap.end() ? XmlTagEnum::kUnknown + : ite->second); + if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kMetadata) { + mapKey2 = node.Name; + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kOrMetadata) { + vectorElement6.PolicyId = node.Name; + vectorElement7.RuleId = node.Name; + } else if (((xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kImmutabilityPolicyUntilDate) || + (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kImmutabilityPolicyMode)) && + !vectorElement1.Details.ImmutabilityPolicy.HasValue()) { + vectorElement1.Details.ImmutabilityPolicy = + Models::BlobImmutabilityPolicy(); + } + } else if (node.Type == _internal::XmlNodeType::Text) { + if (xmlPath.size() == 2 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kPrefix) { + response.Prefix = node.Value; + } else if (xmlPath.size() == 2 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kDelimiter) { + response.Delimiter = node.Value; + } else if (xmlPath.size() == 2 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kNextMarker) { + response.ContinuationToken = node.Value; + } else if (xmlPath.size() == 4 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kName) { + vectorElement1.Name = node.Value; + } else if (xmlPath.size() == 4 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kDeleted) { + vectorElement1.IsDeleted = node.Value == std::string("true"); + } else if (xmlPath.size() == 4 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kSnapshot) { + vectorElement1.Snapshot = node.Value; + } else if (xmlPath.size() == 4 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kVersionId) { + vectorElement1.VersionId = node.Value; + } else if (xmlPath.size() == 4 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kIsCurrentVersion) { + vectorElement1.IsCurrentVersion = node.Value == std::string("true"); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kCreationTime) { + vectorElement1.Details.CreatedOn = + DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kLastModified) { + vectorElement1.Details.LastModified = + DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kEtag) { + vectorElement1.Details.ETag = ETag(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kXMsBlobSequenceNumber) { + vectorElement1.Details.SequenceNumber = std::stoll(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kLeaseStatus) { + vectorElement1.Details.LeaseStatus = Models::LeaseStatus(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kLeaseState) { + vectorElement1.Details.LeaseState = Models::LeaseState(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kLeaseDuration) { + vectorElement1.Details.LeaseDuration = + Models::LeaseDurationType(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kCopyId) { + vectorElement1.Details.CopyId = node.Value; + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kCopyStatus) { + vectorElement1.Details.CopyStatus = Models::CopyStatus(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kCopySource) { + vectorElement1.Details.CopySource = node.Value; + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kCopyProgress) { + vectorElement1.Details.CopyProgress = node.Value; + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kCopyCompletionTime) { + vectorElement1.Details.CopyCompletedOn = + DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kCopyStatusDescription) { + vectorElement1.Details.CopyStatusDescription = node.Value; + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kServerEncrypted) { + vectorElement1.Details.IsServerEncrypted = + node.Value == std::string("true"); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kIncrementalCopy) { + vectorElement1.Details.IsIncrementalCopy = + node.Value == std::string("true"); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kCopyDestinationSnapshot) { + vectorElement1.Details.IncrementalCopyDestinationSnapshot = + node.Value; + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kDeletedTime) { + vectorElement1.Details.DeletedOn = + DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kRemainingRetentionDays) { + vectorElement1.Details.RemainingRetentionDays = std::stoi(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kAccessTier) { + vectorElement1.Details.AccessTier = Models::AccessTier(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kAccessTierInferred) { + vectorElement1.Details.IsAccessTierInferred = + node.Value == std::string("true"); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kArchiveStatus) { + vectorElement1.Details.ArchiveStatus = + Models::ArchiveStatus(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kCustomerProvidedKeySha256) { + vectorElement1.Details.EncryptionKeySha256 = + Core::Convert::Base64Decode(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kEncryptionScope) { + vectorElement1.Details.EncryptionScope = node.Value; + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kAccessTierChangeTime) { + vectorElement1.Details.AccessTierChangedOn = + DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kExpiryTime) { + vectorElement1.Details.ExpiresOn = + DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kSealed) { + vectorElement1.Details.IsSealed = node.Value == std::string("true"); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kRehydratePriority) { + vectorElement1.Details.RehydratePriority = + Models::RehydratePriority(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kLastAccessTime) { + vectorElement1.Details.LastAccessedOn = + DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kLegalHold) { + vectorElement1.Details.HasLegalHold = + node.Value == std::string("true"); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kContentType) { + vectorElement1.Details.HttpHeaders.ContentType = node.Value; + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kContentEncoding) { + vectorElement1.Details.HttpHeaders.ContentEncoding = node.Value; + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kContentLanguage) { + vectorElement1.Details.HttpHeaders.ContentLanguage = node.Value; + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kContentMD5) { + vectorElement1.Details.HttpHeaders.ContentHash.Value = + Core::Convert::Base64Decode(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kContentDisposition) { + vectorElement1.Details.HttpHeaders.ContentDisposition = node.Value; + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kCacheControl) { + vectorElement1.Details.HttpHeaders.CacheControl = node.Value; + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kMetadata) { + mapValue3 = node.Value; + } else if (xmlPath.size() == 7 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kTags && + xmlPath[4] == XmlTagEnum::kTagSet && + xmlPath[5] == XmlTagEnum::kTag && + xmlPath[6] == XmlTagEnum::kKey) { + mapKey4 = node.Value; + } else if (xmlPath.size() == 7 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kTags && + xmlPath[4] == XmlTagEnum::kTagSet && + xmlPath[5] == XmlTagEnum::kTag && + xmlPath[6] == XmlTagEnum::kValue) { + mapValue5 = node.Value; + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kOrMetadata) { + vectorElement7.ReplicationStatus = + Models::ObjectReplicationStatus(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kImmutabilityPolicyUntilDate) { + vectorElement1.Details.ImmutabilityPolicy.Value().ExpiresOn = + DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kImmutabilityPolicyMode) { + vectorElement1.Details.ImmutabilityPolicy.Value().PolicyMode = + Models::BlobImmutabilityPolicyMode(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kContentLength) { + vectorElement1.BlobSize = std::stoll(node.Value); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kProperties && + xmlPath[4] == XmlTagEnum::kBlobType) { + vectorElement1.BlobType = Models::BlobType(node.Value); + } else if (xmlPath.size() == 4 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlobPrefix && + xmlPath[3] == XmlTagEnum::kName) { + vectorElement8 = node.Value; + } + } else if (node.Type == _internal::XmlNodeType::Attribute) { + if (xmlPath.size() == 1 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + node.Name == "ServiceEndpoint") { + response.ServiceEndpoint = node.Value; + } else if (xmlPath.size() == 1 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + node.Name == "ContainerName") { + response.BlobContainerName = node.Value; + } + } else if (node.Type == _internal::XmlNodeType::EndTag) { + if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kMetadata) { + vectorElement1.Details.Metadata[std::move(mapKey2)] = + std::move(mapValue3); + } else if (xmlPath.size() == 7 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kTags && + xmlPath[4] == XmlTagEnum::kTagSet && + xmlPath[5] == XmlTagEnum::kTag && + xmlPath[6] == XmlTagEnum::kValue) { + vectorElement1.Details.Tags[std::move(mapKey4)] = + std::move(mapValue5); + } else if (xmlPath.size() == 5 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob && + xmlPath[3] == XmlTagEnum::kOrMetadata) { + vectorElement6.Rules.push_back(std::move(vectorElement7)); + vectorElement7 = Models::ObjectReplicationRule(); + vectorElement1.Details.ObjectReplicationSourceProperties.push_back( + std::move(vectorElement6)); + vectorElement6 = Models::ObjectReplicationPolicy(); + } else if (xmlPath.size() == 3 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlob) { + response.Items.push_back(std::move(vectorElement1)); + vectorElement1 = Models::BlobItem(); + } else if (xmlPath.size() == 4 && + xmlPath[0] == XmlTagEnum::kEnumerationResults && + xmlPath[1] == XmlTagEnum::kBlobs && + xmlPath[2] == XmlTagEnum::kBlobPrefix && + xmlPath[3] == XmlTagEnum::kName) { + response.BlobPrefixes.push_back(std::move(vectorElement8)); + vectorElement8 = std::string(); + } + xmlPath.pop_back(); + } + } + } + return Response( + std::move(response), std::move(pRawResponse)); +} +Response +BlobClient::Download(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, const DownloadBlobOptions &options, + const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url, false); + if (options.Snapshot.HasValue() && !options.Snapshot.Value().empty()) { + request.GetUrl().AppendQueryParameter( + "snapshot", + _internal::UrlEncodeQueryParameter(options.Snapshot.Value())); + } + if (options.VersionId.HasValue() && !options.VersionId.Value().empty()) { + request.GetUrl().AppendQueryParameter( + "versionid", + _internal::UrlEncodeQueryParameter(options.VersionId.Value())); + } + if (options.Range.HasValue() && !options.Range.Value().empty()) { + request.SetHeader("x-ms-range", options.Range.Value()); + } + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + if (options.RangeGetContentMD5.HasValue()) { + request.SetHeader("x-ms-range-get-content-md5", + options.RangeGetContentMD5.Value() ? "true" : "false"); + } + if (options.RangeGetContentCRC64.HasValue()) { + request.SetHeader("x-ms-range-get-content-crc64", + options.RangeGetContentCRC64.Value() ? "true" : "false"); + } + if (options.EncryptionKey.HasValue() && + !options.EncryptionKey.Value().empty()) { + request.SetHeader("x-ms-encryption-key", options.EncryptionKey.Value()); + } + if (options.EncryptionKeySha256.HasValue() && + !Core::Convert::Base64Encode(options.EncryptionKeySha256.Value()) + .empty()) { + request.SetHeader( + "x-ms-encryption-key-sha256", + Core::Convert::Base64Encode(options.EncryptionKeySha256.Value())); + } + if (options.EncryptionAlgorithm.HasValue() && + !options.EncryptionAlgorithm.Value().empty()) { + request.SetHeader("x-ms-encryption-algorithm", + options.EncryptionAlgorithm.Value()); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfMatch.HasValue() && !options.IfMatch.ToString().empty()) { + request.SetHeader("If-Match", options.IfMatch.ToString()); + } + if (options.IfNoneMatch.HasValue() && + !options.IfNoneMatch.ToString().empty()) { + request.SetHeader("If-None-Match", options.IfNoneMatch.ToString()); + } + if (options.IfTags.HasValue() && !options.IfTags.Value().empty()) { + request.SetHeader("x-ms-if-tags", options.IfTags.Value()); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (!(httpStatusCode == Core::Http::HttpStatusCode::Ok || + httpStatusCode == Core::Http::HttpStatusCode::PartialContent)) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::DownloadBlobResult response; + response.BodyStream = pRawResponse->ExtractBodyStream(); + response.Details.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + for (auto i = pRawResponse->GetHeaders().lower_bound("x-ms-meta-"); + i != pRawResponse->GetHeaders().end() && + i->first.substr(0, 10) == "x-ms-meta-"; + ++i) { + response.Details.Metadata.emplace(i->first.substr(10), i->second); + } + if (pRawResponse->GetHeaders().count("x-ms-or-policy-id") != 0) { + response.Details.ObjectReplicationDestinationPolicyId = + pRawResponse->GetHeaders().at("x-ms-or-policy-id"); + } + if (pRawResponse->GetHeaders().count("Content-Type") != 0) { + response.Details.HttpHeaders.ContentType = + pRawResponse->GetHeaders().at("Content-Type"); + } + response.Details.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + if (pRawResponse->GetHeaders().count("Content-Encoding") != 0) { + response.Details.HttpHeaders.ContentEncoding = + pRawResponse->GetHeaders().at("Content-Encoding"); + } + if (pRawResponse->GetHeaders().count("Cache-Control") != 0) { + response.Details.HttpHeaders.CacheControl = + pRawResponse->GetHeaders().at("Cache-Control"); + } + if (pRawResponse->GetHeaders().count("Content-Disposition") != 0) { + response.Details.HttpHeaders.ContentDisposition = + pRawResponse->GetHeaders().at("Content-Disposition"); + } + if (pRawResponse->GetHeaders().count("Content-Language") != 0) { + response.Details.HttpHeaders.ContentLanguage = + pRawResponse->GetHeaders().at("Content-Language"); + } + if (pRawResponse->GetHeaders().count("x-ms-blob-sequence-number") != 0) { + response.Details.SequenceNumber = + std::stoll(pRawResponse->GetHeaders().at("x-ms-blob-sequence-number")); + } + response.BlobType = + Models::BlobType(pRawResponse->GetHeaders().at("x-ms-blob-type")); + if (pRawResponse->GetHeaders().count("x-ms-copy-completion-time") != 0) { + response.Details.CopyCompletedOn = DateTime::Parse( + pRawResponse->GetHeaders().at("x-ms-copy-completion-time"), + Azure::DateTime::DateFormat::Rfc1123); + } + if (pRawResponse->GetHeaders().count("x-ms-copy-status-description") != 0) { + response.Details.CopyStatusDescription = + pRawResponse->GetHeaders().at("x-ms-copy-status-description"); + } + if (pRawResponse->GetHeaders().count("x-ms-copy-id") != 0) { + response.Details.CopyId = pRawResponse->GetHeaders().at("x-ms-copy-id"); + } + if (pRawResponse->GetHeaders().count("x-ms-copy-progress") != 0) { + response.Details.CopyProgress = + pRawResponse->GetHeaders().at("x-ms-copy-progress"); + } + if (pRawResponse->GetHeaders().count("x-ms-copy-source") != 0) { + response.Details.CopySource = + pRawResponse->GetHeaders().at("x-ms-copy-source"); + } + if (pRawResponse->GetHeaders().count("x-ms-copy-status") != 0) { + response.Details.CopyStatus = + Models::CopyStatus(pRawResponse->GetHeaders().at("x-ms-copy-status")); + } + if (pRawResponse->GetHeaders().count("x-ms-lease-duration") != 0) { + response.Details.LeaseDuration = Models::LeaseDurationType( + pRawResponse->GetHeaders().at("x-ms-lease-duration")); + } + if (pRawResponse->GetHeaders().count("x-ms-lease-state") != 0) { + response.Details.LeaseState = + Models::LeaseState(pRawResponse->GetHeaders().at("x-ms-lease-state")); + } + if (pRawResponse->GetHeaders().count("x-ms-lease-status") != 0) { + response.Details.LeaseStatus = + Models::LeaseStatus(pRawResponse->GetHeaders().at("x-ms-lease-status")); + } + if (pRawResponse->GetHeaders().count("x-ms-version-id") != 0) { + response.Details.VersionId = + pRawResponse->GetHeaders().at("x-ms-version-id"); + } + if (pRawResponse->GetHeaders().count("x-ms-is-current-version") != 0) { + response.Details.IsCurrentVersion = + pRawResponse->GetHeaders().at("x-ms-is-current-version") == + std::string("true"); + } + if (pRawResponse->GetHeaders().count("x-ms-blob-committed-block-count") != + 0) { + response.Details.CommittedBlockCount = std::stoi( + pRawResponse->GetHeaders().at("x-ms-blob-committed-block-count")); + } + response.Details.IsServerEncrypted = + pRawResponse->GetHeaders().at("x-ms-server-encrypted") == + std::string("true"); + if (pRawResponse->GetHeaders().count("x-ms-encryption-key-sha256") != 0) { + response.Details.EncryptionKeySha256 = Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("x-ms-encryption-key-sha256")); + } + if (pRawResponse->GetHeaders().count("x-ms-encryption-scope") != 0) { + response.Details.EncryptionScope = + pRawResponse->GetHeaders().at("x-ms-encryption-scope"); + } + if (pRawResponse->GetHeaders().count("x-ms-tag-count") != 0) { + response.Details.TagCount = + std::stoi(pRawResponse->GetHeaders().at("x-ms-tag-count")); + } + if (pRawResponse->GetHeaders().count("x-ms-blob-sealed") != 0) { + response.Details.IsSealed = pRawResponse->GetHeaders().at( + "x-ms-blob-sealed") == std::string("true"); + } + if (pRawResponse->GetHeaders().count("x-ms-last-access-time") != 0) { + response.Details.LastAccessedOn = + DateTime::Parse(pRawResponse->GetHeaders().at("x-ms-last-access-time"), + Azure::DateTime::DateFormat::Rfc1123); + } + if (pRawResponse->GetHeaders().count("x-ms-immutability-policy-until-date") != + 0) { + if (!response.Details.ImmutabilityPolicy.HasValue()) { + response.Details.ImmutabilityPolicy = Models::BlobImmutabilityPolicy(); + } + response.Details.ImmutabilityPolicy.Value().ExpiresOn = DateTime::Parse( + pRawResponse->GetHeaders().at("x-ms-immutability-policy-until-date"), + Azure::DateTime::DateFormat::Rfc1123); + } + if (pRawResponse->GetHeaders().count("x-ms-immutability-policy-mode") != 0) { + if (!response.Details.ImmutabilityPolicy.HasValue()) { + response.Details.ImmutabilityPolicy = Models::BlobImmutabilityPolicy(); + } + response.Details.ImmutabilityPolicy.Value().PolicyMode = + Models::BlobImmutabilityPolicyMode( + pRawResponse->GetHeaders().at("x-ms-immutability-policy-mode")); + } + if (pRawResponse->GetHeaders().count("x-ms-legal-hold") != 0) { + response.Details.HasLegalHold = + pRawResponse->GetHeaders().at("x-ms-legal-hold") == std::string("true"); + } + response.Details.CreatedOn = + DateTime::Parse(pRawResponse->GetHeaders().at("x-ms-creation-time"), + Azure::DateTime::DateFormat::Rfc1123); + if (httpStatusCode == Core::Http::HttpStatusCode::Ok) { + if (pRawResponse->GetHeaders().count("Content-MD5") != 0) { + response.Details.HttpHeaders.ContentHash.Value = + Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("Content-MD5")); + response.Details.HttpHeaders.ContentHash.Algorithm = HashAlgorithm::Md5; + } + } + if (httpStatusCode == Core::Http::HttpStatusCode::Ok) { + if (pRawResponse->GetHeaders().count("Content-MD5") != 0) { + response.TransactionalContentHash = ContentHash(); + response.TransactionalContentHash.Value().Value = + Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("Content-MD5")); + response.TransactionalContentHash.Value().Algorithm = HashAlgorithm::Md5; + } + } + if (pRawResponse->GetHeaders().count("x-ms-blob-content-md5") != 0) { + response.Details.HttpHeaders.ContentHash.Value = + Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("x-ms-blob-content-md5")); + response.Details.HttpHeaders.ContentHash.Algorithm = HashAlgorithm::Md5; + } + if (httpStatusCode == Core::Http::HttpStatusCode::PartialContent) { + if (pRawResponse->GetHeaders().count("Content-MD5") != 0) { + response.TransactionalContentHash = ContentHash(); + response.TransactionalContentHash.Value().Value = + Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("Content-MD5")); + response.TransactionalContentHash.Value().Algorithm = HashAlgorithm::Md5; + } + } + if (httpStatusCode == Core::Http::HttpStatusCode::PartialContent) { + if (pRawResponse->GetHeaders().count("x-ms-content-crc64") != 0) { + response.TransactionalContentHash = ContentHash(); + response.TransactionalContentHash.Value().Value = + Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("x-ms-content-crc64")); + response.TransactionalContentHash.Value().Algorithm = + HashAlgorithm::Crc64; + } + } + return Response(std::move(response), + std::move(pRawResponse)); +} +Response BlobClient::GetProperties( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const GetBlobPropertiesOptions &options, const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Head, url); + if (options.Snapshot.HasValue() && !options.Snapshot.Value().empty()) { + request.GetUrl().AppendQueryParameter( + "snapshot", + _internal::UrlEncodeQueryParameter(options.Snapshot.Value())); + } + if (options.VersionId.HasValue() && !options.VersionId.Value().empty()) { + request.GetUrl().AppendQueryParameter( + "versionid", + _internal::UrlEncodeQueryParameter(options.VersionId.Value())); + } + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + if (options.EncryptionKey.HasValue() && + !options.EncryptionKey.Value().empty()) { + request.SetHeader("x-ms-encryption-key", options.EncryptionKey.Value()); + } + if (options.EncryptionKeySha256.HasValue() && + !Core::Convert::Base64Encode(options.EncryptionKeySha256.Value()) + .empty()) { + request.SetHeader( + "x-ms-encryption-key-sha256", + Core::Convert::Base64Encode(options.EncryptionKeySha256.Value())); + } + if (options.EncryptionAlgorithm.HasValue() && + !options.EncryptionAlgorithm.Value().empty()) { + request.SetHeader("x-ms-encryption-algorithm", + options.EncryptionAlgorithm.Value()); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfMatch.HasValue() && !options.IfMatch.ToString().empty()) { + request.SetHeader("If-Match", options.IfMatch.ToString()); + } + if (options.IfNoneMatch.HasValue() && + !options.IfNoneMatch.ToString().empty()) { + request.SetHeader("If-None-Match", options.IfNoneMatch.ToString()); + } + if (options.IfTags.HasValue() && !options.IfTags.Value().empty()) { + request.SetHeader("x-ms-if-tags", options.IfTags.Value()); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::BlobProperties response; + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + response.CreatedOn = + DateTime::Parse(pRawResponse->GetHeaders().at("x-ms-creation-time"), + Azure::DateTime::DateFormat::Rfc1123); + for (auto i = pRawResponse->GetHeaders().lower_bound("x-ms-meta-"); + i != pRawResponse->GetHeaders().end() && + i->first.substr(0, 10) == "x-ms-meta-"; + ++i) { + response.Metadata.emplace(i->first.substr(10), i->second); + } + if (pRawResponse->GetHeaders().count("x-ms-or-policy-id") != 0) { + response.ObjectReplicationDestinationPolicyId = + pRawResponse->GetHeaders().at("x-ms-or-policy-id"); + } + response.BlobType = + Models::BlobType(pRawResponse->GetHeaders().at("x-ms-blob-type")); + if (pRawResponse->GetHeaders().count("x-ms-copy-completion-time") != 0) { + response.CopyCompletedOn = DateTime::Parse( + pRawResponse->GetHeaders().at("x-ms-copy-completion-time"), + Azure::DateTime::DateFormat::Rfc1123); + } + if (pRawResponse->GetHeaders().count("x-ms-copy-status-description") != 0) { + response.CopyStatusDescription = + pRawResponse->GetHeaders().at("x-ms-copy-status-description"); + } + if (pRawResponse->GetHeaders().count("x-ms-copy-id") != 0) { + response.CopyId = pRawResponse->GetHeaders().at("x-ms-copy-id"); + } + if (pRawResponse->GetHeaders().count("x-ms-copy-progress") != 0) { + response.CopyProgress = pRawResponse->GetHeaders().at("x-ms-copy-progress"); + } + if (pRawResponse->GetHeaders().count("x-ms-copy-source") != 0) { + response.CopySource = pRawResponse->GetHeaders().at("x-ms-copy-source"); + } + if (pRawResponse->GetHeaders().count("x-ms-copy-status") != 0) { + response.CopyStatus = + Models::CopyStatus(pRawResponse->GetHeaders().at("x-ms-copy-status")); + } + if (pRawResponse->GetHeaders().count("x-ms-incremental-copy") != 0) { + response.IsIncrementalCopy = + pRawResponse->GetHeaders().at("x-ms-incremental-copy") == + std::string("true"); + } + if (pRawResponse->GetHeaders().count("x-ms-copy-destination-snapshot") != 0) { + response.IncrementalCopyDestinationSnapshot = + pRawResponse->GetHeaders().at("x-ms-copy-destination-snapshot"); + } + if (pRawResponse->GetHeaders().count("x-ms-lease-duration") != 0) { + response.LeaseDuration = Models::LeaseDurationType( + pRawResponse->GetHeaders().at("x-ms-lease-duration")); + } + if (pRawResponse->GetHeaders().count("x-ms-lease-state") != 0) { + response.LeaseState = + Models::LeaseState(pRawResponse->GetHeaders().at("x-ms-lease-state")); + } + if (pRawResponse->GetHeaders().count("x-ms-lease-status") != 0) { + response.LeaseStatus = + Models::LeaseStatus(pRawResponse->GetHeaders().at("x-ms-lease-status")); + } + response.BlobSize = + std::stoll(pRawResponse->GetHeaders().at("Content-Length")); + if (pRawResponse->GetHeaders().count("Content-Type") != 0) { + response.HttpHeaders.ContentType = + pRawResponse->GetHeaders().at("Content-Type"); + } + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + if (pRawResponse->GetHeaders().count("Content-MD5") != 0) { + response.HttpHeaders.ContentHash.Value = Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("Content-MD5")); + response.HttpHeaders.ContentHash.Algorithm = HashAlgorithm::Md5; + } + if (pRawResponse->GetHeaders().count("Content-Encoding") != 0) { + response.HttpHeaders.ContentEncoding = + pRawResponse->GetHeaders().at("Content-Encoding"); + } + if (pRawResponse->GetHeaders().count("Content-Disposition") != 0) { + response.HttpHeaders.ContentDisposition = + pRawResponse->GetHeaders().at("Content-Disposition"); + } + if (pRawResponse->GetHeaders().count("Content-Language") != 0) { + response.HttpHeaders.ContentLanguage = + pRawResponse->GetHeaders().at("Content-Language"); + } + if (pRawResponse->GetHeaders().count("Cache-Control") != 0) { + response.HttpHeaders.CacheControl = + pRawResponse->GetHeaders().at("Cache-Control"); + } + if (pRawResponse->GetHeaders().count("x-ms-blob-sequence-number") != 0) { + response.SequenceNumber = + std::stoll(pRawResponse->GetHeaders().at("x-ms-blob-sequence-number")); + } + if (pRawResponse->GetHeaders().count("x-ms-blob-committed-block-count") != + 0) { + response.CommittedBlockCount = std::stoi( + pRawResponse->GetHeaders().at("x-ms-blob-committed-block-count")); + } + response.IsServerEncrypted = + pRawResponse->GetHeaders().at("x-ms-server-encrypted") == + std::string("true"); + if (pRawResponse->GetHeaders().count("x-ms-encryption-key-sha256") != 0) { + response.EncryptionKeySha256 = Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("x-ms-encryption-key-sha256")); + } + if (pRawResponse->GetHeaders().count("x-ms-encryption-scope") != 0) { + response.EncryptionScope = + pRawResponse->GetHeaders().at("x-ms-encryption-scope"); + } + if (pRawResponse->GetHeaders().count("x-ms-access-tier") != 0) { + response.AccessTier = + Models::AccessTier(pRawResponse->GetHeaders().at("x-ms-access-tier")); + } + if (pRawResponse->GetHeaders().count("x-ms-access-tier-inferred") != 0) { + response.IsAccessTierInferred = + pRawResponse->GetHeaders().at("x-ms-access-tier-inferred") == + std::string("true"); + } + if (pRawResponse->GetHeaders().count("x-ms-archive-status") != 0) { + response.ArchiveStatus = Models::ArchiveStatus( + pRawResponse->GetHeaders().at("x-ms-archive-status")); + } + if (pRawResponse->GetHeaders().count("x-ms-access-tier-change-time") != 0) { + response.AccessTierChangedOn = DateTime::Parse( + pRawResponse->GetHeaders().at("x-ms-access-tier-change-time"), + Azure::DateTime::DateFormat::Rfc1123); + } + if (pRawResponse->GetHeaders().count("x-ms-version-id") != 0) { + response.VersionId = pRawResponse->GetHeaders().at("x-ms-version-id"); + } + if (pRawResponse->GetHeaders().count("x-ms-is-current-version") != 0) { + response.IsCurrentVersion = + pRawResponse->GetHeaders().at("x-ms-is-current-version") == + std::string("true"); + } + if (pRawResponse->GetHeaders().count("x-ms-tag-count") != 0) { + response.TagCount = + std::stoi(pRawResponse->GetHeaders().at("x-ms-tag-count")); + } + if (pRawResponse->GetHeaders().count("x-ms-expiry-time") != 0) { + response.ExpiresOn = + DateTime::Parse(pRawResponse->GetHeaders().at("x-ms-expiry-time"), + Azure::DateTime::DateFormat::Rfc1123); + } + if (pRawResponse->GetHeaders().count("x-ms-blob-sealed") != 0) { + response.IsSealed = pRawResponse->GetHeaders().at("x-ms-blob-sealed") == + std::string("true"); + } + if (pRawResponse->GetHeaders().count("x-ms-rehydrate-priority") != 0) { + response.RehydratePriority = Models::RehydratePriority( + pRawResponse->GetHeaders().at("x-ms-rehydrate-priority")); + } + if (pRawResponse->GetHeaders().count("x-ms-last-access-time") != 0) { + response.LastAccessedOn = + DateTime::Parse(pRawResponse->GetHeaders().at("x-ms-last-access-time"), + Azure::DateTime::DateFormat::Rfc1123); + } + if (pRawResponse->GetHeaders().count("x-ms-immutability-policy-until-date") != + 0) { + if (!response.ImmutabilityPolicy.HasValue()) { + response.ImmutabilityPolicy = Models::BlobImmutabilityPolicy(); + } + response.ImmutabilityPolicy.Value().ExpiresOn = DateTime::Parse( + pRawResponse->GetHeaders().at("x-ms-immutability-policy-until-date"), + Azure::DateTime::DateFormat::Rfc1123); + } + if (pRawResponse->GetHeaders().count("x-ms-immutability-policy-mode") != 0) { + if (!response.ImmutabilityPolicy.HasValue()) { + response.ImmutabilityPolicy = Models::BlobImmutabilityPolicy(); + } + response.ImmutabilityPolicy.Value().PolicyMode = + Models::BlobImmutabilityPolicyMode( + pRawResponse->GetHeaders().at("x-ms-immutability-policy-mode")); + } + if (pRawResponse->GetHeaders().count("x-ms-legal-hold") != 0) { + response.HasLegalHold = + pRawResponse->GetHeaders().at("x-ms-legal-hold") == std::string("true"); + } + return Response(std::move(response), + std::move(pRawResponse)); +} +Response +BlobClient::Delete(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, const DeleteBlobOptions &options, + const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Delete, url); + if (options.Snapshot.HasValue() && !options.Snapshot.Value().empty()) { + request.GetUrl().AppendQueryParameter( + "snapshot", + _internal::UrlEncodeQueryParameter(options.Snapshot.Value())); + } + if (options.VersionId.HasValue() && !options.VersionId.Value().empty()) { + request.GetUrl().AppendQueryParameter( + "versionid", + _internal::UrlEncodeQueryParameter(options.VersionId.Value())); + } + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + if (options.DeleteSnapshots.HasValue() && + !options.DeleteSnapshots.Value().ToString().empty()) { + request.SetHeader("x-ms-delete-snapshots", + options.DeleteSnapshots.Value().ToString()); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfMatch.HasValue() && !options.IfMatch.ToString().empty()) { + request.SetHeader("If-Match", options.IfMatch.ToString()); + } + if (options.IfNoneMatch.HasValue() && + !options.IfNoneMatch.ToString().empty()) { + request.SetHeader("If-None-Match", options.IfNoneMatch.ToString()); + } + if (options.IfTags.HasValue() && !options.IfTags.Value().empty()) { + request.SetHeader("x-ms-if-tags", options.IfTags.Value()); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Accepted) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::DeleteBlobResult response; + return Response(std::move(response), + std::move(pRawResponse)); +} +Response +BlobClient::Undelete(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, const UndeleteBlobOptions &options, + const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.GetUrl().AppendQueryParameter("comp", "undelete"); + request.SetHeader("x-ms-version", "2020-08-04"); + (void)options; + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::UndeleteBlobResult response; + return Response(std::move(response), + std::move(pRawResponse)); +} +Response +BlobClient::SetExpiry(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, const SetBlobExpiryOptions &options, + const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.GetUrl().AppendQueryParameter("comp", "expiry"); + request.SetHeader("x-ms-version", "2020-08-04"); + if (!options.ExpiryOptions.ToString().empty()) { + request.SetHeader("x-ms-expiry-option", options.ExpiryOptions.ToString()); + } + if (options.ExpiresOn.HasValue() && !options.ExpiresOn.Value().empty()) { + request.SetHeader("x-ms-expiry-time", options.ExpiresOn.Value()); + } + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::SetBlobExpiryResult response; + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + return Response(std::move(response), + std::move(pRawResponse)); +} +Response BlobClient::SetHttpHeaders( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const SetBlobHttpHeadersOptions &options, const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.GetUrl().AppendQueryParameter("comp", "properties"); + if (!options.BlobCacheControl.empty()) { + request.SetHeader("x-ms-blob-cache-control", options.BlobCacheControl); + } + if (!options.BlobContentType.empty()) { + request.SetHeader("x-ms-blob-content-type", options.BlobContentType); + } + if (!Core::Convert::Base64Encode(options.BlobContentMD5).empty()) { + request.SetHeader("x-ms-blob-content-md5", + Core::Convert::Base64Encode(options.BlobContentMD5)); + } + if (!options.BlobContentEncoding.empty()) { + request.SetHeader("x-ms-blob-content-encoding", + options.BlobContentEncoding); + } + if (!options.BlobContentLanguage.empty()) { + request.SetHeader("x-ms-blob-content-language", + options.BlobContentLanguage); + } + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfMatch.HasValue() && !options.IfMatch.ToString().empty()) { + request.SetHeader("If-Match", options.IfMatch.ToString()); + } + if (options.IfNoneMatch.HasValue() && + !options.IfNoneMatch.ToString().empty()) { + request.SetHeader("If-None-Match", options.IfNoneMatch.ToString()); + } + if (options.IfTags.HasValue() && !options.IfTags.Value().empty()) { + request.SetHeader("x-ms-if-tags", options.IfTags.Value()); + } + if (!options.BlobContentDisposition.empty()) { + request.SetHeader("x-ms-blob-content-disposition", + options.BlobContentDisposition); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::SetBlobHttpHeadersResult response; + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + if (pRawResponse->GetHeaders().count("x-ms-blob-sequence-number") != 0) { + response.SequenceNumber = + std::stoll(pRawResponse->GetHeaders().at("x-ms-blob-sequence-number")); + } + return Response(std::move(response), + std::move(pRawResponse)); +} +Response +BlobClient::SetImmutabilityPolicy( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const SetBlobImmutabilityPolicyOptions &options, + const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.GetUrl().AppendQueryParameter("comp", "immutabilityPolicies"); + request.SetHeader("x-ms-version", "2020-08-04"); + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.ImmutabilityPolicyExpiry.HasValue()) { + request.SetHeader("x-ms-immutability-policy-until-date", + options.ImmutabilityPolicyExpiry.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.ImmutabilityPolicyMode.HasValue() && + !options.ImmutabilityPolicyMode.Value().ToString().empty()) { + request.SetHeader("x-ms-immutability-policy-mode", + options.ImmutabilityPolicyMode.Value().ToString()); + } + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::SetBlobImmutabilityPolicyResult response; + response.ImmutabilityPolicy.ExpiresOn = DateTime::Parse( + pRawResponse->GetHeaders().at("x-ms-immutability-policy-until-date"), + Azure::DateTime::DateFormat::Rfc1123); + response.ImmutabilityPolicy.PolicyMode = Models::BlobImmutabilityPolicyMode( + pRawResponse->GetHeaders().at("x-ms-immutability-policy-mode")); + return Response( + std::move(response), std::move(pRawResponse)); +} +Response +BlobClient::DeleteImmutabilityPolicy( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const DeleteBlobImmutabilityPolicyOptions &options, + const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Delete, url); + request.GetUrl().AppendQueryParameter("comp", "immutabilityPolicies"); + request.SetHeader("x-ms-version", "2020-08-04"); + (void)options; + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::DeleteBlobImmutabilityPolicyResult response; + return Response( + std::move(response), std::move(pRawResponse)); +} +Response BlobClient::SetLegalHold( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const SetBlobLegalHoldOptions &options, const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.GetUrl().AppendQueryParameter("comp", "legalhold"); + request.SetHeader("x-ms-version", "2020-08-04"); + request.SetHeader("x-ms-legal-hold", options.LegalHold ? "true" : "false"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::SetBlobLegalHoldResult response; + response.HasLegalHold = + pRawResponse->GetHeaders().at("x-ms-legal-hold") == std::string("true"); + return Response(std::move(response), + std::move(pRawResponse)); +} +Response BlobClient::SetMetadata( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const SetBlobMetadataOptions &options, const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.GetUrl().AppendQueryParameter("comp", "metadata"); + for (const auto &p : options.Metadata) { + request.SetHeader("x-ms-meta-" + p.first, p.second); + } + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + if (options.EncryptionKey.HasValue() && + !options.EncryptionKey.Value().empty()) { + request.SetHeader("x-ms-encryption-key", options.EncryptionKey.Value()); + } + if (options.EncryptionKeySha256.HasValue() && + !Core::Convert::Base64Encode(options.EncryptionKeySha256.Value()) + .empty()) { + request.SetHeader( + "x-ms-encryption-key-sha256", + Core::Convert::Base64Encode(options.EncryptionKeySha256.Value())); + } + if (options.EncryptionAlgorithm.HasValue() && + !options.EncryptionAlgorithm.Value().empty()) { + request.SetHeader("x-ms-encryption-algorithm", + options.EncryptionAlgorithm.Value()); + } + if (options.EncryptionScope.HasValue() && + !options.EncryptionScope.Value().empty()) { + request.SetHeader("x-ms-encryption-scope", options.EncryptionScope.Value()); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfMatch.HasValue() && !options.IfMatch.ToString().empty()) { + request.SetHeader("If-Match", options.IfMatch.ToString()); + } + if (options.IfNoneMatch.HasValue() && + !options.IfNoneMatch.ToString().empty()) { + request.SetHeader("If-None-Match", options.IfNoneMatch.ToString()); + } + if (options.IfTags.HasValue() && !options.IfTags.Value().empty()) { + request.SetHeader("x-ms-if-tags", options.IfTags.Value()); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::SetBlobMetadataResult response; + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + if (pRawResponse->GetHeaders().count("x-ms-version-id") != 0) { + response.VersionId = pRawResponse->GetHeaders().at("x-ms-version-id"); + } + response.IsServerEncrypted = + pRawResponse->GetHeaders().at("x-ms-request-server-encrypted") == + std::string("true"); + if (pRawResponse->GetHeaders().count("x-ms-encryption-key-sha256") != 0) { + response.EncryptionKeySha256 = Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("x-ms-encryption-key-sha256")); + } + if (pRawResponse->GetHeaders().count("x-ms-encryption-scope") != 0) { + response.EncryptionScope = + pRawResponse->GetHeaders().at("x-ms-encryption-scope"); + } + return Response(std::move(response), + std::move(pRawResponse)); +} +Response BlobClient::AcquireLease( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const AcquireBlobLeaseOptions &options, const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.GetUrl().AppendQueryParameter("comp", "lease"); + request.SetHeader("x-ms-lease-action", "acquire"); + if (options.Duration.HasValue()) { + request.SetHeader("x-ms-lease-duration", + std::to_string(options.Duration.Value())); + } + if (options.ProposedLeaseId.HasValue() && + !options.ProposedLeaseId.Value().empty()) { + request.SetHeader("x-ms-proposed-lease-id", + options.ProposedLeaseId.Value()); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfMatch.HasValue() && !options.IfMatch.ToString().empty()) { + request.SetHeader("If-Match", options.IfMatch.ToString()); + } + if (options.IfNoneMatch.HasValue() && + !options.IfNoneMatch.ToString().empty()) { + request.SetHeader("If-None-Match", options.IfNoneMatch.ToString()); + } + if (options.IfTags.HasValue() && !options.IfTags.Value().empty()) { + request.SetHeader("x-ms-if-tags", options.IfTags.Value()); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Created) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::_detail::AcquireBlobLeaseResult response; + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + response.LeaseId = pRawResponse->GetHeaders().at("x-ms-lease-id"); + return Response( + std::move(response), std::move(pRawResponse)); +} +Response BlobClient::ReleaseLease( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const ReleaseBlobLeaseOptions &options, const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.GetUrl().AppendQueryParameter("comp", "lease"); + request.SetHeader("x-ms-lease-action", "release"); + if (!options.LeaseId.empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfMatch.HasValue() && !options.IfMatch.ToString().empty()) { + request.SetHeader("If-Match", options.IfMatch.ToString()); + } + if (options.IfNoneMatch.HasValue() && + !options.IfNoneMatch.ToString().empty()) { + request.SetHeader("If-None-Match", options.IfNoneMatch.ToString()); + } + if (options.IfTags.HasValue() && !options.IfTags.Value().empty()) { + request.SetHeader("x-ms-if-tags", options.IfTags.Value()); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::_detail::ReleaseBlobLeaseResult response; + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + return Response( + std::move(response), std::move(pRawResponse)); +} +Response BlobClient::RenewLease( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const RenewBlobLeaseOptions &options, const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.GetUrl().AppendQueryParameter("comp", "lease"); + request.SetHeader("x-ms-lease-action", "renew"); + if (!options.LeaseId.empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfMatch.HasValue() && !options.IfMatch.ToString().empty()) { + request.SetHeader("If-Match", options.IfMatch.ToString()); + } + if (options.IfNoneMatch.HasValue() && + !options.IfNoneMatch.ToString().empty()) { + request.SetHeader("If-None-Match", options.IfNoneMatch.ToString()); + } + if (options.IfTags.HasValue() && !options.IfTags.Value().empty()) { + request.SetHeader("x-ms-if-tags", options.IfTags.Value()); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::_detail::RenewBlobLeaseResult response; + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + response.LeaseId = pRawResponse->GetHeaders().at("x-ms-lease-id"); + return Response( + std::move(response), std::move(pRawResponse)); +} +Response BlobClient::ChangeLease( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const ChangeBlobLeaseOptions &options, const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.GetUrl().AppendQueryParameter("comp", "lease"); + request.SetHeader("x-ms-lease-action", "change"); + if (!options.LeaseId.empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId); + } + if (!options.ProposedLeaseId.empty()) { + request.SetHeader("x-ms-proposed-lease-id", options.ProposedLeaseId); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfMatch.HasValue() && !options.IfMatch.ToString().empty()) { + request.SetHeader("If-Match", options.IfMatch.ToString()); + } + if (options.IfNoneMatch.HasValue() && + !options.IfNoneMatch.ToString().empty()) { + request.SetHeader("If-None-Match", options.IfNoneMatch.ToString()); + } + if (options.IfTags.HasValue() && !options.IfTags.Value().empty()) { + request.SetHeader("x-ms-if-tags", options.IfTags.Value()); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::_detail::ChangeBlobLeaseResult response; + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + response.LeaseId = pRawResponse->GetHeaders().at("x-ms-lease-id"); + return Response( + std::move(response), std::move(pRawResponse)); +} +Response BlobClient::BreakLease( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const BreakBlobLeaseOptions &options, const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.GetUrl().AppendQueryParameter("comp", "lease"); + request.SetHeader("x-ms-lease-action", "break"); + if (options.BreakPeriod.HasValue()) { + request.SetHeader("x-ms-lease-break-period", + std::to_string(options.BreakPeriod.Value())); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfMatch.HasValue() && !options.IfMatch.ToString().empty()) { + request.SetHeader("If-Match", options.IfMatch.ToString()); + } + if (options.IfNoneMatch.HasValue() && + !options.IfNoneMatch.ToString().empty()) { + request.SetHeader("If-None-Match", options.IfNoneMatch.ToString()); + } + if (options.IfTags.HasValue() && !options.IfTags.Value().empty()) { + request.SetHeader("x-ms-if-tags", options.IfTags.Value()); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Accepted) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::_detail::BreakBlobLeaseResult response; + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + response.LeaseTime = + std::stoi(pRawResponse->GetHeaders().at("x-ms-lease-time")); + return Response( + std::move(response), std::move(pRawResponse)); +} +Response BlobClient::CreateSnapshot( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const CreateBlobSnapshotOptions &options, const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.GetUrl().AppendQueryParameter("comp", "snapshot"); + for (const auto &p : options.Metadata) { + request.SetHeader("x-ms-meta-" + p.first, p.second); + } + if (options.EncryptionKey.HasValue() && + !options.EncryptionKey.Value().empty()) { + request.SetHeader("x-ms-encryption-key", options.EncryptionKey.Value()); + } + if (options.EncryptionKeySha256.HasValue() && + !Core::Convert::Base64Encode(options.EncryptionKeySha256.Value()) + .empty()) { + request.SetHeader( + "x-ms-encryption-key-sha256", + Core::Convert::Base64Encode(options.EncryptionKeySha256.Value())); + } + if (options.EncryptionAlgorithm.HasValue() && + !options.EncryptionAlgorithm.Value().empty()) { + request.SetHeader("x-ms-encryption-algorithm", + options.EncryptionAlgorithm.Value()); + } + if (options.EncryptionScope.HasValue() && + !options.EncryptionScope.Value().empty()) { + request.SetHeader("x-ms-encryption-scope", options.EncryptionScope.Value()); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfMatch.HasValue() && !options.IfMatch.ToString().empty()) { + request.SetHeader("If-Match", options.IfMatch.ToString()); + } + if (options.IfNoneMatch.HasValue() && + !options.IfNoneMatch.ToString().empty()) { + request.SetHeader("If-None-Match", options.IfNoneMatch.ToString()); + } + if (options.IfTags.HasValue() && !options.IfTags.Value().empty()) { + request.SetHeader("x-ms-if-tags", options.IfTags.Value()); + } + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Created) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::CreateBlobSnapshotResult response; + response.Snapshot = pRawResponse->GetHeaders().at("x-ms-snapshot"); + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + if (pRawResponse->GetHeaders().count("x-ms-version-id") != 0) { + response.VersionId = pRawResponse->GetHeaders().at("x-ms-version-id"); + } + response.IsServerEncrypted = + pRawResponse->GetHeaders().at("x-ms-request-server-encrypted") == + std::string("true"); + return Response(std::move(response), + std::move(pRawResponse)); +} +Response +BlobClient::StartCopyFromUri(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const StartBlobCopyFromUriOptions &options, + const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + if (options.SourceLeaseId.HasValue() && + !options.SourceLeaseId.Value().empty()) { + request.SetHeader("x-ms-source-lease-id", options.SourceLeaseId.Value()); + } + for (const auto &p : options.Metadata) { + request.SetHeader("x-ms-meta-" + p.first, p.second); + } + if (options.Tier.HasValue() && !options.Tier.Value().ToString().empty()) { + request.SetHeader("x-ms-access-tier", options.Tier.Value().ToString()); + } + if (options.RehydratePriority.HasValue() && + !options.RehydratePriority.Value().ToString().empty()) { + request.SetHeader("x-ms-rehydrate-priority", + options.RehydratePriority.Value().ToString()); + } + if (options.SourceIfModifiedSince.HasValue()) { + request.SetHeader("x-ms-source-if-modified-since", + options.SourceIfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.SourceIfUnmodifiedSince.HasValue()) { + request.SetHeader("x-ms-source-if-unmodified-since", + options.SourceIfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.SourceIfMatch.HasValue() && + !options.SourceIfMatch.ToString().empty()) { + request.SetHeader("x-ms-source-if-match", options.SourceIfMatch.ToString()); + } + if (options.SourceIfNoneMatch.HasValue() && + !options.SourceIfNoneMatch.ToString().empty()) { + request.SetHeader("x-ms-source-if-none-match", + options.SourceIfNoneMatch.ToString()); + } + if (options.SourceIfTags.HasValue() && + !options.SourceIfTags.Value().empty()) { + request.SetHeader("x-ms-source-if-tags", options.SourceIfTags.Value()); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfMatch.HasValue() && !options.IfMatch.ToString().empty()) { + request.SetHeader("If-Match", options.IfMatch.ToString()); + } + if (options.IfNoneMatch.HasValue() && + !options.IfNoneMatch.ToString().empty()) { + request.SetHeader("If-None-Match", options.IfNoneMatch.ToString()); + } + if (options.IfTags.HasValue() && !options.IfTags.Value().empty()) { + request.SetHeader("x-ms-if-tags", options.IfTags.Value()); + } + if (!options.CopySource.empty()) { + request.SetHeader("x-ms-copy-source", options.CopySource); + } + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + request.SetHeader("x-ms-version", "2020-08-04"); + if (options.BlobTagsString.HasValue() && + !options.BlobTagsString.Value().empty()) { + request.SetHeader("x-ms-tags", options.BlobTagsString.Value()); + } + if (options.SealBlob.HasValue()) { + request.SetHeader("x-ms-seal-blob", + options.SealBlob.Value() ? "true" : "false"); + } + if (options.ImmutabilityPolicyExpiry.HasValue()) { + request.SetHeader("x-ms-immutability-policy-until-date", + options.ImmutabilityPolicyExpiry.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.ImmutabilityPolicyMode.HasValue() && + !options.ImmutabilityPolicyMode.Value().ToString().empty()) { + request.SetHeader("x-ms-immutability-policy-mode", + options.ImmutabilityPolicyMode.Value().ToString()); + } + if (options.LegalHold.HasValue()) { + request.SetHeader("x-ms-legal-hold", + options.LegalHold.Value() ? "true" : "false"); + } + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Accepted) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::_detail::StartBlobCopyFromUriResult response; + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + if (pRawResponse->GetHeaders().count("x-ms-version-id") != 0) { + response.VersionId = pRawResponse->GetHeaders().at("x-ms-version-id"); + } + response.CopyId = pRawResponse->GetHeaders().at("x-ms-copy-id"); + response.CopyStatus = + Models::CopyStatus(pRawResponse->GetHeaders().at("x-ms-copy-status")); + return Response( + std::move(response), std::move(pRawResponse)); +} +Response BlobClient::CopyFromUri( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const CopyBlobFromUriOptions &options, const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.SetHeader("x-ms-requires-sync", "true"); + for (const auto &p : options.Metadata) { + request.SetHeader("x-ms-meta-" + p.first, p.second); + } + if (options.Tier.HasValue() && !options.Tier.Value().ToString().empty()) { + request.SetHeader("x-ms-access-tier", options.Tier.Value().ToString()); + } + if (options.SourceIfModifiedSince.HasValue()) { + request.SetHeader("x-ms-source-if-modified-since", + options.SourceIfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.SourceIfUnmodifiedSince.HasValue()) { + request.SetHeader("x-ms-source-if-unmodified-since", + options.SourceIfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.SourceIfMatch.HasValue() && + !options.SourceIfMatch.ToString().empty()) { + request.SetHeader("x-ms-source-if-match", options.SourceIfMatch.ToString()); + } + if (options.SourceIfNoneMatch.HasValue() && + !options.SourceIfNoneMatch.ToString().empty()) { + request.SetHeader("x-ms-source-if-none-match", + options.SourceIfNoneMatch.ToString()); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfMatch.HasValue() && !options.IfMatch.ToString().empty()) { + request.SetHeader("If-Match", options.IfMatch.ToString()); + } + if (options.IfNoneMatch.HasValue() && + !options.IfNoneMatch.ToString().empty()) { + request.SetHeader("If-None-Match", options.IfNoneMatch.ToString()); + } + if (options.IfTags.HasValue() && !options.IfTags.Value().empty()) { + request.SetHeader("x-ms-if-tags", options.IfTags.Value()); + } + if (!options.CopySource.empty()) { + request.SetHeader("x-ms-copy-source", options.CopySource); + } + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + request.SetHeader("x-ms-version", "2020-08-04"); + if (options.SourceContentMD5.HasValue() && + !Core::Convert::Base64Encode(options.SourceContentMD5.Value()).empty()) { + request.SetHeader( + "x-ms-source-content-md5", + Core::Convert::Base64Encode(options.SourceContentMD5.Value())); + } + if (options.BlobTagsString.HasValue() && + !options.BlobTagsString.Value().empty()) { + request.SetHeader("x-ms-tags", options.BlobTagsString.Value()); + } + if (options.ImmutabilityPolicyExpiry.HasValue()) { + request.SetHeader("x-ms-immutability-policy-until-date", + options.ImmutabilityPolicyExpiry.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.ImmutabilityPolicyMode.HasValue() && + !options.ImmutabilityPolicyMode.Value().ToString().empty()) { + request.SetHeader("x-ms-immutability-policy-mode", + options.ImmutabilityPolicyMode.Value().ToString()); + } + if (options.LegalHold.HasValue()) { + request.SetHeader("x-ms-legal-hold", + options.LegalHold.Value() ? "true" : "false"); + } + if (options.SourceContentcrc64.HasValue() && + !Core::Convert::Base64Encode(options.SourceContentcrc64.Value()) + .empty()) { + request.SetHeader( + "x-ms-source-content-crc64", + Core::Convert::Base64Encode(options.SourceContentcrc64.Value())); + } + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Accepted) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::CopyBlobFromUriResult response; + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + if (pRawResponse->GetHeaders().count("x-ms-version-id") != 0) { + response.VersionId = pRawResponse->GetHeaders().at("x-ms-version-id"); + } + response.CopyId = pRawResponse->GetHeaders().at("x-ms-copy-id"); + response.CopyStatus = + Models::CopyStatus(pRawResponse->GetHeaders().at("x-ms-copy-status")); + if (pRawResponse->GetHeaders().count("Content-MD5") != 0) { + response.TransactionalContentHash = ContentHash(); + response.TransactionalContentHash.Value().Value = + Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("Content-MD5")); + response.TransactionalContentHash.Value().Algorithm = HashAlgorithm::Md5; + } + if (pRawResponse->GetHeaders().count("x-ms-content-crc64") != 0) { + response.TransactionalContentHash = ContentHash(); + response.TransactionalContentHash.Value().Value = + Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("x-ms-content-crc64")); + response.TransactionalContentHash.Value().Algorithm = HashAlgorithm::Crc64; + } + return Response(std::move(response), + std::move(pRawResponse)); +} +Response BlobClient::AbortCopyFromUri( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const AbortBlobCopyFromUriOptions &options, const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.GetUrl().AppendQueryParameter("comp", "copy"); + request.SetHeader("x-ms-copy-action", "abort"); + if (!options.CopyId.empty()) { + request.GetUrl().AppendQueryParameter( + "copyid", _internal::UrlEncodeQueryParameter(options.CopyId)); + } + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::NoContent) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::AbortBlobCopyFromUriResult response; + return Response(std::move(response), + std::move(pRawResponse)); +} +Response +BlobClient::SetTier(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, const SetBlobTierOptions &options, + const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.GetUrl().AppendQueryParameter("comp", "tier"); + if (options.Snapshot.HasValue() && !options.Snapshot.Value().empty()) { + request.GetUrl().AppendQueryParameter( + "snapshot", + _internal::UrlEncodeQueryParameter(options.Snapshot.Value())); + } + if (options.VersionId.HasValue() && !options.VersionId.Value().empty()) { + request.GetUrl().AppendQueryParameter( + "versionid", + _internal::UrlEncodeQueryParameter(options.VersionId.Value())); + } + if (!options.Tier.ToString().empty()) { + request.SetHeader("x-ms-access-tier", options.Tier.ToString()); + } + if (options.RehydratePriority.HasValue() && + !options.RehydratePriority.Value().ToString().empty()) { + request.SetHeader("x-ms-rehydrate-priority", + options.RehydratePriority.Value().ToString()); + } + request.SetHeader("x-ms-version", "2020-08-04"); + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + if (options.IfTags.HasValue() && !options.IfTags.Value().empty()) { + request.SetHeader("x-ms-if-tags", options.IfTags.Value()); + } + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (!(httpStatusCode == Core::Http::HttpStatusCode::Ok || + httpStatusCode == Core::Http::HttpStatusCode::Accepted)) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::SetBlobAccessTierResult response; + return Response(std::move(response), + std::move(pRawResponse)); +} +Response> +BlobClient::GetTags(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, const GetBlobTagsOptions &options, + const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url); + request.GetUrl().AppendQueryParameter("comp", "tags"); + request.SetHeader("x-ms-version", "2020-08-04"); + if (options.Snapshot.HasValue() && !options.Snapshot.Value().empty()) { + request.GetUrl().AppendQueryParameter( + "snapshot", + _internal::UrlEncodeQueryParameter(options.Snapshot.Value())); + } + if (options.VersionId.HasValue() && !options.VersionId.Value().empty()) { + request.GetUrl().AppendQueryParameter( + "versionid", + _internal::UrlEncodeQueryParameter(options.VersionId.Value())); + } + if (options.IfTags.HasValue() && !options.IfTags.Value().empty()) { + request.SetHeader("x-ms-if-tags", options.IfTags.Value()); + } + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + std::map response; + { + const auto &responseBody = pRawResponse->GetBody(); + _internal::XmlReader reader( + reinterpret_cast(responseBody.data()), + responseBody.size()); + enum class XmlTagEnum { + kUnknown, + kTags, + kTagSet, + kTag, + kKey, + kValue, + }; + const std::unordered_map XmlTagEnumMap{ + {"Tags", XmlTagEnum::kTags}, {"TagSet", XmlTagEnum::kTagSet}, + {"Tag", XmlTagEnum::kTag}, {"Key", XmlTagEnum::kKey}, + {"Value", XmlTagEnum::kValue}, + }; + std::vector xmlPath; + + std::string mapKey1; + std::string mapValue2; + while (true) { + auto node = reader.Read(); + if (node.Type == _internal::XmlNodeType::End) { + break; + } else if (node.Type == _internal::XmlNodeType::StartTag) { + auto ite = XmlTagEnumMap.find(node.Name); + xmlPath.push_back(ite == XmlTagEnumMap.end() ? XmlTagEnum::kUnknown + : ite->second); + + } else if (node.Type == _internal::XmlNodeType::Text) { + if (xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kTags && + xmlPath[1] == XmlTagEnum::kTagSet && + xmlPath[2] == XmlTagEnum::kTag && xmlPath[3] == XmlTagEnum::kKey) { + mapKey1 = node.Value; + } else if (xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kTags && + xmlPath[1] == XmlTagEnum::kTagSet && + xmlPath[2] == XmlTagEnum::kTag && + xmlPath[3] == XmlTagEnum::kValue) { + mapValue2 = node.Value; + } + } else if (node.Type == _internal::XmlNodeType::Attribute) { + + } else if (node.Type == _internal::XmlNodeType::EndTag) { + if (xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kTags && + xmlPath[1] == XmlTagEnum::kTagSet && + xmlPath[2] == XmlTagEnum::kTag && + xmlPath[3] == XmlTagEnum::kValue) { + response[std::move(mapKey1)] = std::move(mapValue2); + } + xmlPath.pop_back(); + } + } + } + return Response>(std::move(response), + std::move(pRawResponse)); +} +Response +BlobClient::SetTags(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, const SetBlobTagsOptions &options, + const Core::Context &context) { + std::string xmlBody; + { + _internal::XmlWriter writer; + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "Tags"}); + writer.Write( + _internal::XmlNode{_internal::XmlNodeType::StartTag, "TagSet"}); + for (const auto &i1i2 : options.Tags) { + const auto &i1 = i1i2.first; + const auto &i2 = i1i2.second; + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "Tag"}); + writer.Write( + _internal::XmlNode{_internal::XmlNodeType::StartTag, "Key", i1}); + writer.Write( + _internal::XmlNode{_internal::XmlNodeType::StartTag, "Value", i2}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + } + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::End}); + xmlBody = writer.GetDocument(); + } + Core::IO::MemoryBodyStream requestBody( + reinterpret_cast(xmlBody.data()), xmlBody.length()); + auto request = + Core::Http::Request(Core::Http::HttpMethod::Put, url, &requestBody); + request.SetHeader("Content-Type", "application/xml; charset=UTF-8"); + request.SetHeader("Content-Length", std::to_string(requestBody.Length())); + request.GetUrl().AppendQueryParameter("comp", "tags"); + request.SetHeader("x-ms-version", "2020-08-04"); + if (options.VersionId.HasValue() && !options.VersionId.Value().empty()) { + request.GetUrl().AppendQueryParameter( + "versionid", + _internal::UrlEncodeQueryParameter(options.VersionId.Value())); + } + if (options.TransactionalContentMD5.HasValue() && + !Core::Convert::Base64Encode(options.TransactionalContentMD5.Value()) + .empty()) { + request.SetHeader( + "Content-MD5", + Core::Convert::Base64Encode(options.TransactionalContentMD5.Value())); + } + if (options.TransactionalContentCrc64.HasValue() && + !Core::Convert::Base64Encode(options.TransactionalContentCrc64.Value()) + .empty()) { + request.SetHeader( + "x-ms-content-crc64", + Core::Convert::Base64Encode(options.TransactionalContentCrc64.Value())); + } + if (options.IfTags.HasValue() && !options.IfTags.Value().empty()) { + request.SetHeader("x-ms-if-tags", options.IfTags.Value()); + } + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::NoContent) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::SetBlobTagsResult response; + return Response(std::move(response), + std::move(pRawResponse)); +} +Response PageBlobClient::Create( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const CreatePageBlobOptions &options, const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.SetHeader("x-ms-blob-type", "PageBlob"); + request.SetHeader("Content-Length", "0"); + if (options.Tier.HasValue() && !options.Tier.Value().ToString().empty()) { + request.SetHeader("x-ms-access-tier", options.Tier.Value().ToString()); + } + if (!options.BlobContentType.empty()) { + request.SetHeader("x-ms-blob-content-type", options.BlobContentType); + } + if (!options.BlobContentEncoding.empty()) { + request.SetHeader("x-ms-blob-content-encoding", + options.BlobContentEncoding); + } + if (!options.BlobContentLanguage.empty()) { + request.SetHeader("x-ms-blob-content-language", + options.BlobContentLanguage); + } + if (!Core::Convert::Base64Encode(options.BlobContentMD5).empty()) { + request.SetHeader("x-ms-blob-content-md5", + Core::Convert::Base64Encode(options.BlobContentMD5)); + } + if (!options.BlobCacheControl.empty()) { + request.SetHeader("x-ms-blob-cache-control", options.BlobCacheControl); + } + for (const auto &p : options.Metadata) { + request.SetHeader("x-ms-meta-" + p.first, p.second); + } + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + if (!options.BlobContentDisposition.empty()) { + request.SetHeader("x-ms-blob-content-disposition", + options.BlobContentDisposition); + } + if (options.EncryptionKey.HasValue() && + !options.EncryptionKey.Value().empty()) { + request.SetHeader("x-ms-encryption-key", options.EncryptionKey.Value()); + } + if (options.EncryptionKeySha256.HasValue() && + !Core::Convert::Base64Encode(options.EncryptionKeySha256.Value()) + .empty()) { + request.SetHeader( + "x-ms-encryption-key-sha256", + Core::Convert::Base64Encode(options.EncryptionKeySha256.Value())); + } + if (options.EncryptionAlgorithm.HasValue() && + !options.EncryptionAlgorithm.Value().empty()) { + request.SetHeader("x-ms-encryption-algorithm", + options.EncryptionAlgorithm.Value()); + } + if (options.EncryptionScope.HasValue() && + !options.EncryptionScope.Value().empty()) { + request.SetHeader("x-ms-encryption-scope", options.EncryptionScope.Value()); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfMatch.HasValue() && !options.IfMatch.ToString().empty()) { + request.SetHeader("If-Match", options.IfMatch.ToString()); + } + if (options.IfNoneMatch.HasValue() && + !options.IfNoneMatch.ToString().empty()) { + request.SetHeader("If-None-Match", options.IfNoneMatch.ToString()); + } + if (options.IfTags.HasValue() && !options.IfTags.Value().empty()) { + request.SetHeader("x-ms-if-tags", options.IfTags.Value()); + } + request.SetHeader("x-ms-blob-content-length", + std::to_string(options.BlobContentLength)); + if (options.BlobSequenceNumber.HasValue()) { + request.SetHeader("x-ms-blob-sequence-number", + std::to_string(options.BlobSequenceNumber.Value())); + } + request.SetHeader("x-ms-version", "2020-08-04"); + if (options.BlobTagsString.HasValue() && + !options.BlobTagsString.Value().empty()) { + request.SetHeader("x-ms-tags", options.BlobTagsString.Value()); + } + if (options.ImmutabilityPolicyExpiry.HasValue()) { + request.SetHeader("x-ms-immutability-policy-until-date", + options.ImmutabilityPolicyExpiry.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.ImmutabilityPolicyMode.HasValue() && + !options.ImmutabilityPolicyMode.Value().ToString().empty()) { + request.SetHeader("x-ms-immutability-policy-mode", + options.ImmutabilityPolicyMode.Value().ToString()); + } + if (options.LegalHold.HasValue()) { + request.SetHeader("x-ms-legal-hold", + options.LegalHold.Value() ? "true" : "false"); + } + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Created) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::CreatePageBlobResult response; + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + if (pRawResponse->GetHeaders().count("x-ms-version-id") != 0) { + response.VersionId = pRawResponse->GetHeaders().at("x-ms-version-id"); + } + response.IsServerEncrypted = + pRawResponse->GetHeaders().at("x-ms-request-server-encrypted") == + std::string("true"); + if (pRawResponse->GetHeaders().count("x-ms-encryption-key-sha256") != 0) { + response.EncryptionKeySha256 = Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("x-ms-encryption-key-sha256")); + } + if (pRawResponse->GetHeaders().count("x-ms-encryption-scope") != 0) { + response.EncryptionScope = + pRawResponse->GetHeaders().at("x-ms-encryption-scope"); + } + return Response(std::move(response), + std::move(pRawResponse)); +} +Response PageBlobClient::UploadPages( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + Core::IO::BodyStream &requestBody, + const UploadPageBlobPagesOptions &options, const Core::Context &context) { + auto request = + Core::Http::Request(Core::Http::HttpMethod::Put, url, &requestBody); + request.GetUrl().AppendQueryParameter("comp", "page"); + request.SetHeader("x-ms-page-write", "update"); + request.SetHeader("Content-Length", std::to_string(requestBody.Length())); + if (options.TransactionalContentMD5.HasValue() && + !Core::Convert::Base64Encode(options.TransactionalContentMD5.Value()) + .empty()) { + request.SetHeader( + "Content-MD5", + Core::Convert::Base64Encode(options.TransactionalContentMD5.Value())); + } + if (options.TransactionalContentCrc64.HasValue() && + !Core::Convert::Base64Encode(options.TransactionalContentCrc64.Value()) + .empty()) { + request.SetHeader( + "x-ms-content-crc64", + Core::Convert::Base64Encode(options.TransactionalContentCrc64.Value())); + } + if (options.Range.HasValue() && !options.Range.Value().empty()) { + request.SetHeader("x-ms-range", options.Range.Value()); + } + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + if (options.EncryptionKey.HasValue() && + !options.EncryptionKey.Value().empty()) { + request.SetHeader("x-ms-encryption-key", options.EncryptionKey.Value()); + } + if (options.EncryptionKeySha256.HasValue() && + !Core::Convert::Base64Encode(options.EncryptionKeySha256.Value()) + .empty()) { + request.SetHeader( + "x-ms-encryption-key-sha256", + Core::Convert::Base64Encode(options.EncryptionKeySha256.Value())); + } + if (options.EncryptionAlgorithm.HasValue() && + !options.EncryptionAlgorithm.Value().empty()) { + request.SetHeader("x-ms-encryption-algorithm", + options.EncryptionAlgorithm.Value()); + } + if (options.EncryptionScope.HasValue() && + !options.EncryptionScope.Value().empty()) { + request.SetHeader("x-ms-encryption-scope", options.EncryptionScope.Value()); + } + if (options.IfSequenceNumberLessThanOrEqualTo.HasValue()) { + request.SetHeader( + "x-ms-if-sequence-number-le", + std::to_string(options.IfSequenceNumberLessThanOrEqualTo.Value())); + } + if (options.IfSequenceNumberLessThan.HasValue()) { + request.SetHeader("x-ms-if-sequence-number-lt", + std::to_string(options.IfSequenceNumberLessThan.Value())); + } + if (options.IfSequenceNumberEqualTo.HasValue()) { + request.SetHeader("x-ms-if-sequence-number-eq", + std::to_string(options.IfSequenceNumberEqualTo.Value())); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfMatch.HasValue() && !options.IfMatch.ToString().empty()) { + request.SetHeader("If-Match", options.IfMatch.ToString()); + } + if (options.IfNoneMatch.HasValue() && + !options.IfNoneMatch.ToString().empty()) { + request.SetHeader("If-None-Match", options.IfNoneMatch.ToString()); + } + if (options.IfTags.HasValue() && !options.IfTags.Value().empty()) { + request.SetHeader("x-ms-if-tags", options.IfTags.Value()); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Created) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::UploadPagesResult response; + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + if (pRawResponse->GetHeaders().count("Content-MD5") != 0) { + response.TransactionalContentHash = ContentHash(); + response.TransactionalContentHash.Value().Value = + Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("Content-MD5")); + response.TransactionalContentHash.Value().Algorithm = HashAlgorithm::Md5; + } + if (pRawResponse->GetHeaders().count("x-ms-content-crc64") != 0) { + response.TransactionalContentHash = ContentHash(); + response.TransactionalContentHash.Value().Value = + Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("x-ms-content-crc64")); + response.TransactionalContentHash.Value().Algorithm = HashAlgorithm::Crc64; + } + response.SequenceNumber = + std::stoll(pRawResponse->GetHeaders().at("x-ms-blob-sequence-number")); + response.IsServerEncrypted = + pRawResponse->GetHeaders().at("x-ms-request-server-encrypted") == + std::string("true"); + if (pRawResponse->GetHeaders().count("x-ms-encryption-key-sha256") != 0) { + response.EncryptionKeySha256 = Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("x-ms-encryption-key-sha256")); + } + if (pRawResponse->GetHeaders().count("x-ms-encryption-scope") != 0) { + response.EncryptionScope = + pRawResponse->GetHeaders().at("x-ms-encryption-scope"); + } + return Response(std::move(response), + std::move(pRawResponse)); +} +Response PageBlobClient::ClearPages( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const ClearPageBlobPagesOptions &options, const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.GetUrl().AppendQueryParameter("comp", "page"); + request.SetHeader("x-ms-page-write", "clear"); + request.SetHeader("Content-Length", "0"); + if (options.Range.HasValue() && !options.Range.Value().empty()) { + request.SetHeader("x-ms-range", options.Range.Value()); + } + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + if (options.EncryptionKey.HasValue() && + !options.EncryptionKey.Value().empty()) { + request.SetHeader("x-ms-encryption-key", options.EncryptionKey.Value()); + } + if (options.EncryptionKeySha256.HasValue() && + !Core::Convert::Base64Encode(options.EncryptionKeySha256.Value()) + .empty()) { + request.SetHeader( + "x-ms-encryption-key-sha256", + Core::Convert::Base64Encode(options.EncryptionKeySha256.Value())); + } + if (options.EncryptionAlgorithm.HasValue() && + !options.EncryptionAlgorithm.Value().empty()) { + request.SetHeader("x-ms-encryption-algorithm", + options.EncryptionAlgorithm.Value()); + } + if (options.EncryptionScope.HasValue() && + !options.EncryptionScope.Value().empty()) { + request.SetHeader("x-ms-encryption-scope", options.EncryptionScope.Value()); + } + if (options.IfSequenceNumberLessThanOrEqualTo.HasValue()) { + request.SetHeader( + "x-ms-if-sequence-number-le", + std::to_string(options.IfSequenceNumberLessThanOrEqualTo.Value())); + } + if (options.IfSequenceNumberLessThan.HasValue()) { + request.SetHeader("x-ms-if-sequence-number-lt", + std::to_string(options.IfSequenceNumberLessThan.Value())); + } + if (options.IfSequenceNumberEqualTo.HasValue()) { + request.SetHeader("x-ms-if-sequence-number-eq", + std::to_string(options.IfSequenceNumberEqualTo.Value())); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfMatch.HasValue() && !options.IfMatch.ToString().empty()) { + request.SetHeader("If-Match", options.IfMatch.ToString()); + } + if (options.IfNoneMatch.HasValue() && + !options.IfNoneMatch.ToString().empty()) { + request.SetHeader("If-None-Match", options.IfNoneMatch.ToString()); + } + if (options.IfTags.HasValue() && !options.IfTags.Value().empty()) { + request.SetHeader("x-ms-if-tags", options.IfTags.Value()); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Created) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::ClearPagesResult response; + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + response.SequenceNumber = + std::stoll(pRawResponse->GetHeaders().at("x-ms-blob-sequence-number")); + return Response(std::move(response), + std::move(pRawResponse)); +} +Response PageBlobClient::UploadPagesFromUri( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const UploadPageBlobPagesFromUriOptions &options, + const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.GetUrl().AppendQueryParameter("comp", "page"); + request.SetHeader("x-ms-page-write", "update"); + if (!options.SourceUrl.empty()) { + request.SetHeader("x-ms-copy-source", options.SourceUrl); + } + if (!options.SourceRange.empty()) { + request.SetHeader("x-ms-source-range", options.SourceRange); + } + if (options.SourceContentMD5.HasValue() && + !Core::Convert::Base64Encode(options.SourceContentMD5.Value()).empty()) { + request.SetHeader( + "x-ms-source-content-md5", + Core::Convert::Base64Encode(options.SourceContentMD5.Value())); + } + if (options.SourceContentcrc64.HasValue() && + !Core::Convert::Base64Encode(options.SourceContentcrc64.Value()) + .empty()) { + request.SetHeader( + "x-ms-source-content-crc64", + Core::Convert::Base64Encode(options.SourceContentcrc64.Value())); + } + request.SetHeader("Content-Length", "0"); + if (!options.Range.empty()) { + request.SetHeader("x-ms-range", options.Range); + } + if (options.EncryptionKey.HasValue() && + !options.EncryptionKey.Value().empty()) { + request.SetHeader("x-ms-encryption-key", options.EncryptionKey.Value()); + } + if (options.EncryptionKeySha256.HasValue() && + !Core::Convert::Base64Encode(options.EncryptionKeySha256.Value()) + .empty()) { + request.SetHeader( + "x-ms-encryption-key-sha256", + Core::Convert::Base64Encode(options.EncryptionKeySha256.Value())); + } + if (options.EncryptionAlgorithm.HasValue() && + !options.EncryptionAlgorithm.Value().empty()) { + request.SetHeader("x-ms-encryption-algorithm", + options.EncryptionAlgorithm.Value()); + } + if (options.EncryptionScope.HasValue() && + !options.EncryptionScope.Value().empty()) { + request.SetHeader("x-ms-encryption-scope", options.EncryptionScope.Value()); + } + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + if (options.IfSequenceNumberLessThanOrEqualTo.HasValue()) { + request.SetHeader( + "x-ms-if-sequence-number-le", + std::to_string(options.IfSequenceNumberLessThanOrEqualTo.Value())); + } + if (options.IfSequenceNumberLessThan.HasValue()) { + request.SetHeader("x-ms-if-sequence-number-lt", + std::to_string(options.IfSequenceNumberLessThan.Value())); + } + if (options.IfSequenceNumberEqualTo.HasValue()) { + request.SetHeader("x-ms-if-sequence-number-eq", + std::to_string(options.IfSequenceNumberEqualTo.Value())); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfMatch.HasValue() && !options.IfMatch.ToString().empty()) { + request.SetHeader("If-Match", options.IfMatch.ToString()); + } + if (options.IfNoneMatch.HasValue() && + !options.IfNoneMatch.ToString().empty()) { + request.SetHeader("If-None-Match", options.IfNoneMatch.ToString()); + } + if (options.IfTags.HasValue() && !options.IfTags.Value().empty()) { + request.SetHeader("x-ms-if-tags", options.IfTags.Value()); + } + if (options.SourceIfModifiedSince.HasValue()) { + request.SetHeader("x-ms-source-if-modified-since", + options.SourceIfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.SourceIfUnmodifiedSince.HasValue()) { + request.SetHeader("x-ms-source-if-unmodified-since", + options.SourceIfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.SourceIfMatch.HasValue() && + !options.SourceIfMatch.ToString().empty()) { + request.SetHeader("x-ms-source-if-match", options.SourceIfMatch.ToString()); + } + if (options.SourceIfNoneMatch.HasValue() && + !options.SourceIfNoneMatch.ToString().empty()) { + request.SetHeader("x-ms-source-if-none-match", + options.SourceIfNoneMatch.ToString()); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Created) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::UploadPagesFromUriResult response; + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + if (pRawResponse->GetHeaders().count("Content-MD5") != 0) { + response.TransactionalContentHash = ContentHash(); + response.TransactionalContentHash.Value().Value = + Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("Content-MD5")); + response.TransactionalContentHash.Value().Algorithm = HashAlgorithm::Md5; + } + if (pRawResponse->GetHeaders().count("x-ms-content-crc64") != 0) { + response.TransactionalContentHash = ContentHash(); + response.TransactionalContentHash.Value().Value = + Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("x-ms-content-crc64")); + response.TransactionalContentHash.Value().Algorithm = HashAlgorithm::Crc64; + } + response.SequenceNumber = + std::stoll(pRawResponse->GetHeaders().at("x-ms-blob-sequence-number")); + response.IsServerEncrypted = + pRawResponse->GetHeaders().at("x-ms-request-server-encrypted") == + std::string("true"); + if (pRawResponse->GetHeaders().count("x-ms-encryption-key-sha256") != 0) { + response.EncryptionKeySha256 = Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("x-ms-encryption-key-sha256")); + } + if (pRawResponse->GetHeaders().count("x-ms-encryption-scope") != 0) { + response.EncryptionScope = + pRawResponse->GetHeaders().at("x-ms-encryption-scope"); + } + return Response(std::move(response), + std::move(pRawResponse)); +} +Response PageBlobClient::GetPageRanges( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const GetPageBlobPageRangesOptions &options, const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url); + request.GetUrl().AppendQueryParameter("comp", "pagelist"); + if (options.Snapshot.HasValue() && !options.Snapshot.Value().empty()) { + request.GetUrl().AppendQueryParameter( + "snapshot", + _internal::UrlEncodeQueryParameter(options.Snapshot.Value())); + } + if (options.Range.HasValue() && !options.Range.Value().empty()) { + request.SetHeader("x-ms-range", options.Range.Value()); + } + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfMatch.HasValue() && !options.IfMatch.ToString().empty()) { + request.SetHeader("If-Match", options.IfMatch.ToString()); + } + if (options.IfNoneMatch.HasValue() && + !options.IfNoneMatch.ToString().empty()) { + request.SetHeader("If-None-Match", options.IfNoneMatch.ToString()); + } + if (options.IfTags.HasValue() && !options.IfTags.Value().empty()) { + request.SetHeader("x-ms-if-tags", options.IfTags.Value()); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::_detail::GetPageRangesResult response; + { + const auto &responseBody = pRawResponse->GetBody(); + _internal::XmlReader reader( + reinterpret_cast(responseBody.data()), + responseBody.size()); + enum class XmlTagEnum { + kUnknown, + kPageList, + kPageRange, + kStart, + kEnd, + kClearRange, + }; + const std::unordered_map XmlTagEnumMap{ + {"PageList", XmlTagEnum::kPageList}, + {"PageRange", XmlTagEnum::kPageRange}, + {"Start", XmlTagEnum::kStart}, + {"End", XmlTagEnum::kEnd}, + {"ClearRange", XmlTagEnum::kClearRange}, + }; + std::vector xmlPath; + Core::Http::HttpRange vectorElement1; + Core::Http::HttpRange vectorElement2; + while (true) { + auto node = reader.Read(); + if (node.Type == _internal::XmlNodeType::End) { + break; + } else if (node.Type == _internal::XmlNodeType::StartTag) { + auto ite = XmlTagEnumMap.find(node.Name); + xmlPath.push_back(ite == XmlTagEnumMap.end() ? XmlTagEnum::kUnknown + : ite->second); + + } else if (node.Type == _internal::XmlNodeType::Text) { + if (xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kPageList && + xmlPath[1] == XmlTagEnum::kPageRange && + xmlPath[2] == XmlTagEnum::kStart) { + vectorElement1.Offset = std::stoll(node.Value); + } else if (xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kPageList && + xmlPath[1] == XmlTagEnum::kPageRange && + xmlPath[2] == XmlTagEnum::kEnd) { + vectorElement1.Length = std::stoll(node.Value); + } else if (xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kPageList && + xmlPath[1] == XmlTagEnum::kClearRange && + xmlPath[2] == XmlTagEnum::kStart) { + vectorElement2.Offset = std::stoll(node.Value); + } else if (xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kPageList && + xmlPath[1] == XmlTagEnum::kClearRange && + xmlPath[2] == XmlTagEnum::kEnd) { + vectorElement2.Length = std::stoll(node.Value); + } + } else if (node.Type == _internal::XmlNodeType::Attribute) { + + } else if (node.Type == _internal::XmlNodeType::EndTag) { + if (xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kPageList && + xmlPath[1] == XmlTagEnum::kPageRange) { + vectorElement1.Length = + vectorElement1.Length.Value() - vectorElement1.Offset + 1; + response.PageRanges.push_back(std::move(vectorElement1)); + vectorElement1 = Core::Http::HttpRange(); + } else if (xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kPageList && + xmlPath[1] == XmlTagEnum::kClearRange) { + vectorElement2.Length = + vectorElement2.Length.Value() - vectorElement2.Offset + 1; + response.ClearRanges.push_back(std::move(vectorElement2)); + vectorElement2 = Core::Http::HttpRange(); + } + xmlPath.pop_back(); + } + } + } + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.BlobSize = + std::stoll(pRawResponse->GetHeaders().at("x-ms-blob-content-length")); + return Response( + std::move(response), std::move(pRawResponse)); +} +Response +PageBlobClient::GetPageRangesDiff( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const GetPageBlobPageRangesDiffOptions &options, + const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url); + request.GetUrl().AppendQueryParameter("comp", "pagelist"); + if (options.Snapshot.HasValue() && !options.Snapshot.Value().empty()) { + request.GetUrl().AppendQueryParameter( + "snapshot", + _internal::UrlEncodeQueryParameter(options.Snapshot.Value())); + } + if (options.Prevsnapshot.HasValue() && + !options.Prevsnapshot.Value().empty()) { + request.GetUrl().AppendQueryParameter( + "prevsnapshot", + _internal::UrlEncodeQueryParameter(options.Prevsnapshot.Value())); + } + if (options.PrevSnapshotUrl.HasValue() && + !options.PrevSnapshotUrl.Value().empty()) { + request.SetHeader("x-ms-previous-snapshot-url", + options.PrevSnapshotUrl.Value()); + } + if (options.Range.HasValue() && !options.Range.Value().empty()) { + request.SetHeader("x-ms-range", options.Range.Value()); + } + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfMatch.HasValue() && !options.IfMatch.ToString().empty()) { + request.SetHeader("If-Match", options.IfMatch.ToString()); + } + if (options.IfNoneMatch.HasValue() && + !options.IfNoneMatch.ToString().empty()) { + request.SetHeader("If-None-Match", options.IfNoneMatch.ToString()); + } + if (options.IfTags.HasValue() && !options.IfTags.Value().empty()) { + request.SetHeader("x-ms-if-tags", options.IfTags.Value()); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::_detail::GetPageRangesDiffResult response; + { + const auto &responseBody = pRawResponse->GetBody(); + _internal::XmlReader reader( + reinterpret_cast(responseBody.data()), + responseBody.size()); + enum class XmlTagEnum { + kUnknown, + kPageList, + kPageRange, + kStart, + kEnd, + kClearRange, + }; + const std::unordered_map XmlTagEnumMap{ + {"PageList", XmlTagEnum::kPageList}, + {"PageRange", XmlTagEnum::kPageRange}, + {"Start", XmlTagEnum::kStart}, + {"End", XmlTagEnum::kEnd}, + {"ClearRange", XmlTagEnum::kClearRange}, + }; + std::vector xmlPath; + Core::Http::HttpRange vectorElement1; + Core::Http::HttpRange vectorElement2; + while (true) { + auto node = reader.Read(); + if (node.Type == _internal::XmlNodeType::End) { + break; + } else if (node.Type == _internal::XmlNodeType::StartTag) { + auto ite = XmlTagEnumMap.find(node.Name); + xmlPath.push_back(ite == XmlTagEnumMap.end() ? XmlTagEnum::kUnknown + : ite->second); + + } else if (node.Type == _internal::XmlNodeType::Text) { + if (xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kPageList && + xmlPath[1] == XmlTagEnum::kPageRange && + xmlPath[2] == XmlTagEnum::kStart) { + vectorElement1.Offset = std::stoll(node.Value); + } else if (xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kPageList && + xmlPath[1] == XmlTagEnum::kPageRange && + xmlPath[2] == XmlTagEnum::kEnd) { + vectorElement1.Length = std::stoll(node.Value); + } else if (xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kPageList && + xmlPath[1] == XmlTagEnum::kClearRange && + xmlPath[2] == XmlTagEnum::kStart) { + vectorElement2.Offset = std::stoll(node.Value); + } else if (xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kPageList && + xmlPath[1] == XmlTagEnum::kClearRange && + xmlPath[2] == XmlTagEnum::kEnd) { + vectorElement2.Length = std::stoll(node.Value); + } + } else if (node.Type == _internal::XmlNodeType::Attribute) { + + } else if (node.Type == _internal::XmlNodeType::EndTag) { + if (xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kPageList && + xmlPath[1] == XmlTagEnum::kPageRange) { + vectorElement1.Length = + vectorElement1.Length.Value() - vectorElement1.Offset + 1; + response.PageRanges.push_back(std::move(vectorElement1)); + vectorElement1 = Core::Http::HttpRange(); + } else if (xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kPageList && + xmlPath[1] == XmlTagEnum::kClearRange) { + vectorElement2.Length = + vectorElement2.Length.Value() - vectorElement2.Offset + 1; + response.ClearRanges.push_back(std::move(vectorElement2)); + vectorElement2 = Core::Http::HttpRange(); + } + xmlPath.pop_back(); + } + } + } + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.BlobSize = + std::stoll(pRawResponse->GetHeaders().at("x-ms-blob-content-length")); + return Response( + std::move(response), std::move(pRawResponse)); +} +Response PageBlobClient::Resize( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const ResizePageBlobOptions &options, const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.GetUrl().AppendQueryParameter("comp", "properties"); + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + if (options.EncryptionKey.HasValue() && + !options.EncryptionKey.Value().empty()) { + request.SetHeader("x-ms-encryption-key", options.EncryptionKey.Value()); + } + if (options.EncryptionKeySha256.HasValue() && + !Core::Convert::Base64Encode(options.EncryptionKeySha256.Value()) + .empty()) { + request.SetHeader( + "x-ms-encryption-key-sha256", + Core::Convert::Base64Encode(options.EncryptionKeySha256.Value())); + } + if (options.EncryptionAlgorithm.HasValue() && + !options.EncryptionAlgorithm.Value().empty()) { + request.SetHeader("x-ms-encryption-algorithm", + options.EncryptionAlgorithm.Value()); + } + if (options.EncryptionScope.HasValue() && + !options.EncryptionScope.Value().empty()) { + request.SetHeader("x-ms-encryption-scope", options.EncryptionScope.Value()); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfMatch.HasValue() && !options.IfMatch.ToString().empty()) { + request.SetHeader("If-Match", options.IfMatch.ToString()); + } + if (options.IfNoneMatch.HasValue() && + !options.IfNoneMatch.ToString().empty()) { + request.SetHeader("If-None-Match", options.IfNoneMatch.ToString()); + } + if (options.IfTags.HasValue() && !options.IfTags.Value().empty()) { + request.SetHeader("x-ms-if-tags", options.IfTags.Value()); + } + request.SetHeader("x-ms-blob-content-length", + std::to_string(options.BlobContentLength)); + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::ResizePageBlobResult response; + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + response.SequenceNumber = + std::stoll(pRawResponse->GetHeaders().at("x-ms-blob-sequence-number")); + return Response(std::move(response), + std::move(pRawResponse)); +} +Response +PageBlobClient::UpdateSequenceNumber( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const UpdatePageBlobSequenceNumberOptions &options, + const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.GetUrl().AppendQueryParameter("comp", "properties"); + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfMatch.HasValue() && !options.IfMatch.ToString().empty()) { + request.SetHeader("If-Match", options.IfMatch.ToString()); + } + if (options.IfNoneMatch.HasValue() && + !options.IfNoneMatch.ToString().empty()) { + request.SetHeader("If-None-Match", options.IfNoneMatch.ToString()); + } + if (options.IfTags.HasValue() && !options.IfTags.Value().empty()) { + request.SetHeader("x-ms-if-tags", options.IfTags.Value()); + } + if (!options.SequenceNumberAction.ToString().empty()) { + request.SetHeader("x-ms-sequence-number-action", + options.SequenceNumberAction.ToString()); + } + if (options.BlobSequenceNumber.HasValue()) { + request.SetHeader("x-ms-blob-sequence-number", + std::to_string(options.BlobSequenceNumber.Value())); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::UpdateSequenceNumberResult response; + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + response.SequenceNumber = + std::stoll(pRawResponse->GetHeaders().at("x-ms-blob-sequence-number")); + return Response(std::move(response), + std::move(pRawResponse)); +} +Response +PageBlobClient::StartCopyIncremental( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const StartPageBlobCopyIncrementalOptions &options, + const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.GetUrl().AppendQueryParameter("comp", "incrementalcopy"); + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfMatch.HasValue() && !options.IfMatch.ToString().empty()) { + request.SetHeader("If-Match", options.IfMatch.ToString()); + } + if (options.IfNoneMatch.HasValue() && + !options.IfNoneMatch.ToString().empty()) { + request.SetHeader("If-None-Match", options.IfNoneMatch.ToString()); + } + if (options.IfTags.HasValue() && !options.IfTags.Value().empty()) { + request.SetHeader("x-ms-if-tags", options.IfTags.Value()); + } + if (!options.CopySource.empty()) { + request.SetHeader("x-ms-copy-source", options.CopySource); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Accepted) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::_detail::StartBlobCopyIncrementalResult response; + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + response.CopyId = pRawResponse->GetHeaders().at("x-ms-copy-id"); + response.CopyStatus = + Models::CopyStatus(pRawResponse->GetHeaders().at("x-ms-copy-status")); + if (pRawResponse->GetHeaders().count("x-ms-version-id") != 0) { + response.VersionId = pRawResponse->GetHeaders().at("x-ms-version-id"); + } + return Response( + std::move(response), std::move(pRawResponse)); +} +Response AppendBlobClient::Create( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const CreateAppendBlobOptions &options, const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.SetHeader("x-ms-blob-type", "AppendBlob"); + request.SetHeader("Content-Length", "0"); + if (!options.BlobContentType.empty()) { + request.SetHeader("x-ms-blob-content-type", options.BlobContentType); + } + if (!options.BlobContentEncoding.empty()) { + request.SetHeader("x-ms-blob-content-encoding", + options.BlobContentEncoding); + } + if (!options.BlobContentLanguage.empty()) { + request.SetHeader("x-ms-blob-content-language", + options.BlobContentLanguage); + } + if (!Core::Convert::Base64Encode(options.BlobContentMD5).empty()) { + request.SetHeader("x-ms-blob-content-md5", + Core::Convert::Base64Encode(options.BlobContentMD5)); + } + if (!options.BlobCacheControl.empty()) { + request.SetHeader("x-ms-blob-cache-control", options.BlobCacheControl); + } + for (const auto &p : options.Metadata) { + request.SetHeader("x-ms-meta-" + p.first, p.second); + } + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + if (!options.BlobContentDisposition.empty()) { + request.SetHeader("x-ms-blob-content-disposition", + options.BlobContentDisposition); + } + if (options.EncryptionKey.HasValue() && + !options.EncryptionKey.Value().empty()) { + request.SetHeader("x-ms-encryption-key", options.EncryptionKey.Value()); + } + if (options.EncryptionKeySha256.HasValue() && + !Core::Convert::Base64Encode(options.EncryptionKeySha256.Value()) + .empty()) { + request.SetHeader( + "x-ms-encryption-key-sha256", + Core::Convert::Base64Encode(options.EncryptionKeySha256.Value())); + } + if (options.EncryptionAlgorithm.HasValue() && + !options.EncryptionAlgorithm.Value().empty()) { + request.SetHeader("x-ms-encryption-algorithm", + options.EncryptionAlgorithm.Value()); + } + if (options.EncryptionScope.HasValue() && + !options.EncryptionScope.Value().empty()) { + request.SetHeader("x-ms-encryption-scope", options.EncryptionScope.Value()); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfMatch.HasValue() && !options.IfMatch.ToString().empty()) { + request.SetHeader("If-Match", options.IfMatch.ToString()); + } + if (options.IfNoneMatch.HasValue() && + !options.IfNoneMatch.ToString().empty()) { + request.SetHeader("If-None-Match", options.IfNoneMatch.ToString()); + } + if (options.IfTags.HasValue() && !options.IfTags.Value().empty()) { + request.SetHeader("x-ms-if-tags", options.IfTags.Value()); + } + request.SetHeader("x-ms-version", "2020-08-04"); + if (options.BlobTagsString.HasValue() && + !options.BlobTagsString.Value().empty()) { + request.SetHeader("x-ms-tags", options.BlobTagsString.Value()); + } + if (options.ImmutabilityPolicyExpiry.HasValue()) { + request.SetHeader("x-ms-immutability-policy-until-date", + options.ImmutabilityPolicyExpiry.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.ImmutabilityPolicyMode.HasValue() && + !options.ImmutabilityPolicyMode.Value().ToString().empty()) { + request.SetHeader("x-ms-immutability-policy-mode", + options.ImmutabilityPolicyMode.Value().ToString()); + } + if (options.LegalHold.HasValue()) { + request.SetHeader("x-ms-legal-hold", + options.LegalHold.Value() ? "true" : "false"); + } + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Created) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::CreateAppendBlobResult response; + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + if (pRawResponse->GetHeaders().count("x-ms-version-id") != 0) { + response.VersionId = pRawResponse->GetHeaders().at("x-ms-version-id"); + } + response.IsServerEncrypted = + pRawResponse->GetHeaders().at("x-ms-request-server-encrypted") == + std::string("true"); + if (pRawResponse->GetHeaders().count("x-ms-encryption-key-sha256") != 0) { + response.EncryptionKeySha256 = Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("x-ms-encryption-key-sha256")); + } + if (pRawResponse->GetHeaders().count("x-ms-encryption-scope") != 0) { + response.EncryptionScope = + pRawResponse->GetHeaders().at("x-ms-encryption-scope"); + } + return Response(std::move(response), + std::move(pRawResponse)); +} +Response AppendBlobClient::AppendBlock( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + Core::IO::BodyStream &requestBody, + const AppendAppendBlobBlockOptions &options, const Core::Context &context) { + auto request = + Core::Http::Request(Core::Http::HttpMethod::Put, url, &requestBody); + request.GetUrl().AppendQueryParameter("comp", "appendblock"); + request.SetHeader("Content-Length", std::to_string(requestBody.Length())); + if (options.TransactionalContentMD5.HasValue() && + !Core::Convert::Base64Encode(options.TransactionalContentMD5.Value()) + .empty()) { + request.SetHeader( + "Content-MD5", + Core::Convert::Base64Encode(options.TransactionalContentMD5.Value())); + } + if (options.TransactionalContentCrc64.HasValue() && + !Core::Convert::Base64Encode(options.TransactionalContentCrc64.Value()) + .empty()) { + request.SetHeader( + "x-ms-content-crc64", + Core::Convert::Base64Encode(options.TransactionalContentCrc64.Value())); + } + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + if (options.MaxSize.HasValue()) { + request.SetHeader("x-ms-blob-condition-maxsize", + std::to_string(options.MaxSize.Value())); + } + if (options.AppendPosition.HasValue()) { + request.SetHeader("x-ms-blob-condition-appendpos", + std::to_string(options.AppendPosition.Value())); + } + if (options.EncryptionKey.HasValue() && + !options.EncryptionKey.Value().empty()) { + request.SetHeader("x-ms-encryption-key", options.EncryptionKey.Value()); + } + if (options.EncryptionKeySha256.HasValue() && + !Core::Convert::Base64Encode(options.EncryptionKeySha256.Value()) + .empty()) { + request.SetHeader( + "x-ms-encryption-key-sha256", + Core::Convert::Base64Encode(options.EncryptionKeySha256.Value())); + } + if (options.EncryptionAlgorithm.HasValue() && + !options.EncryptionAlgorithm.Value().empty()) { + request.SetHeader("x-ms-encryption-algorithm", + options.EncryptionAlgorithm.Value()); + } + if (options.EncryptionScope.HasValue() && + !options.EncryptionScope.Value().empty()) { + request.SetHeader("x-ms-encryption-scope", options.EncryptionScope.Value()); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfMatch.HasValue() && !options.IfMatch.ToString().empty()) { + request.SetHeader("If-Match", options.IfMatch.ToString()); + } + if (options.IfNoneMatch.HasValue() && + !options.IfNoneMatch.ToString().empty()) { + request.SetHeader("If-None-Match", options.IfNoneMatch.ToString()); + } + if (options.IfTags.HasValue() && !options.IfTags.Value().empty()) { + request.SetHeader("x-ms-if-tags", options.IfTags.Value()); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Created) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::AppendBlockResult response; + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + if (pRawResponse->GetHeaders().count("Content-MD5") != 0) { + response.TransactionalContentHash = ContentHash(); + response.TransactionalContentHash.Value().Value = + Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("Content-MD5")); + response.TransactionalContentHash.Value().Algorithm = HashAlgorithm::Md5; + } + if (pRawResponse->GetHeaders().count("x-ms-content-crc64") != 0) { + response.TransactionalContentHash = ContentHash(); + response.TransactionalContentHash.Value().Value = + Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("x-ms-content-crc64")); + response.TransactionalContentHash.Value().Algorithm = HashAlgorithm::Crc64; + } + response.AppendOffset = + std::stoll(pRawResponse->GetHeaders().at("x-ms-blob-append-offset")); + response.CommittedBlockCount = std::stoi( + pRawResponse->GetHeaders().at("x-ms-blob-committed-block-count")); + response.IsServerEncrypted = + pRawResponse->GetHeaders().at("x-ms-request-server-encrypted") == + std::string("true"); + if (pRawResponse->GetHeaders().count("x-ms-encryption-key-sha256") != 0) { + response.EncryptionKeySha256 = Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("x-ms-encryption-key-sha256")); + } + if (pRawResponse->GetHeaders().count("x-ms-encryption-scope") != 0) { + response.EncryptionScope = + pRawResponse->GetHeaders().at("x-ms-encryption-scope"); + } + return Response(std::move(response), + std::move(pRawResponse)); +} +Response AppendBlobClient::AppendBlockFromUri( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const AppendAppendBlobBlockFromUriOptions &options, + const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.GetUrl().AppendQueryParameter("comp", "appendblock"); + if (!options.SourceUrl.empty()) { + request.SetHeader("x-ms-copy-source", options.SourceUrl); + } + if (options.SourceRange.HasValue() && !options.SourceRange.Value().empty()) { + request.SetHeader("x-ms-source-range", options.SourceRange.Value()); + } + if (options.SourceContentMD5.HasValue() && + !Core::Convert::Base64Encode(options.SourceContentMD5.Value()).empty()) { + request.SetHeader( + "x-ms-source-content-md5", + Core::Convert::Base64Encode(options.SourceContentMD5.Value())); + } + if (options.SourceContentcrc64.HasValue() && + !Core::Convert::Base64Encode(options.SourceContentcrc64.Value()) + .empty()) { + request.SetHeader( + "x-ms-source-content-crc64", + Core::Convert::Base64Encode(options.SourceContentcrc64.Value())); + } + request.SetHeader("Content-Length", "0"); + if (options.TransactionalContentMD5.HasValue() && + !Core::Convert::Base64Encode(options.TransactionalContentMD5.Value()) + .empty()) { + request.SetHeader( + "Content-MD5", + Core::Convert::Base64Encode(options.TransactionalContentMD5.Value())); + } + if (options.EncryptionKey.HasValue() && + !options.EncryptionKey.Value().empty()) { + request.SetHeader("x-ms-encryption-key", options.EncryptionKey.Value()); + } + if (options.EncryptionKeySha256.HasValue() && + !Core::Convert::Base64Encode(options.EncryptionKeySha256.Value()) + .empty()) { + request.SetHeader( + "x-ms-encryption-key-sha256", + Core::Convert::Base64Encode(options.EncryptionKeySha256.Value())); + } + if (options.EncryptionAlgorithm.HasValue() && + !options.EncryptionAlgorithm.Value().empty()) { + request.SetHeader("x-ms-encryption-algorithm", + options.EncryptionAlgorithm.Value()); + } + if (options.EncryptionScope.HasValue() && + !options.EncryptionScope.Value().empty()) { + request.SetHeader("x-ms-encryption-scope", options.EncryptionScope.Value()); + } + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + if (options.MaxSize.HasValue()) { + request.SetHeader("x-ms-blob-condition-maxsize", + std::to_string(options.MaxSize.Value())); + } + if (options.AppendPosition.HasValue()) { + request.SetHeader("x-ms-blob-condition-appendpos", + std::to_string(options.AppendPosition.Value())); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfMatch.HasValue() && !options.IfMatch.ToString().empty()) { + request.SetHeader("If-Match", options.IfMatch.ToString()); + } + if (options.IfNoneMatch.HasValue() && + !options.IfNoneMatch.ToString().empty()) { + request.SetHeader("If-None-Match", options.IfNoneMatch.ToString()); + } + if (options.IfTags.HasValue() && !options.IfTags.Value().empty()) { + request.SetHeader("x-ms-if-tags", options.IfTags.Value()); + } + if (options.SourceIfModifiedSince.HasValue()) { + request.SetHeader("x-ms-source-if-modified-since", + options.SourceIfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.SourceIfUnmodifiedSince.HasValue()) { + request.SetHeader("x-ms-source-if-unmodified-since", + options.SourceIfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.SourceIfMatch.HasValue() && + !options.SourceIfMatch.ToString().empty()) { + request.SetHeader("x-ms-source-if-match", options.SourceIfMatch.ToString()); + } + if (options.SourceIfNoneMatch.HasValue() && + !options.SourceIfNoneMatch.ToString().empty()) { + request.SetHeader("x-ms-source-if-none-match", + options.SourceIfNoneMatch.ToString()); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Created) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::AppendBlockFromUriResult response; + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + if (pRawResponse->GetHeaders().count("Content-MD5") != 0) { + response.TransactionalContentHash = ContentHash(); + response.TransactionalContentHash.Value().Value = + Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("Content-MD5")); + response.TransactionalContentHash.Value().Algorithm = HashAlgorithm::Md5; + } + if (pRawResponse->GetHeaders().count("x-ms-content-crc64") != 0) { + response.TransactionalContentHash = ContentHash(); + response.TransactionalContentHash.Value().Value = + Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("x-ms-content-crc64")); + response.TransactionalContentHash.Value().Algorithm = HashAlgorithm::Crc64; + } + response.AppendOffset = + std::stoll(pRawResponse->GetHeaders().at("x-ms-blob-append-offset")); + response.CommittedBlockCount = std::stoi( + pRawResponse->GetHeaders().at("x-ms-blob-committed-block-count")); + if (pRawResponse->GetHeaders().count("x-ms-encryption-key-sha256") != 0) { + response.EncryptionKeySha256 = Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("x-ms-encryption-key-sha256")); + } + if (pRawResponse->GetHeaders().count("x-ms-encryption-scope") != 0) { + response.EncryptionScope = + pRawResponse->GetHeaders().at("x-ms-encryption-scope"); + } + response.IsServerEncrypted = + pRawResponse->GetHeaders().at("x-ms-request-server-encrypted") == + std::string("true"); + return Response(std::move(response), + std::move(pRawResponse)); +} +Response AppendBlobClient::Seal( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const SealAppendBlobOptions &options, const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.GetUrl().AppendQueryParameter("comp", "seal"); + request.SetHeader("x-ms-version", "2020-08-04"); + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfMatch.HasValue() && !options.IfMatch.ToString().empty()) { + request.SetHeader("If-Match", options.IfMatch.ToString()); + } + if (options.IfNoneMatch.HasValue() && + !options.IfNoneMatch.ToString().empty()) { + request.SetHeader("If-None-Match", options.IfNoneMatch.ToString()); + } + if (options.AppendPosition.HasValue()) { + request.SetHeader("x-ms-blob-condition-appendpos", + std::to_string(options.AppendPosition.Value())); + } + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::SealAppendBlobResult response; + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + response.IsSealed = + pRawResponse->GetHeaders().at("x-ms-blob-sealed") == std::string("true"); + return Response(std::move(response), + std::move(pRawResponse)); +} +Response +BlockBlobClient::Upload(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, Core::IO::BodyStream &requestBody, + const UploadBlockBlobOptions &options, + const Core::Context &context) { + auto request = + Core::Http::Request(Core::Http::HttpMethod::Put, url, &requestBody); + request.SetHeader("x-ms-blob-type", "BlockBlob"); + if (options.TransactionalContentMD5.HasValue() && + !Core::Convert::Base64Encode(options.TransactionalContentMD5.Value()) + .empty()) { + request.SetHeader( + "Content-MD5", + Core::Convert::Base64Encode(options.TransactionalContentMD5.Value())); + } + request.SetHeader("Content-Length", std::to_string(requestBody.Length())); + if (!options.BlobContentType.empty()) { + request.SetHeader("x-ms-blob-content-type", options.BlobContentType); + } + if (!options.BlobContentEncoding.empty()) { + request.SetHeader("x-ms-blob-content-encoding", + options.BlobContentEncoding); + } + if (!options.BlobContentLanguage.empty()) { + request.SetHeader("x-ms-blob-content-language", + options.BlobContentLanguage); + } + if (!Core::Convert::Base64Encode(options.BlobContentMD5).empty()) { + request.SetHeader("x-ms-blob-content-md5", + Core::Convert::Base64Encode(options.BlobContentMD5)); + } + if (!options.BlobCacheControl.empty()) { + request.SetHeader("x-ms-blob-cache-control", options.BlobCacheControl); + } + for (const auto &p : options.Metadata) { + request.SetHeader("x-ms-meta-" + p.first, p.second); + } + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + if (!options.BlobContentDisposition.empty()) { + request.SetHeader("x-ms-blob-content-disposition", + options.BlobContentDisposition); + } + if (options.EncryptionKey.HasValue() && + !options.EncryptionKey.Value().empty()) { + request.SetHeader("x-ms-encryption-key", options.EncryptionKey.Value()); + } + if (options.EncryptionKeySha256.HasValue() && + !Core::Convert::Base64Encode(options.EncryptionKeySha256.Value()) + .empty()) { + request.SetHeader( + "x-ms-encryption-key-sha256", + Core::Convert::Base64Encode(options.EncryptionKeySha256.Value())); + } + if (options.EncryptionAlgorithm.HasValue() && + !options.EncryptionAlgorithm.Value().empty()) { + request.SetHeader("x-ms-encryption-algorithm", + options.EncryptionAlgorithm.Value()); + } + if (options.EncryptionScope.HasValue() && + !options.EncryptionScope.Value().empty()) { + request.SetHeader("x-ms-encryption-scope", options.EncryptionScope.Value()); + } + if (options.Tier.HasValue() && !options.Tier.Value().ToString().empty()) { + request.SetHeader("x-ms-access-tier", options.Tier.Value().ToString()); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfMatch.HasValue() && !options.IfMatch.ToString().empty()) { + request.SetHeader("If-Match", options.IfMatch.ToString()); + } + if (options.IfNoneMatch.HasValue() && + !options.IfNoneMatch.ToString().empty()) { + request.SetHeader("If-None-Match", options.IfNoneMatch.ToString()); + } + if (options.IfTags.HasValue() && !options.IfTags.Value().empty()) { + request.SetHeader("x-ms-if-tags", options.IfTags.Value()); + } + request.SetHeader("x-ms-version", "2020-08-04"); + if (options.BlobTagsString.HasValue() && + !options.BlobTagsString.Value().empty()) { + request.SetHeader("x-ms-tags", options.BlobTagsString.Value()); + } + if (options.ImmutabilityPolicyExpiry.HasValue()) { + request.SetHeader("x-ms-immutability-policy-until-date", + options.ImmutabilityPolicyExpiry.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.ImmutabilityPolicyMode.HasValue() && + !options.ImmutabilityPolicyMode.Value().ToString().empty()) { + request.SetHeader("x-ms-immutability-policy-mode", + options.ImmutabilityPolicyMode.Value().ToString()); + } + if (options.LegalHold.HasValue()) { + request.SetHeader("x-ms-legal-hold", + options.LegalHold.Value() ? "true" : "false"); + } + if (options.TransactionalContentCrc64.HasValue() && + !Core::Convert::Base64Encode(options.TransactionalContentCrc64.Value()) + .empty()) { + request.SetHeader( + "x-ms-content-crc64", + Core::Convert::Base64Encode(options.TransactionalContentCrc64.Value())); + } + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Created) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::UploadBlockBlobResult response; + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + if (pRawResponse->GetHeaders().count("Content-MD5") != 0) { + response.TransactionalContentHash = ContentHash(); + response.TransactionalContentHash.Value().Value = + Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("Content-MD5")); + response.TransactionalContentHash.Value().Algorithm = HashAlgorithm::Md5; + } + if (pRawResponse->GetHeaders().count("x-ms-version-id") != 0) { + response.VersionId = pRawResponse->GetHeaders().at("x-ms-version-id"); + } + response.IsServerEncrypted = + pRawResponse->GetHeaders().at("x-ms-request-server-encrypted") == + std::string("true"); + if (pRawResponse->GetHeaders().count("x-ms-encryption-key-sha256") != 0) { + response.EncryptionKeySha256 = Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("x-ms-encryption-key-sha256")); + } + if (pRawResponse->GetHeaders().count("x-ms-encryption-scope") != 0) { + response.EncryptionScope = + pRawResponse->GetHeaders().at("x-ms-encryption-scope"); + } + if (pRawResponse->GetHeaders().count("x-ms-content-crc64") != 0) { + response.TransactionalContentHash = ContentHash(); + response.TransactionalContentHash.Value().Value = + Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("x-ms-content-crc64")); + response.TransactionalContentHash.Value().Algorithm = HashAlgorithm::Crc64; + } + return Response(std::move(response), + std::move(pRawResponse)); +} +Response +BlockBlobClient::UploadFromUri(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const UploadBlockBlobFromUriOptions &options, + const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.SetHeader("x-ms-blob-type", "BlockBlob"); + request.SetHeader("Content-Length", "0"); + if (!options.BlobContentType.empty()) { + request.SetHeader("x-ms-blob-content-type", options.BlobContentType); + } + if (!options.BlobContentEncoding.empty()) { + request.SetHeader("x-ms-blob-content-encoding", + options.BlobContentEncoding); + } + if (!options.BlobContentLanguage.empty()) { + request.SetHeader("x-ms-blob-content-language", + options.BlobContentLanguage); + } + if (!Core::Convert::Base64Encode(options.BlobContentMD5).empty()) { + request.SetHeader("x-ms-blob-content-md5", + Core::Convert::Base64Encode(options.BlobContentMD5)); + } + if (!options.BlobCacheControl.empty()) { + request.SetHeader("x-ms-blob-cache-control", options.BlobCacheControl); + } + for (const auto &p : options.Metadata) { + request.SetHeader("x-ms-meta-" + p.first, p.second); + } + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + if (!options.BlobContentDisposition.empty()) { + request.SetHeader("x-ms-blob-content-disposition", + options.BlobContentDisposition); + } + if (options.EncryptionKey.HasValue() && + !options.EncryptionKey.Value().empty()) { + request.SetHeader("x-ms-encryption-key", options.EncryptionKey.Value()); + } + if (options.EncryptionKeySha256.HasValue() && + !Core::Convert::Base64Encode(options.EncryptionKeySha256.Value()) + .empty()) { + request.SetHeader( + "x-ms-encryption-key-sha256", + Core::Convert::Base64Encode(options.EncryptionKeySha256.Value())); + } + if (options.EncryptionAlgorithm.HasValue() && + !options.EncryptionAlgorithm.Value().empty()) { + request.SetHeader("x-ms-encryption-algorithm", + options.EncryptionAlgorithm.Value()); + } + if (options.EncryptionScope.HasValue() && + !options.EncryptionScope.Value().empty()) { + request.SetHeader("x-ms-encryption-scope", options.EncryptionScope.Value()); + } + if (options.Tier.HasValue() && !options.Tier.Value().ToString().empty()) { + request.SetHeader("x-ms-access-tier", options.Tier.Value().ToString()); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfMatch.HasValue() && !options.IfMatch.ToString().empty()) { + request.SetHeader("If-Match", options.IfMatch.ToString()); + } + if (options.IfNoneMatch.HasValue() && + !options.IfNoneMatch.ToString().empty()) { + request.SetHeader("If-None-Match", options.IfNoneMatch.ToString()); + } + if (options.IfTags.HasValue() && !options.IfTags.Value().empty()) { + request.SetHeader("x-ms-if-tags", options.IfTags.Value()); + } + if (options.SourceIfModifiedSince.HasValue()) { + request.SetHeader("x-ms-source-if-modified-since", + options.SourceIfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.SourceIfUnmodifiedSince.HasValue()) { + request.SetHeader("x-ms-source-if-unmodified-since", + options.SourceIfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.SourceIfMatch.HasValue() && + !options.SourceIfMatch.ToString().empty()) { + request.SetHeader("x-ms-source-if-match", options.SourceIfMatch.ToString()); + } + if (options.SourceIfNoneMatch.HasValue() && + !options.SourceIfNoneMatch.ToString().empty()) { + request.SetHeader("x-ms-source-if-none-match", + options.SourceIfNoneMatch.ToString()); + } + if (options.SourceIfTags.HasValue() && + !options.SourceIfTags.Value().empty()) { + request.SetHeader("x-ms-source-if-tags", options.SourceIfTags.Value()); + } + request.SetHeader("x-ms-version", "2020-08-04"); + if (options.SourceContentMD5.HasValue() && + !Core::Convert::Base64Encode(options.SourceContentMD5.Value()).empty()) { + request.SetHeader( + "x-ms-source-content-md5", + Core::Convert::Base64Encode(options.SourceContentMD5.Value())); + } + if (options.BlobTagsString.HasValue() && + !options.BlobTagsString.Value().empty()) { + request.SetHeader("x-ms-tags", options.BlobTagsString.Value()); + } + if (!options.CopySource.empty()) { + request.SetHeader("x-ms-copy-source", options.CopySource); + } + if (options.CopySourceBlobProperties.HasValue()) { + request.SetHeader("x-ms-copy-source-blob-properties", + options.CopySourceBlobProperties.Value() ? "true" + : "false"); + } + if (options.SourceContentcrc64.HasValue() && + !Core::Convert::Base64Encode(options.SourceContentcrc64.Value()) + .empty()) { + request.SetHeader( + "x-ms-source-content-crc64", + Core::Convert::Base64Encode(options.SourceContentcrc64.Value())); + } + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Created) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::UploadBlockBlobFromUriResult response; + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + if (pRawResponse->GetHeaders().count("Content-MD5") != 0) { + response.TransactionalContentHash = ContentHash(); + response.TransactionalContentHash.Value().Value = + Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("Content-MD5")); + response.TransactionalContentHash.Value().Algorithm = HashAlgorithm::Md5; + } + if (pRawResponse->GetHeaders().count("x-ms-version-id") != 0) { + response.VersionId = pRawResponse->GetHeaders().at("x-ms-version-id"); + } + response.IsServerEncrypted = + pRawResponse->GetHeaders().at("x-ms-request-server-encrypted") == + std::string("true"); + if (pRawResponse->GetHeaders().count("x-ms-encryption-key-sha256") != 0) { + response.EncryptionKeySha256 = Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("x-ms-encryption-key-sha256")); + } + if (pRawResponse->GetHeaders().count("x-ms-encryption-scope") != 0) { + response.EncryptionScope = + pRawResponse->GetHeaders().at("x-ms-encryption-scope"); + } + if (pRawResponse->GetHeaders().count("x-ms-content-crc64") != 0) { + response.TransactionalContentHash = ContentHash(); + response.TransactionalContentHash.Value().Value = + Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("x-ms-content-crc64")); + response.TransactionalContentHash.Value().Algorithm = HashAlgorithm::Crc64; + } + return Response( + std::move(response), std::move(pRawResponse)); +} +Response BlockBlobClient::StageBlock( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + Core::IO::BodyStream &requestBody, + const StageBlockBlobBlockOptions &options, const Core::Context &context) { + auto request = + Core::Http::Request(Core::Http::HttpMethod::Put, url, &requestBody); + request.GetUrl().AppendQueryParameter("comp", "block"); + if (!options.BlockId.empty()) { + request.GetUrl().AppendQueryParameter( + "blockid", _internal::UrlEncodeQueryParameter(options.BlockId)); + } + request.SetHeader("Content-Length", std::to_string(requestBody.Length())); + if (options.TransactionalContentMD5.HasValue() && + !Core::Convert::Base64Encode(options.TransactionalContentMD5.Value()) + .empty()) { + request.SetHeader( + "Content-MD5", + Core::Convert::Base64Encode(options.TransactionalContentMD5.Value())); + } + if (options.TransactionalContentCrc64.HasValue() && + !Core::Convert::Base64Encode(options.TransactionalContentCrc64.Value()) + .empty()) { + request.SetHeader( + "x-ms-content-crc64", + Core::Convert::Base64Encode(options.TransactionalContentCrc64.Value())); + } + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + if (options.EncryptionKey.HasValue() && + !options.EncryptionKey.Value().empty()) { + request.SetHeader("x-ms-encryption-key", options.EncryptionKey.Value()); + } + if (options.EncryptionKeySha256.HasValue() && + !Core::Convert::Base64Encode(options.EncryptionKeySha256.Value()) + .empty()) { + request.SetHeader( + "x-ms-encryption-key-sha256", + Core::Convert::Base64Encode(options.EncryptionKeySha256.Value())); + } + if (options.EncryptionAlgorithm.HasValue() && + !options.EncryptionAlgorithm.Value().empty()) { + request.SetHeader("x-ms-encryption-algorithm", + options.EncryptionAlgorithm.Value()); + } + if (options.EncryptionScope.HasValue() && + !options.EncryptionScope.Value().empty()) { + request.SetHeader("x-ms-encryption-scope", options.EncryptionScope.Value()); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Created) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::StageBlockResult response; + if (pRawResponse->GetHeaders().count("Content-MD5") != 0) { + response.TransactionalContentHash = ContentHash(); + response.TransactionalContentHash.Value().Value = + Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("Content-MD5")); + response.TransactionalContentHash.Value().Algorithm = HashAlgorithm::Md5; + } + if (pRawResponse->GetHeaders().count("x-ms-content-crc64") != 0) { + response.TransactionalContentHash = ContentHash(); + response.TransactionalContentHash.Value().Value = + Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("x-ms-content-crc64")); + response.TransactionalContentHash.Value().Algorithm = HashAlgorithm::Crc64; + } + response.IsServerEncrypted = + pRawResponse->GetHeaders().at("x-ms-request-server-encrypted") == + std::string("true"); + if (pRawResponse->GetHeaders().count("x-ms-encryption-key-sha256") != 0) { + response.EncryptionKeySha256 = Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("x-ms-encryption-key-sha256")); + } + if (pRawResponse->GetHeaders().count("x-ms-encryption-scope") != 0) { + response.EncryptionScope = + pRawResponse->GetHeaders().at("x-ms-encryption-scope"); + } + return Response(std::move(response), + std::move(pRawResponse)); +} +Response BlockBlobClient::StageBlockFromUri( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const StageBlockBlobBlockFromUriOptions &options, + const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.GetUrl().AppendQueryParameter("comp", "block"); + if (!options.BlockId.empty()) { + request.GetUrl().AppendQueryParameter( + "blockid", _internal::UrlEncodeQueryParameter(options.BlockId)); + } + request.SetHeader("Content-Length", "0"); + if (!options.SourceUrl.empty()) { + request.SetHeader("x-ms-copy-source", options.SourceUrl); + } + if (options.SourceRange.HasValue() && !options.SourceRange.Value().empty()) { + request.SetHeader("x-ms-source-range", options.SourceRange.Value()); + } + if (options.SourceContentMD5.HasValue() && + !Core::Convert::Base64Encode(options.SourceContentMD5.Value()).empty()) { + request.SetHeader( + "x-ms-source-content-md5", + Core::Convert::Base64Encode(options.SourceContentMD5.Value())); + } + if (options.SourceContentcrc64.HasValue() && + !Core::Convert::Base64Encode(options.SourceContentcrc64.Value()) + .empty()) { + request.SetHeader( + "x-ms-source-content-crc64", + Core::Convert::Base64Encode(options.SourceContentcrc64.Value())); + } + if (options.EncryptionKey.HasValue() && + !options.EncryptionKey.Value().empty()) { + request.SetHeader("x-ms-encryption-key", options.EncryptionKey.Value()); + } + if (options.EncryptionKeySha256.HasValue() && + !Core::Convert::Base64Encode(options.EncryptionKeySha256.Value()) + .empty()) { + request.SetHeader( + "x-ms-encryption-key-sha256", + Core::Convert::Base64Encode(options.EncryptionKeySha256.Value())); + } + if (options.EncryptionAlgorithm.HasValue() && + !options.EncryptionAlgorithm.Value().empty()) { + request.SetHeader("x-ms-encryption-algorithm", + options.EncryptionAlgorithm.Value()); + } + if (options.EncryptionScope.HasValue() && + !options.EncryptionScope.Value().empty()) { + request.SetHeader("x-ms-encryption-scope", options.EncryptionScope.Value()); + } + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + if (options.SourceIfModifiedSince.HasValue()) { + request.SetHeader("x-ms-source-if-modified-since", + options.SourceIfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.SourceIfUnmodifiedSince.HasValue()) { + request.SetHeader("x-ms-source-if-unmodified-since", + options.SourceIfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.SourceIfMatch.HasValue() && + !options.SourceIfMatch.ToString().empty()) { + request.SetHeader("x-ms-source-if-match", options.SourceIfMatch.ToString()); + } + if (options.SourceIfNoneMatch.HasValue() && + !options.SourceIfNoneMatch.ToString().empty()) { + request.SetHeader("x-ms-source-if-none-match", + options.SourceIfNoneMatch.ToString()); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Created) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::StageBlockFromUriResult response; + if (pRawResponse->GetHeaders().count("Content-MD5") != 0) { + response.TransactionalContentHash = ContentHash(); + response.TransactionalContentHash.Value().Value = + Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("Content-MD5")); + response.TransactionalContentHash.Value().Algorithm = HashAlgorithm::Md5; + } + if (pRawResponse->GetHeaders().count("x-ms-content-crc64") != 0) { + response.TransactionalContentHash = ContentHash(); + response.TransactionalContentHash.Value().Value = + Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("x-ms-content-crc64")); + response.TransactionalContentHash.Value().Algorithm = HashAlgorithm::Crc64; + } + response.IsServerEncrypted = + pRawResponse->GetHeaders().at("x-ms-request-server-encrypted") == + std::string("true"); + if (pRawResponse->GetHeaders().count("x-ms-encryption-key-sha256") != 0) { + response.EncryptionKeySha256 = Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("x-ms-encryption-key-sha256")); + } + if (pRawResponse->GetHeaders().count("x-ms-encryption-scope") != 0) { + response.EncryptionScope = + pRawResponse->GetHeaders().at("x-ms-encryption-scope"); + } + return Response(std::move(response), + std::move(pRawResponse)); +} +Response +BlockBlobClient::CommitBlockList(Core::Http::_internal::HttpPipeline &pipeline, + const Core::Url &url, + const CommitBlockBlobBlockListOptions &options, + const Core::Context &context) { + std::string xmlBody; + { + _internal::XmlWriter writer; + writer.Write( + _internal::XmlNode{_internal::XmlNodeType::StartTag, "BlockList"}); + for (const auto &i1 : options.Blocks.Committed) { + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, + "Committed", i1}); + } + for (const auto &i2 : options.Blocks.Uncommitted) { + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, + "Uncommitted", i2}); + } + for (const auto &i3 : options.Blocks.Latest) { + writer.Write( + _internal::XmlNode{_internal::XmlNodeType::StartTag, "Latest", i3}); + } + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::End}); + xmlBody = writer.GetDocument(); + } + Core::IO::MemoryBodyStream requestBody( + reinterpret_cast(xmlBody.data()), xmlBody.length()); + auto request = + Core::Http::Request(Core::Http::HttpMethod::Put, url, &requestBody); + request.SetHeader("Content-Type", "application/xml; charset=UTF-8"); + request.SetHeader("Content-Length", std::to_string(requestBody.Length())); + request.GetUrl().AppendQueryParameter("comp", "blocklist"); + if (!options.BlobCacheControl.empty()) { + request.SetHeader("x-ms-blob-cache-control", options.BlobCacheControl); + } + if (!options.BlobContentType.empty()) { + request.SetHeader("x-ms-blob-content-type", options.BlobContentType); + } + if (!options.BlobContentEncoding.empty()) { + request.SetHeader("x-ms-blob-content-encoding", + options.BlobContentEncoding); + } + if (!options.BlobContentLanguage.empty()) { + request.SetHeader("x-ms-blob-content-language", + options.BlobContentLanguage); + } + if (!Core::Convert::Base64Encode(options.BlobContentMD5).empty()) { + request.SetHeader("x-ms-blob-content-md5", + Core::Convert::Base64Encode(options.BlobContentMD5)); + } + if (options.TransactionalContentMD5.HasValue() && + !Core::Convert::Base64Encode(options.TransactionalContentMD5.Value()) + .empty()) { + request.SetHeader( + "Content-MD5", + Core::Convert::Base64Encode(options.TransactionalContentMD5.Value())); + } + if (options.TransactionalContentCrc64.HasValue() && + !Core::Convert::Base64Encode(options.TransactionalContentCrc64.Value()) + .empty()) { + request.SetHeader( + "x-ms-content-crc64", + Core::Convert::Base64Encode(options.TransactionalContentCrc64.Value())); + } + for (const auto &p : options.Metadata) { + request.SetHeader("x-ms-meta-" + p.first, p.second); + } + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + if (!options.BlobContentDisposition.empty()) { + request.SetHeader("x-ms-blob-content-disposition", + options.BlobContentDisposition); + } + if (options.EncryptionKey.HasValue() && + !options.EncryptionKey.Value().empty()) { + request.SetHeader("x-ms-encryption-key", options.EncryptionKey.Value()); + } + if (options.EncryptionKeySha256.HasValue() && + !Core::Convert::Base64Encode(options.EncryptionKeySha256.Value()) + .empty()) { + request.SetHeader( + "x-ms-encryption-key-sha256", + Core::Convert::Base64Encode(options.EncryptionKeySha256.Value())); + } + if (options.EncryptionAlgorithm.HasValue() && + !options.EncryptionAlgorithm.Value().empty()) { + request.SetHeader("x-ms-encryption-algorithm", + options.EncryptionAlgorithm.Value()); + } + if (options.EncryptionScope.HasValue() && + !options.EncryptionScope.Value().empty()) { + request.SetHeader("x-ms-encryption-scope", options.EncryptionScope.Value()); + } + if (options.Tier.HasValue() && !options.Tier.Value().ToString().empty()) { + request.SetHeader("x-ms-access-tier", options.Tier.Value().ToString()); + } + if (options.IfModifiedSince.HasValue()) { + request.SetHeader("If-Modified-Since", + options.IfModifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfUnmodifiedSince.HasValue()) { + request.SetHeader("If-Unmodified-Since", + options.IfUnmodifiedSince.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.IfMatch.HasValue() && !options.IfMatch.ToString().empty()) { + request.SetHeader("If-Match", options.IfMatch.ToString()); + } + if (options.IfNoneMatch.HasValue() && + !options.IfNoneMatch.ToString().empty()) { + request.SetHeader("If-None-Match", options.IfNoneMatch.ToString()); + } + if (options.IfTags.HasValue() && !options.IfTags.Value().empty()) { + request.SetHeader("x-ms-if-tags", options.IfTags.Value()); + } + request.SetHeader("x-ms-version", "2020-08-04"); + if (options.BlobTagsString.HasValue() && + !options.BlobTagsString.Value().empty()) { + request.SetHeader("x-ms-tags", options.BlobTagsString.Value()); + } + if (options.ImmutabilityPolicyExpiry.HasValue()) { + request.SetHeader("x-ms-immutability-policy-until-date", + options.ImmutabilityPolicyExpiry.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123)); + } + if (options.ImmutabilityPolicyMode.HasValue() && + !options.ImmutabilityPolicyMode.Value().ToString().empty()) { + request.SetHeader("x-ms-immutability-policy-mode", + options.ImmutabilityPolicyMode.Value().ToString()); + } + if (options.LegalHold.HasValue()) { + request.SetHeader("x-ms-legal-hold", + options.LegalHold.Value() ? "true" : "false"); + } + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Created) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::CommitBlockListResult response; + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + if (pRawResponse->GetHeaders().count("Content-MD5") != 0) { + response.TransactionalContentHash = ContentHash(); + response.TransactionalContentHash.Value().Value = + Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("Content-MD5")); + response.TransactionalContentHash.Value().Algorithm = HashAlgorithm::Md5; + } + if (pRawResponse->GetHeaders().count("x-ms-content-crc64") != 0) { + response.TransactionalContentHash = ContentHash(); + response.TransactionalContentHash.Value().Value = + Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("x-ms-content-crc64")); + response.TransactionalContentHash.Value().Algorithm = HashAlgorithm::Crc64; + } + if (pRawResponse->GetHeaders().count("x-ms-version-id") != 0) { + response.VersionId = pRawResponse->GetHeaders().at("x-ms-version-id"); + } + response.IsServerEncrypted = + pRawResponse->GetHeaders().at("x-ms-request-server-encrypted") == + std::string("true"); + if (pRawResponse->GetHeaders().count("x-ms-encryption-key-sha256") != 0) { + response.EncryptionKeySha256 = Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("x-ms-encryption-key-sha256")); + } + if (pRawResponse->GetHeaders().count("x-ms-encryption-scope") != 0) { + response.EncryptionScope = + pRawResponse->GetHeaders().at("x-ms-encryption-scope"); + } + return Response(std::move(response), + std::move(pRawResponse)); +} +Response BlockBlobClient::GetBlockList( + Core::Http::_internal::HttpPipeline &pipeline, const Core::Url &url, + const GetBlockBlobBlockListOptions &options, const Core::Context &context) { + auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url); + request.GetUrl().AppendQueryParameter("comp", "blocklist"); + if (options.Snapshot.HasValue() && !options.Snapshot.Value().empty()) { + request.GetUrl().AppendQueryParameter( + "snapshot", + _internal::UrlEncodeQueryParameter(options.Snapshot.Value())); + } + if (!options.ListType.ToString().empty()) { + request.GetUrl().AppendQueryParameter( + "blocklisttype", + _internal::UrlEncodeQueryParameter(options.ListType.ToString())); + } + if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { + request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); + } + if (options.IfTags.HasValue() && !options.IfTags.Value().empty()) { + request.SetHeader("x-ms-if-tags", options.IfTags.Value()); + } + request.SetHeader("x-ms-version", "2020-08-04"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::GetBlockListResult response; + { + const auto &responseBody = pRawResponse->GetBody(); + _internal::XmlReader reader( + reinterpret_cast(responseBody.data()), + responseBody.size()); + enum class XmlTagEnum { + kUnknown, + kBlockList, + kCommittedBlocks, + kBlock, + kName, + kSize, + kUncommittedBlocks, + }; + const std::unordered_map XmlTagEnumMap{ + {"BlockList", XmlTagEnum::kBlockList}, + {"CommittedBlocks", XmlTagEnum::kCommittedBlocks}, + {"Block", XmlTagEnum::kBlock}, + {"Name", XmlTagEnum::kName}, + {"Size", XmlTagEnum::kSize}, + {"UncommittedBlocks", XmlTagEnum::kUncommittedBlocks}, + }; + std::vector xmlPath; + Models::BlobBlock vectorElement1; + Models::BlobBlock vectorElement2; + while (true) { + auto node = reader.Read(); + if (node.Type == _internal::XmlNodeType::End) { + break; + } else if (node.Type == _internal::XmlNodeType::StartTag) { + auto ite = XmlTagEnumMap.find(node.Name); + xmlPath.push_back(ite == XmlTagEnumMap.end() ? XmlTagEnum::kUnknown + : ite->second); + + } else if (node.Type == _internal::XmlNodeType::Text) { + if (xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kBlockList && + xmlPath[1] == XmlTagEnum::kCommittedBlocks && + xmlPath[2] == XmlTagEnum::kBlock && + xmlPath[3] == XmlTagEnum::kName) { + vectorElement1.Name = node.Value; + } else if (xmlPath.size() == 4 && + xmlPath[0] == XmlTagEnum::kBlockList && + xmlPath[1] == XmlTagEnum::kCommittedBlocks && + xmlPath[2] == XmlTagEnum::kBlock && + xmlPath[3] == XmlTagEnum::kSize) { + vectorElement1.Size = std::stoll(node.Value); + } else if (xmlPath.size() == 4 && + xmlPath[0] == XmlTagEnum::kBlockList && + xmlPath[1] == XmlTagEnum::kUncommittedBlocks && + xmlPath[2] == XmlTagEnum::kBlock && + xmlPath[3] == XmlTagEnum::kName) { + vectorElement2.Name = node.Value; + } else if (xmlPath.size() == 4 && + xmlPath[0] == XmlTagEnum::kBlockList && + xmlPath[1] == XmlTagEnum::kUncommittedBlocks && + xmlPath[2] == XmlTagEnum::kBlock && + xmlPath[3] == XmlTagEnum::kSize) { + vectorElement2.Size = std::stoll(node.Value); + } + } else if (node.Type == _internal::XmlNodeType::Attribute) { + + } else if (node.Type == _internal::XmlNodeType::EndTag) { + if (xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kBlockList && + xmlPath[1] == XmlTagEnum::kCommittedBlocks && + xmlPath[2] == XmlTagEnum::kBlock) { + response.CommittedBlocks.push_back(std::move(vectorElement1)); + vectorElement1 = Models::BlobBlock(); + } else if (xmlPath.size() == 3 && + xmlPath[0] == XmlTagEnum::kBlockList && + xmlPath[1] == XmlTagEnum::kUncommittedBlocks && + xmlPath[2] == XmlTagEnum::kBlock) { + response.UncommittedBlocks.push_back(std::move(vectorElement2)); + vectorElement2 = Models::BlobBlock(); + } + xmlPath.pop_back(); + } + } + } + if (pRawResponse->GetHeaders().count("Last-Modified") != 0) { + response.LastModified = + DateTime::Parse(pRawResponse->GetHeaders().at("Last-Modified"), + Azure::DateTime::DateFormat::Rfc1123); + } + if (pRawResponse->GetHeaders().count("ETag") != 0) { + response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); + } + if (pRawResponse->GetHeaders().count("x-ms-blob-content-length") != 0) { + response.BlobSize = + std::stoll(pRawResponse->GetHeaders().at("x-ms-blob-content-length")); + } + return Response(std::move(response), + std::move(pRawResponse)); +} +} // namespace _detail +} // namespace Blobs +} // namespace Storage +} // namespace Azure \ No newline at end of file diff --git a/sdk/template/azure-template/src/template_client.cpp b/sdk/template/azure-template/src/template_client.cpp index cb1e74e4c..6c5cd2c79 100644 --- a/sdk/template/azure-template/src/template_client.cpp +++ b/sdk/template/azure-template/src/template_client.cpp @@ -10,15 +10,15 @@ using namespace Azure::Template; using namespace Azure::Template::_detail; -TemplateClient::TemplateClient(TemplateClientOptions const& options) - : m_tracingFactory(options, "Template", PackageVersion::ToString()) +// TemplateClient::TemplateClient(TemplateClientOptions const& options) +// : m_tracingFactory(options, "Template", PackageVersion::ToString()) -{ -} +// { +// } -int TemplateClient::GetValue(int key, Azure::Core::Context const& context) const +int TemplateClient::GetValue(int key, Azure::Core::Context const&) const { - auto tracingContext = m_tracingFactory.CreateTracingContext("GetValue", context); + // auto tracingContext = m_tracingFactory.CreateTracingContext("GetValue", context); try { @@ -60,7 +60,7 @@ int TemplateClient::GetValue(int key, Azure::Core::Context const& context) const } catch (std::exception const& e) { - tracingContext.Span.AddEvent(e); + // tracingContext.Span.AddEvent(e); throw; } } diff --git a/sdk/template/azure-template/vcpkg.json b/sdk/template/azure-template/vcpkg.json index 27a6d5e1b..e46938c89 100644 --- a/sdk/template/azure-template/vcpkg.json +++ b/sdk/template/azure-template/vcpkg.json @@ -5,6 +5,9 @@ { "name": "azure-core-cpp" }, + { + "name": "azure-storage-common-cpp" + }, { "name": "vcpkg-cmake", "host": true