diff --git a/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/protocol/datalake_rest_client.hpp b/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/protocol/datalake_rest_client.hpp index 74a305cdf..bad48ba22 100644 --- a/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/protocol/datalake_rest_client.hpp +++ b/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/protocol/datalake_rest_client.hpp @@ -43,10 +43,9 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { constexpr static const char* c_QueryResource = "resource"; constexpr static const char* c_QueryPathResourceType = "resource"; constexpr static const char* c_QueryPathRenameMode = "mode"; - constexpr static const char* c_QueryPathUpdateAction = "action"; - constexpr static const char* c_QueryMaxRecords = "maxrecords"; constexpr static const char* c_QueryPathGetPropertiesAction = "action"; constexpr static const char* c_QueryAction = "action"; + constexpr static const char* c_QueryMaxRecords = "maxrecords"; constexpr static const char* c_QueryComp = "comp"; constexpr static const char* c_HeaderApiVersionParameter = "x-ms-version"; constexpr static const char* c_HeaderClientRequestId = "x-ms-client-request-id"; @@ -91,9 +90,6 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { constexpr static const char* c_HeaderLastModified = "last-modified"; constexpr static const char* c_HeaderXMsNamespaceEnabled = "x-ms-namespace-enabled"; constexpr static const char* c_HeaderXMsProperties = "x-ms-properties"; - constexpr static const char* c_HeaderAcceptRanges = "accept-ranges"; - constexpr static const char* c_HeaderContentRange = "content-range"; - constexpr static const char* c_HeaderContentMD5 = "content-md5"; constexpr static const char* c_HeaderPathLeaseAction = "x-ms-lease-action"; constexpr static const char* c_HeaderXMsLeaseDuration = "x-ms-lease-duration"; constexpr static const char* c_HeaderXMsLeaseBreakPeriod = "x-ms-lease-break-period"; @@ -101,6 +97,9 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { constexpr static const char* c_HeaderXMsLeaseTime = "x-ms-lease-time"; constexpr static const char* c_HeaderRange = "range"; constexpr static const char* c_HeaderXMsRangeGetContentMd5 = "x-ms-range-get-content-md5"; + constexpr static const char* c_HeaderAcceptRanges = "accept-ranges"; + constexpr static const char* c_HeaderContentRange = "content-range"; + constexpr static const char* c_HeaderContentMD5 = "content-md5"; constexpr static const char* c_HeaderXMsResourceType = "x-ms-resource-type"; constexpr static const char* c_HeaderXMsLeaseState = "x-ms-lease-state"; constexpr static const char* c_HeaderXMsLeaseStatus = "x-ms-lease-status"; @@ -132,42 +131,6 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { Unknown }; - inline std::string PathSetAccessControlRecursiveModeToString( - const PathSetAccessControlRecursiveMode& pathSetAccessControlRecursiveMode) - { - switch (pathSetAccessControlRecursiveMode) - { - case PathSetAccessControlRecursiveMode::Set: - return "set"; - case PathSetAccessControlRecursiveMode::Modify: - return "modify"; - case PathSetAccessControlRecursiveMode::Remove: - return "remove"; - default: - return std::string(); - } - } - - inline PathSetAccessControlRecursiveMode PathSetAccessControlRecursiveModeFromString( - const std::string& pathSetAccessControlRecursiveMode) - { - if (pathSetAccessControlRecursiveMode == "set") - { - return PathSetAccessControlRecursiveMode::Set; - } - if (pathSetAccessControlRecursiveMode == "modify") - { - return PathSetAccessControlRecursiveMode::Modify; - } - if (pathSetAccessControlRecursiveMode == "remove") - { - return PathSetAccessControlRecursiveMode::Remove; - } - throw std::runtime_error( - "Cannot convert " + pathSetAccessControlRecursiveMode - + " to PathSetAccessControlRecursiveMode"); - } - // Required. Indicates mode of the expiry time enum class PathExpiryOptions { @@ -178,58 +141,11 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { Unknown }; - inline std::string PathExpiryOptionsToString(const PathExpiryOptions& pathExpiryOptions) - { - switch (pathExpiryOptions) - { - case PathExpiryOptions::NeverExpire: - return "NeverExpire"; - case PathExpiryOptions::RelativeToCreation: - return "RelativeToCreation"; - case PathExpiryOptions::RelativeToNow: - return "RelativeToNow"; - case PathExpiryOptions::Absolute: - return "Absolute"; - default: - return std::string(); - } - } - - inline PathExpiryOptions PathExpiryOptionsFromString(const std::string& pathExpiryOptions) - { - if (pathExpiryOptions == "NeverExpire") - { - return PathExpiryOptions::NeverExpire; - } - if (pathExpiryOptions == "RelativeToCreation") - { - return PathExpiryOptions::RelativeToCreation; - } - if (pathExpiryOptions == "RelativeToNow") - { - return PathExpiryOptions::RelativeToNow; - } - if (pathExpiryOptions == "Absolute") - { - return PathExpiryOptions::Absolute; - } - throw std::runtime_error("Cannot convert " + pathExpiryOptions + " to PathExpiryOptions"); - } - struct AclFailedEntry { std::string Name; std::string Type; std::string ErrorMessage; - - static AclFailedEntry CreateFromJson(const nlohmann::json& node) - { - AclFailedEntry result; - result.Name = node["name"].get(); - result.Type = node["type"].get(); - result.ErrorMessage = node["errorMessage"].get(); - return result; - } }; struct SetAccessControlRecursiveResponse @@ -238,19 +154,6 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { int32_t FilesSuccessful = int32_t(); int32_t FailureCount = int32_t(); std::vector FailedEntries; - - static SetAccessControlRecursiveResponse CreateFromJson(const nlohmann::json& node) - { - SetAccessControlRecursiveResponse result; - result.DirectoriesSuccessful = node["directoriesSuccessful"].get(); - result.FilesSuccessful = node["filesSuccessful"].get(); - result.FailureCount = node["failureCount"].get(); - for (const auto& element : node["failedEntries"]) - { - result.FailedEntries.emplace_back(AclFailedEntry::CreateFromJson(element)); - } - return result; - } }; struct Path @@ -263,41 +166,11 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { std::string Owner; std::string Group; std::string Permissions; - - static Path CreateFromJson(const nlohmann::json& node) - { - Path result; - result.Name = node["name"].get(); - if (node.contains("isDirectory")) - { - result.IsDirectory = (node["isDirectory"].get() == "true"); - } - result.LastModified = node["lastModified"].get(); - result.ETag = node["etag"].get(); - if (node.contains("contentLength")) - { - result.ContentLength = std::stoll(node["contentLength"].get()); - } - result.Owner = node["owner"].get(); - result.Group = node["group"].get(); - result.Permissions = node["permissions"].get(); - return result; - } }; struct PathList { std::vector Paths; - - static PathList CreateFromJson(const nlohmann::json& node) - { - PathList result; - for (const auto& element : node["paths"]) - { - result.Paths.emplace_back(Path::CreateFromJson(element)); - } - return result; - } }; struct FileSystem @@ -305,30 +178,11 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { std::string Name; std::string LastModified; std::string ETag; - - static FileSystem CreateFromJson(const nlohmann::json& node) - { - FileSystem result; - result.Name = node["name"].get(); - result.LastModified = node["lastModified"].get(); - result.ETag = node["etag"].get(); - return result; - } }; struct FileSystemList { std::vector Filesystems; - - static FileSystemList CreateFromJson(const nlohmann::json& node) - { - FileSystemList result; - for (const auto& element : node["filesystems"]) - { - result.Filesystems.emplace_back(FileSystem::CreateFromJson(element)); - } - return result; - } }; struct StorageError @@ -352,32 +206,6 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { Unknown }; - inline std::string PathResourceTypeToString(const PathResourceType& pathResourceType) - { - switch (pathResourceType) - { - case PathResourceType::Directory: - return "directory"; - case PathResourceType::File: - return "file"; - default: - return std::string(); - } - } - - inline PathResourceType PathResourceTypeFromString(const std::string& pathResourceType) - { - if (pathResourceType == "directory") - { - return PathResourceType::Directory; - } - if (pathResourceType == "file") - { - return PathResourceType::File; - } - throw std::runtime_error("Cannot convert " + pathResourceType + " to PathResourceType"); - } - // Optional. Valid only when namespace is enabled. This parameter determines the behavior of the // rename operation. The value must be "legacy" or "posix", and the default value will be "posix". enum class PathRenameMode @@ -387,94 +215,6 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { Unknown }; - inline std::string PathRenameModeToString(const PathRenameMode& pathRenameMode) - { - switch (pathRenameMode) - { - case PathRenameMode::Legacy: - return "legacy"; - case PathRenameMode::Posix: - return "posix"; - default: - return std::string(); - } - } - - inline PathRenameMode PathRenameModeFromString(const std::string& pathRenameMode) - { - if (pathRenameMode == "legacy") - { - return PathRenameMode::Legacy; - } - if (pathRenameMode == "posix") - { - return PathRenameMode::Posix; - } - throw std::runtime_error("Cannot convert " + pathRenameMode + " to PathRenameMode"); - } - - // The action must be "append" to upload data to be appended to a file, "flush" to flush - // previously uploaded data to a file, "setProperties" to set the properties of a file or - // directory, "setAccessControl" to set the owner, group, permissions, or access control list for - // a file or directory, or "setAccessControlRecursive" to set the access control list for a - // directory recursively. Note that Hierarchical Namespace must be enabled for the account in - // order to use access control. Also note that the Access Control List (ACL) includes permissions - // for the owner, owning group, and others, so the x-ms-permissions and x-ms-acl request headers - // are mutually exclusive. - enum class PathUpdateAction - { - Append, - Flush, - SetProperties, - SetAccessControl, - SetAccessControlRecursive, - Unknown - }; - - inline std::string PathUpdateActionToString(const PathUpdateAction& pathUpdateAction) - { - switch (pathUpdateAction) - { - case PathUpdateAction::Append: - return "append"; - case PathUpdateAction::Flush: - return "flush"; - case PathUpdateAction::SetProperties: - return "setProperties"; - case PathUpdateAction::SetAccessControl: - return "setAccessControl"; - case PathUpdateAction::SetAccessControlRecursive: - return "setAccessControlRecursive"; - default: - return std::string(); - } - } - - inline PathUpdateAction PathUpdateActionFromString(const std::string& pathUpdateAction) - { - if (pathUpdateAction == "append") - { - return PathUpdateAction::Append; - } - if (pathUpdateAction == "flush") - { - return PathUpdateAction::Flush; - } - if (pathUpdateAction == "setProperties") - { - return PathUpdateAction::SetProperties; - } - if (pathUpdateAction == "setAccessControl") - { - return PathUpdateAction::SetAccessControl; - } - if (pathUpdateAction == "setAccessControlRecursive") - { - return PathUpdateAction::SetAccessControlRecursive; - } - throw std::runtime_error("Cannot convert " + pathUpdateAction + " to PathUpdateAction"); - } - // There are five lease actions: "acquire", "break", "change", "renew", and "release". Use // "acquire" and specify the "x-ms-proposed-lease-id" and "x-ms-lease-duration" to acquire a new // lease. Use "break" to break an existing lease. When a lease is broken, the lease break period @@ -494,50 +234,6 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { Unknown }; - inline std::string PathLeaseActionToString(const PathLeaseAction& pathLeaseAction) - { - switch (pathLeaseAction) - { - case PathLeaseAction::Acquire: - return "acquire"; - case PathLeaseAction::Break: - return "break"; - case PathLeaseAction::Change: - return "change"; - case PathLeaseAction::Renew: - return "renew"; - case PathLeaseAction::Release: - return "release"; - default: - return std::string(); - } - } - - inline PathLeaseAction PathLeaseActionFromString(const std::string& pathLeaseAction) - { - if (pathLeaseAction == "acquire") - { - return PathLeaseAction::Acquire; - } - if (pathLeaseAction == "break") - { - return PathLeaseAction::Break; - } - if (pathLeaseAction == "change") - { - return PathLeaseAction::Change; - } - if (pathLeaseAction == "renew") - { - return PathLeaseAction::Renew; - } - if (pathLeaseAction == "release") - { - return PathLeaseAction::Release; - } - throw std::runtime_error("Cannot convert " + pathLeaseAction + " to PathLeaseAction"); - } - // Lease state of the resource. enum class LeaseStateType { @@ -549,50 +245,6 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { Unknown }; - inline std::string LeaseStateTypeToString(const LeaseStateType& leaseStateType) - { - switch (leaseStateType) - { - case LeaseStateType::Available: - return "available"; - case LeaseStateType::Leased: - return "leased"; - case LeaseStateType::Expired: - return "expired"; - case LeaseStateType::Breaking: - return "breaking"; - case LeaseStateType::Broken: - return "broken"; - default: - return std::string(); - } - } - - inline LeaseStateType LeaseStateTypeFromString(const std::string& leaseStateType) - { - if (leaseStateType == "available") - { - return LeaseStateType::Available; - } - if (leaseStateType == "leased") - { - return LeaseStateType::Leased; - } - if (leaseStateType == "expired") - { - return LeaseStateType::Expired; - } - if (leaseStateType == "breaking") - { - return LeaseStateType::Breaking; - } - if (leaseStateType == "broken") - { - return LeaseStateType::Broken; - } - throw std::runtime_error("Cannot convert " + leaseStateType + " to LeaseStateType"); - } - // The lease status of the resource. enum class LeaseStatusType { @@ -601,32 +253,6 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { Unknown }; - inline std::string LeaseStatusTypeToString(const LeaseStatusType& leaseStatusType) - { - switch (leaseStatusType) - { - case LeaseStatusType::Locked: - return "locked"; - case LeaseStatusType::Unlocked: - return "unlocked"; - default: - return std::string(); - } - } - - inline LeaseStatusType LeaseStatusTypeFromString(const std::string& leaseStatusType) - { - if (leaseStatusType == "locked") - { - return LeaseStatusType::Locked; - } - if (leaseStatusType == "unlocked") - { - return LeaseStatusType::Unlocked; - } - throw std::runtime_error("Cannot convert " + leaseStatusType + " to LeaseStatusType"); - } - // Optional. If the value is "getStatus" only the system defined properties for the path are // returned. If the value is "getAccessControl" the access control list is returned in the // response headers (Hierarchical Namespace must be enabled for the account), otherwise the @@ -638,48 +264,10 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { Unknown }; - inline std::string PathGetPropertiesActionToString( - const PathGetPropertiesAction& pathGetPropertiesAction) - { - switch (pathGetPropertiesAction) - { - case PathGetPropertiesAction::GetAccessControl: - return "getAccessControl"; - case PathGetPropertiesAction::GetStatus: - return "getStatus"; - default: - return std::string(); - } - } - - inline PathGetPropertiesAction PathGetPropertiesActionFromString( - const std::string& pathGetPropertiesAction) - { - if (pathGetPropertiesAction == "getAccessControl") - { - return PathGetPropertiesAction::GetAccessControl; - } - if (pathGetPropertiesAction == "getStatus") - { - return PathGetPropertiesAction::GetStatus; - } - throw std::runtime_error( - "Cannot convert " + pathGetPropertiesAction + " to PathGetPropertiesAction"); - } - struct ServiceListFileSystemsResult { Azure::Core::Nullable ContinuationToken; std::vector Filesystems; - - static ServiceListFileSystemsResult ServiceListFileSystemsResultFromFileSystemList( - FileSystemList object) - { - ServiceListFileSystemsResult result; - result.Filesystems = std::move(object.Filesystems); - - return result; - } }; struct FileSystemCreateResult @@ -711,14 +299,6 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { { Azure::Core::Nullable ContinuationToken; std::vector Paths; - - static FileSystemListPathsResult FileSystemListPathsResultFromPathList(PathList object) - { - FileSystemListPathsResult result; - result.Paths = std::move(object.Paths); - - return result; - } }; struct PathCreateResult @@ -729,35 +309,6 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { Azure::Core::Nullable ContentLength; }; - struct PathUpdateResult - { - Azure::Core::Nullable ETag; - Azure::Core::Nullable LastModified; - Azure::Core::Nullable AcceptRanges; - DataLakeHttpHeaders HttpHeaders; - int64_t ContentLength = int64_t(); - Azure::Core::Nullable ContentRange; - Azure::Core::Nullable ContentMd5; - Azure::Core::Nullable Properties; - Azure::Core::Nullable ContinuationToken; - int32_t DirectoriesSuccessful = int32_t(); - int32_t FilesSuccessful = int32_t(); - int32_t FailureCount = int32_t(); - std::vector FailedEntries; - - static PathUpdateResult PathUpdateResultFromSetAccessControlRecursiveResponse( - SetAccessControlRecursiveResponse object) - { - PathUpdateResult result; - result.DirectoriesSuccessful = object.DirectoriesSuccessful; - result.FilesSuccessful = object.FilesSuccessful; - result.FailureCount = object.FailureCount; - result.FailedEntries = std::move(object.FailedEntries); - - return result; - } - }; - struct PathLeaseResult { std::string ETag; @@ -822,19 +373,6 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { int32_t FilesSuccessful = int32_t(); int32_t FailureCount = int32_t(); std::vector FailedEntries; - - static PathSetAccessControlRecursiveResult - PathSetAccessControlRecursiveResultFromSetAccessControlRecursiveResponse( - SetAccessControlRecursiveResponse object) - { - PathSetAccessControlRecursiveResult result; - result.DirectoriesSuccessful = object.DirectoriesSuccessful; - result.FilesSuccessful = object.FilesSuccessful; - result.FailureCount = object.FailureCount; - result.FailedEntries = std::move(object.FailedEntries); - - return result; - } }; struct PathFlushDataResult @@ -857,2619 +395,2656 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { std::string LastModified; }; - class DataLakeRestClient { - public: - class Service { - public: - struct ListFileSystemsOptions + namespace Details { + inline std::string PathSetAccessControlRecursiveModeToString( + const PathSetAccessControlRecursiveMode& pathSetAccessControlRecursiveMode) + { + switch (pathSetAccessControlRecursiveMode) { - Azure::Core::Nullable - Prefix; // Filters results to filesystems within the specified prefix. - Azure::Core::Nullable - ContinuationToken; // Optional. The number of paths processed with each invocation is - // limited. If the number of paths to be processed exceeds this - // limit, a continuation token is returned in the response header - // x-ms-continuation. When a continuation token is returned in the - // response, it must be percent-encoded and specified in a subsequent - // invocation of setAcessControlRecursive operation. - Azure::Core::Nullable - MaxResults; // An optional value that specifies the maximum number of items to return. - // If omitted or greater than 5,000, the response will include up to 5,000 - // items. - Azure::Core::Nullable - ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character - // limit that is recorded in the analytics logs when storage analytics - // logging is enabled. - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for Blob Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - }; - - static Azure::Core::Response ListFileSystems( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - const Azure::Core::Context& context, - const ListFileSystemsOptions& listFileSystemsOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Get, url); - request.GetUrl().AppendQueryParameter(Details::c_QueryResource, "account"); - if (listFileSystemsOptions.Prefix.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryPrefix, - Storage::Details::UrlEncodeQueryParameter(listFileSystemsOptions.Prefix.GetValue())); - } - if (listFileSystemsOptions.ContinuationToken.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryContinuationToken, - Storage::Details::UrlEncodeQueryParameter( - listFileSystemsOptions.ContinuationToken.GetValue())); - } - if (listFileSystemsOptions.MaxResults.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryMaxResults, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(listFileSystemsOptions.MaxResults.GetValue()))); - } - if (listFileSystemsOptions.ClientRequestId.HasValue()) - { - request.AddHeader( - Details::c_HeaderClientRequestId, listFileSystemsOptions.ClientRequestId.GetValue()); - } - if (listFileSystemsOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(listFileSystemsOptions.Timeout.GetValue()))); - } - request.AddHeader( - Details::c_HeaderApiVersionParameter, listFileSystemsOptions.ApiVersionParameter); - return ListFileSystemsParseResult(context, pipeline.Send(context, request)); + case PathSetAccessControlRecursiveMode::Set: + return "set"; + case PathSetAccessControlRecursiveMode::Modify: + return "modify"; + case PathSetAccessControlRecursiveMode::Remove: + return "remove"; + default: + return std::string(); } + } - private: - static Azure::Core::Response ListFileSystemsParseResult( - const Azure::Core::Context& context, - std::unique_ptr responsePtr) + inline PathSetAccessControlRecursiveMode PathSetAccessControlRecursiveModeFromString( + const std::string& pathSetAccessControlRecursiveMode) + { + if (pathSetAccessControlRecursiveMode == "set") { - /* const */ auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + return PathSetAccessControlRecursiveMode::Set; + } + if (pathSetAccessControlRecursiveMode == "modify") + { + return PathSetAccessControlRecursiveMode::Modify; + } + if (pathSetAccessControlRecursiveMode == "remove") + { + return PathSetAccessControlRecursiveMode::Remove; + } + throw std::runtime_error( + "Cannot convert " + pathSetAccessControlRecursiveMode + + " to PathSetAccessControlRecursiveMode"); + } + + inline std::string PathExpiryOptionsToString(const PathExpiryOptions& pathExpiryOptions) + { + switch (pathExpiryOptions) + { + case PathExpiryOptions::NeverExpire: + return "NeverExpire"; + case PathExpiryOptions::RelativeToCreation: + return "RelativeToCreation"; + case PathExpiryOptions::RelativeToNow: + return "RelativeToNow"; + case PathExpiryOptions::Absolute: + return "Absolute"; + default: + return std::string(); + } + } + + inline PathExpiryOptions PathExpiryOptionsFromString(const std::string& pathExpiryOptions) + { + if (pathExpiryOptions == "NeverExpire") + { + return PathExpiryOptions::NeverExpire; + } + if (pathExpiryOptions == "RelativeToCreation") + { + return PathExpiryOptions::RelativeToCreation; + } + if (pathExpiryOptions == "RelativeToNow") + { + return PathExpiryOptions::RelativeToNow; + } + if (pathExpiryOptions == "Absolute") + { + return PathExpiryOptions::Absolute; + } + throw std::runtime_error("Cannot convert " + pathExpiryOptions + " to PathExpiryOptions"); + } + + inline std::string PathResourceTypeToString(const PathResourceType& pathResourceType) + { + switch (pathResourceType) + { + case PathResourceType::Directory: + return "directory"; + case PathResourceType::File: + return "file"; + default: + return std::string(); + } + } + + inline PathResourceType PathResourceTypeFromString(const std::string& pathResourceType) + { + if (pathResourceType == "directory") + { + return PathResourceType::Directory; + } + if (pathResourceType == "file") + { + return PathResourceType::File; + } + throw std::runtime_error("Cannot convert " + pathResourceType + " to PathResourceType"); + } + + inline std::string PathRenameModeToString(const PathRenameMode& pathRenameMode) + { + switch (pathRenameMode) + { + case PathRenameMode::Legacy: + return "legacy"; + case PathRenameMode::Posix: + return "posix"; + default: + return std::string(); + } + } + + inline PathRenameMode PathRenameModeFromString(const std::string& pathRenameMode) + { + if (pathRenameMode == "legacy") + { + return PathRenameMode::Legacy; + } + if (pathRenameMode == "posix") + { + return PathRenameMode::Posix; + } + throw std::runtime_error("Cannot convert " + pathRenameMode + " to PathRenameMode"); + } + + inline std::string PathLeaseActionToString(const PathLeaseAction& pathLeaseAction) + { + switch (pathLeaseAction) + { + case PathLeaseAction::Acquire: + return "acquire"; + case PathLeaseAction::Break: + return "break"; + case PathLeaseAction::Change: + return "change"; + case PathLeaseAction::Renew: + return "renew"; + case PathLeaseAction::Release: + return "release"; + default: + return std::string(); + } + } + + inline PathLeaseAction PathLeaseActionFromString(const std::string& pathLeaseAction) + { + if (pathLeaseAction == "acquire") + { + return PathLeaseAction::Acquire; + } + if (pathLeaseAction == "break") + { + return PathLeaseAction::Break; + } + if (pathLeaseAction == "change") + { + return PathLeaseAction::Change; + } + if (pathLeaseAction == "renew") + { + return PathLeaseAction::Renew; + } + if (pathLeaseAction == "release") + { + return PathLeaseAction::Release; + } + throw std::runtime_error("Cannot convert " + pathLeaseAction + " to PathLeaseAction"); + } + + inline std::string LeaseStateTypeToString(const LeaseStateType& leaseStateType) + { + switch (leaseStateType) + { + case LeaseStateType::Available: + return "available"; + case LeaseStateType::Leased: + return "leased"; + case LeaseStateType::Expired: + return "expired"; + case LeaseStateType::Breaking: + return "breaking"; + case LeaseStateType::Broken: + return "broken"; + default: + return std::string(); + } + } + + inline LeaseStateType LeaseStateTypeFromString(const std::string& leaseStateType) + { + if (leaseStateType == "available") + { + return LeaseStateType::Available; + } + if (leaseStateType == "leased") + { + return LeaseStateType::Leased; + } + if (leaseStateType == "expired") + { + return LeaseStateType::Expired; + } + if (leaseStateType == "breaking") + { + return LeaseStateType::Breaking; + } + if (leaseStateType == "broken") + { + return LeaseStateType::Broken; + } + throw std::runtime_error("Cannot convert " + leaseStateType + " to LeaseStateType"); + } + + inline std::string LeaseStatusTypeToString(const LeaseStatusType& leaseStatusType) + { + switch (leaseStatusType) + { + case LeaseStatusType::Locked: + return "locked"; + case LeaseStatusType::Unlocked: + return "unlocked"; + default: + return std::string(); + } + } + + inline LeaseStatusType LeaseStatusTypeFromString(const std::string& leaseStatusType) + { + if (leaseStatusType == "locked") + { + return LeaseStatusType::Locked; + } + if (leaseStatusType == "unlocked") + { + return LeaseStatusType::Unlocked; + } + throw std::runtime_error("Cannot convert " + leaseStatusType + " to LeaseStatusType"); + } + + inline std::string PathGetPropertiesActionToString( + const PathGetPropertiesAction& pathGetPropertiesAction) + { + switch (pathGetPropertiesAction) + { + case PathGetPropertiesAction::GetAccessControl: + return "getAccessControl"; + case PathGetPropertiesAction::GetStatus: + return "getStatus"; + default: + return std::string(); + } + } + + inline PathGetPropertiesAction PathGetPropertiesActionFromString( + const std::string& pathGetPropertiesAction) + { + if (pathGetPropertiesAction == "getAccessControl") + { + return PathGetPropertiesAction::GetAccessControl; + } + if (pathGetPropertiesAction == "getStatus") + { + return PathGetPropertiesAction::GetStatus; + } + throw std::runtime_error( + "Cannot convert " + pathGetPropertiesAction + " to PathGetPropertiesAction"); + } + + class DataLakeRestClient { + public: + class Service { + public: + struct ListFileSystemsOptions { - // OK - const auto& bodyBuffer = response.GetBody(); - ServiceListFileSystemsResult result = bodyBuffer.empty() - ? ServiceListFileSystemsResult() - : ServiceListFileSystemsResult::ServiceListFileSystemsResultFromFileSystemList( - FileSystemList::CreateFromJson(nlohmann::json::parse(bodyBuffer))); - if (response.GetHeaders().find(Details::c_HeaderXMsContinuation) - != response.GetHeaders().end()) + Azure::Core::Nullable + Prefix; // Filters results to filesystems within the specified prefix. + Azure::Core::Nullable + ContinuationToken; // Optional. When deleting a directory, the number of paths that + // are deleted with each invocation is limited. If the number of + // paths to be deleted exceeds this limit, a continuation token is + // returned in this response header. When a continuation token is + // returned in the response, it must be specified in a subsequent + // invocation of the delete operation to continue deleting the + // directory. + Azure::Core::Nullable + MaxResults; // An optional value that specifies the maximum number of items to return. + // If omitted or greater than 5,000, the response will include up to 5,000 + // items. + Azure::Core::Nullable + ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character + // limit that is recorded in the analytics logs when storage + // analytics logging is enabled. + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for Blob Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + }; + + static Azure::Core::Response ListFileSystems( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + const Azure::Core::Context& context, + const ListFileSystemsOptions& listFileSystemsOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Get, url); + request.GetUrl().AppendQueryParameter(Details::c_QueryResource, "account"); + if (listFileSystemsOptions.Prefix.HasValue()) { - result.ContinuationToken = response.GetHeaders().at(Details::c_HeaderXMsContinuation); + request.GetUrl().AppendQueryParameter( + Details::c_QueryPrefix, + Storage::Details::UrlEncodeQueryParameter( + listFileSystemsOptions.Prefix.GetValue())); } - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - }; - - class FileSystem { - public: - struct CreateOptions - { - Azure::Core::Nullable - ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character - // limit that is recorded in the analytics logs when storage analytics - // logging is enabled. - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for Blob Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - Properties; // Optional. User-defined properties to be stored with the filesystem, in - // the format of a comma-separated list of name and value pairs "n1=v1, - // n2=v2, ...", where each value is a base64 encoded string. Note that the - // string may only contain ASCII characters in the ISO-8859-1 character set. - // If the filesystem exists, any properties not included in the list will be - // removed. All properties are removed if the header is omitted. To merge - // new and existing properties, first get all existing properties and the - // current E-Tag, then make a conditional request with the E-Tag and include - // values for all properties. - }; - - static Azure::Core::Response Create( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - const Azure::Core::Context& context, - const CreateOptions& createOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); - request.AddHeader(Details::c_HeaderContentLength, "0"); - request.GetUrl().AppendQueryParameter( - Details::c_QueryFileSystemResource, - Storage::Details::UrlEncodeQueryParameter("filesystem")); - if (createOptions.ClientRequestId.HasValue()) - { - request.AddHeader( - Details::c_HeaderClientRequestId, createOptions.ClientRequestId.GetValue()); - } - if (createOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(createOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderApiVersionParameter, createOptions.ApiVersionParameter); - if (createOptions.Properties.HasValue()) - { - request.AddHeader(Details::c_HeaderProperties, createOptions.Properties.GetValue()); - } - return CreateParseResult(context, pipeline.Send(context, request)); - } - - struct SetPropertiesOptions - { - Azure::Core::Nullable - ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character - // limit that is recorded in the analytics logs when storage analytics - // logging is enabled. - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for Blob Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - Properties; // Optional. User-defined properties to be stored with the filesystem, in - // the format of a comma-separated list of name and value pairs "n1=v1, - // n2=v2, ...", where each value is a base64 encoded string. Note that the - // string may only contain ASCII characters in the ISO-8859-1 character set. - // If the filesystem exists, any properties not included in the list will be - // removed. All properties are removed if the header is omitted. To merge - // new and existing properties, first get all existing properties and the - // current E-Tag, then make a conditional request with the E-Tag and include - // values for all properties. - Azure::Core::Nullable - IfModifiedSince; // Specify this header value to operate only on a blob if it has been - // modified since the specified date/time. - Azure::Core::Nullable - IfUnmodifiedSince; // Specify this header value to operate only on a blob if it has not - // been modified since the specified date/time. - }; - - static Azure::Core::Response SetProperties( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - const Azure::Core::Context& context, - const SetPropertiesOptions& setPropertiesOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Patch, url); - request.GetUrl().AppendQueryParameter( - Details::c_QueryFileSystemResource, - Storage::Details::UrlEncodeQueryParameter("filesystem")); - if (setPropertiesOptions.ClientRequestId.HasValue()) - { - request.AddHeader( - Details::c_HeaderClientRequestId, setPropertiesOptions.ClientRequestId.GetValue()); - } - if (setPropertiesOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(setPropertiesOptions.Timeout.GetValue()))); - } - request.AddHeader( - Details::c_HeaderApiVersionParameter, setPropertiesOptions.ApiVersionParameter); - if (setPropertiesOptions.Properties.HasValue()) - { - request.AddHeader( - Details::c_HeaderProperties, setPropertiesOptions.Properties.GetValue()); - } - if (setPropertiesOptions.IfModifiedSince.HasValue()) - { - request.AddHeader( - Details::c_HeaderIfModifiedSince, setPropertiesOptions.IfModifiedSince.GetValue()); - } - if (setPropertiesOptions.IfUnmodifiedSince.HasValue()) - { - request.AddHeader( - Details::c_HeaderIfUnmodifiedSince, - setPropertiesOptions.IfUnmodifiedSince.GetValue()); - } - return SetPropertiesParseResult(context, pipeline.Send(context, request)); - } - - struct GetPropertiesOptions - { - Azure::Core::Nullable - ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character - // limit that is recorded in the analytics logs when storage analytics - // logging is enabled. - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for Blob Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - }; - - static Azure::Core::Response GetProperties( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - const Azure::Core::Context& context, - const GetPropertiesOptions& getPropertiesOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Head, url); - request.GetUrl().AppendQueryParameter( - Details::c_QueryFileSystemResource, - Storage::Details::UrlEncodeQueryParameter("filesystem")); - if (getPropertiesOptions.ClientRequestId.HasValue()) - { - request.AddHeader( - Details::c_HeaderClientRequestId, getPropertiesOptions.ClientRequestId.GetValue()); - } - if (getPropertiesOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(getPropertiesOptions.Timeout.GetValue()))); - } - request.AddHeader( - Details::c_HeaderApiVersionParameter, getPropertiesOptions.ApiVersionParameter); - return GetPropertiesParseResult(context, pipeline.Send(context, request)); - } - - struct DeleteOptions - { - Azure::Core::Nullable - ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character - // limit that is recorded in the analytics logs when storage analytics - // logging is enabled. - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for Blob Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - IfModifiedSince; // Specify this header value to operate only on a blob if it has been - // modified since the specified date/time. - Azure::Core::Nullable - IfUnmodifiedSince; // Specify this header value to operate only on a blob if it has not - // been modified since the specified date/time. - }; - - static Azure::Core::Response Delete( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - const Azure::Core::Context& context, - const DeleteOptions& deleteOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Delete, url); - request.GetUrl().AppendQueryParameter( - Details::c_QueryFileSystemResource, - Storage::Details::UrlEncodeQueryParameter("filesystem")); - if (deleteOptions.ClientRequestId.HasValue()) - { - request.AddHeader( - Details::c_HeaderClientRequestId, deleteOptions.ClientRequestId.GetValue()); - } - if (deleteOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(deleteOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderApiVersionParameter, deleteOptions.ApiVersionParameter); - if (deleteOptions.IfModifiedSince.HasValue()) - { - request.AddHeader( - Details::c_HeaderIfModifiedSince, deleteOptions.IfModifiedSince.GetValue()); - } - if (deleteOptions.IfUnmodifiedSince.HasValue()) - { - request.AddHeader( - Details::c_HeaderIfUnmodifiedSince, deleteOptions.IfUnmodifiedSince.GetValue()); - } - return DeleteParseResult(context, pipeline.Send(context, request)); - } - - struct ListPathsOptions - { - Azure::Core::Nullable - ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character - // limit that is recorded in the analytics logs when storage analytics - // logging is enabled. - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for Blob Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - ContinuationToken; // Optional. The number of paths processed with each invocation is - // limited. If the number of paths to be processed exceeds this - // limit, a continuation token is returned in the response header - // x-ms-continuation. When a continuation token is returned in the - // response, it must be percent-encoded and specified in a subsequent - // invocation of setAcessControlRecursive operation. - Azure::Core::Nullable - Directory; // Optional. Filters results to paths within the specified directory. An - // error occurs if the directory does not exist. - bool RecursiveRequired = bool(); // Required - Azure::Core::Nullable - MaxResults; // An optional value that specifies the maximum number of items to return. - // If omitted or greater than 5,000, the response will include up to 5,000 - // items. - Azure::Core::Nullable - Upn; // Optional. Valid only when Hierarchical Namespace is enabled for the account. If - // "true", the user identity values returned in the x-ms-owner, x-ms-group, and - // x-ms-acl response headers will be transformed from Azure Active Directory Object - // IDs to User Principal Names. If "false", the values will be returned as Azure - // Active Directory Object IDs. The default value is false. Note that group and - // application Object IDs are not translated because they do not have unique - // friendly names. - }; - - static Azure::Core::Response ListPaths( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - const Azure::Core::Context& context, - const ListPathsOptions& listPathsOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Get, url); - request.GetUrl().AppendQueryParameter( - Details::c_QueryFileSystemResource, - Storage::Details::UrlEncodeQueryParameter("filesystem")); - if (listPathsOptions.ClientRequestId.HasValue()) - { - request.AddHeader( - Details::c_HeaderClientRequestId, listPathsOptions.ClientRequestId.GetValue()); - } - if (listPathsOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(listPathsOptions.Timeout.GetValue()))); - } - request.AddHeader( - Details::c_HeaderApiVersionParameter, listPathsOptions.ApiVersionParameter); - if (listPathsOptions.ContinuationToken.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryContinuationToken, - Storage::Details::UrlEncodeQueryParameter( - listPathsOptions.ContinuationToken.GetValue())); - } - if (listPathsOptions.Directory.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryDirectory, - Storage::Details::UrlEncodeQueryParameter(listPathsOptions.Directory.GetValue())); - } - request.GetUrl().AppendQueryParameter( - Details::c_QueryRecursiveRequired, - Storage::Details::UrlEncodeQueryParameter( - (listPathsOptions.RecursiveRequired ? "true" : "false"))); - if (listPathsOptions.MaxResults.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryMaxResults, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(listPathsOptions.MaxResults.GetValue()))); - } - if (listPathsOptions.Upn.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryUpn, - Storage::Details::UrlEncodeQueryParameter( - (listPathsOptions.Upn.GetValue() ? "true" : "false"))); - } - return ListPathsParseResult(context, pipeline.Send(context, request)); - } - - private: - static Azure::Core::Response CreateParseResult( - const Azure::Core::Context& context, - std::unique_ptr responsePtr) - { - /* const */ auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Created) - { - // Created - FileSystemCreateResult result; - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - result.NamespaceEnabled = response.GetHeaders().at(Details::c_HeaderXMsNamespaceEnabled); - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response SetPropertiesParseResult( - const Azure::Core::Context& context, - std::unique_ptr responsePtr) - { - /* const */ auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) - { - // Ok - FileSystemSetPropertiesResult result; - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response GetPropertiesParseResult( - const Azure::Core::Context& context, - std::unique_ptr responsePtr) - { - /* const */ auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) - { - // Ok - FileSystemGetPropertiesResult result; - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - result.Properties = response.GetHeaders().at(Details::c_HeaderXMsProperties); - result.NamespaceEnabled = response.GetHeaders().at(Details::c_HeaderXMsNamespaceEnabled); - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response DeleteParseResult( - const Azure::Core::Context& context, - std::unique_ptr responsePtr) - { - /* const */ auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Accepted) - { - // Accepted - FileSystemDeleteResult result; - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response ListPathsParseResult( - const Azure::Core::Context& context, - std::unique_ptr responsePtr) - { - /* const */ auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) - { - // Ok - const auto& bodyBuffer = response.GetBody(); - FileSystemListPathsResult result = bodyBuffer.empty() - ? FileSystemListPathsResult() - : FileSystemListPathsResult::FileSystemListPathsResultFromPathList( - PathList::CreateFromJson(nlohmann::json::parse(bodyBuffer))); - if (response.GetHeaders().find(Details::c_HeaderXMsContinuation) - != response.GetHeaders().end()) + if (listFileSystemsOptions.ContinuationToken.HasValue()) { - result.ContinuationToken = response.GetHeaders().at(Details::c_HeaderXMsContinuation); + request.GetUrl().AppendQueryParameter( + Details::c_QueryContinuationToken, + Storage::Details::UrlEncodeQueryParameter( + listFileSystemsOptions.ContinuationToken.GetValue())); } - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); + if (listFileSystemsOptions.MaxResults.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryMaxResults, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(listFileSystemsOptions.MaxResults.GetValue()))); + } + if (listFileSystemsOptions.ClientRequestId.HasValue()) + { + request.AddHeader( + Details::c_HeaderClientRequestId, + listFileSystemsOptions.ClientRequestId.GetValue()); + } + if (listFileSystemsOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(listFileSystemsOptions.Timeout.GetValue()))); + } + request.AddHeader( + Details::c_HeaderApiVersionParameter, listFileSystemsOptions.ApiVersionParameter); + return ListFileSystemsParseResult(context, pipeline.Send(context, request)); } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - }; - class Path { - public: - struct CreateOptions - { - Azure::Core::Nullable - ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character - // limit that is recorded in the analytics logs when storage analytics - // logging is enabled. - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for Blob Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - Resource; // Required only for Create File and Create Directory. The value must be - // "file" or "directory". - Azure::Core::Nullable - ContinuationToken; // Optional. The number of paths processed with each invocation is - // limited. If the number of paths to be processed exceeds this - // limit, a continuation token is returned in the response header - // x-ms-continuation. When a continuation token is returned in the - // response, it must be percent-encoded and specified in a subsequent - // invocation of setAcessControlRecursive operation. - Azure::Core::Nullable - Mode; // Optional. Valid only when namespace is enabled. This parameter determines the - // behavior of the rename operation. The value must be "legacy" or "posix", and - // the default value will be "posix". - Azure::Core::Nullable - CacheControl; // Optional. Sets the blob's cache control. If specified, this property is - // stored with the blob and returned with a read request. - Azure::Core::Nullable - ContentEncoding; // Optional. Sets the blob's content encoding. If specified, this - // property is stored with the blob and returned with a read request. - Azure::Core::Nullable - ContentLanguage; // Optional. Set the blob's content language. If specified, this - // property is stored with the blob and returned with a read request. - Azure::Core::Nullable - ContentDisposition; // Optional. Sets the blob's Content-Disposition header. - Azure::Core::Nullable - ContentType; // Optional. Sets the blob's content type. If specified, this property is - // stored with the blob and returned with a read request. - Azure::Core::Nullable - RenameSource; // An optional file or directory to be renamed. The value must have the - // following format: "/{filesystem}/{path}". If "x-ms-properties" is - // specified, the properties will overwrite the existing properties; - // otherwise, the existing properties will be preserved. This value must - // be a URL percent-encoded string. Note that the string may only contain - // ASCII characters in the ISO-8859-1 character set. - Azure::Core::Nullable - LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease is - // active and matches this ID. - Azure::Core::Nullable - SourceLeaseId; // A lease ID for the source path. If specified, the source path must - // have an active lease and the lease ID must match. - Azure::Core::Nullable - Properties; // Optional. User-defined properties to be stored with the filesystem, in - // the format of a comma-separated list of name and value pairs "n1=v1, - // n2=v2, ...", where each value is a base64 encoded string. Note that the - // string may only contain ASCII characters in the ISO-8859-1 character set. - // If the filesystem exists, any properties not included in the list will be - // removed. All properties are removed if the header is omitted. To merge - // new and existing properties, first get all existing properties and the - // current E-Tag, then make a conditional request with the E-Tag and include - // values for all properties. - Azure::Core::Nullable - Permissions; // Optional and only valid if Hierarchical Namespace is enabled for the - // account. Sets POSIX access permissions for the file owner, the file - // owning group, and others. Each class may be granted read, write, or - // execute permission. The sticky bit is also supported. Both symbolic - // (rwxrw-rw-) and 4-digit octal notation (e.g. 0766) are supported. - Azure::Core::Nullable - Umask; // Optional and only valid if Hierarchical Namespace is enabled for the account. - // When creating a file or directory and the parent folder does not have a - // default ACL, the umask restricts the permissions of the file or directory to - // be created. The resulting permission is given by p bitwise and not u, where p - // is the permission and u is the umask. For example, if p is 0777 and u is - // 0057, then the resulting permission is 0720. The default permission is 0777 - // for a directory and 0666 for a file. The default umask is 0027. The umask - // must be specified in 4-digit octal notation (e.g. 0766). - Azure::Core::Nullable - IfMatch; // Specify an ETag value to operate only on blobs with a matching value. - Azure::Core::Nullable - IfNoneMatch; // Specify an ETag value to operate only on blobs without a matching value. - Azure::Core::Nullable - IfModifiedSince; // Specify this header value to operate only on a blob if it has been - // modified since the specified date/time. - Azure::Core::Nullable - IfUnmodifiedSince; // Specify this header value to operate only on a blob if it has not - // been modified since the specified date/time. - Azure::Core::Nullable - SourceIfMatch; // Specify an ETag value to operate only on blobs with a matching value. - Azure::Core::Nullable - SourceIfNoneMatch; // Specify an ETag value to operate only on blobs without a matching - // value. - Azure::Core::Nullable - SourceIfModifiedSince; // Specify this header value to operate only on a blob if it has - // been modified since the specified date/time. - Azure::Core::Nullable - SourceIfUnmodifiedSince; // Specify this header value to operate only on a blob if it - // has not been modified since the specified date/time. + private: + static Azure::Core::Response ListFileSystemsParseResult( + const Azure::Core::Context& context, + std::unique_ptr responsePtr) + { + /* const */ auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + { + // OK + const auto& bodyBuffer = response.GetBody(); + ServiceListFileSystemsResult result = bodyBuffer.empty() + ? ServiceListFileSystemsResult() + : ServiceListFileSystemsResultFromFileSystemList( + FileSystemListFromJson(nlohmann::json::parse(bodyBuffer))); + if (response.GetHeaders().find(Details::c_HeaderXMsContinuation) + != response.GetHeaders().end()) + { + result.ContinuationToken = response.GetHeaders().at(Details::c_HeaderXMsContinuation); + } + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Storage::Files::DataLake::FileSystem FileSystemFromJson( + const nlohmann::json& node) + { + Azure::Storage::Files::DataLake::FileSystem result; + result.Name = node["name"].get(); + result.LastModified = node["lastModified"].get(); + result.ETag = node["etag"].get(); + return result; + } + + static Azure::Storage::Files::DataLake::FileSystemList FileSystemListFromJson( + const nlohmann::json& node) + { + Azure::Storage::Files::DataLake::FileSystemList result; + for (const auto& element : node["filesystems"]) + { + result.Filesystems.emplace_back(FileSystemFromJson(element)); + } + return result; + } + + static ServiceListFileSystemsResult ServiceListFileSystemsResultFromFileSystemList( + FileSystemList object) + { + ServiceListFileSystemsResult result; + result.Filesystems = std::move(object.Filesystems); + + return result; + } }; - static Azure::Core::Response Create( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - const Azure::Core::Context& context, - const CreateOptions& createOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); - request.AddHeader(Details::c_HeaderContentLength, "0"); - if (createOptions.ClientRequestId.HasValue()) + class FileSystem { + public: + struct CreateOptions { - request.AddHeader( - Details::c_HeaderClientRequestId, createOptions.ClientRequestId.GetValue()); - } - if (createOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(createOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderApiVersionParameter, createOptions.ApiVersionParameter); - if (createOptions.Resource.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryPathResourceType, - Storage::Details::UrlEncodeQueryParameter( - PathResourceTypeToString(createOptions.Resource.GetValue()))); - } - if (createOptions.ContinuationToken.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryContinuationToken, - Storage::Details::UrlEncodeQueryParameter( - createOptions.ContinuationToken.GetValue())); - } - if (createOptions.Mode.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryPathRenameMode, - Storage::Details::UrlEncodeQueryParameter( - PathRenameModeToString(createOptions.Mode.GetValue()))); - } - if (createOptions.CacheControl.HasValue()) - { - request.AddHeader(Details::c_HeaderCacheControl, createOptions.CacheControl.GetValue()); - } - if (createOptions.ContentEncoding.HasValue()) - { - request.AddHeader( - Details::c_HeaderContentEncoding, createOptions.ContentEncoding.GetValue()); - } - if (createOptions.ContentLanguage.HasValue()) - { - request.AddHeader( - Details::c_HeaderContentLanguage, createOptions.ContentLanguage.GetValue()); - } - if (createOptions.ContentDisposition.HasValue()) - { - request.AddHeader( - Details::c_HeaderContentDisposition, createOptions.ContentDisposition.GetValue()); - } - if (createOptions.ContentType.HasValue()) - { - request.AddHeader(Details::c_HeaderContentType, createOptions.ContentType.GetValue()); - } - if (createOptions.RenameSource.HasValue()) - { - request.AddHeader(Details::c_HeaderRenameSource, createOptions.RenameSource.GetValue()); - } - if (createOptions.LeaseIdOptional.HasValue()) - { - request.AddHeader( - Details::c_HeaderLeaseIdOptional, createOptions.LeaseIdOptional.GetValue()); - } - if (createOptions.SourceLeaseId.HasValue()) - { - request.AddHeader(Details::c_HeaderSourceLeaseId, createOptions.SourceLeaseId.GetValue()); - } - if (createOptions.Properties.HasValue()) - { - request.AddHeader(Details::c_HeaderProperties, createOptions.Properties.GetValue()); - } - if (createOptions.Permissions.HasValue()) - { - request.AddHeader(Details::c_HeaderPermissions, createOptions.Permissions.GetValue()); - } - if (createOptions.Umask.HasValue()) - { - request.AddHeader(Details::c_HeaderUmask, createOptions.Umask.GetValue()); - } - if (createOptions.IfMatch.HasValue()) - { - request.AddHeader(Details::c_HeaderIfMatch, createOptions.IfMatch.GetValue()); - } - if (createOptions.IfNoneMatch.HasValue()) - { - request.AddHeader(Details::c_HeaderIfNoneMatch, createOptions.IfNoneMatch.GetValue()); - } - if (createOptions.IfModifiedSince.HasValue()) - { - request.AddHeader( - Details::c_HeaderIfModifiedSince, createOptions.IfModifiedSince.GetValue()); - } - if (createOptions.IfUnmodifiedSince.HasValue()) - { - request.AddHeader( - Details::c_HeaderIfUnmodifiedSince, createOptions.IfUnmodifiedSince.GetValue()); - } - if (createOptions.SourceIfMatch.HasValue()) - { - request.AddHeader(Details::c_HeaderSourceIfMatch, createOptions.SourceIfMatch.GetValue()); - } - if (createOptions.SourceIfNoneMatch.HasValue()) - { - request.AddHeader( - Details::c_HeaderSourceIfNoneMatch, createOptions.SourceIfNoneMatch.GetValue()); - } - if (createOptions.SourceIfModifiedSince.HasValue()) - { - request.AddHeader( - Details::c_HeaderSourceIfModifiedSince, - createOptions.SourceIfModifiedSince.GetValue()); - } - if (createOptions.SourceIfUnmodifiedSince.HasValue()) - { - request.AddHeader( - Details::c_HeaderSourceIfUnmodifiedSince, - createOptions.SourceIfUnmodifiedSince.GetValue()); - } - return CreateParseResult(context, pipeline.Send(context, request)); - } + Azure::Core::Nullable + ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character + // limit that is recorded in the analytics logs when storage + // analytics logging is enabled. + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for Blob Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + Properties; // Optional. User-defined properties to be stored with the filesystem, in + // the format of a comma-separated list of name and value pairs "n1=v1, + // n2=v2, ...", where each value is a base64 encoded string. Note that the + // string may only contain ASCII characters in the ISO-8859-1 character + // set. If the filesystem exists, any properties not included in the list + // will be removed. All properties are removed if the header is omitted. + // To merge new and existing properties, first get all existing properties + // and the current E-Tag, then make a conditional request with the E-Tag + // and include values for all properties. + }; - struct UpdateOptions - { - Azure::Core::Nullable - ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character - // limit that is recorded in the analytics logs when storage analytics - // logging is enabled. - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for Blob Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - PathUpdateAction - Action; // The action must be "append" to upload data to be appended to a file, "flush" - // to flush previously uploaded data to a file, "setProperties" to set the - // properties of a file or directory, "setAccessControl" to set the owner, - // group, permissions, or access control list for a file or directory, or - // "setAccessControlRecursive" to set the access control list for a directory - // recursively. Note that Hierarchical Namespace must be enabled for the account - // in order to use access control. Also note that the Access Control List (ACL) - // includes permissions for the owner, owning group, and others, so the - // x-ms-permissions and x-ms-acl request headers are mutually exclusive. - Azure::Core::Nullable - MaxRecords; // Optional. Valid for "SetAccessControlRecursive" operation. It specifies - // the maximum number of files or directories on which the acl change will - // be applied. If omitted or greater than 2,000, the request will process up - // to 2,000 items - Azure::Core::Nullable - ContinuationToken; // Optional. The number of paths processed with each invocation is - // limited. If the number of paths to be processed exceeds this - // limit, a continuation token is returned in the response header - // x-ms-continuation. When a continuation token is returned in the - // response, it must be percent-encoded and specified in a subsequent - // invocation of setAcessControlRecursive operation. - PathSetAccessControlRecursiveMode - Mode; // Mode "set" sets POSIX access control rights on files and directories, "modify" - // modifies one or more POSIX access control rights that pre-exist on files and - // directories, "remove" removes one or more POSIX access control rights that - // were present earlier on files and directories - Azure::Core::Nullable - ForceFlag; // Optional. Valid for "SetAccessControlRecursive" operation. If set to - // false, the operation will terminate quickly on encountering user errors - // (4XX). If true, the operation will ignore user errors and proceed with the - // operation on other sub-entities of the directory. Continuation token will - // only be returned when forceFlag is true in case of user errors. If not set - // the default value is false for this. - Azure::Core::Nullable - Position; // This parameter allows the caller to upload data in parallel and control the - // order in which it is appended to the file. It is required when uploading - // data to be appended to the file and when flushing previously uploaded data - // to the file. The value must be the position where the data is to be - // appended. Uploaded data is not immediately flushed, or written, to the - // file. To flush, the previously uploaded data must be contiguous, the - // position parameter must be specified and equal to the length of the file - // after all data has been written, and there must not be a request entity - // body included with the request. - Azure::Core::Nullable - RetainUncommittedData; // Valid only for flush operations. If "true", uncommitted data - // is retained after the flush operation completes; otherwise, - // the uncommitted data is deleted after the flush operation. The - // default is false. Data at offsets less than the specified - // position are written to the file when flush succeeds, but this - // optional parameter allows data after the flush position to be - // retained for a future flush operation. - Azure::Core::Nullable - Close; // Azure Storage Events allow applications to receive notifications when files - // change. When Azure Storage Events are enabled, a file changed event is raised. - // This event has a property indicating whether this is the final change to - // distinguish the difference between an intermediate flush to a file stream and - // the final close of a file stream. The close query parameter is valid only when - // the action is "flush" and change notifications are enabled. If the value of - // close is "true" and the flush operation completes successfully, the service - // raises a file change notification with a property indicating that this is the - // final update (the file stream has been closed). If "false" a change - // notification is raised indicating the file has changed. The default is false. - // This query parameter is set to true by the Hadoop ABFS driver to indicate that - // the file stream has been closed." - Azure::Core::Nullable - ContentLength; // Required for "Append Data" and "Flush Data". Must be 0 for "Flush - // Data". Must be the length of the request content in bytes for "Append - // Data". - Azure::Core::Nullable ContentMd5; // Specify the transactional md5 for the - // body, to be validated by the service. - Azure::Core::Nullable - LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease is - // active and matches this ID. - Azure::Core::Nullable - CacheControl; // Optional. Sets the blob's cache control. If specified, this property is - // stored with the blob and returned with a read request. - Azure::Core::Nullable - ContentType; // Optional. Sets the blob's content type. If specified, this property is - // stored with the blob and returned with a read request. - Azure::Core::Nullable - ContentDisposition; // Optional. Sets the blob's Content-Disposition header. - Azure::Core::Nullable - ContentEncoding; // Optional. Sets the blob's content encoding. If specified, this - // property is stored with the blob and returned with a read request. - Azure::Core::Nullable - ContentLanguage; // Optional. Set the blob's content language. If specified, this - // property is stored with the blob and returned with a read request. - Azure::Core::Nullable - Properties; // Optional. User-defined properties to be stored with the filesystem, in - // the format of a comma-separated list of name and value pairs "n1=v1, - // n2=v2, ...", where each value is a base64 encoded string. Note that the - // string may only contain ASCII characters in the ISO-8859-1 character set. - // If the filesystem exists, any properties not included in the list will be - // removed. All properties are removed if the header is omitted. To merge - // new and existing properties, first get all existing properties and the - // current E-Tag, then make a conditional request with the E-Tag and include - // values for all properties. - Azure::Core::Nullable Owner; // Optional. The owner of the blob or directory. - Azure::Core::Nullable - Group; // Optional. The owning group of the blob or directory. - Azure::Core::Nullable - Permissions; // Optional and only valid if Hierarchical Namespace is enabled for the - // account. Sets POSIX access permissions for the file owner, the file - // owning group, and others. Each class may be granted read, write, or - // execute permission. The sticky bit is also supported. Both symbolic - // (rwxrw-rw-) and 4-digit octal notation (e.g. 0766) are supported. - Azure::Core::Nullable - Acl; // Sets POSIX access control rights on files and directories. The value is a - // comma-separated list of access control entries. Each access control entry (ACE) - // consists of a scope, a type, a user or group identifier, and permissions in the - // format "[scope:][type]:[id]:[permissions]". - Azure::Core::Nullable - IfMatch; // Specify an ETag value to operate only on blobs with a matching value. - Azure::Core::Nullable - IfNoneMatch; // Specify an ETag value to operate only on blobs without a matching value. - Azure::Core::Nullable - IfModifiedSince; // Specify this header value to operate only on a blob if it has been - // modified since the specified date/time. - Azure::Core::Nullable - IfUnmodifiedSince; // Specify this header value to operate only on a blob if it has not - // been modified since the specified date/time. + static Azure::Core::Response Create( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + const Azure::Core::Context& context, + const CreateOptions& createOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); + request.AddHeader(Details::c_HeaderContentLength, "0"); + request.GetUrl().AppendQueryParameter( + Details::c_QueryFileSystemResource, + Storage::Details::UrlEncodeQueryParameter("filesystem")); + if (createOptions.ClientRequestId.HasValue()) + { + request.AddHeader( + Details::c_HeaderClientRequestId, createOptions.ClientRequestId.GetValue()); + } + if (createOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(createOptions.Timeout.GetValue()))); + } + request.AddHeader( + Details::c_HeaderApiVersionParameter, createOptions.ApiVersionParameter); + if (createOptions.Properties.HasValue()) + { + request.AddHeader(Details::c_HeaderProperties, createOptions.Properties.GetValue()); + } + return CreateParseResult(context, pipeline.Send(context, request)); + } + + struct SetPropertiesOptions + { + Azure::Core::Nullable + ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character + // limit that is recorded in the analytics logs when storage + // analytics logging is enabled. + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for Blob Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + Properties; // Optional. User-defined properties to be stored with the filesystem, in + // the format of a comma-separated list of name and value pairs "n1=v1, + // n2=v2, ...", where each value is a base64 encoded string. Note that the + // string may only contain ASCII characters in the ISO-8859-1 character + // set. If the filesystem exists, any properties not included in the list + // will be removed. All properties are removed if the header is omitted. + // To merge new and existing properties, first get all existing properties + // and the current E-Tag, then make a conditional request with the E-Tag + // and include values for all properties. + Azure::Core::Nullable + IfModifiedSince; // Specify this header value to operate only on a blob if it has been + // modified since the specified date/time. + Azure::Core::Nullable + IfUnmodifiedSince; // Specify this header value to operate only on a blob if it has + // not been modified since the specified date/time. + }; + + static Azure::Core::Response SetProperties( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + const Azure::Core::Context& context, + const SetPropertiesOptions& setPropertiesOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Patch, url); + request.GetUrl().AppendQueryParameter( + Details::c_QueryFileSystemResource, + Storage::Details::UrlEncodeQueryParameter("filesystem")); + if (setPropertiesOptions.ClientRequestId.HasValue()) + { + request.AddHeader( + Details::c_HeaderClientRequestId, setPropertiesOptions.ClientRequestId.GetValue()); + } + if (setPropertiesOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(setPropertiesOptions.Timeout.GetValue()))); + } + request.AddHeader( + Details::c_HeaderApiVersionParameter, setPropertiesOptions.ApiVersionParameter); + if (setPropertiesOptions.Properties.HasValue()) + { + request.AddHeader( + Details::c_HeaderProperties, setPropertiesOptions.Properties.GetValue()); + } + if (setPropertiesOptions.IfModifiedSince.HasValue()) + { + request.AddHeader( + Details::c_HeaderIfModifiedSince, setPropertiesOptions.IfModifiedSince.GetValue()); + } + if (setPropertiesOptions.IfUnmodifiedSince.HasValue()) + { + request.AddHeader( + Details::c_HeaderIfUnmodifiedSince, + setPropertiesOptions.IfUnmodifiedSince.GetValue()); + } + return SetPropertiesParseResult(context, pipeline.Send(context, request)); + } + + struct GetPropertiesOptions + { + Azure::Core::Nullable + ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character + // limit that is recorded in the analytics logs when storage + // analytics logging is enabled. + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for Blob Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + }; + + static Azure::Core::Response GetProperties( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + const Azure::Core::Context& context, + const GetPropertiesOptions& getPropertiesOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Head, url); + request.GetUrl().AppendQueryParameter( + Details::c_QueryFileSystemResource, + Storage::Details::UrlEncodeQueryParameter("filesystem")); + if (getPropertiesOptions.ClientRequestId.HasValue()) + { + request.AddHeader( + Details::c_HeaderClientRequestId, getPropertiesOptions.ClientRequestId.GetValue()); + } + if (getPropertiesOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(getPropertiesOptions.Timeout.GetValue()))); + } + request.AddHeader( + Details::c_HeaderApiVersionParameter, getPropertiesOptions.ApiVersionParameter); + return GetPropertiesParseResult(context, pipeline.Send(context, request)); + } + + struct DeleteOptions + { + Azure::Core::Nullable + ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character + // limit that is recorded in the analytics logs when storage + // analytics logging is enabled. + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for Blob Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + IfModifiedSince; // Specify this header value to operate only on a blob if it has been + // modified since the specified date/time. + Azure::Core::Nullable + IfUnmodifiedSince; // Specify this header value to operate only on a blob if it has + // not been modified since the specified date/time. + }; + + static Azure::Core::Response Delete( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + const Azure::Core::Context& context, + const DeleteOptions& deleteOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Delete, url); + request.GetUrl().AppendQueryParameter( + Details::c_QueryFileSystemResource, + Storage::Details::UrlEncodeQueryParameter("filesystem")); + if (deleteOptions.ClientRequestId.HasValue()) + { + request.AddHeader( + Details::c_HeaderClientRequestId, deleteOptions.ClientRequestId.GetValue()); + } + if (deleteOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(deleteOptions.Timeout.GetValue()))); + } + request.AddHeader( + Details::c_HeaderApiVersionParameter, deleteOptions.ApiVersionParameter); + if (deleteOptions.IfModifiedSince.HasValue()) + { + request.AddHeader( + Details::c_HeaderIfModifiedSince, deleteOptions.IfModifiedSince.GetValue()); + } + if (deleteOptions.IfUnmodifiedSince.HasValue()) + { + request.AddHeader( + Details::c_HeaderIfUnmodifiedSince, deleteOptions.IfUnmodifiedSince.GetValue()); + } + return DeleteParseResult(context, pipeline.Send(context, request)); + } + + struct ListPathsOptions + { + Azure::Core::Nullable + ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character + // limit that is recorded in the analytics logs when storage + // analytics logging is enabled. + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for Blob Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + ContinuationToken; // Optional. When deleting a directory, the number of paths that + // are deleted with each invocation is limited. If the number of + // paths to be deleted exceeds this limit, a continuation token is + // returned in this response header. When a continuation token is + // returned in the response, it must be specified in a subsequent + // invocation of the delete operation to continue deleting the + // directory. + Azure::Core::Nullable + Directory; // Optional. Filters results to paths within the specified directory. An + // error occurs if the directory does not exist. + bool RecursiveRequired = bool(); // Required + Azure::Core::Nullable + MaxResults; // An optional value that specifies the maximum number of items to return. + // If omitted or greater than 5,000, the response will include up to 5,000 + // items. + Azure::Core::Nullable + Upn; // Optional. Valid only when Hierarchical Namespace is enabled for the account. + // If "true", the user identity values returned in the x-ms-owner, x-ms-group, + // and x-ms-acl response headers will be transformed from Azure Active Directory + // Object IDs to User Principal Names. If "false", the values will be returned + // as Azure Active Directory Object IDs. The default value is false. Note that + // group and application Object IDs are not translated because they do not have + // unique friendly names. + }; + + static Azure::Core::Response ListPaths( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + const Azure::Core::Context& context, + const ListPathsOptions& listPathsOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Get, url); + request.GetUrl().AppendQueryParameter( + Details::c_QueryFileSystemResource, + Storage::Details::UrlEncodeQueryParameter("filesystem")); + if (listPathsOptions.ClientRequestId.HasValue()) + { + request.AddHeader( + Details::c_HeaderClientRequestId, listPathsOptions.ClientRequestId.GetValue()); + } + if (listPathsOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(listPathsOptions.Timeout.GetValue()))); + } + request.AddHeader( + Details::c_HeaderApiVersionParameter, listPathsOptions.ApiVersionParameter); + if (listPathsOptions.ContinuationToken.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryContinuationToken, + Storage::Details::UrlEncodeQueryParameter( + listPathsOptions.ContinuationToken.GetValue())); + } + if (listPathsOptions.Directory.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryDirectory, + Storage::Details::UrlEncodeQueryParameter(listPathsOptions.Directory.GetValue())); + } + request.GetUrl().AppendQueryParameter( + Details::c_QueryRecursiveRequired, + Storage::Details::UrlEncodeQueryParameter( + (listPathsOptions.RecursiveRequired ? "true" : "false"))); + if (listPathsOptions.MaxResults.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryMaxResults, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(listPathsOptions.MaxResults.GetValue()))); + } + if (listPathsOptions.Upn.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryUpn, + Storage::Details::UrlEncodeQueryParameter( + (listPathsOptions.Upn.GetValue() ? "true" : "false"))); + } + return ListPathsParseResult(context, pipeline.Send(context, request)); + } + + private: + static Azure::Core::Response CreateParseResult( + const Azure::Core::Context& context, + std::unique_ptr responsePtr) + { + /* const */ auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Created) + { + // Created + FileSystemCreateResult result; + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + result.NamespaceEnabled + = response.GetHeaders().at(Details::c_HeaderXMsNamespaceEnabled); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Core::Response SetPropertiesParseResult( + const Azure::Core::Context& context, + std::unique_ptr responsePtr) + { + /* const */ auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + { + // Ok + FileSystemSetPropertiesResult result; + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Core::Response GetPropertiesParseResult( + const Azure::Core::Context& context, + std::unique_ptr responsePtr) + { + /* const */ auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + { + // Ok + FileSystemGetPropertiesResult result; + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + result.Properties = response.GetHeaders().at(Details::c_HeaderXMsProperties); + result.NamespaceEnabled + = response.GetHeaders().at(Details::c_HeaderXMsNamespaceEnabled); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Core::Response DeleteParseResult( + const Azure::Core::Context& context, + std::unique_ptr responsePtr) + { + /* const */ auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Accepted) + { + // Accepted + FileSystemDeleteResult result; + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Core::Response ListPathsParseResult( + const Azure::Core::Context& context, + std::unique_ptr responsePtr) + { + /* const */ auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + { + // Ok + const auto& bodyBuffer = response.GetBody(); + FileSystemListPathsResult result = bodyBuffer.empty() + ? FileSystemListPathsResult() + : FileSystemListPathsResultFromPathList( + PathListFromJson(nlohmann::json::parse(bodyBuffer))); + if (response.GetHeaders().find(Details::c_HeaderXMsContinuation) + != response.GetHeaders().end()) + { + result.ContinuationToken = response.GetHeaders().at(Details::c_HeaderXMsContinuation); + } + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Storage::Files::DataLake::Path PathFromJson(const nlohmann::json& node) + { + Azure::Storage::Files::DataLake::Path result; + result.Name = node["name"].get(); + if (node.contains("isDirectory")) + { + result.IsDirectory = (node["isDirectory"].get() == "true"); + } + result.LastModified = node["lastModified"].get(); + result.ETag = node["etag"].get(); + if (node.contains("contentLength")) + { + result.ContentLength = std::stoll(node["contentLength"].get()); + } + result.Owner = node["owner"].get(); + result.Group = node["group"].get(); + result.Permissions = node["permissions"].get(); + return result; + } + + static Azure::Storage::Files::DataLake::PathList PathListFromJson( + const nlohmann::json& node) + { + Azure::Storage::Files::DataLake::PathList result; + for (const auto& element : node["paths"]) + { + result.Paths.emplace_back(PathFromJson(element)); + } + return result; + } + + static FileSystemListPathsResult FileSystemListPathsResultFromPathList(PathList object) + { + FileSystemListPathsResult result; + result.Paths = std::move(object.Paths); + + return result; + } }; - static Azure::Core::Response Update( - const Azure::Core::Http::Url& url, - Azure::Core::Http::BodyStream& bodyStream, - Azure::Core::Http::HttpPipeline& pipeline, - const Azure::Core::Context& context, - const UpdateOptions& updateOptions) - { - Azure::Core::Http::Request request( - Azure::Core::Http::HttpMethod::Patch, std::move(url), &bodyStream); - if (updateOptions.ClientRequestId.HasValue()) + class Path { + public: + struct CreateOptions { - request.AddHeader( - Details::c_HeaderClientRequestId, updateOptions.ClientRequestId.GetValue()); - } - if (updateOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(updateOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderApiVersionParameter, updateOptions.ApiVersionParameter); - request.GetUrl().AppendQueryParameter( - Details::c_QueryPathUpdateAction, - Storage::Details::UrlEncodeQueryParameter( - PathUpdateActionToString(updateOptions.Action))); - if (updateOptions.MaxRecords.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryMaxRecords, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(updateOptions.MaxRecords.GetValue()))); - } - if (updateOptions.ContinuationToken.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryContinuationToken, - Storage::Details::UrlEncodeQueryParameter( - updateOptions.ContinuationToken.GetValue())); - } - request.GetUrl().AppendQueryParameter( - Details::c_QueryPathSetAccessControlRecursiveMode, - Storage::Details::UrlEncodeQueryParameter( - PathSetAccessControlRecursiveModeToString(updateOptions.Mode))); - if (updateOptions.ForceFlag.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryForceFlag, - Storage::Details::UrlEncodeQueryParameter( - (updateOptions.ForceFlag.GetValue() ? "true" : "false"))); - } - if (updateOptions.Position.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryPosition, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(updateOptions.Position.GetValue()))); - } - if (updateOptions.RetainUncommittedData.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryRetainUncommittedData, - Storage::Details::UrlEncodeQueryParameter( - (updateOptions.RetainUncommittedData.GetValue() ? "true" : "false"))); - } - if (updateOptions.Close.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryClose, - Storage::Details::UrlEncodeQueryParameter( - (updateOptions.Close.GetValue() ? "true" : "false"))); - } - if (updateOptions.ContentLength.HasValue()) - { - request.AddHeader( - Details::c_HeaderContentLength, - std::to_string(updateOptions.ContentLength.GetValue())); - } - if (updateOptions.ContentMd5.HasValue()) - { - request.AddHeader(Details::c_HeaderContentMd5, updateOptions.ContentMd5.GetValue()); - } - if (updateOptions.LeaseIdOptional.HasValue()) - { - request.AddHeader( - Details::c_HeaderLeaseIdOptional, updateOptions.LeaseIdOptional.GetValue()); - } - if (updateOptions.CacheControl.HasValue()) - { - request.AddHeader(Details::c_HeaderCacheControl, updateOptions.CacheControl.GetValue()); - } - if (updateOptions.ContentType.HasValue()) - { - request.AddHeader(Details::c_HeaderContentType, updateOptions.ContentType.GetValue()); - } - if (updateOptions.ContentDisposition.HasValue()) - { - request.AddHeader( - Details::c_HeaderContentDisposition, updateOptions.ContentDisposition.GetValue()); - } - if (updateOptions.ContentEncoding.HasValue()) - { - request.AddHeader( - Details::c_HeaderContentEncoding, updateOptions.ContentEncoding.GetValue()); - } - if (updateOptions.ContentLanguage.HasValue()) - { - request.AddHeader( - Details::c_HeaderContentLanguage, updateOptions.ContentLanguage.GetValue()); - } - if (updateOptions.Properties.HasValue()) - { - request.AddHeader(Details::c_HeaderProperties, updateOptions.Properties.GetValue()); - } - if (updateOptions.Owner.HasValue()) - { - request.AddHeader(Details::c_HeaderOwner, updateOptions.Owner.GetValue()); - } - if (updateOptions.Group.HasValue()) - { - request.AddHeader(Details::c_HeaderGroup, updateOptions.Group.GetValue()); - } - if (updateOptions.Permissions.HasValue()) - { - request.AddHeader(Details::c_HeaderPermissions, updateOptions.Permissions.GetValue()); - } - if (updateOptions.Acl.HasValue()) - { - request.AddHeader(Details::c_HeaderAcl, updateOptions.Acl.GetValue()); - } - if (updateOptions.IfMatch.HasValue()) - { - request.AddHeader(Details::c_HeaderIfMatch, updateOptions.IfMatch.GetValue()); - } - if (updateOptions.IfNoneMatch.HasValue()) - { - request.AddHeader(Details::c_HeaderIfNoneMatch, updateOptions.IfNoneMatch.GetValue()); - } - if (updateOptions.IfModifiedSince.HasValue()) - { - request.AddHeader( - Details::c_HeaderIfModifiedSince, updateOptions.IfModifiedSince.GetValue()); - } - if (updateOptions.IfUnmodifiedSince.HasValue()) - { - request.AddHeader( - Details::c_HeaderIfUnmodifiedSince, updateOptions.IfUnmodifiedSince.GetValue()); - } - return UpdateParseResult(context, pipeline.Send(context, request)); - } + Azure::Core::Nullable + ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character + // limit that is recorded in the analytics logs when storage + // analytics logging is enabled. + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for Blob Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + Resource; // Required only for Create File and Create Directory. The value must be + // "file" or "directory". + Azure::Core::Nullable + ContinuationToken; // Optional. When deleting a directory, the number of paths that + // are deleted with each invocation is limited. If the number of + // paths to be deleted exceeds this limit, a continuation token is + // returned in this response header. When a continuation token is + // returned in the response, it must be specified in a subsequent + // invocation of the delete operation to continue deleting the + // directory. + Azure::Core::Nullable + Mode; // Optional. Valid only when namespace is enabled. This parameter determines the + // behavior of the rename operation. The value must be "legacy" or "posix", and + // the default value will be "posix". + Azure::Core::Nullable + CacheControl; // Optional. Sets the blob's cache control. If specified, this property + // is stored with the blob and returned with a read request. + Azure::Core::Nullable + ContentEncoding; // Optional. Sets the blob's content encoding. If specified, this + // property is stored with the blob and returned with a read request. + Azure::Core::Nullable + ContentLanguage; // Optional. Set the blob's content language. If specified, this + // property is stored with the blob and returned with a read request. + Azure::Core::Nullable + ContentDisposition; // Optional. Sets the blob's Content-Disposition header. + Azure::Core::Nullable + ContentType; // Optional. Sets the blob's content type. If specified, this property is + // stored with the blob and returned with a read request. + Azure::Core::Nullable + RenameSource; // An optional file or directory to be renamed. The value must have the + // following format: "/{filesystem}/{path}". If "x-ms-properties" is + // specified, the properties will overwrite the existing properties; + // otherwise, the existing properties will be preserved. This value must + // be a URL percent-encoded string. Note that the string may only + // contain ASCII characters in the ISO-8859-1 character set. + Azure::Core::Nullable + LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease + // is active and matches this ID. + Azure::Core::Nullable + SourceLeaseId; // A lease ID for the source path. If specified, the source path must + // have an active lease and the lease ID must match. + Azure::Core::Nullable + Properties; // Optional. User-defined properties to be stored with the filesystem, in + // the format of a comma-separated list of name and value pairs "n1=v1, + // n2=v2, ...", where each value is a base64 encoded string. Note that the + // string may only contain ASCII characters in the ISO-8859-1 character + // set. If the filesystem exists, any properties not included in the list + // will be removed. All properties are removed if the header is omitted. + // To merge new and existing properties, first get all existing properties + // and the current E-Tag, then make a conditional request with the E-Tag + // and include values for all properties. + Azure::Core::Nullable + Permissions; // Optional and only valid if Hierarchical Namespace is enabled for the + // account. Sets POSIX access permissions for the file owner, the file + // owning group, and others. Each class may be granted read, write, or + // execute permission. The sticky bit is also supported. Both symbolic + // (rwxrw-rw-) and 4-digit octal notation (e.g. 0766) are supported. + Azure::Core::Nullable + Umask; // Optional and only valid if Hierarchical Namespace is enabled for the + // account. When creating a file or directory and the parent folder does not + // have a default ACL, the umask restricts the permissions of the file or + // directory to be created. The resulting permission is given by p bitwise and + // not u, where p is the permission and u is the umask. For example, if p is + // 0777 and u is 0057, then the resulting permission is 0720. The default + // permission is 0777 for a directory and 0666 for a file. The default umask + // is 0027. The umask must be specified in 4-digit octal notation (e.g. 0766). + Azure::Core::Nullable + IfMatch; // Specify an ETag value to operate only on blobs with a matching value. + Azure::Core::Nullable IfNoneMatch; // Specify an ETag value to operate only + // on blobs without a matching value. + Azure::Core::Nullable + IfModifiedSince; // Specify this header value to operate only on a blob if it has been + // modified since the specified date/time. + Azure::Core::Nullable + IfUnmodifiedSince; // Specify this header value to operate only on a blob if it has + // not been modified since the specified date/time. + Azure::Core::Nullable SourceIfMatch; // Specify an ETag value to operate only + // on blobs with a matching value. + Azure::Core::Nullable + SourceIfNoneMatch; // Specify an ETag value to operate only on blobs without a + // matching value. + Azure::Core::Nullable + SourceIfModifiedSince; // Specify this header value to operate only on a blob if it + // has been modified since the specified date/time. + Azure::Core::Nullable + SourceIfUnmodifiedSince; // Specify this header value to operate only on a blob if it + // has not been modified since the specified date/time. + }; - struct LeaseOptions - { - Azure::Core::Nullable - ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character - // limit that is recorded in the analytics logs when storage analytics - // logging is enabled. - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for Blob Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - PathLeaseAction - XMsLeaseAction; // There are five lease actions: "acquire", "break", "change", "renew", - // and "release". Use "acquire" and specify the "x-ms-proposed-lease-id" - // and "x-ms-lease-duration" to acquire a new lease. Use "break" to - // break an existing lease. When a lease is broken, the lease break - // period is allowed to elapse, during which time no lease operation - // except break and release can be performed on the file. When a lease - // is successfully broken, the response indicates the interval in - // seconds until a new lease can be acquired. Use "change" and specify - // the current lease ID in "x-ms-lease-id" and the new lease ID in - // "x-ms-proposed-lease-id" to change the lease ID of an active lease. - // Use "renew" and specify the "x-ms-lease-id" to renew an existing - // lease. Use "release" and specify the "x-ms-lease-id" to release a - // lease. - Azure::Core::Nullable - XMsLeaseDuration; // The lease duration is required to acquire a lease, and specifies - // the duration of the lease in seconds. The lease duration must be - // between 15 and 60 seconds or -1 for infinite lease. - Azure::Core::Nullable - XMsLeaseBreakPeriod; // The lease break period duration is optional to break a lease, - // and specifies the break period of the lease in seconds. The - // lease break duration must be between 0 and 60 seconds. - Azure::Core::Nullable - LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease is - // active and matches this ID. - Azure::Core::Nullable - ProposedLeaseIdOptional; // Proposed lease ID, in a GUID string format. The Blob service - // returns 400 (Invalid request) if the proposed lease ID is - // not in the correct format. See Guid Constructor (String) for - // a list of valid GUID string formats. - Azure::Core::Nullable - IfMatch; // Specify an ETag value to operate only on blobs with a matching value. - Azure::Core::Nullable - IfNoneMatch; // Specify an ETag value to operate only on blobs without a matching value. - Azure::Core::Nullable - IfModifiedSince; // Specify this header value to operate only on a blob if it has been - // modified since the specified date/time. - Azure::Core::Nullable - IfUnmodifiedSince; // Specify this header value to operate only on a blob if it has not - // been modified since the specified date/time. - }; + static Azure::Core::Response Create( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + const Azure::Core::Context& context, + const CreateOptions& createOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); + request.AddHeader(Details::c_HeaderContentLength, "0"); + if (createOptions.ClientRequestId.HasValue()) + { + request.AddHeader( + Details::c_HeaderClientRequestId, createOptions.ClientRequestId.GetValue()); + } + if (createOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(createOptions.Timeout.GetValue()))); + } + request.AddHeader( + Details::c_HeaderApiVersionParameter, createOptions.ApiVersionParameter); + if (createOptions.Resource.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryPathResourceType, + Storage::Details::UrlEncodeQueryParameter( + PathResourceTypeToString(createOptions.Resource.GetValue()))); + } + if (createOptions.ContinuationToken.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryContinuationToken, + Storage::Details::UrlEncodeQueryParameter( + createOptions.ContinuationToken.GetValue())); + } + if (createOptions.Mode.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryPathRenameMode, + Storage::Details::UrlEncodeQueryParameter( + PathRenameModeToString(createOptions.Mode.GetValue()))); + } + if (createOptions.CacheControl.HasValue()) + { + request.AddHeader(Details::c_HeaderCacheControl, createOptions.CacheControl.GetValue()); + } + if (createOptions.ContentEncoding.HasValue()) + { + request.AddHeader( + Details::c_HeaderContentEncoding, createOptions.ContentEncoding.GetValue()); + } + if (createOptions.ContentLanguage.HasValue()) + { + request.AddHeader( + Details::c_HeaderContentLanguage, createOptions.ContentLanguage.GetValue()); + } + if (createOptions.ContentDisposition.HasValue()) + { + request.AddHeader( + Details::c_HeaderContentDisposition, createOptions.ContentDisposition.GetValue()); + } + if (createOptions.ContentType.HasValue()) + { + request.AddHeader(Details::c_HeaderContentType, createOptions.ContentType.GetValue()); + } + if (createOptions.RenameSource.HasValue()) + { + request.AddHeader(Details::c_HeaderRenameSource, createOptions.RenameSource.GetValue()); + } + if (createOptions.LeaseIdOptional.HasValue()) + { + request.AddHeader( + Details::c_HeaderLeaseIdOptional, createOptions.LeaseIdOptional.GetValue()); + } + if (createOptions.SourceLeaseId.HasValue()) + { + request.AddHeader( + Details::c_HeaderSourceLeaseId, createOptions.SourceLeaseId.GetValue()); + } + if (createOptions.Properties.HasValue()) + { + request.AddHeader(Details::c_HeaderProperties, createOptions.Properties.GetValue()); + } + if (createOptions.Permissions.HasValue()) + { + request.AddHeader(Details::c_HeaderPermissions, createOptions.Permissions.GetValue()); + } + if (createOptions.Umask.HasValue()) + { + request.AddHeader(Details::c_HeaderUmask, createOptions.Umask.GetValue()); + } + if (createOptions.IfMatch.HasValue()) + { + request.AddHeader(Details::c_HeaderIfMatch, createOptions.IfMatch.GetValue()); + } + if (createOptions.IfNoneMatch.HasValue()) + { + request.AddHeader(Details::c_HeaderIfNoneMatch, createOptions.IfNoneMatch.GetValue()); + } + if (createOptions.IfModifiedSince.HasValue()) + { + request.AddHeader( + Details::c_HeaderIfModifiedSince, createOptions.IfModifiedSince.GetValue()); + } + if (createOptions.IfUnmodifiedSince.HasValue()) + { + request.AddHeader( + Details::c_HeaderIfUnmodifiedSince, createOptions.IfUnmodifiedSince.GetValue()); + } + if (createOptions.SourceIfMatch.HasValue()) + { + request.AddHeader( + Details::c_HeaderSourceIfMatch, createOptions.SourceIfMatch.GetValue()); + } + if (createOptions.SourceIfNoneMatch.HasValue()) + { + request.AddHeader( + Details::c_HeaderSourceIfNoneMatch, createOptions.SourceIfNoneMatch.GetValue()); + } + if (createOptions.SourceIfModifiedSince.HasValue()) + { + request.AddHeader( + Details::c_HeaderSourceIfModifiedSince, + createOptions.SourceIfModifiedSince.GetValue()); + } + if (createOptions.SourceIfUnmodifiedSince.HasValue()) + { + request.AddHeader( + Details::c_HeaderSourceIfUnmodifiedSince, + createOptions.SourceIfUnmodifiedSince.GetValue()); + } + return CreateParseResult(context, pipeline.Send(context, request)); + } - static Azure::Core::Response Lease( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - const Azure::Core::Context& context, - const LeaseOptions& leaseOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Post, url); - request.AddHeader(Details::c_HeaderContentLength, "0"); - if (leaseOptions.ClientRequestId.HasValue()) + struct LeaseOptions { - request.AddHeader( - Details::c_HeaderClientRequestId, leaseOptions.ClientRequestId.GetValue()); - } - if (leaseOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(leaseOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderApiVersionParameter, leaseOptions.ApiVersionParameter); - request.AddHeader( - Details::c_HeaderPathLeaseAction, PathLeaseActionToString(leaseOptions.XMsLeaseAction)); - if (leaseOptions.XMsLeaseDuration.HasValue()) - { - request.AddHeader( - Details::c_HeaderXMsLeaseDuration, - std::to_string(leaseOptions.XMsLeaseDuration.GetValue())); - } - if (leaseOptions.XMsLeaseBreakPeriod.HasValue()) - { - request.AddHeader( - Details::c_HeaderXMsLeaseBreakPeriod, - std::to_string(leaseOptions.XMsLeaseBreakPeriod.GetValue())); - } - if (leaseOptions.LeaseIdOptional.HasValue()) - { - request.AddHeader( - Details::c_HeaderLeaseIdOptional, leaseOptions.LeaseIdOptional.GetValue()); - } - if (leaseOptions.ProposedLeaseIdOptional.HasValue()) - { - request.AddHeader( - Details::c_HeaderProposedLeaseIdOptional, - leaseOptions.ProposedLeaseIdOptional.GetValue()); - } - if (leaseOptions.IfMatch.HasValue()) - { - request.AddHeader(Details::c_HeaderIfMatch, leaseOptions.IfMatch.GetValue()); - } - if (leaseOptions.IfNoneMatch.HasValue()) - { - request.AddHeader(Details::c_HeaderIfNoneMatch, leaseOptions.IfNoneMatch.GetValue()); - } - if (leaseOptions.IfModifiedSince.HasValue()) - { - request.AddHeader( - Details::c_HeaderIfModifiedSince, leaseOptions.IfModifiedSince.GetValue()); - } - if (leaseOptions.IfUnmodifiedSince.HasValue()) - { - request.AddHeader( - Details::c_HeaderIfUnmodifiedSince, leaseOptions.IfUnmodifiedSince.GetValue()); - } - return LeaseParseResult(context, pipeline.Send(context, request)); - } + Azure::Core::Nullable + ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character + // limit that is recorded in the analytics logs when storage + // analytics logging is enabled. + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for Blob Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + PathLeaseAction + XMsLeaseAction; // There are five lease actions: "acquire", "break", "change", + // "renew", and "release". Use "acquire" and specify the + // "x-ms-proposed-lease-id" and "x-ms-lease-duration" to acquire a new + // lease. Use "break" to break an existing lease. When a lease is + // broken, the lease break period is allowed to elapse, during which + // time no lease operation except break and release can be performed + // on the file. When a lease is successfully broken, the response + // indicates the interval in seconds until a new lease can be + // acquired. Use "change" and specify the current lease ID in + // "x-ms-lease-id" and the new lease ID in "x-ms-proposed-lease-id" to + // change the lease ID of an active lease. Use "renew" and specify the + // "x-ms-lease-id" to renew an existing lease. Use "release" and + // specify the "x-ms-lease-id" to release a lease. + Azure::Core::Nullable + XMsLeaseDuration; // The lease duration is required to acquire a lease, and specifies + // the duration of the lease in seconds. The lease duration must be + // between 15 and 60 seconds or -1 for infinite lease. + Azure::Core::Nullable + XMsLeaseBreakPeriod; // The lease break period duration is optional to break a lease, + // and specifies the break period of the lease in seconds. The + // lease break duration must be between 0 and 60 seconds. + Azure::Core::Nullable + LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease + // is active and matches this ID. + Azure::Core::Nullable + ProposedLeaseIdOptional; // Proposed lease ID, in a GUID string format. The Blob + // service returns 400 (Invalid request) if the proposed + // lease ID is not in the correct format. See Guid + // Constructor (String) for a list of valid GUID string + // formats. + Azure::Core::Nullable + IfMatch; // Specify an ETag value to operate only on blobs with a matching value. + Azure::Core::Nullable IfNoneMatch; // Specify an ETag value to operate only + // on blobs without a matching value. + Azure::Core::Nullable + IfModifiedSince; // Specify this header value to operate only on a blob if it has been + // modified since the specified date/time. + Azure::Core::Nullable + IfUnmodifiedSince; // Specify this header value to operate only on a blob if it has + // not been modified since the specified date/time. + }; - struct ReadOptions - { - Azure::Core::Nullable - ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character - // limit that is recorded in the analytics logs when storage analytics - // logging is enabled. - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for Blob Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - Range; // The HTTP Range request header specifies one or more byte ranges of the - // resource to be retrieved. - Azure::Core::Nullable - LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease is - // active and matches this ID. - Azure::Core::Nullable - XMsRangeGetContentMd5; // Optional. When this header is set to "true" and specified - // together with the Range header, the service returns the MD5 - // hash for the range, as long as the range is less than or equal - // to 4MB in size. If this header is specified without the Range - // header, the service returns status code 400 (Bad Request). If - // this header is set to true when the range exceeds 4 MB in - // size, the service returns status code 400 (Bad Request). - Azure::Core::Nullable - IfMatch; // Specify an ETag value to operate only on blobs with a matching value. - Azure::Core::Nullable - IfNoneMatch; // Specify an ETag value to operate only on blobs without a matching value. - Azure::Core::Nullable - IfModifiedSince; // Specify this header value to operate only on a blob if it has been - // modified since the specified date/time. - Azure::Core::Nullable - IfUnmodifiedSince; // Specify this header value to operate only on a blob if it has not - // been modified since the specified date/time. - }; + static Azure::Core::Response Lease( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + const Azure::Core::Context& context, + const LeaseOptions& leaseOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Post, url); + request.AddHeader(Details::c_HeaderContentLength, "0"); + if (leaseOptions.ClientRequestId.HasValue()) + { + request.AddHeader( + Details::c_HeaderClientRequestId, leaseOptions.ClientRequestId.GetValue()); + } + if (leaseOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(leaseOptions.Timeout.GetValue()))); + } + request.AddHeader(Details::c_HeaderApiVersionParameter, leaseOptions.ApiVersionParameter); + request.AddHeader( + Details::c_HeaderPathLeaseAction, + PathLeaseActionToString(leaseOptions.XMsLeaseAction)); + if (leaseOptions.XMsLeaseDuration.HasValue()) + { + request.AddHeader( + Details::c_HeaderXMsLeaseDuration, + std::to_string(leaseOptions.XMsLeaseDuration.GetValue())); + } + if (leaseOptions.XMsLeaseBreakPeriod.HasValue()) + { + request.AddHeader( + Details::c_HeaderXMsLeaseBreakPeriod, + std::to_string(leaseOptions.XMsLeaseBreakPeriod.GetValue())); + } + if (leaseOptions.LeaseIdOptional.HasValue()) + { + request.AddHeader( + Details::c_HeaderLeaseIdOptional, leaseOptions.LeaseIdOptional.GetValue()); + } + if (leaseOptions.ProposedLeaseIdOptional.HasValue()) + { + request.AddHeader( + Details::c_HeaderProposedLeaseIdOptional, + leaseOptions.ProposedLeaseIdOptional.GetValue()); + } + if (leaseOptions.IfMatch.HasValue()) + { + request.AddHeader(Details::c_HeaderIfMatch, leaseOptions.IfMatch.GetValue()); + } + if (leaseOptions.IfNoneMatch.HasValue()) + { + request.AddHeader(Details::c_HeaderIfNoneMatch, leaseOptions.IfNoneMatch.GetValue()); + } + if (leaseOptions.IfModifiedSince.HasValue()) + { + request.AddHeader( + Details::c_HeaderIfModifiedSince, leaseOptions.IfModifiedSince.GetValue()); + } + if (leaseOptions.IfUnmodifiedSince.HasValue()) + { + request.AddHeader( + Details::c_HeaderIfUnmodifiedSince, leaseOptions.IfUnmodifiedSince.GetValue()); + } + return LeaseParseResult(context, pipeline.Send(context, request)); + } - static Azure::Core::Response Read( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - const Azure::Core::Context& context, - const ReadOptions& readOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Get, url, true); - if (readOptions.ClientRequestId.HasValue()) + struct ReadOptions { - request.AddHeader( - Details::c_HeaderClientRequestId, readOptions.ClientRequestId.GetValue()); - } - if (readOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(readOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderApiVersionParameter, readOptions.ApiVersionParameter); - if (readOptions.Range.HasValue()) - { - request.AddHeader(Details::c_HeaderRange, readOptions.Range.GetValue()); - } - if (readOptions.LeaseIdOptional.HasValue()) - { - request.AddHeader( - Details::c_HeaderLeaseIdOptional, readOptions.LeaseIdOptional.GetValue()); - } - if (readOptions.XMsRangeGetContentMd5.HasValue()) - { - request.AddHeader( - Details::c_HeaderXMsRangeGetContentMd5, - (readOptions.XMsRangeGetContentMd5.GetValue() ? "true" : "false")); - } - if (readOptions.IfMatch.HasValue()) - { - request.AddHeader(Details::c_HeaderIfMatch, readOptions.IfMatch.GetValue()); - } - if (readOptions.IfNoneMatch.HasValue()) - { - request.AddHeader(Details::c_HeaderIfNoneMatch, readOptions.IfNoneMatch.GetValue()); - } - if (readOptions.IfModifiedSince.HasValue()) - { - request.AddHeader( - Details::c_HeaderIfModifiedSince, readOptions.IfModifiedSince.GetValue()); - } - if (readOptions.IfUnmodifiedSince.HasValue()) - { - request.AddHeader( - Details::c_HeaderIfUnmodifiedSince, readOptions.IfUnmodifiedSince.GetValue()); - } - return ReadParseResult(context, pipeline.Send(context, request)); - } + Azure::Core::Nullable + ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character + // limit that is recorded in the analytics logs when storage + // analytics logging is enabled. + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for Blob Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + Range; // The HTTP Range request header specifies one or more byte ranges of the + // resource to be retrieved. + Azure::Core::Nullable + LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease + // is active and matches this ID. + Azure::Core::Nullable + XMsRangeGetContentMd5; // Optional. When this header is set to "true" and specified + // together with the Range header, the service returns the MD5 + // hash for the range, as long as the range is less than or + // equal to 4MB in size. If this header is specified without + // the Range header, the service returns status code 400 (Bad + // Request). If this header is set to true when the range + // exceeds 4 MB in size, the service returns status code 400 + // (Bad Request). + Azure::Core::Nullable + IfMatch; // Specify an ETag value to operate only on blobs with a matching value. + Azure::Core::Nullable IfNoneMatch; // Specify an ETag value to operate only + // on blobs without a matching value. + Azure::Core::Nullable + IfModifiedSince; // Specify this header value to operate only on a blob if it has been + // modified since the specified date/time. + Azure::Core::Nullable + IfUnmodifiedSince; // Specify this header value to operate only on a blob if it has + // not been modified since the specified date/time. + }; - struct GetPropertiesOptions - { - Azure::Core::Nullable - ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character - // limit that is recorded in the analytics logs when storage analytics - // logging is enabled. - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for Blob Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - Action; // Optional. If the value is "getStatus" only the system defined properties for - // the path are returned. If the value is "getAccessControl" the access control - // list is returned in the response headers (Hierarchical Namespace must be - // enabled for the account), otherwise the properties are returned. - Azure::Core::Nullable - Upn; // Optional. Valid only when Hierarchical Namespace is enabled for the account. If - // "true", the user identity values returned in the x-ms-owner, x-ms-group, and - // x-ms-acl response headers will be transformed from Azure Active Directory Object - // IDs to User Principal Names. If "false", the values will be returned as Azure - // Active Directory Object IDs. The default value is false. Note that group and - // application Object IDs are not translated because they do not have unique - // friendly names. - Azure::Core::Nullable - LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease is - // active and matches this ID. - Azure::Core::Nullable - IfMatch; // Specify an ETag value to operate only on blobs with a matching value. - Azure::Core::Nullable - IfNoneMatch; // Specify an ETag value to operate only on blobs without a matching value. - Azure::Core::Nullable - IfModifiedSince; // Specify this header value to operate only on a blob if it has been - // modified since the specified date/time. - Azure::Core::Nullable - IfUnmodifiedSince; // Specify this header value to operate only on a blob if it has not - // been modified since the specified date/time. - }; + static Azure::Core::Response Read( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + const Azure::Core::Context& context, + const ReadOptions& readOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Get, url, true); + if (readOptions.ClientRequestId.HasValue()) + { + request.AddHeader( + Details::c_HeaderClientRequestId, readOptions.ClientRequestId.GetValue()); + } + if (readOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(readOptions.Timeout.GetValue()))); + } + request.AddHeader(Details::c_HeaderApiVersionParameter, readOptions.ApiVersionParameter); + if (readOptions.Range.HasValue()) + { + request.AddHeader(Details::c_HeaderRange, readOptions.Range.GetValue()); + } + if (readOptions.LeaseIdOptional.HasValue()) + { + request.AddHeader( + Details::c_HeaderLeaseIdOptional, readOptions.LeaseIdOptional.GetValue()); + } + if (readOptions.XMsRangeGetContentMd5.HasValue()) + { + request.AddHeader( + Details::c_HeaderXMsRangeGetContentMd5, + (readOptions.XMsRangeGetContentMd5.GetValue() ? "true" : "false")); + } + if (readOptions.IfMatch.HasValue()) + { + request.AddHeader(Details::c_HeaderIfMatch, readOptions.IfMatch.GetValue()); + } + if (readOptions.IfNoneMatch.HasValue()) + { + request.AddHeader(Details::c_HeaderIfNoneMatch, readOptions.IfNoneMatch.GetValue()); + } + if (readOptions.IfModifiedSince.HasValue()) + { + request.AddHeader( + Details::c_HeaderIfModifiedSince, readOptions.IfModifiedSince.GetValue()); + } + if (readOptions.IfUnmodifiedSince.HasValue()) + { + request.AddHeader( + Details::c_HeaderIfUnmodifiedSince, readOptions.IfUnmodifiedSince.GetValue()); + } + return ReadParseResult(context, pipeline.Send(context, request)); + } - static Azure::Core::Response GetProperties( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - const Azure::Core::Context& context, - const GetPropertiesOptions& getPropertiesOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Head, url); - if (getPropertiesOptions.ClientRequestId.HasValue()) + struct GetPropertiesOptions { - request.AddHeader( - Details::c_HeaderClientRequestId, getPropertiesOptions.ClientRequestId.GetValue()); - } - if (getPropertiesOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(getPropertiesOptions.Timeout.GetValue()))); - } - request.AddHeader( - Details::c_HeaderApiVersionParameter, getPropertiesOptions.ApiVersionParameter); - if (getPropertiesOptions.Action.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryPathGetPropertiesAction, - Storage::Details::UrlEncodeQueryParameter( - PathGetPropertiesActionToString(getPropertiesOptions.Action.GetValue()))); - } - if (getPropertiesOptions.Upn.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryUpn, - Storage::Details::UrlEncodeQueryParameter( - (getPropertiesOptions.Upn.GetValue() ? "true" : "false"))); - } - if (getPropertiesOptions.LeaseIdOptional.HasValue()) - { - request.AddHeader( - Details::c_HeaderLeaseIdOptional, getPropertiesOptions.LeaseIdOptional.GetValue()); - } - if (getPropertiesOptions.IfMatch.HasValue()) - { - request.AddHeader(Details::c_HeaderIfMatch, getPropertiesOptions.IfMatch.GetValue()); - } - if (getPropertiesOptions.IfNoneMatch.HasValue()) - { - request.AddHeader( - Details::c_HeaderIfNoneMatch, getPropertiesOptions.IfNoneMatch.GetValue()); - } - if (getPropertiesOptions.IfModifiedSince.HasValue()) - { - request.AddHeader( - Details::c_HeaderIfModifiedSince, getPropertiesOptions.IfModifiedSince.GetValue()); - } - if (getPropertiesOptions.IfUnmodifiedSince.HasValue()) - { - request.AddHeader( - Details::c_HeaderIfUnmodifiedSince, - getPropertiesOptions.IfUnmodifiedSince.GetValue()); - } - return GetPropertiesParseResult(context, pipeline.Send(context, request)); - } + Azure::Core::Nullable + ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character + // limit that is recorded in the analytics logs when storage + // analytics logging is enabled. + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for Blob Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + Action; // Optional. If the value is "getStatus" only the system defined properties + // for the path are returned. If the value is "getAccessControl" the access + // control list is returned in the response headers (Hierarchical Namespace + // must be enabled for the account), otherwise the properties are returned. + Azure::Core::Nullable + Upn; // Optional. Valid only when Hierarchical Namespace is enabled for the account. + // If "true", the user identity values returned in the x-ms-owner, x-ms-group, + // and x-ms-acl response headers will be transformed from Azure Active Directory + // Object IDs to User Principal Names. If "false", the values will be returned + // as Azure Active Directory Object IDs. The default value is false. Note that + // group and application Object IDs are not translated because they do not have + // unique friendly names. + Azure::Core::Nullable + LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease + // is active and matches this ID. + Azure::Core::Nullable + IfMatch; // Specify an ETag value to operate only on blobs with a matching value. + Azure::Core::Nullable IfNoneMatch; // Specify an ETag value to operate only + // on blobs without a matching value. + Azure::Core::Nullable + IfModifiedSince; // Specify this header value to operate only on a blob if it has been + // modified since the specified date/time. + Azure::Core::Nullable + IfUnmodifiedSince; // Specify this header value to operate only on a blob if it has + // not been modified since the specified date/time. + }; - struct DeleteOptions - { - Azure::Core::Nullable - ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character - // limit that is recorded in the analytics logs when storage analytics - // logging is enabled. - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for Blob Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable RecursiveOptional; // Required - Azure::Core::Nullable - ContinuationToken; // Optional. The number of paths processed with each invocation is - // limited. If the number of paths to be processed exceeds this - // limit, a continuation token is returned in the response header - // x-ms-continuation. When a continuation token is returned in the - // response, it must be percent-encoded and specified in a subsequent - // invocation of setAcessControlRecursive operation. - Azure::Core::Nullable - LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease is - // active and matches this ID. - Azure::Core::Nullable - IfMatch; // Specify an ETag value to operate only on blobs with a matching value. - Azure::Core::Nullable - IfNoneMatch; // Specify an ETag value to operate only on blobs without a matching value. - Azure::Core::Nullable - IfModifiedSince; // Specify this header value to operate only on a blob if it has been - // modified since the specified date/time. - Azure::Core::Nullable - IfUnmodifiedSince; // Specify this header value to operate only on a blob if it has not - // been modified since the specified date/time. - }; + static Azure::Core::Response GetProperties( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + const Azure::Core::Context& context, + const GetPropertiesOptions& getPropertiesOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Head, url); + if (getPropertiesOptions.ClientRequestId.HasValue()) + { + request.AddHeader( + Details::c_HeaderClientRequestId, getPropertiesOptions.ClientRequestId.GetValue()); + } + if (getPropertiesOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(getPropertiesOptions.Timeout.GetValue()))); + } + request.AddHeader( + Details::c_HeaderApiVersionParameter, getPropertiesOptions.ApiVersionParameter); + if (getPropertiesOptions.Action.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryPathGetPropertiesAction, + Storage::Details::UrlEncodeQueryParameter( + PathGetPropertiesActionToString(getPropertiesOptions.Action.GetValue()))); + } + if (getPropertiesOptions.Upn.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryUpn, + Storage::Details::UrlEncodeQueryParameter( + (getPropertiesOptions.Upn.GetValue() ? "true" : "false"))); + } + if (getPropertiesOptions.LeaseIdOptional.HasValue()) + { + request.AddHeader( + Details::c_HeaderLeaseIdOptional, getPropertiesOptions.LeaseIdOptional.GetValue()); + } + if (getPropertiesOptions.IfMatch.HasValue()) + { + request.AddHeader(Details::c_HeaderIfMatch, getPropertiesOptions.IfMatch.GetValue()); + } + if (getPropertiesOptions.IfNoneMatch.HasValue()) + { + request.AddHeader( + Details::c_HeaderIfNoneMatch, getPropertiesOptions.IfNoneMatch.GetValue()); + } + if (getPropertiesOptions.IfModifiedSince.HasValue()) + { + request.AddHeader( + Details::c_HeaderIfModifiedSince, getPropertiesOptions.IfModifiedSince.GetValue()); + } + if (getPropertiesOptions.IfUnmodifiedSince.HasValue()) + { + request.AddHeader( + Details::c_HeaderIfUnmodifiedSince, + getPropertiesOptions.IfUnmodifiedSince.GetValue()); + } + return GetPropertiesParseResult(context, pipeline.Send(context, request)); + } - static Azure::Core::Response Delete( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - const Azure::Core::Context& context, - const DeleteOptions& deleteOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Delete, url); - if (deleteOptions.ClientRequestId.HasValue()) + struct DeleteOptions { - request.AddHeader( - Details::c_HeaderClientRequestId, deleteOptions.ClientRequestId.GetValue()); - } - if (deleteOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(deleteOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderApiVersionParameter, deleteOptions.ApiVersionParameter); - if (deleteOptions.RecursiveOptional.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryRecursiveOptional, - Storage::Details::UrlEncodeQueryParameter( - (deleteOptions.RecursiveOptional.GetValue() ? "true" : "false"))); - } - if (deleteOptions.ContinuationToken.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryContinuationToken, - Storage::Details::UrlEncodeQueryParameter( - deleteOptions.ContinuationToken.GetValue())); - } - if (deleteOptions.LeaseIdOptional.HasValue()) - { - request.AddHeader( - Details::c_HeaderLeaseIdOptional, deleteOptions.LeaseIdOptional.GetValue()); - } - if (deleteOptions.IfMatch.HasValue()) - { - request.AddHeader(Details::c_HeaderIfMatch, deleteOptions.IfMatch.GetValue()); - } - if (deleteOptions.IfNoneMatch.HasValue()) - { - request.AddHeader(Details::c_HeaderIfNoneMatch, deleteOptions.IfNoneMatch.GetValue()); - } - if (deleteOptions.IfModifiedSince.HasValue()) - { - request.AddHeader( - Details::c_HeaderIfModifiedSince, deleteOptions.IfModifiedSince.GetValue()); - } - if (deleteOptions.IfUnmodifiedSince.HasValue()) - { - request.AddHeader( - Details::c_HeaderIfUnmodifiedSince, deleteOptions.IfUnmodifiedSince.GetValue()); - } - return DeleteParseResult(context, pipeline.Send(context, request)); - } + Azure::Core::Nullable + ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character + // limit that is recorded in the analytics logs when storage + // analytics logging is enabled. + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for Blob Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable RecursiveOptional; // Required + Azure::Core::Nullable + ContinuationToken; // Optional. When deleting a directory, the number of paths that + // are deleted with each invocation is limited. If the number of + // paths to be deleted exceeds this limit, a continuation token is + // returned in this response header. When a continuation token is + // returned in the response, it must be specified in a subsequent + // invocation of the delete operation to continue deleting the + // directory. + Azure::Core::Nullable + LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease + // is active and matches this ID. + Azure::Core::Nullable + IfMatch; // Specify an ETag value to operate only on blobs with a matching value. + Azure::Core::Nullable IfNoneMatch; // Specify an ETag value to operate only + // on blobs without a matching value. + Azure::Core::Nullable + IfModifiedSince; // Specify this header value to operate only on a blob if it has been + // modified since the specified date/time. + Azure::Core::Nullable + IfUnmodifiedSince; // Specify this header value to operate only on a blob if it has + // not been modified since the specified date/time. + }; - struct SetAccessControlOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for Blob Service Operations. - Azure::Core::Nullable - LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease is - // active and matches this ID. - Azure::Core::Nullable Owner; // Optional. The owner of the blob or directory. - Azure::Core::Nullable - Group; // Optional. The owning group of the blob or directory. - Azure::Core::Nullable - Permissions; // Optional and only valid if Hierarchical Namespace is enabled for the - // account. Sets POSIX access permissions for the file owner, the file - // owning group, and others. Each class may be granted read, write, or - // execute permission. The sticky bit is also supported. Both symbolic - // (rwxrw-rw-) and 4-digit octal notation (e.g. 0766) are supported. - Azure::Core::Nullable - Acl; // Sets POSIX access control rights on files and directories. The value is a - // comma-separated list of access control entries. Each access control entry (ACE) - // consists of a scope, a type, a user or group identifier, and permissions in the - // format "[scope:][type]:[id]:[permissions]". - Azure::Core::Nullable - IfMatch; // Specify an ETag value to operate only on blobs with a matching value. - Azure::Core::Nullable - IfNoneMatch; // Specify an ETag value to operate only on blobs without a matching value. - Azure::Core::Nullable - IfModifiedSince; // Specify this header value to operate only on a blob if it has been - // modified since the specified date/time. - Azure::Core::Nullable - IfUnmodifiedSince; // Specify this header value to operate only on a blob if it has not - // been modified since the specified date/time. - Azure::Core::Nullable - ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character - // limit that is recorded in the analytics logs when storage analytics - // logging is enabled. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - }; + static Azure::Core::Response Delete( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + const Azure::Core::Context& context, + const DeleteOptions& deleteOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Delete, url); + if (deleteOptions.ClientRequestId.HasValue()) + { + request.AddHeader( + Details::c_HeaderClientRequestId, deleteOptions.ClientRequestId.GetValue()); + } + if (deleteOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(deleteOptions.Timeout.GetValue()))); + } + request.AddHeader( + Details::c_HeaderApiVersionParameter, deleteOptions.ApiVersionParameter); + if (deleteOptions.RecursiveOptional.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryRecursiveOptional, + Storage::Details::UrlEncodeQueryParameter( + (deleteOptions.RecursiveOptional.GetValue() ? "true" : "false"))); + } + if (deleteOptions.ContinuationToken.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryContinuationToken, + Storage::Details::UrlEncodeQueryParameter( + deleteOptions.ContinuationToken.GetValue())); + } + if (deleteOptions.LeaseIdOptional.HasValue()) + { + request.AddHeader( + Details::c_HeaderLeaseIdOptional, deleteOptions.LeaseIdOptional.GetValue()); + } + if (deleteOptions.IfMatch.HasValue()) + { + request.AddHeader(Details::c_HeaderIfMatch, deleteOptions.IfMatch.GetValue()); + } + if (deleteOptions.IfNoneMatch.HasValue()) + { + request.AddHeader(Details::c_HeaderIfNoneMatch, deleteOptions.IfNoneMatch.GetValue()); + } + if (deleteOptions.IfModifiedSince.HasValue()) + { + request.AddHeader( + Details::c_HeaderIfModifiedSince, deleteOptions.IfModifiedSince.GetValue()); + } + if (deleteOptions.IfUnmodifiedSince.HasValue()) + { + request.AddHeader( + Details::c_HeaderIfUnmodifiedSince, deleteOptions.IfUnmodifiedSince.GetValue()); + } + return DeleteParseResult(context, pipeline.Send(context, request)); + } - static Azure::Core::Response SetAccessControl( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - const Azure::Core::Context& context, - const SetAccessControlOptions& setAccessControlOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Patch, url); - request.GetUrl().AppendQueryParameter(Details::c_QueryAction, "setAccessControl"); - if (setAccessControlOptions.Timeout.HasValue()) + struct SetAccessControlOptions { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(setAccessControlOptions.Timeout.GetValue()))); - } - if (setAccessControlOptions.LeaseIdOptional.HasValue()) - { - request.AddHeader( - Details::c_HeaderLeaseIdOptional, setAccessControlOptions.LeaseIdOptional.GetValue()); - } - if (setAccessControlOptions.Owner.HasValue()) - { - request.AddHeader(Details::c_HeaderOwner, setAccessControlOptions.Owner.GetValue()); - } - if (setAccessControlOptions.Group.HasValue()) - { - request.AddHeader(Details::c_HeaderGroup, setAccessControlOptions.Group.GetValue()); - } - if (setAccessControlOptions.Permissions.HasValue()) - { - request.AddHeader( - Details::c_HeaderPermissions, setAccessControlOptions.Permissions.GetValue()); - } - if (setAccessControlOptions.Acl.HasValue()) - { - request.AddHeader(Details::c_HeaderAcl, setAccessControlOptions.Acl.GetValue()); - } - if (setAccessControlOptions.IfMatch.HasValue()) - { - request.AddHeader(Details::c_HeaderIfMatch, setAccessControlOptions.IfMatch.GetValue()); - } - if (setAccessControlOptions.IfNoneMatch.HasValue()) - { - request.AddHeader( - Details::c_HeaderIfNoneMatch, setAccessControlOptions.IfNoneMatch.GetValue()); - } - if (setAccessControlOptions.IfModifiedSince.HasValue()) - { - request.AddHeader( - Details::c_HeaderIfModifiedSince, setAccessControlOptions.IfModifiedSince.GetValue()); - } - if (setAccessControlOptions.IfUnmodifiedSince.HasValue()) - { - request.AddHeader( - Details::c_HeaderIfUnmodifiedSince, - setAccessControlOptions.IfUnmodifiedSince.GetValue()); - } - if (setAccessControlOptions.ClientRequestId.HasValue()) - { - request.AddHeader( - Details::c_HeaderClientRequestId, setAccessControlOptions.ClientRequestId.GetValue()); - } - request.AddHeader( - Details::c_HeaderApiVersionParameter, setAccessControlOptions.ApiVersionParameter); - return SetAccessControlParseResult(context, pipeline.Send(context, request)); - } + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for Blob Service Operations. + Azure::Core::Nullable + LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease + // is active and matches this ID. + Azure::Core::Nullable Owner; // Optional. The owner of the blob or directory. + Azure::Core::Nullable + Group; // Optional. The owning group of the blob or directory. + Azure::Core::Nullable + Permissions; // Optional and only valid if Hierarchical Namespace is enabled for the + // account. Sets POSIX access permissions for the file owner, the file + // owning group, and others. Each class may be granted read, write, or + // execute permission. The sticky bit is also supported. Both symbolic + // (rwxrw-rw-) and 4-digit octal notation (e.g. 0766) are supported. + Azure::Core::Nullable + Acl; // Sets POSIX access control rights on files and directories. The value is a + // comma-separated list of access control entries. Each access control entry + // (ACE) consists of a scope, a type, a user or group identifier, and permissions + // in the format "[scope:][type]:[id]:[permissions]". + Azure::Core::Nullable + IfMatch; // Specify an ETag value to operate only on blobs with a matching value. + Azure::Core::Nullable IfNoneMatch; // Specify an ETag value to operate only + // on blobs without a matching value. + Azure::Core::Nullable + IfModifiedSince; // Specify this header value to operate only on a blob if it has been + // modified since the specified date/time. + Azure::Core::Nullable + IfUnmodifiedSince; // Specify this header value to operate only on a blob if it has + // not been modified since the specified date/time. + Azure::Core::Nullable + ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character + // limit that is recorded in the analytics logs when storage + // analytics logging is enabled. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + }; - struct SetAccessControlRecursiveOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for Blob Service Operations. - Azure::Core::Nullable - ContinuationToken; // Optional. The number of paths processed with each invocation is - // limited. If the number of paths to be processed exceeds this - // limit, a continuation token is returned in the response header - // x-ms-continuation. When a continuation token is returned in the - // response, it must be percent-encoded and specified in a subsequent - // invocation of setAcessControlRecursive operation. - PathSetAccessControlRecursiveMode - Mode; // Mode "set" sets POSIX access control rights on files and directories, "modify" - // modifies one or more POSIX access control rights that pre-exist on files and - // directories, "remove" removes one or more POSIX access control rights that - // were present earlier on files and directories - Azure::Core::Nullable - ForceFlag; // Optional. Valid for "SetAccessControlRecursive" operation. If set to - // false, the operation will terminate quickly on encountering user errors - // (4XX). If true, the operation will ignore user errors and proceed with the - // operation on other sub-entities of the directory. Continuation token will - // only be returned when forceFlag is true in case of user errors. If not set - // the default value is false for this. - Azure::Core::Nullable - MaxRecords; // Optional. It specifies the maximum number of files or directories on - // which the acl change will be applied. If omitted or greater than 2,000, - // the request will process up to 2,000 items - Azure::Core::Nullable - Acl; // Sets POSIX access control rights on files and directories. The value is a - // comma-separated list of access control entries. Each access control entry (ACE) - // consists of a scope, a type, a user or group identifier, and permissions in the - // format "[scope:][type]:[id]:[permissions]". - Azure::Core::Nullable - ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character - // limit that is recorded in the analytics logs when storage analytics - // logging is enabled. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - }; + static Azure::Core::Response SetAccessControl( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + const Azure::Core::Context& context, + const SetAccessControlOptions& setAccessControlOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Patch, url); + request.GetUrl().AppendQueryParameter(Details::c_QueryAction, "setAccessControl"); + if (setAccessControlOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(setAccessControlOptions.Timeout.GetValue()))); + } + if (setAccessControlOptions.LeaseIdOptional.HasValue()) + { + request.AddHeader( + Details::c_HeaderLeaseIdOptional, + setAccessControlOptions.LeaseIdOptional.GetValue()); + } + if (setAccessControlOptions.Owner.HasValue()) + { + request.AddHeader(Details::c_HeaderOwner, setAccessControlOptions.Owner.GetValue()); + } + if (setAccessControlOptions.Group.HasValue()) + { + request.AddHeader(Details::c_HeaderGroup, setAccessControlOptions.Group.GetValue()); + } + if (setAccessControlOptions.Permissions.HasValue()) + { + request.AddHeader( + Details::c_HeaderPermissions, setAccessControlOptions.Permissions.GetValue()); + } + if (setAccessControlOptions.Acl.HasValue()) + { + request.AddHeader(Details::c_HeaderAcl, setAccessControlOptions.Acl.GetValue()); + } + if (setAccessControlOptions.IfMatch.HasValue()) + { + request.AddHeader(Details::c_HeaderIfMatch, setAccessControlOptions.IfMatch.GetValue()); + } + if (setAccessControlOptions.IfNoneMatch.HasValue()) + { + request.AddHeader( + Details::c_HeaderIfNoneMatch, setAccessControlOptions.IfNoneMatch.GetValue()); + } + if (setAccessControlOptions.IfModifiedSince.HasValue()) + { + request.AddHeader( + Details::c_HeaderIfModifiedSince, + setAccessControlOptions.IfModifiedSince.GetValue()); + } + if (setAccessControlOptions.IfUnmodifiedSince.HasValue()) + { + request.AddHeader( + Details::c_HeaderIfUnmodifiedSince, + setAccessControlOptions.IfUnmodifiedSince.GetValue()); + } + if (setAccessControlOptions.ClientRequestId.HasValue()) + { + request.AddHeader( + Details::c_HeaderClientRequestId, + setAccessControlOptions.ClientRequestId.GetValue()); + } + request.AddHeader( + Details::c_HeaderApiVersionParameter, setAccessControlOptions.ApiVersionParameter); + return SetAccessControlParseResult(context, pipeline.Send(context, request)); + } - static Azure::Core::Response SetAccessControlRecursive( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - const Azure::Core::Context& context, - const SetAccessControlRecursiveOptions& setAccessControlRecursiveOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Patch, url); - request.GetUrl().AppendQueryParameter(Details::c_QueryAction, "setAccessControlRecursive"); - if (setAccessControlRecursiveOptions.Timeout.HasValue()) + struct SetAccessControlRecursiveOptions { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(setAccessControlRecursiveOptions.Timeout.GetValue()))); - } - if (setAccessControlRecursiveOptions.ContinuationToken.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryContinuationToken, - Storage::Details::UrlEncodeQueryParameter( - setAccessControlRecursiveOptions.ContinuationToken.GetValue())); - } - request.GetUrl().AppendQueryParameter( - Details::c_QueryPathSetAccessControlRecursiveMode, - Storage::Details::UrlEncodeQueryParameter( - PathSetAccessControlRecursiveModeToString(setAccessControlRecursiveOptions.Mode))); - if (setAccessControlRecursiveOptions.ForceFlag.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryForceFlag, - Storage::Details::UrlEncodeQueryParameter( - (setAccessControlRecursiveOptions.ForceFlag.GetValue() ? "true" : "false"))); - } - if (setAccessControlRecursiveOptions.MaxRecords.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryMaxRecords, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(setAccessControlRecursiveOptions.MaxRecords.GetValue()))); - } - if (setAccessControlRecursiveOptions.Acl.HasValue()) - { - request.AddHeader(Details::c_HeaderAcl, setAccessControlRecursiveOptions.Acl.GetValue()); - } - if (setAccessControlRecursiveOptions.ClientRequestId.HasValue()) - { - request.AddHeader( - Details::c_HeaderClientRequestId, - setAccessControlRecursiveOptions.ClientRequestId.GetValue()); - } - request.AddHeader( - Details::c_HeaderApiVersionParameter, - setAccessControlRecursiveOptions.ApiVersionParameter); - return SetAccessControlRecursiveParseResult(context, pipeline.Send(context, request)); - } + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for Blob Service Operations. + Azure::Core::Nullable + ContinuationToken; // Optional. When deleting a directory, the number of paths that + // are deleted with each invocation is limited. If the number of + // paths to be deleted exceeds this limit, a continuation token is + // returned in this response header. When a continuation token is + // returned in the response, it must be specified in a subsequent + // invocation of the delete operation to continue deleting the + // directory. + PathSetAccessControlRecursiveMode + Mode; // Mode "set" sets POSIX access control rights on files and directories, + // "modify" modifies one or more POSIX access control rights that pre-exist on + // files and directories, "remove" removes one or more POSIX access control + // rights that were present earlier on files and directories + Azure::Core::Nullable + ForceFlag; // Optional. Valid for "SetAccessControlRecursive" operation. If set to + // false, the operation will terminate quickly on encountering user errors + // (4XX). If true, the operation will ignore user errors and proceed with + // the operation on other sub-entities of the directory. Continuation token + // will only be returned when forceFlag is true in case of user errors. If + // not set the default value is false for this. + Azure::Core::Nullable + MaxRecords; // Optional. It specifies the maximum number of files or directories on + // which the acl change will be applied. If omitted or greater than 2,000, + // the request will process up to 2,000 items + Azure::Core::Nullable + Acl; // Sets POSIX access control rights on files and directories. The value is a + // comma-separated list of access control entries. Each access control entry + // (ACE) consists of a scope, a type, a user or group identifier, and permissions + // in the format "[scope:][type]:[id]:[permissions]". + Azure::Core::Nullable + ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character + // limit that is recorded in the analytics logs when storage + // analytics logging is enabled. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + }; - struct FlushDataOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for Blob Service Operations. - Azure::Core::Nullable - Position; // This parameter allows the caller to upload data in parallel and control the - // order in which it is appended to the file. It is required when uploading - // data to be appended to the file and when flushing previously uploaded data - // to the file. The value must be the position where the data is to be - // appended. Uploaded data is not immediately flushed, or written, to the - // file. To flush, the previously uploaded data must be contiguous, the - // position parameter must be specified and equal to the length of the file - // after all data has been written, and there must not be a request entity - // body included with the request. - Azure::Core::Nullable - RetainUncommittedData; // Valid only for flush operations. If "true", uncommitted data - // is retained after the flush operation completes; otherwise, - // the uncommitted data is deleted after the flush operation. The - // default is false. Data at offsets less than the specified - // position are written to the file when flush succeeds, but this - // optional parameter allows data after the flush position to be - // retained for a future flush operation. - Azure::Core::Nullable - Close; // Azure Storage Events allow applications to receive notifications when files - // change. When Azure Storage Events are enabled, a file changed event is raised. - // This event has a property indicating whether this is the final change to - // distinguish the difference between an intermediate flush to a file stream and - // the final close of a file stream. The close query parameter is valid only when - // the action is "flush" and change notifications are enabled. If the value of - // close is "true" and the flush operation completes successfully, the service - // raises a file change notification with a property indicating that this is the - // final update (the file stream has been closed). If "false" a change - // notification is raised indicating the file has changed. The default is false. - // This query parameter is set to true by the Hadoop ABFS driver to indicate that - // the file stream has been closed." - Azure::Core::Nullable - ContentLength; // Required for "Append Data" and "Flush Data". Must be 0 for "Flush - // Data". Must be the length of the request content in bytes for "Append - // Data". - Azure::Core::Nullable ContentMd5; // Specify the transactional md5 for the - // body, to be validated by the service. - Azure::Core::Nullable - LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease is - // active and matches this ID. - Azure::Core::Nullable - CacheControl; // Optional. Sets the blob's cache control. If specified, this property is - // stored with the blob and returned with a read request. - Azure::Core::Nullable - ContentType; // Optional. Sets the blob's content type. If specified, this property is - // stored with the blob and returned with a read request. - Azure::Core::Nullable - ContentDisposition; // Optional. Sets the blob's Content-Disposition header. - Azure::Core::Nullable - ContentEncoding; // Optional. Sets the blob's content encoding. If specified, this - // property is stored with the blob and returned with a read request. - Azure::Core::Nullable - ContentLanguage; // Optional. Set the blob's content language. If specified, this - // property is stored with the blob and returned with a read request. - Azure::Core::Nullable - IfMatch; // Specify an ETag value to operate only on blobs with a matching value. - Azure::Core::Nullable - IfNoneMatch; // Specify an ETag value to operate only on blobs without a matching value. - Azure::Core::Nullable - IfModifiedSince; // Specify this header value to operate only on a blob if it has been - // modified since the specified date/time. - Azure::Core::Nullable - IfUnmodifiedSince; // Specify this header value to operate only on a blob if it has not - // been modified since the specified date/time. - Azure::Core::Nullable - ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character - // limit that is recorded in the analytics logs when storage analytics - // logging is enabled. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - }; + static Azure::Core::Response SetAccessControlRecursive( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + const Azure::Core::Context& context, + const SetAccessControlRecursiveOptions& setAccessControlRecursiveOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Patch, url); + request.GetUrl().AppendQueryParameter( + Details::c_QueryAction, "setAccessControlRecursive"); + if (setAccessControlRecursiveOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(setAccessControlRecursiveOptions.Timeout.GetValue()))); + } + if (setAccessControlRecursiveOptions.ContinuationToken.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryContinuationToken, + Storage::Details::UrlEncodeQueryParameter( + setAccessControlRecursiveOptions.ContinuationToken.GetValue())); + } + request.GetUrl().AppendQueryParameter( + Details::c_QueryPathSetAccessControlRecursiveMode, + Storage::Details::UrlEncodeQueryParameter(PathSetAccessControlRecursiveModeToString( + setAccessControlRecursiveOptions.Mode))); + if (setAccessControlRecursiveOptions.ForceFlag.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryForceFlag, + Storage::Details::UrlEncodeQueryParameter( + (setAccessControlRecursiveOptions.ForceFlag.GetValue() ? "true" : "false"))); + } + if (setAccessControlRecursiveOptions.MaxRecords.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryMaxRecords, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(setAccessControlRecursiveOptions.MaxRecords.GetValue()))); + } + if (setAccessControlRecursiveOptions.Acl.HasValue()) + { + request.AddHeader( + Details::c_HeaderAcl, setAccessControlRecursiveOptions.Acl.GetValue()); + } + if (setAccessControlRecursiveOptions.ClientRequestId.HasValue()) + { + request.AddHeader( + Details::c_HeaderClientRequestId, + setAccessControlRecursiveOptions.ClientRequestId.GetValue()); + } + request.AddHeader( + Details::c_HeaderApiVersionParameter, + setAccessControlRecursiveOptions.ApiVersionParameter); + return SetAccessControlRecursiveParseResult(context, pipeline.Send(context, request)); + } - static Azure::Core::Response FlushData( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - const Azure::Core::Context& context, - const FlushDataOptions& flushDataOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Patch, url); - request.GetUrl().AppendQueryParameter(Details::c_QueryAction, "flush"); - if (flushDataOptions.Timeout.HasValue()) + struct FlushDataOptions { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(flushDataOptions.Timeout.GetValue()))); - } - if (flushDataOptions.Position.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryPosition, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(flushDataOptions.Position.GetValue()))); - } - if (flushDataOptions.RetainUncommittedData.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryRetainUncommittedData, - Storage::Details::UrlEncodeQueryParameter( - (flushDataOptions.RetainUncommittedData.GetValue() ? "true" : "false"))); - } - if (flushDataOptions.Close.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryClose, - Storage::Details::UrlEncodeQueryParameter( - (flushDataOptions.Close.GetValue() ? "true" : "false"))); - } - if (flushDataOptions.ContentLength.HasValue()) - { - request.AddHeader( - Details::c_HeaderContentLength, - std::to_string(flushDataOptions.ContentLength.GetValue())); - } - if (flushDataOptions.ContentMd5.HasValue()) - { - request.AddHeader(Details::c_HeaderContentMd5, flushDataOptions.ContentMd5.GetValue()); - } - if (flushDataOptions.LeaseIdOptional.HasValue()) - { - request.AddHeader( - Details::c_HeaderLeaseIdOptional, flushDataOptions.LeaseIdOptional.GetValue()); - } - if (flushDataOptions.CacheControl.HasValue()) - { - request.AddHeader( - Details::c_HeaderCacheControl, flushDataOptions.CacheControl.GetValue()); - } - if (flushDataOptions.ContentType.HasValue()) - { - request.AddHeader(Details::c_HeaderContentType, flushDataOptions.ContentType.GetValue()); - } - if (flushDataOptions.ContentDisposition.HasValue()) - { - request.AddHeader( - Details::c_HeaderContentDisposition, flushDataOptions.ContentDisposition.GetValue()); - } - if (flushDataOptions.ContentEncoding.HasValue()) - { - request.AddHeader( - Details::c_HeaderContentEncoding, flushDataOptions.ContentEncoding.GetValue()); - } - if (flushDataOptions.ContentLanguage.HasValue()) - { - request.AddHeader( - Details::c_HeaderContentLanguage, flushDataOptions.ContentLanguage.GetValue()); - } - if (flushDataOptions.IfMatch.HasValue()) - { - request.AddHeader(Details::c_HeaderIfMatch, flushDataOptions.IfMatch.GetValue()); - } - if (flushDataOptions.IfNoneMatch.HasValue()) - { - request.AddHeader(Details::c_HeaderIfNoneMatch, flushDataOptions.IfNoneMatch.GetValue()); - } - if (flushDataOptions.IfModifiedSince.HasValue()) - { - request.AddHeader( - Details::c_HeaderIfModifiedSince, flushDataOptions.IfModifiedSince.GetValue()); - } - if (flushDataOptions.IfUnmodifiedSince.HasValue()) - { - request.AddHeader( - Details::c_HeaderIfUnmodifiedSince, flushDataOptions.IfUnmodifiedSince.GetValue()); - } - if (flushDataOptions.ClientRequestId.HasValue()) - { - request.AddHeader( - Details::c_HeaderClientRequestId, flushDataOptions.ClientRequestId.GetValue()); - } - request.AddHeader( - Details::c_HeaderApiVersionParameter, flushDataOptions.ApiVersionParameter); - return FlushDataParseResult(context, pipeline.Send(context, request)); - } - - struct AppendDataOptions - { - Azure::Core::Nullable - Position; // This parameter allows the caller to upload data in parallel and control the - // order in which it is appended to the file. It is required when uploading - // data to be appended to the file and when flushing previously uploaded data - // to the file. The value must be the position where the data is to be - // appended. Uploaded data is not immediately flushed, or written, to the - // file. To flush, the previously uploaded data must be contiguous, the - // position parameter must be specified and equal to the length of the file - // after all data has been written, and there must not be a request entity - // body included with the request. - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for Blob Service Operations. - Azure::Core::Nullable - ContentLength; // Required for "Append Data" and "Flush Data". Must be 0 for "Flush - // Data". Must be the length of the request content in bytes for "Append - // Data". - Azure::Core::Nullable - TransactionalContentMd5; // Specify the transactional md5 for the body, to be validated - // by the service. - Azure::Core::Nullable ContentCrc64; // Specify the transactional crc64 for the + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for Blob Service Operations. + Azure::Core::Nullable + Position; // This parameter allows the caller to upload data in parallel and control + // the order in which it is appended to the file. It is required when + // uploading data to be appended to the file and when flushing previously + // uploaded data to the file. The value must be the position where the data + // is to be appended. Uploaded data is not immediately flushed, or written, + // to the file. To flush, the previously uploaded data must be contiguous, + // the position parameter must be specified and equal to the length of the + // file after all data has been written, and there must not be a request + // entity body included with the request. + Azure::Core::Nullable + RetainUncommittedData; // Valid only for flush operations. If "true", uncommitted + // data is retained after the flush operation completes; + // otherwise, the uncommitted data is deleted after the flush + // operation. The default is false. Data at offsets less than + // the specified position are written to the file when flush + // succeeds, but this optional parameter allows data after the + // flush position to be retained for a future flush operation. + Azure::Core::Nullable + Close; // Azure Storage Events allow applications to receive notifications when files + // change. When Azure Storage Events are enabled, a file changed event is + // raised. This event has a property indicating whether this is the final + // change to distinguish the difference between an intermediate flush to a file + // stream and the final close of a file stream. The close query parameter is + // valid only when the action is "flush" and change notifications are enabled. + // If the value of close is "true" and the flush operation completes + // successfully, the service raises a file change notification with a property + // indicating that this is the final update (the file stream has been closed). + // If "false" a change notification is raised indicating the file has changed. + // The default is false. This query parameter is set to true by the Hadoop ABFS + // driver to indicate that the file stream has been closed." + Azure::Core::Nullable + ContentLength; // Required for "Append Data" and "Flush Data". Must be 0 for "Flush + // Data". Must be the length of the request content in bytes for + // "Append Data". + Azure::Core::Nullable ContentMd5; // Specify the transactional md5 for the // body, to be validated by the service. - Azure::Core::Nullable - LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease is - // active and matches this ID. - Azure::Core::Nullable - ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character - // limit that is recorded in the analytics logs when storage analytics - // logging is enabled. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - }; + Azure::Core::Nullable + LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease + // is active and matches this ID. + Azure::Core::Nullable + CacheControl; // Optional. Sets the blob's cache control. If specified, this property + // is stored with the blob and returned with a read request. + Azure::Core::Nullable + ContentType; // Optional. Sets the blob's content type. If specified, this property is + // stored with the blob and returned with a read request. + Azure::Core::Nullable + ContentDisposition; // Optional. Sets the blob's Content-Disposition header. + Azure::Core::Nullable + ContentEncoding; // Optional. Sets the blob's content encoding. If specified, this + // property is stored with the blob and returned with a read request. + Azure::Core::Nullable + ContentLanguage; // Optional. Set the blob's content language. If specified, this + // property is stored with the blob and returned with a read request. + Azure::Core::Nullable + IfMatch; // Specify an ETag value to operate only on blobs with a matching value. + Azure::Core::Nullable IfNoneMatch; // Specify an ETag value to operate only + // on blobs without a matching value. + Azure::Core::Nullable + IfModifiedSince; // Specify this header value to operate only on a blob if it has been + // modified since the specified date/time. + Azure::Core::Nullable + IfUnmodifiedSince; // Specify this header value to operate only on a blob if it has + // not been modified since the specified date/time. + Azure::Core::Nullable + ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character + // limit that is recorded in the analytics logs when storage + // analytics logging is enabled. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + }; - static Azure::Core::Response AppendData( - const Azure::Core::Http::Url& url, - Azure::Core::Http::BodyStream& bodyStream, - Azure::Core::Http::HttpPipeline& pipeline, - const Azure::Core::Context& context, - const AppendDataOptions& appendDataOptions) - { - Azure::Core::Http::Request request( - Azure::Core::Http::HttpMethod::Patch, std::move(url), &bodyStream); - request.GetUrl().AppendQueryParameter(Details::c_QueryAction, "append"); - if (appendDataOptions.Position.HasValue()) + static Azure::Core::Response FlushData( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + const Azure::Core::Context& context, + const FlushDataOptions& flushDataOptions) { - request.GetUrl().AppendQueryParameter( - Details::c_QueryPosition, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(appendDataOptions.Position.GetValue()))); - } - if (appendDataOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(appendDataOptions.Timeout.GetValue()))); - } - if (appendDataOptions.ContentLength.HasValue()) - { - request.AddHeader( - Details::c_HeaderContentLength, - std::to_string(appendDataOptions.ContentLength.GetValue())); - } - if (appendDataOptions.TransactionalContentMd5.HasValue()) - { - request.AddHeader( - Details::c_HeaderTransactionalContentMd5, - appendDataOptions.TransactionalContentMd5.GetValue()); - } - if (appendDataOptions.ContentCrc64.HasValue()) - { - request.AddHeader( - Details::c_HeaderContentCrc64, appendDataOptions.ContentCrc64.GetValue()); - } - if (appendDataOptions.LeaseIdOptional.HasValue()) - { - request.AddHeader( - Details::c_HeaderLeaseIdOptional, appendDataOptions.LeaseIdOptional.GetValue()); - } - if (appendDataOptions.ClientRequestId.HasValue()) - { - request.AddHeader( - Details::c_HeaderClientRequestId, appendDataOptions.ClientRequestId.GetValue()); - } - request.AddHeader( - Details::c_HeaderApiVersionParameter, appendDataOptions.ApiVersionParameter); - return AppendDataParseResult(context, pipeline.Send(context, request)); - } - - struct SetExpiryOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for Blob Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character - // limit that is recorded in the analytics logs when storage analytics - // logging is enabled. - PathExpiryOptions XMsExpiryOption; // Required. Indicates mode of the expiry time - Azure::Core::Nullable PathExpiryTime; // The time to set the blob to expiry - }; - - static Azure::Core::Response SetExpiry( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - const Azure::Core::Context& context, - const SetExpiryOptions& setExpiryOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); - request.AddHeader(Details::c_HeaderContentLength, "0"); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "expiry"); - if (setExpiryOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(setExpiryOptions.Timeout.GetValue()))); - } - request.AddHeader( - Details::c_HeaderApiVersionParameter, setExpiryOptions.ApiVersionParameter); - if (setExpiryOptions.ClientRequestId.HasValue()) - { - request.AddHeader( - Details::c_HeaderClientRequestId, setExpiryOptions.ClientRequestId.GetValue()); - } - request.AddHeader( - Details::c_HeaderPathExpiryOptions, - PathExpiryOptionsToString(setExpiryOptions.XMsExpiryOption)); - if (setExpiryOptions.PathExpiryTime.HasValue()) - { - request.AddHeader( - Details::c_HeaderPathExpiryTime, setExpiryOptions.PathExpiryTime.GetValue()); - } - return SetExpiryParseResult(context, pipeline.Send(context, request)); - } - - private: - static Azure::Core::Response CreateParseResult( - const Azure::Core::Context& context, - std::unique_ptr responsePtr) - { - /* const */ auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Created) - { - // The file or directory was created. - PathCreateResult result; - if (response.GetHeaders().find(Details::c_HeaderETag) != response.GetHeaders().end()) + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Patch, url); + request.GetUrl().AppendQueryParameter(Details::c_QueryAction, "flush"); + if (flushDataOptions.Timeout.HasValue()) { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(flushDataOptions.Timeout.GetValue()))); + } + if (flushDataOptions.Position.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryPosition, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(flushDataOptions.Position.GetValue()))); + } + if (flushDataOptions.RetainUncommittedData.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryRetainUncommittedData, + Storage::Details::UrlEncodeQueryParameter( + (flushDataOptions.RetainUncommittedData.GetValue() ? "true" : "false"))); + } + if (flushDataOptions.Close.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryClose, + Storage::Details::UrlEncodeQueryParameter( + (flushDataOptions.Close.GetValue() ? "true" : "false"))); + } + if (flushDataOptions.ContentLength.HasValue()) + { + request.AddHeader( + Details::c_HeaderContentLength, + std::to_string(flushDataOptions.ContentLength.GetValue())); + } + if (flushDataOptions.ContentMd5.HasValue()) + { + request.AddHeader(Details::c_HeaderContentMd5, flushDataOptions.ContentMd5.GetValue()); + } + if (flushDataOptions.LeaseIdOptional.HasValue()) + { + request.AddHeader( + Details::c_HeaderLeaseIdOptional, flushDataOptions.LeaseIdOptional.GetValue()); + } + if (flushDataOptions.CacheControl.HasValue()) + { + request.AddHeader( + Details::c_HeaderCacheControl, flushDataOptions.CacheControl.GetValue()); + } + if (flushDataOptions.ContentType.HasValue()) + { + request.AddHeader( + Details::c_HeaderContentType, flushDataOptions.ContentType.GetValue()); + } + if (flushDataOptions.ContentDisposition.HasValue()) + { + request.AddHeader( + Details::c_HeaderContentDisposition, + flushDataOptions.ContentDisposition.GetValue()); + } + if (flushDataOptions.ContentEncoding.HasValue()) + { + request.AddHeader( + Details::c_HeaderContentEncoding, flushDataOptions.ContentEncoding.GetValue()); + } + if (flushDataOptions.ContentLanguage.HasValue()) + { + request.AddHeader( + Details::c_HeaderContentLanguage, flushDataOptions.ContentLanguage.GetValue()); + } + if (flushDataOptions.IfMatch.HasValue()) + { + request.AddHeader(Details::c_HeaderIfMatch, flushDataOptions.IfMatch.GetValue()); + } + if (flushDataOptions.IfNoneMatch.HasValue()) + { + request.AddHeader( + Details::c_HeaderIfNoneMatch, flushDataOptions.IfNoneMatch.GetValue()); + } + if (flushDataOptions.IfModifiedSince.HasValue()) + { + request.AddHeader( + Details::c_HeaderIfModifiedSince, flushDataOptions.IfModifiedSince.GetValue()); + } + if (flushDataOptions.IfUnmodifiedSince.HasValue()) + { + request.AddHeader( + Details::c_HeaderIfUnmodifiedSince, flushDataOptions.IfUnmodifiedSince.GetValue()); + } + if (flushDataOptions.ClientRequestId.HasValue()) + { + request.AddHeader( + Details::c_HeaderClientRequestId, flushDataOptions.ClientRequestId.GetValue()); + } + request.AddHeader( + Details::c_HeaderApiVersionParameter, flushDataOptions.ApiVersionParameter); + return FlushDataParseResult(context, pipeline.Send(context, request)); + } + + struct AppendDataOptions + { + Azure::Core::Nullable + Position; // This parameter allows the caller to upload data in parallel and control + // the order in which it is appended to the file. It is required when + // uploading data to be appended to the file and when flushing previously + // uploaded data to the file. The value must be the position where the data + // is to be appended. Uploaded data is not immediately flushed, or written, + // to the file. To flush, the previously uploaded data must be contiguous, + // the position parameter must be specified and equal to the length of the + // file after all data has been written, and there must not be a request + // entity body included with the request. + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for Blob Service Operations. + Azure::Core::Nullable + ContentLength; // Required for "Append Data" and "Flush Data". Must be 0 for "Flush + // Data". Must be the length of the request content in bytes for + // "Append Data". + Azure::Core::Nullable + TransactionalContentMd5; // Specify the transactional md5 for the body, to be + // validated by the service. + Azure::Core::Nullable + ContentCrc64; // Specify the transactional crc64 for the body, to be validated by the + // service. + Azure::Core::Nullable + LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease + // is active and matches this ID. + Azure::Core::Nullable + ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character + // limit that is recorded in the analytics logs when storage + // analytics logging is enabled. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + }; + + static Azure::Core::Response AppendData( + const Azure::Core::Http::Url& url, + Azure::Core::Http::BodyStream& bodyStream, + Azure::Core::Http::HttpPipeline& pipeline, + const Azure::Core::Context& context, + const AppendDataOptions& appendDataOptions) + { + Azure::Core::Http::Request request( + Azure::Core::Http::HttpMethod::Patch, std::move(url), &bodyStream); + request.GetUrl().AppendQueryParameter(Details::c_QueryAction, "append"); + if (appendDataOptions.Position.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryPosition, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(appendDataOptions.Position.GetValue()))); + } + if (appendDataOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(appendDataOptions.Timeout.GetValue()))); + } + if (appendDataOptions.ContentLength.HasValue()) + { + request.AddHeader( + Details::c_HeaderContentLength, + std::to_string(appendDataOptions.ContentLength.GetValue())); + } + if (appendDataOptions.TransactionalContentMd5.HasValue()) + { + request.AddHeader( + Details::c_HeaderTransactionalContentMd5, + appendDataOptions.TransactionalContentMd5.GetValue()); + } + if (appendDataOptions.ContentCrc64.HasValue()) + { + request.AddHeader( + Details::c_HeaderContentCrc64, appendDataOptions.ContentCrc64.GetValue()); + } + if (appendDataOptions.LeaseIdOptional.HasValue()) + { + request.AddHeader( + Details::c_HeaderLeaseIdOptional, appendDataOptions.LeaseIdOptional.GetValue()); + } + if (appendDataOptions.ClientRequestId.HasValue()) + { + request.AddHeader( + Details::c_HeaderClientRequestId, appendDataOptions.ClientRequestId.GetValue()); + } + request.AddHeader( + Details::c_HeaderApiVersionParameter, appendDataOptions.ApiVersionParameter); + return AppendDataParseResult(context, pipeline.Send(context, request)); + } + + struct SetExpiryOptions + { + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for Blob Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character + // limit that is recorded in the analytics logs when storage + // analytics logging is enabled. + PathExpiryOptions XMsExpiryOption; // Required. Indicates mode of the expiry time + Azure::Core::Nullable PathExpiryTime; // The time to set the blob to expiry + }; + + static Azure::Core::Response SetExpiry( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + const Azure::Core::Context& context, + const SetExpiryOptions& setExpiryOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); + request.AddHeader(Details::c_HeaderContentLength, "0"); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "expiry"); + if (setExpiryOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(setExpiryOptions.Timeout.GetValue()))); + } + request.AddHeader( + Details::c_HeaderApiVersionParameter, setExpiryOptions.ApiVersionParameter); + if (setExpiryOptions.ClientRequestId.HasValue()) + { + request.AddHeader( + Details::c_HeaderClientRequestId, setExpiryOptions.ClientRequestId.GetValue()); + } + request.AddHeader( + Details::c_HeaderPathExpiryOptions, + PathExpiryOptionsToString(setExpiryOptions.XMsExpiryOption)); + if (setExpiryOptions.PathExpiryTime.HasValue()) + { + request.AddHeader( + Details::c_HeaderPathExpiryTime, setExpiryOptions.PathExpiryTime.GetValue()); + } + return SetExpiryParseResult(context, pipeline.Send(context, request)); + } + + private: + static Azure::Core::Response CreateParseResult( + const Azure::Core::Context& context, + std::unique_ptr responsePtr) + { + /* const */ auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Created) + { + // The file or directory was created. + PathCreateResult result; + if (response.GetHeaders().find(Details::c_HeaderETag) != response.GetHeaders().end()) + { + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + } + if (response.GetHeaders().find(Details::c_HeaderLastModified) + != response.GetHeaders().end()) + { + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + } + if (response.GetHeaders().find(Details::c_HeaderXMsContinuation) + != response.GetHeaders().end()) + { + result.ContinuationToken = response.GetHeaders().at(Details::c_HeaderXMsContinuation); + } + if (response.GetHeaders().find(Details::c_HeaderContentLength) + != response.GetHeaders().end()) + { + result.ContentLength + = std::stoll(response.GetHeaders().at(Details::c_HeaderContentLength)); + } + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Core::Response LeaseParseResult( + const Azure::Core::Context& context, + std::unique_ptr responsePtr) + { + /* const */ auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + { + // The "renew", "change" or "release" action was successful. + PathLeaseResult result; result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - } - if (response.GetHeaders().find(Details::c_HeaderLastModified) - != response.GetHeaders().end()) - { result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + if (response.GetHeaders().find(Details::c_HeaderXMsLeaseId) + != response.GetHeaders().end()) + { + result.LeaseId = response.GetHeaders().at(Details::c_HeaderXMsLeaseId); + } + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); } - if (response.GetHeaders().find(Details::c_HeaderXMsContinuation) - != response.GetHeaders().end()) - { - result.ContinuationToken = response.GetHeaders().at(Details::c_HeaderXMsContinuation); - } - if (response.GetHeaders().find(Details::c_HeaderContentLength) - != response.GetHeaders().end()) - { - result.ContentLength - = std::stoll(response.GetHeaders().at(Details::c_HeaderContentLength)); - } - return Azure::Core::Response(std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response UpdateParseResult( - const Azure::Core::Context& context, - std::unique_ptr responsePtr) - { - /* const */ auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) - { - // The data was flushed (written) to the file or the properties were set successfully. - // Response body is optional and is valid only for "SetAccessControlRecursive" - const auto& bodyBuffer = response.GetBody(); - PathUpdateResult result = bodyBuffer.empty() - ? PathUpdateResult() - : PathUpdateResult::PathUpdateResultFromSetAccessControlRecursiveResponse( - SetAccessControlRecursiveResponse::CreateFromJson( - nlohmann::json::parse(bodyBuffer))); - if (response.GetHeaders().find(Details::c_HeaderETag) != response.GetHeaders().end()) + else if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Created) { + // A new lease has been created. The "acquire" action was successful. + PathLeaseResult result; result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - } - if (response.GetHeaders().find(Details::c_HeaderLastModified) - != response.GetHeaders().end()) - { result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + if (response.GetHeaders().find(Details::c_HeaderXMsLeaseId) + != response.GetHeaders().end()) + { + result.LeaseId = response.GetHeaders().at(Details::c_HeaderXMsLeaseId); + } + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); } - if (response.GetHeaders().find(Details::c_HeaderAcceptRanges) - != response.GetHeaders().end()) + else if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Accepted) { - result.AcceptRanges = response.GetHeaders().at(Details::c_HeaderAcceptRanges); + // The "break" lease action was successful. + PathLeaseResult result; + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + result.LeaseTime = response.GetHeaders().at(Details::c_HeaderXMsLeaseTime); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); } - if (response.GetHeaders().find("cache-control") != response.GetHeaders().end()) + else { - result.HttpHeaders.CacheControl = response.GetHeaders().at("cache-control"); + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); } - if (response.GetHeaders().find("content-disposition") != response.GetHeaders().end()) - { - result.HttpHeaders.ContentDisposition = response.GetHeaders().at("content-disposition"); - } - if (response.GetHeaders().find("content-encoding") != response.GetHeaders().end()) - { - result.HttpHeaders.ContentEncoding = response.GetHeaders().at("content-encoding"); - } - if (response.GetHeaders().find("content-language") != response.GetHeaders().end()) - { - result.HttpHeaders.ContentLanguage = response.GetHeaders().at("content-language"); - } - if (response.GetHeaders().find(Details::c_HeaderContentLength) - != response.GetHeaders().end()) - { - result.ContentLength - = std::stoll(response.GetHeaders().at(Details::c_HeaderContentLength)); - } - if (response.GetHeaders().find(Details::c_HeaderContentRange) - != response.GetHeaders().end()) - { - result.ContentRange = response.GetHeaders().at(Details::c_HeaderContentRange); - } - if (response.GetHeaders().find("content-type") != response.GetHeaders().end()) - { - result.HttpHeaders.ContentType = response.GetHeaders().at("content-type"); - } - if (response.GetHeaders().find(Details::c_HeaderContentMD5) - != response.GetHeaders().end()) - { - result.ContentMd5 = response.GetHeaders().at(Details::c_HeaderContentMD5); - } - if (response.GetHeaders().find(Details::c_HeaderXMsProperties) - != response.GetHeaders().end()) - { - result.Properties = response.GetHeaders().at(Details::c_HeaderXMsProperties); - } - if (response.GetHeaders().find(Details::c_HeaderXMsContinuation) - != response.GetHeaders().end()) - { - result.ContinuationToken = response.GetHeaders().at(Details::c_HeaderXMsContinuation); - } - return Azure::Core::Response(std::move(result), std::move(responsePtr)); } - else if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Accepted) - { - // The uploaded data was accepted. - PathUpdateResult result; - if (response.GetHeaders().find(Details::c_HeaderContentMD5) - != response.GetHeaders().end()) - { - result.ContentMd5 = response.GetHeaders().at(Details::c_HeaderContentMD5); - } - return Azure::Core::Response(std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - static Azure::Core::Response LeaseParseResult( - const Azure::Core::Context& context, - std::unique_ptr responsePtr) - { - /* const */ auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + static Azure::Core::Response ReadParseResult( + const Azure::Core::Context& context, + std::unique_ptr responsePtr) { - // The "renew", "change" or "release" action was successful. - PathLeaseResult result; - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - if (response.GetHeaders().find(Details::c_HeaderXMsLeaseId) - != response.GetHeaders().end()) - { - result.LeaseId = response.GetHeaders().at(Details::c_HeaderXMsLeaseId); - } - return Azure::Core::Response(std::move(result), std::move(responsePtr)); - } - else if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Created) - { - // A new lease has been created. The "acquire" action was successful. - PathLeaseResult result; - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - if (response.GetHeaders().find(Details::c_HeaderXMsLeaseId) - != response.GetHeaders().end()) - { - result.LeaseId = response.GetHeaders().at(Details::c_HeaderXMsLeaseId); - } - return Azure::Core::Response(std::move(result), std::move(responsePtr)); - } - else if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Accepted) - { - // The "break" lease action was successful. - PathLeaseResult result; - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - result.LeaseTime = response.GetHeaders().at(Details::c_HeaderXMsLeaseTime); - return Azure::Core::Response(std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response ReadParseResult( - const Azure::Core::Context& context, - std::unique_ptr responsePtr) - { - /* const */ auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) - { - // Ok - PathReadResult result; - result.BodyStream = response.GetBodyStream(); - if (response.GetHeaders().find(Details::c_HeaderAcceptRanges) - != response.GetHeaders().end()) + /* const */ auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) { + // Ok + PathReadResult result; + result.BodyStream = response.GetBodyStream(); result.AcceptRanges = response.GetHeaders().at(Details::c_HeaderAcceptRanges); - } - if (response.GetHeaders().find("cache-control") != response.GetHeaders().end()) - { - result.HttpHeaders.CacheControl = response.GetHeaders().at("cache-control"); - } - if (response.GetHeaders().find("content-disposition") != response.GetHeaders().end()) - { - result.HttpHeaders.ContentDisposition = response.GetHeaders().at("content-disposition"); - } - if (response.GetHeaders().find("content-encoding") != response.GetHeaders().end()) - { - result.HttpHeaders.ContentEncoding = response.GetHeaders().at("content-encoding"); - } - if (response.GetHeaders().find("content-language") != response.GetHeaders().end()) - { - result.HttpHeaders.ContentLanguage = response.GetHeaders().at("content-language"); - } - if (response.GetHeaders().find(Details::c_HeaderContentLength) - != response.GetHeaders().end()) - { - result.ContentLength - = std::stoll(response.GetHeaders().at(Details::c_HeaderContentLength)); - } - if (response.GetHeaders().find(Details::c_HeaderContentRange) - != response.GetHeaders().end()) - { - result.ContentRange = response.GetHeaders().at(Details::c_HeaderContentRange); - } - if (response.GetHeaders().find("content-type") != response.GetHeaders().end()) - { - result.HttpHeaders.ContentType = response.GetHeaders().at("content-type"); - } - if (response.GetHeaders().find(Details::c_HeaderContentMD5) - != response.GetHeaders().end()) - { - result.ContentMd5 = response.GetHeaders().at(Details::c_HeaderContentMD5); - } - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - result.ResourceType = response.GetHeaders().at(Details::c_HeaderXMsResourceType); - if (response.GetHeaders().find(Details::c_HeaderXMsProperties) - != response.GetHeaders().end()) - { - result.Properties = response.GetHeaders().at(Details::c_HeaderXMsProperties); - } - if (response.GetHeaders().find(Details::c_HeaderXMsLeaseDuration) - != response.GetHeaders().end()) - { - result.LeaseDuration = response.GetHeaders().at(Details::c_HeaderXMsLeaseDuration); - } - result.LeaseState - = LeaseStateTypeFromString(response.GetHeaders().at(Details::c_HeaderXMsLeaseState)); - result.LeaseStatus = LeaseStatusTypeFromString( - response.GetHeaders().at(Details::c_HeaderXMsLeaseStatus)); - return Azure::Core::Response(std::move(result), std::move(responsePtr)); - } - else if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::PartialContent) - { - // Partial content - PathReadResult result; - result.BodyStream = response.GetBodyStream(); - if (response.GetHeaders().find(Details::c_HeaderAcceptRanges) - != response.GetHeaders().end()) - { - result.AcceptRanges = response.GetHeaders().at(Details::c_HeaderAcceptRanges); - } - if (response.GetHeaders().find("cache-control") != response.GetHeaders().end()) - { - result.HttpHeaders.CacheControl = response.GetHeaders().at("cache-control"); - } - if (response.GetHeaders().find("content-disposition") != response.GetHeaders().end()) - { - result.HttpHeaders.ContentDisposition = response.GetHeaders().at("content-disposition"); - } - if (response.GetHeaders().find("content-encoding") != response.GetHeaders().end()) - { - result.HttpHeaders.ContentEncoding = response.GetHeaders().at("content-encoding"); - } - if (response.GetHeaders().find("content-language") != response.GetHeaders().end()) - { - result.HttpHeaders.ContentLanguage = response.GetHeaders().at("content-language"); - } - if (response.GetHeaders().find(Details::c_HeaderContentLength) - != response.GetHeaders().end()) - { - result.ContentLength - = std::stoll(response.GetHeaders().at(Details::c_HeaderContentLength)); - } - if (response.GetHeaders().find(Details::c_HeaderContentRange) - != response.GetHeaders().end()) - { - result.ContentRange = response.GetHeaders().at(Details::c_HeaderContentRange); - } - if (response.GetHeaders().find("content-type") != response.GetHeaders().end()) - { - result.HttpHeaders.ContentType = response.GetHeaders().at("content-type"); - } - if (response.GetHeaders().find(Details::c_HeaderContentMD5) - != response.GetHeaders().end()) - { - result.TransactionalMd5 = response.GetHeaders().at(Details::c_HeaderContentMD5); - } - if (response.GetHeaders().find(Details::c_HeaderXMsContentMd5) - != response.GetHeaders().end()) - { - result.ContentMd5 = response.GetHeaders().at(Details::c_HeaderXMsContentMd5); - } - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - result.ResourceType = response.GetHeaders().at(Details::c_HeaderXMsResourceType); - if (response.GetHeaders().find(Details::c_HeaderXMsProperties) - != response.GetHeaders().end()) - { - result.Properties = response.GetHeaders().at(Details::c_HeaderXMsProperties); - } - if (response.GetHeaders().find(Details::c_HeaderXMsLeaseDuration) - != response.GetHeaders().end()) - { - result.LeaseDuration = response.GetHeaders().at(Details::c_HeaderXMsLeaseDuration); - } - result.LeaseState - = LeaseStateTypeFromString(response.GetHeaders().at(Details::c_HeaderXMsLeaseState)); - result.LeaseStatus = LeaseStatusTypeFromString( - response.GetHeaders().at(Details::c_HeaderXMsLeaseStatus)); - return Azure::Core::Response(std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response GetPropertiesParseResult( - const Azure::Core::Context& context, - std::unique_ptr responsePtr) - { - /* const */ auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) - { - // Returns all properties for the file or directory. - PathGetPropertiesResult result; - if (response.GetHeaders().find(Details::c_HeaderAcceptRanges) - != response.GetHeaders().end()) - { - result.AcceptRanges = response.GetHeaders().at(Details::c_HeaderAcceptRanges); - } - if (response.GetHeaders().find("cache-control") != response.GetHeaders().end()) - { - result.HttpHeaders.CacheControl = response.GetHeaders().at("cache-control"); - } - if (response.GetHeaders().find("content-disposition") != response.GetHeaders().end()) - { - result.HttpHeaders.ContentDisposition = response.GetHeaders().at("content-disposition"); - } - if (response.GetHeaders().find("content-encoding") != response.GetHeaders().end()) - { - result.HttpHeaders.ContentEncoding = response.GetHeaders().at("content-encoding"); - } - if (response.GetHeaders().find("content-language") != response.GetHeaders().end()) - { - result.HttpHeaders.ContentLanguage = response.GetHeaders().at("content-language"); - } - if (response.GetHeaders().find(Details::c_HeaderContentLength) - != response.GetHeaders().end()) - { - result.ContentLength - = std::stoll(response.GetHeaders().at(Details::c_HeaderContentLength)); - } - if (response.GetHeaders().find(Details::c_HeaderContentRange) - != response.GetHeaders().end()) - { - result.ContentRange = response.GetHeaders().at(Details::c_HeaderContentRange); - } - if (response.GetHeaders().find("content-type") != response.GetHeaders().end()) - { - result.HttpHeaders.ContentType = response.GetHeaders().at("content-type"); - } - if (response.GetHeaders().find(Details::c_HeaderContentMD5) - != response.GetHeaders().end()) - { - result.ContentMd5 = response.GetHeaders().at(Details::c_HeaderContentMD5); - } - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - if (response.GetHeaders().find(Details::c_HeaderXMsResourceType) - != response.GetHeaders().end()) - { + if (response.GetHeaders().find("cache-control") != response.GetHeaders().end()) + { + result.HttpHeaders.CacheControl = response.GetHeaders().at("cache-control"); + } + if (response.GetHeaders().find("content-disposition") != response.GetHeaders().end()) + { + result.HttpHeaders.ContentDisposition + = response.GetHeaders().at("content-disposition"); + } + if (response.GetHeaders().find("content-encoding") != response.GetHeaders().end()) + { + result.HttpHeaders.ContentEncoding = response.GetHeaders().at("content-encoding"); + } + if (response.GetHeaders().find("content-language") != response.GetHeaders().end()) + { + result.HttpHeaders.ContentLanguage = response.GetHeaders().at("content-language"); + } + if (response.GetHeaders().find(Details::c_HeaderContentLength) + != response.GetHeaders().end()) + { + result.ContentLength + = std::stoll(response.GetHeaders().at(Details::c_HeaderContentLength)); + } + if (response.GetHeaders().find(Details::c_HeaderContentRange) + != response.GetHeaders().end()) + { + result.ContentRange = response.GetHeaders().at(Details::c_HeaderContentRange); + } + if (response.GetHeaders().find("content-type") != response.GetHeaders().end()) + { + result.HttpHeaders.ContentType = response.GetHeaders().at("content-type"); + } + if (response.GetHeaders().find(Details::c_HeaderContentMD5) + != response.GetHeaders().end()) + { + result.ContentMd5 = response.GetHeaders().at(Details::c_HeaderContentMD5); + } + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); result.ResourceType = response.GetHeaders().at(Details::c_HeaderXMsResourceType); - } - if (response.GetHeaders().find(Details::c_HeaderXMsProperties) - != response.GetHeaders().end()) - { - result.Properties = response.GetHeaders().at(Details::c_HeaderXMsProperties); - } - if (response.GetHeaders().find(Details::c_HeaderXMsOwner) != response.GetHeaders().end()) - { - result.Owner = response.GetHeaders().at(Details::c_HeaderXMsOwner); - } - if (response.GetHeaders().find(Details::c_HeaderXMsGroup) != response.GetHeaders().end()) - { - result.Group = response.GetHeaders().at(Details::c_HeaderXMsGroup); - } - if (response.GetHeaders().find(Details::c_HeaderXMsPermissions) - != response.GetHeaders().end()) - { - result.Permissions = response.GetHeaders().at(Details::c_HeaderXMsPermissions); - } - if (response.GetHeaders().find(Details::c_HeaderXMsAcl) != response.GetHeaders().end()) - { - result.Acl = response.GetHeaders().at(Details::c_HeaderXMsAcl); - } - if (response.GetHeaders().find(Details::c_HeaderXMsLeaseDuration) - != response.GetHeaders().end()) - { - result.LeaseDuration = response.GetHeaders().at(Details::c_HeaderXMsLeaseDuration); - } - if (response.GetHeaders().find(Details::c_HeaderXMsLeaseState) - != response.GetHeaders().end()) - { + if (response.GetHeaders().find(Details::c_HeaderXMsProperties) + != response.GetHeaders().end()) + { + result.Properties = response.GetHeaders().at(Details::c_HeaderXMsProperties); + } + if (response.GetHeaders().find(Details::c_HeaderXMsLeaseDuration) + != response.GetHeaders().end()) + { + result.LeaseDuration = response.GetHeaders().at(Details::c_HeaderXMsLeaseDuration); + } result.LeaseState = LeaseStateTypeFromString( response.GetHeaders().at(Details::c_HeaderXMsLeaseState)); - } - if (response.GetHeaders().find(Details::c_HeaderXMsLeaseStatus) - != response.GetHeaders().end()) - { result.LeaseStatus = LeaseStatusTypeFromString( response.GetHeaders().at(Details::c_HeaderXMsLeaseStatus)); + return Azure::Core::Response(std::move(result), std::move(responsePtr)); } - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response DeleteParseResult( - const Azure::Core::Context& context, - std::unique_ptr responsePtr) - { - /* const */ auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) - { - // The file was deleted. - PathDeleteResult result; - if (response.GetHeaders().find(Details::c_HeaderXMsContinuation) - != response.GetHeaders().end()) + else if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::PartialContent) { - result.ContinuationToken = response.GetHeaders().at(Details::c_HeaderXMsContinuation); + // Partial content + PathReadResult result; + result.BodyStream = response.GetBodyStream(); + result.AcceptRanges = response.GetHeaders().at(Details::c_HeaderAcceptRanges); + if (response.GetHeaders().find("cache-control") != response.GetHeaders().end()) + { + result.HttpHeaders.CacheControl = response.GetHeaders().at("cache-control"); + } + if (response.GetHeaders().find("content-disposition") != response.GetHeaders().end()) + { + result.HttpHeaders.ContentDisposition + = response.GetHeaders().at("content-disposition"); + } + if (response.GetHeaders().find("content-encoding") != response.GetHeaders().end()) + { + result.HttpHeaders.ContentEncoding = response.GetHeaders().at("content-encoding"); + } + if (response.GetHeaders().find("content-language") != response.GetHeaders().end()) + { + result.HttpHeaders.ContentLanguage = response.GetHeaders().at("content-language"); + } + if (response.GetHeaders().find(Details::c_HeaderContentLength) + != response.GetHeaders().end()) + { + result.ContentLength + = std::stoll(response.GetHeaders().at(Details::c_HeaderContentLength)); + } + if (response.GetHeaders().find(Details::c_HeaderContentRange) + != response.GetHeaders().end()) + { + result.ContentRange = response.GetHeaders().at(Details::c_HeaderContentRange); + } + if (response.GetHeaders().find("content-type") != response.GetHeaders().end()) + { + result.HttpHeaders.ContentType = response.GetHeaders().at("content-type"); + } + if (response.GetHeaders().find(Details::c_HeaderContentMD5) + != response.GetHeaders().end()) + { + result.TransactionalMd5 = response.GetHeaders().at(Details::c_HeaderContentMD5); + } + if (response.GetHeaders().find(Details::c_HeaderXMsContentMd5) + != response.GetHeaders().end()) + { + result.ContentMd5 = response.GetHeaders().at(Details::c_HeaderXMsContentMd5); + } + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + result.ResourceType = response.GetHeaders().at(Details::c_HeaderXMsResourceType); + if (response.GetHeaders().find(Details::c_HeaderXMsProperties) + != response.GetHeaders().end()) + { + result.Properties = response.GetHeaders().at(Details::c_HeaderXMsProperties); + } + if (response.GetHeaders().find(Details::c_HeaderXMsLeaseDuration) + != response.GetHeaders().end()) + { + result.LeaseDuration = response.GetHeaders().at(Details::c_HeaderXMsLeaseDuration); + } + result.LeaseState = LeaseStateTypeFromString( + response.GetHeaders().at(Details::c_HeaderXMsLeaseState)); + result.LeaseStatus = LeaseStatusTypeFromString( + response.GetHeaders().at(Details::c_HeaderXMsLeaseStatus)); + return Azure::Core::Response(std::move(result), std::move(responsePtr)); } - return Azure::Core::Response(std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response SetAccessControlParseResult( - const Azure::Core::Context& context, - std::unique_ptr responsePtr) - { - /* const */ auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) - { - // Set directory access control response. - PathSetAccessControlResult result; - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response - SetAccessControlRecursiveParseResult( - const Azure::Core::Context& context, - std::unique_ptr responsePtr) - { - /* const */ auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) - { - // Set directory access control recursive response. - const auto& bodyBuffer = response.GetBody(); - PathSetAccessControlRecursiveResult result = bodyBuffer.empty() - ? PathSetAccessControlRecursiveResult() - : PathSetAccessControlRecursiveResult:: - PathSetAccessControlRecursiveResultFromSetAccessControlRecursiveResponse( - SetAccessControlRecursiveResponse::CreateFromJson( - nlohmann::json::parse(bodyBuffer))); - if (response.GetHeaders().find(Details::c_HeaderXMsContinuation) - != response.GetHeaders().end()) + else { - result.ContinuationToken = response.GetHeaders().at(Details::c_HeaderXMsContinuation); + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); } - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - static Azure::Core::Response FlushDataParseResult( - const Azure::Core::Context& context, - std::unique_ptr responsePtr) - { - /* const */ auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + static Azure::Core::Response GetPropertiesParseResult( + const Azure::Core::Context& context, + std::unique_ptr responsePtr) { - // The data was flushed (written) to the file successfully. - PathFlushDataResult result; - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - if (response.GetHeaders().find(Details::c_HeaderContentLength) - != response.GetHeaders().end()) + /* const */ auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) { - result.ContentLength - = std::stoll(response.GetHeaders().at(Details::c_HeaderContentLength)); + // Returns all properties for the file or directory. + PathGetPropertiesResult result; + if (response.GetHeaders().find(Details::c_HeaderAcceptRanges) + != response.GetHeaders().end()) + { + result.AcceptRanges = response.GetHeaders().at(Details::c_HeaderAcceptRanges); + } + if (response.GetHeaders().find("cache-control") != response.GetHeaders().end()) + { + result.HttpHeaders.CacheControl = response.GetHeaders().at("cache-control"); + } + if (response.GetHeaders().find("content-disposition") != response.GetHeaders().end()) + { + result.HttpHeaders.ContentDisposition + = response.GetHeaders().at("content-disposition"); + } + if (response.GetHeaders().find("content-encoding") != response.GetHeaders().end()) + { + result.HttpHeaders.ContentEncoding = response.GetHeaders().at("content-encoding"); + } + if (response.GetHeaders().find("content-language") != response.GetHeaders().end()) + { + result.HttpHeaders.ContentLanguage = response.GetHeaders().at("content-language"); + } + if (response.GetHeaders().find(Details::c_HeaderContentLength) + != response.GetHeaders().end()) + { + result.ContentLength + = std::stoll(response.GetHeaders().at(Details::c_HeaderContentLength)); + } + if (response.GetHeaders().find(Details::c_HeaderContentRange) + != response.GetHeaders().end()) + { + result.ContentRange = response.GetHeaders().at(Details::c_HeaderContentRange); + } + if (response.GetHeaders().find("content-type") != response.GetHeaders().end()) + { + result.HttpHeaders.ContentType = response.GetHeaders().at("content-type"); + } + if (response.GetHeaders().find(Details::c_HeaderContentMD5) + != response.GetHeaders().end()) + { + result.ContentMd5 = response.GetHeaders().at(Details::c_HeaderContentMD5); + } + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + if (response.GetHeaders().find(Details::c_HeaderXMsResourceType) + != response.GetHeaders().end()) + { + result.ResourceType = response.GetHeaders().at(Details::c_HeaderXMsResourceType); + } + if (response.GetHeaders().find(Details::c_HeaderXMsProperties) + != response.GetHeaders().end()) + { + result.Properties = response.GetHeaders().at(Details::c_HeaderXMsProperties); + } + if (response.GetHeaders().find(Details::c_HeaderXMsOwner) + != response.GetHeaders().end()) + { + result.Owner = response.GetHeaders().at(Details::c_HeaderXMsOwner); + } + if (response.GetHeaders().find(Details::c_HeaderXMsGroup) + != response.GetHeaders().end()) + { + result.Group = response.GetHeaders().at(Details::c_HeaderXMsGroup); + } + if (response.GetHeaders().find(Details::c_HeaderXMsPermissions) + != response.GetHeaders().end()) + { + result.Permissions = response.GetHeaders().at(Details::c_HeaderXMsPermissions); + } + if (response.GetHeaders().find(Details::c_HeaderXMsAcl) != response.GetHeaders().end()) + { + result.Acl = response.GetHeaders().at(Details::c_HeaderXMsAcl); + } + if (response.GetHeaders().find(Details::c_HeaderXMsLeaseDuration) + != response.GetHeaders().end()) + { + result.LeaseDuration = response.GetHeaders().at(Details::c_HeaderXMsLeaseDuration); + } + if (response.GetHeaders().find(Details::c_HeaderXMsLeaseState) + != response.GetHeaders().end()) + { + result.LeaseState = LeaseStateTypeFromString( + response.GetHeaders().at(Details::c_HeaderXMsLeaseState)); + } + if (response.GetHeaders().find(Details::c_HeaderXMsLeaseStatus) + != response.GetHeaders().end()) + { + result.LeaseStatus = LeaseStatusTypeFromString( + response.GetHeaders().at(Details::c_HeaderXMsLeaseStatus)); + } + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); } - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response AppendDataParseResult( - const Azure::Core::Context& context, - std::unique_ptr responsePtr) - { - /* const */ auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Accepted) - { - // Append data to file control response. - PathAppendDataResult result; - if (response.GetHeaders().find(Details::c_HeaderContentMD5) - != response.GetHeaders().end()) + else { - result.ContentMD5 = response.GetHeaders().at(Details::c_HeaderContentMD5); + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); } - if (response.GetHeaders().find(Details::c_HeaderXMsContentCrc64) - != response.GetHeaders().end()) + } + + static Azure::Core::Response DeleteParseResult( + const Azure::Core::Context& context, + std::unique_ptr responsePtr) + { + /* const */ auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) { - result.ContentCrc64 = response.GetHeaders().at(Details::c_HeaderXMsContentCrc64); + // The file was deleted. + PathDeleteResult result; + if (response.GetHeaders().find(Details::c_HeaderXMsContinuation) + != response.GetHeaders().end()) + { + result.ContinuationToken = response.GetHeaders().at(Details::c_HeaderXMsContinuation); + } + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); } - result.IsServerEncrypted - = response.GetHeaders().at(Details::c_HeaderXMsRequestServerEncrypted) == "true"; - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - static Azure::Core::Response SetExpiryParseResult( - const Azure::Core::Context& context, - std::unique_ptr responsePtr) - { - /* const */ auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + static Azure::Core::Response SetAccessControlParseResult( + const Azure::Core::Context& context, + std::unique_ptr responsePtr) { - // The blob expiry was set successfully. - PathSetExpiryResult result; - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); + /* const */ auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + { + // Set directory access control response. + PathSetAccessControlResult result; + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - }; - }; // class DataLakeRestClient + static Azure::Core::Response + SetAccessControlRecursiveParseResult( + const Azure::Core::Context& context, + std::unique_ptr responsePtr) + { + /* const */ auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + { + // Set directory access control recursive response. + const auto& bodyBuffer = response.GetBody(); + PathSetAccessControlRecursiveResult result = bodyBuffer.empty() + ? PathSetAccessControlRecursiveResult() + : PathSetAccessControlRecursiveResultFromSetAccessControlRecursiveResponse( + SetAccessControlRecursiveResponseFromJson(nlohmann::json::parse(bodyBuffer))); + if (response.GetHeaders().find(Details::c_HeaderXMsContinuation) + != response.GetHeaders().end()) + { + result.ContinuationToken = response.GetHeaders().at(Details::c_HeaderXMsContinuation); + } + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Storage::Files::DataLake::AclFailedEntry AclFailedEntryFromJson( + const nlohmann::json& node) + { + Azure::Storage::Files::DataLake::AclFailedEntry result; + result.Name = node["name"].get(); + result.Type = node["type"].get(); + result.ErrorMessage = node["errorMessage"].get(); + return result; + } + + static Azure::Storage::Files::DataLake::SetAccessControlRecursiveResponse + SetAccessControlRecursiveResponseFromJson(const nlohmann::json& node) + { + Azure::Storage::Files::DataLake::SetAccessControlRecursiveResponse result; + result.DirectoriesSuccessful = node["directoriesSuccessful"].get(); + result.FilesSuccessful = node["filesSuccessful"].get(); + result.FailureCount = node["failureCount"].get(); + for (const auto& element : node["failedEntries"]) + { + result.FailedEntries.emplace_back(AclFailedEntryFromJson(element)); + } + return result; + } + + static PathSetAccessControlRecursiveResult + PathSetAccessControlRecursiveResultFromSetAccessControlRecursiveResponse( + SetAccessControlRecursiveResponse object) + { + PathSetAccessControlRecursiveResult result; + result.DirectoriesSuccessful = object.DirectoriesSuccessful; + result.FilesSuccessful = object.FilesSuccessful; + result.FailureCount = object.FailureCount; + result.FailedEntries = std::move(object.FailedEntries); + + return result; + } + static Azure::Core::Response FlushDataParseResult( + const Azure::Core::Context& context, + std::unique_ptr responsePtr) + { + /* const */ auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + { + // The data was flushed (written) to the file successfully. + PathFlushDataResult result; + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + if (response.GetHeaders().find(Details::c_HeaderContentLength) + != response.GetHeaders().end()) + { + result.ContentLength + = std::stoll(response.GetHeaders().at(Details::c_HeaderContentLength)); + } + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Core::Response AppendDataParseResult( + const Azure::Core::Context& context, + std::unique_ptr responsePtr) + { + /* const */ auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Accepted) + { + // Append data to file control response. + PathAppendDataResult result; + if (response.GetHeaders().find(Details::c_HeaderContentMD5) + != response.GetHeaders().end()) + { + result.ContentMD5 = response.GetHeaders().at(Details::c_HeaderContentMD5); + } + if (response.GetHeaders().find(Details::c_HeaderXMsContentCrc64) + != response.GetHeaders().end()) + { + result.ContentCrc64 = response.GetHeaders().at(Details::c_HeaderXMsContentCrc64); + } + result.IsServerEncrypted + = response.GetHeaders().at(Details::c_HeaderXMsRequestServerEncrypted) == "true"; + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Core::Response SetExpiryParseResult( + const Azure::Core::Context& context, + std::unique_ptr responsePtr) + { + /* const */ auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + { + // The blob expiry was set successfully. + PathSetExpiryResult result; + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + }; + + }; // class DataLakeRestClient + + } // namespace Details }}}} // namespace Azure::Storage::Files::DataLake diff --git a/sdk/storage/azure-storage-files-datalake/src/datalake_directory_client.cpp b/sdk/storage/azure-storage-files-datalake/src/datalake_directory_client.cpp index 74d02867a..f0d82378f 100644 --- a/sdk/storage/azure-storage-files-datalake/src/datalake_directory_client.cpp +++ b/sdk/storage/azure-storage-files-datalake/src/datalake_directory_client.cpp @@ -160,7 +160,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { auto destinationDfsUri = m_dfsUri; destinationDfsUri.SetPath(destinationFileSystem.GetValue() + '/' + destinationPath); - DataLakeRestClient::Path::CreateOptions protocolLayerOptions; + Details::DataLakeRestClient::Path::CreateOptions protocolLayerOptions; protocolLayerOptions.ContinuationToken = options.ContinuationToken; protocolLayerOptions.Mode = options.Mode; protocolLayerOptions.SourceLeaseId = options.SourceAccessConditions.LeaseId; @@ -174,7 +174,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { protocolLayerOptions.SourceIfModifiedSince = options.SourceAccessConditions.IfModifiedSince; protocolLayerOptions.SourceIfUnmodifiedSince = options.SourceAccessConditions.IfUnmodifiedSince; protocolLayerOptions.RenameSource = "/" + m_dfsUri.GetPath(); - auto result = DataLakeRestClient::Path::Create( + auto result = Details::DataLakeRestClient::Path::Create( destinationDfsUri, *m_pipeline, options.Context, protocolLayerOptions); // At this point, there is not more exception thrown, meaning the rename is successful. auto ret = RenameDirectoryResult(); @@ -187,7 +187,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { bool Recursive, const DeleteDirectoryOptions& options) const { - DataLakeRestClient::Path::DeleteOptions protocolLayerOptions; + Details::DataLakeRestClient::Path::DeleteOptions protocolLayerOptions; protocolLayerOptions.ContinuationToken = options.ContinuationToken; protocolLayerOptions.LeaseIdOptional = options.AccessConditions.LeaseId; protocolLayerOptions.IfMatch = options.AccessConditions.IfMatch; @@ -195,7 +195,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { protocolLayerOptions.IfModifiedSince = options.AccessConditions.IfModifiedSince; protocolLayerOptions.IfUnmodifiedSince = options.AccessConditions.IfUnmodifiedSince; protocolLayerOptions.RecursiveOptional = Recursive; - return DataLakeRestClient::Path::Delete( + return Details::DataLakeRestClient::Path::Delete( m_dfsUri, *m_pipeline, options.Context, protocolLayerOptions); } @@ -205,13 +205,13 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { std::vector acls, const SetDirectoryAccessControlRecursiveOptions& options) const { - DataLakeRestClient::Path::SetAccessControlRecursiveOptions protocolLayerOptions; + Details::DataLakeRestClient::Path::SetAccessControlRecursiveOptions protocolLayerOptions; protocolLayerOptions.Mode = mode; protocolLayerOptions.ContinuationToken = options.ContinuationToken; protocolLayerOptions.MaxRecords = options.MaxRecords; protocolLayerOptions.ForceFlag = options.ForceFlag; protocolLayerOptions.Acl = Acl::SerializeAcls(acls); - return DataLakeRestClient::Path::SetAccessControlRecursive( + return Details::DataLakeRestClient::Path::SetAccessControlRecursive( m_dfsUri, *m_pipeline, options.Context, protocolLayerOptions); } diff --git a/sdk/storage/azure-storage-files-datalake/src/datalake_file_client.cpp b/sdk/storage/azure-storage-files-datalake/src/datalake_file_client.cpp index 4d4b25875..eaa48ced4 100644 --- a/sdk/storage/azure-storage-files-datalake/src/datalake_file_client.cpp +++ b/sdk/storage/azure-storage-files-datalake/src/datalake_file_client.cpp @@ -210,12 +210,12 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { int64_t offset, const AppendFileDataOptions& options) const { - DataLakeRestClient::Path::AppendDataOptions protocolLayerOptions; + Details::DataLakeRestClient::Path::AppendDataOptions protocolLayerOptions; protocolLayerOptions.Position = offset; protocolLayerOptions.ContentLength = content->Length(); protocolLayerOptions.TransactionalContentMd5 = options.ContentMd5; protocolLayerOptions.LeaseIdOptional = options.AccessConditions.LeaseId; - return DataLakeRestClient::Path::AppendData( + return Details::DataLakeRestClient::Path::AppendData( m_dfsUri, *content, *m_pipeline, options.Context, protocolLayerOptions); } @@ -223,7 +223,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { int64_t endingOffset, const FlushFileDataOptions& options) const { - DataLakeRestClient::Path::FlushDataOptions protocolLayerOptions; + Details::DataLakeRestClient::Path::FlushDataOptions protocolLayerOptions; protocolLayerOptions.Position = endingOffset; protocolLayerOptions.RetainUncommittedData = options.RetainUncommittedData; protocolLayerOptions.Close = options.Close; @@ -239,7 +239,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { protocolLayerOptions.IfNoneMatch = options.AccessConditions.IfNoneMatch; protocolLayerOptions.IfModifiedSince = options.AccessConditions.IfModifiedSince; protocolLayerOptions.IfUnmodifiedSince = options.AccessConditions.IfUnmodifiedSince; - return DataLakeRestClient::Path::FlushData( + return Details::DataLakeRestClient::Path::FlushData( m_dfsUri, *m_pipeline, options.Context, protocolLayerOptions); } @@ -257,7 +257,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { auto destinationDfsUri = m_dfsUri; destinationDfsUri.SetPath(destinationFileSystem.GetValue() + '/' + destinationPath); - DataLakeRestClient::Path::CreateOptions protocolLayerOptions; + Details::DataLakeRestClient::Path::CreateOptions protocolLayerOptions; protocolLayerOptions.Mode = options.Mode; protocolLayerOptions.SourceLeaseId = options.SourceAccessConditions.LeaseId; protocolLayerOptions.LeaseIdOptional = options.AccessConditions.LeaseId; @@ -270,7 +270,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { protocolLayerOptions.SourceIfModifiedSince = options.SourceAccessConditions.IfModifiedSince; protocolLayerOptions.SourceIfUnmodifiedSince = options.SourceAccessConditions.IfUnmodifiedSince; protocolLayerOptions.RenameSource = "/" + m_dfsUri.GetPath(); - auto result = DataLakeRestClient::Path::Create( + auto result = Details::DataLakeRestClient::Path::Create( destinationDfsUri, *m_pipeline, options.Context, protocolLayerOptions); // At this point, there is not more exception thrown, meaning the rename is successful. auto ret = RenameFileResult(); @@ -279,13 +279,13 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { Azure::Core::Response FileClient::Delete(const FileDeleteOptions& options) const { - DataLakeRestClient::Path::DeleteOptions protocolLayerOptions; + Details::DataLakeRestClient::Path::DeleteOptions protocolLayerOptions; protocolLayerOptions.LeaseIdOptional = options.AccessConditions.LeaseId; protocolLayerOptions.IfMatch = options.AccessConditions.IfMatch; protocolLayerOptions.IfNoneMatch = options.AccessConditions.IfNoneMatch; protocolLayerOptions.IfModifiedSince = options.AccessConditions.IfModifiedSince; protocolLayerOptions.IfUnmodifiedSince = options.AccessConditions.IfUnmodifiedSince; - auto result = DataLakeRestClient::Path::Delete( + auto result = Details::DataLakeRestClient::Path::Delete( m_dfsUri, *m_pipeline, options.Context, protocolLayerOptions); auto ret = DeleteFileResult(); return Azure::Core::Response(std::move(ret), result.ExtractRawResponse()); diff --git a/sdk/storage/azure-storage-files-datalake/src/datalake_file_system_client.cpp b/sdk/storage/azure-storage-files-datalake/src/datalake_file_system_client.cpp index c9adf6c0d..fdb55fdfa 100644 --- a/sdk/storage/azure-storage-files-datalake/src/datalake_file_system_client.cpp +++ b/sdk/storage/azure-storage-files-datalake/src/datalake_file_system_client.cpp @@ -245,13 +245,13 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { bool recursive, const ListPathsOptions& options) const { - DataLakeRestClient::FileSystem::ListPathsOptions protocolLayerOptions; + Details::DataLakeRestClient::FileSystem::ListPathsOptions protocolLayerOptions; protocolLayerOptions.Upn = options.UserPrincipalName; protocolLayerOptions.ContinuationToken = options.ContinuationToken; protocolLayerOptions.MaxResults = options.MaxResults; protocolLayerOptions.Directory = options.Directory; protocolLayerOptions.RecursiveRequired = recursive; - return DataLakeRestClient::FileSystem::ListPaths( + return Details::DataLakeRestClient::FileSystem::ListPaths( m_dfsUri, *m_pipeline, options.Context, protocolLayerOptions); } diff --git a/sdk/storage/azure-storage-files-datalake/src/datalake_path_client.cpp b/sdk/storage/azure-storage-files-datalake/src/datalake_path_client.cpp index 3e03f2541..39602eb6c 100644 --- a/sdk/storage/azure-storage-files-datalake/src/datalake_path_client.cpp +++ b/sdk/storage/azure-storage-files-datalake/src/datalake_path_client.cpp @@ -194,7 +194,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { std::vector acls, const SetPathAccessControlOptions& options) const { - DataLakeRestClient::Path::SetAccessControlOptions protocolLayerOptions; + Details::DataLakeRestClient::Path::SetAccessControlOptions protocolLayerOptions; protocolLayerOptions.LeaseIdOptional = options.AccessConditions.LeaseId; protocolLayerOptions.Owner = options.Owner; protocolLayerOptions.Group = options.Group; @@ -204,7 +204,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { protocolLayerOptions.IfNoneMatch = options.AccessConditions.IfNoneMatch; protocolLayerOptions.IfModifiedSince = options.AccessConditions.IfModifiedSince; protocolLayerOptions.IfUnmodifiedSince = options.AccessConditions.IfUnmodifiedSince; - return DataLakeRestClient::Path::SetAccessControl( + return Details::DataLakeRestClient::Path::SetAccessControl( m_dfsUri, *m_pipeline, options.Context, protocolLayerOptions); } @@ -237,7 +237,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { PathResourceType type, const CreatePathOptions& options) const { - DataLakeRestClient::Path::CreateOptions protocolLayerOptions; + Details::DataLakeRestClient::Path::CreateOptions protocolLayerOptions; protocolLayerOptions.Resource = type; protocolLayerOptions.LeaseIdOptional = options.AccessConditions.LeaseId; protocolLayerOptions.CacheControl = options.HttpHeaders.CacheControl; @@ -252,7 +252,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { protocolLayerOptions.Properties = Details::SerializeMetadata(options.Metadata); protocolLayerOptions.Umask = options.Umask; protocolLayerOptions.Permissions = options.Permissions; - auto result = DataLakeRestClient::Path::Create( + auto result = Details::DataLakeRestClient::Path::Create( m_dfsUri, *m_pipeline, options.Context, protocolLayerOptions); auto ret = CreatePathResult(); ret.ETag = std::move(result->ETag.GetValue()); @@ -263,7 +263,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { Azure::Core::Response PathClient::Delete(const DeletePathOptions& options) const { - DataLakeRestClient::Path::DeleteOptions protocolLayerOptions; + Details::DataLakeRestClient::Path::DeleteOptions protocolLayerOptions; protocolLayerOptions.ContinuationToken = options.ContinuationToken; protocolLayerOptions.LeaseIdOptional = options.AccessConditions.LeaseId; protocolLayerOptions.IfMatch = options.AccessConditions.IfMatch; @@ -271,7 +271,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { protocolLayerOptions.IfModifiedSince = options.AccessConditions.IfModifiedSince; protocolLayerOptions.IfUnmodifiedSince = options.AccessConditions.IfUnmodifiedSince; protocolLayerOptions.RecursiveOptional = options.Recursive; - return DataLakeRestClient::Path::Delete( + return Details::DataLakeRestClient::Path::Delete( m_dfsUri, *m_pipeline, options.Context, protocolLayerOptions); } @@ -321,14 +321,14 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { Azure::Core::Response PathClient::GetAccessControls( const GetPathAccessControlOptions& options) const { - DataLakeRestClient::Path::GetPropertiesOptions protocolLayerOptions; + Details::DataLakeRestClient::Path::GetPropertiesOptions protocolLayerOptions; protocolLayerOptions.Action = PathGetPropertiesAction::GetAccessControl; protocolLayerOptions.LeaseIdOptional = options.AccessConditions.LeaseId; protocolLayerOptions.IfMatch = options.AccessConditions.IfMatch; protocolLayerOptions.IfNoneMatch = options.AccessConditions.IfNoneMatch; protocolLayerOptions.IfModifiedSince = options.AccessConditions.IfModifiedSince; protocolLayerOptions.IfUnmodifiedSince = options.AccessConditions.IfUnmodifiedSince; - auto result = DataLakeRestClient::Path::GetProperties( + auto result = Details::DataLakeRestClient::Path::GetProperties( m_dfsUri, *m_pipeline, options.Context, protocolLayerOptions); Azure::Core::Nullable> acl; if (result->Acl.HasValue()) diff --git a/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/protocol/share_rest_client.hpp b/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/protocol/share_rest_client.hpp index 6e2c00d33..6de911064 100644 --- a/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/protocol/share_rest_client.hpp +++ b/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/protocol/share_rest_client.hpp @@ -200,35 +200,6 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { Unknown }; - inline std::string PermissionCopyModeTypeToString( - const PermissionCopyModeType& permissionCopyModeType) - { - switch (permissionCopyModeType) - { - case PermissionCopyModeType::Source: - return "source"; - case PermissionCopyModeType::Override: - return "override"; - default: - return std::string(); - } - } - - inline PermissionCopyModeType PermissionCopyModeTypeFromString( - const std::string& permissionCopyModeType) - { - if (permissionCopyModeType == "source") - { - return PermissionCopyModeType::Source; - } - if (permissionCopyModeType == "override") - { - return PermissionCopyModeType::Override; - } - throw std::runtime_error( - "Cannot convert " + permissionCopyModeType + " to PermissionCopyModeType"); - } - // Specifies the option include to delete the base share and all of its snapshots. enum class DeleteSnapshotsOptionType { @@ -236,29 +207,6 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { Unknown }; - inline std::string DeleteSnapshotsOptionTypeToString( - const DeleteSnapshotsOptionType& deleteSnapshotsOptionType) - { - switch (deleteSnapshotsOptionType) - { - case DeleteSnapshotsOptionType::Include: - return "include"; - default: - return std::string(); - } - } - - inline DeleteSnapshotsOptionType DeleteSnapshotsOptionTypeFromString( - const std::string& deleteSnapshotsOptionType) - { - if (deleteSnapshotsOptionType == "include") - { - return DeleteSnapshotsOptionType::Include; - } - throw std::runtime_error( - "Cannot convert " + deleteSnapshotsOptionType + " to DeleteSnapshotsOptionType"); - } - // Only update is supported: - Update: Writes the bytes downloaded from the source url into the // specified range. enum class FileRangeWriteFromUrlType @@ -267,29 +215,6 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { Unknown }; - inline std::string FileRangeWriteFromUrlTypeToString( - const FileRangeWriteFromUrlType& fileRangeWriteFromUrlType) - { - switch (fileRangeWriteFromUrlType) - { - case FileRangeWriteFromUrlType::Update: - return "update"; - default: - return std::string(); - } - } - - inline FileRangeWriteFromUrlType FileRangeWriteFromUrlTypeFromString( - const std::string& fileRangeWriteFromUrlType) - { - if (fileRangeWriteFromUrlType == "update") - { - return FileRangeWriteFromUrlType::Update; - } - throw std::runtime_error( - "Cannot convert " + fileRangeWriteFromUrlType + " to FileRangeWriteFromUrlType"); - } - // An Access policy. struct AccessPolicy { @@ -372,32 +297,6 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { Unknown }; - inline std::string LeaseDurationTypeToString(const LeaseDurationType& leaseDurationType) - { - switch (leaseDurationType) - { - case LeaseDurationType::Infinite: - return "infinite"; - case LeaseDurationType::Fixed: - return "fixed"; - default: - return std::string(); - } - } - - inline LeaseDurationType LeaseDurationTypeFromString(const std::string& leaseDurationType) - { - if (leaseDurationType == "infinite") - { - return LeaseDurationType::Infinite; - } - if (leaseDurationType == "fixed") - { - return LeaseDurationType::Fixed; - } - throw std::runtime_error("Cannot convert " + leaseDurationType + " to LeaseDurationType"); - } - // Lease state of the file or share. enum class LeaseStateType { @@ -409,50 +308,6 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { Unknown }; - inline std::string LeaseStateTypeToString(const LeaseStateType& leaseStateType) - { - switch (leaseStateType) - { - case LeaseStateType::Available: - return "available"; - case LeaseStateType::Leased: - return "leased"; - case LeaseStateType::Expired: - return "expired"; - case LeaseStateType::Breaking: - return "breaking"; - case LeaseStateType::Broken: - return "broken"; - default: - return std::string(); - } - } - - inline LeaseStateType LeaseStateTypeFromString(const std::string& leaseStateType) - { - if (leaseStateType == "available") - { - return LeaseStateType::Available; - } - if (leaseStateType == "leased") - { - return LeaseStateType::Leased; - } - if (leaseStateType == "expired") - { - return LeaseStateType::Expired; - } - if (leaseStateType == "breaking") - { - return LeaseStateType::Breaking; - } - if (leaseStateType == "broken") - { - return LeaseStateType::Broken; - } - throw std::runtime_error("Cannot convert " + leaseStateType + " to LeaseStateType"); - } - // The current lease status of the file or share. enum class LeaseStatusType { @@ -461,32 +316,6 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { Unknown }; - inline std::string LeaseStatusTypeToString(const LeaseStatusType& leaseStatusType) - { - switch (leaseStatusType) - { - case LeaseStatusType::Locked: - return "locked"; - case LeaseStatusType::Unlocked: - return "unlocked"; - default: - return std::string(); - } - } - - inline LeaseStatusType LeaseStatusTypeFromString(const std::string& leaseStatusType) - { - if (leaseStatusType == "locked") - { - return LeaseStatusType::Locked; - } - if (leaseStatusType == "unlocked") - { - return LeaseStatusType::Unlocked; - } - throw std::runtime_error("Cannot convert " + leaseStatusType + " to LeaseStatusType"); - } - // An enumeration of directories and files. struct ListFilesAndDirectoriesSegmentResponse { @@ -653,50 +482,6 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { Unknown }; - inline std::string LeaseActionToString(const LeaseAction& leaseAction) - { - switch (leaseAction) - { - case LeaseAction::Acquire: - return "acquire"; - case LeaseAction::Release: - return "release"; - case LeaseAction::Change: - return "change"; - case LeaseAction::Renew: - return "renew"; - case LeaseAction::Break: - return "break"; - default: - return std::string(); - } - } - - inline LeaseAction LeaseActionFromString(const std::string& leaseAction) - { - if (leaseAction == "acquire") - { - return LeaseAction::Acquire; - } - if (leaseAction == "release") - { - return LeaseAction::Release; - } - if (leaseAction == "change") - { - return LeaseAction::Change; - } - if (leaseAction == "renew") - { - return LeaseAction::Renew; - } - if (leaseAction == "break") - { - return LeaseAction::Break; - } - throw std::runtime_error("Cannot convert " + leaseAction + " to LeaseAction"); - } - // State of the copy operation identified by 'x-ms-copy-id'. enum class CopyStatusType { @@ -707,44 +492,6 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { Unknown }; - inline std::string CopyStatusTypeToString(const CopyStatusType& copyStatusType) - { - switch (copyStatusType) - { - case CopyStatusType::Pending: - return "pending"; - case CopyStatusType::Success: - return "success"; - case CopyStatusType::Aborted: - return "aborted"; - case CopyStatusType::Failed: - return "failed"; - default: - return std::string(); - } - } - - inline CopyStatusType CopyStatusTypeFromString(const std::string& copyStatusType) - { - if (copyStatusType == "pending") - { - return CopyStatusType::Pending; - } - if (copyStatusType == "success") - { - return CopyStatusType::Success; - } - if (copyStatusType == "aborted") - { - return CopyStatusType::Aborted; - } - if (copyStatusType == "failed") - { - return CopyStatusType::Failed; - } - throw std::runtime_error("Cannot convert " + copyStatusType + " to CopyStatusType"); - } - // Specify one of the following options: - Update: Writes the bytes specified by the request body // into the specified range. The Range and Content-Length headers must match to perform the // update. - Clear: Clears the specified range and releases the space used in storage for that @@ -757,32 +504,6 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { Unknown }; - inline std::string FileRangeWriteTypeToString(const FileRangeWriteType& fileRangeWriteType) - { - switch (fileRangeWriteType) - { - case FileRangeWriteType::Update: - return "update"; - case FileRangeWriteType::Clear: - return "clear"; - default: - return std::string(); - } - } - - inline FileRangeWriteType FileRangeWriteTypeFromString(const std::string& fileRangeWriteType) - { - if (fileRangeWriteType == "update") - { - return FileRangeWriteType::Update; - } - if (fileRangeWriteType == "clear") - { - return FileRangeWriteType::Clear; - } - throw std::runtime_error("Cannot convert " + fileRangeWriteType + " to FileRangeWriteType"); - } - struct ServiceSetPropertiesResult { }; @@ -1178,6687 +899,7049 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { int32_t numberOfHandlesFailedToClose = int32_t(); }; - class ShareRestClient { - public: - class Service { + namespace Details { + inline std::string PermissionCopyModeTypeToString( + const PermissionCopyModeType& permissionCopyModeType) + { + switch (permissionCopyModeType) + { + case PermissionCopyModeType::Source: + return "source"; + case PermissionCopyModeType::Override: + return "override"; + default: + return std::string(); + } + } + + inline PermissionCopyModeType PermissionCopyModeTypeFromString( + const std::string& permissionCopyModeType) + { + if (permissionCopyModeType == "source") + { + return PermissionCopyModeType::Source; + } + if (permissionCopyModeType == "override") + { + return PermissionCopyModeType::Override; + } + throw std::runtime_error( + "Cannot convert " + permissionCopyModeType + " to PermissionCopyModeType"); + } + + inline std::string DeleteSnapshotsOptionTypeToString( + const DeleteSnapshotsOptionType& deleteSnapshotsOptionType) + { + switch (deleteSnapshotsOptionType) + { + case DeleteSnapshotsOptionType::Include: + return "include"; + default: + return std::string(); + } + } + + inline DeleteSnapshotsOptionType DeleteSnapshotsOptionTypeFromString( + const std::string& deleteSnapshotsOptionType) + { + if (deleteSnapshotsOptionType == "include") + { + return DeleteSnapshotsOptionType::Include; + } + throw std::runtime_error( + "Cannot convert " + deleteSnapshotsOptionType + " to DeleteSnapshotsOptionType"); + } + + inline std::string FileRangeWriteFromUrlTypeToString( + const FileRangeWriteFromUrlType& fileRangeWriteFromUrlType) + { + switch (fileRangeWriteFromUrlType) + { + case FileRangeWriteFromUrlType::Update: + return "update"; + default: + return std::string(); + } + } + + inline FileRangeWriteFromUrlType FileRangeWriteFromUrlTypeFromString( + const std::string& fileRangeWriteFromUrlType) + { + if (fileRangeWriteFromUrlType == "update") + { + return FileRangeWriteFromUrlType::Update; + } + throw std::runtime_error( + "Cannot convert " + fileRangeWriteFromUrlType + " to FileRangeWriteFromUrlType"); + } + + inline std::string LeaseDurationTypeToString(const LeaseDurationType& leaseDurationType) + { + switch (leaseDurationType) + { + case LeaseDurationType::Infinite: + return "infinite"; + case LeaseDurationType::Fixed: + return "fixed"; + default: + return std::string(); + } + } + + inline LeaseDurationType LeaseDurationTypeFromString(const std::string& leaseDurationType) + { + if (leaseDurationType == "infinite") + { + return LeaseDurationType::Infinite; + } + if (leaseDurationType == "fixed") + { + return LeaseDurationType::Fixed; + } + throw std::runtime_error("Cannot convert " + leaseDurationType + " to LeaseDurationType"); + } + + inline std::string LeaseStateTypeToString(const LeaseStateType& leaseStateType) + { + switch (leaseStateType) + { + case LeaseStateType::Available: + return "available"; + case LeaseStateType::Leased: + return "leased"; + case LeaseStateType::Expired: + return "expired"; + case LeaseStateType::Breaking: + return "breaking"; + case LeaseStateType::Broken: + return "broken"; + default: + return std::string(); + } + } + + inline LeaseStateType LeaseStateTypeFromString(const std::string& leaseStateType) + { + if (leaseStateType == "available") + { + return LeaseStateType::Available; + } + if (leaseStateType == "leased") + { + return LeaseStateType::Leased; + } + if (leaseStateType == "expired") + { + return LeaseStateType::Expired; + } + if (leaseStateType == "breaking") + { + return LeaseStateType::Breaking; + } + if (leaseStateType == "broken") + { + return LeaseStateType::Broken; + } + throw std::runtime_error("Cannot convert " + leaseStateType + " to LeaseStateType"); + } + + inline std::string LeaseStatusTypeToString(const LeaseStatusType& leaseStatusType) + { + switch (leaseStatusType) + { + case LeaseStatusType::Locked: + return "locked"; + case LeaseStatusType::Unlocked: + return "unlocked"; + default: + return std::string(); + } + } + + inline LeaseStatusType LeaseStatusTypeFromString(const std::string& leaseStatusType) + { + if (leaseStatusType == "locked") + { + return LeaseStatusType::Locked; + } + if (leaseStatusType == "unlocked") + { + return LeaseStatusType::Unlocked; + } + throw std::runtime_error("Cannot convert " + leaseStatusType + " to LeaseStatusType"); + } + + inline std::string LeaseActionToString(const LeaseAction& leaseAction) + { + switch (leaseAction) + { + case LeaseAction::Acquire: + return "acquire"; + case LeaseAction::Release: + return "release"; + case LeaseAction::Change: + return "change"; + case LeaseAction::Renew: + return "renew"; + case LeaseAction::Break: + return "break"; + default: + return std::string(); + } + } + + inline LeaseAction LeaseActionFromString(const std::string& leaseAction) + { + if (leaseAction == "acquire") + { + return LeaseAction::Acquire; + } + if (leaseAction == "release") + { + return LeaseAction::Release; + } + if (leaseAction == "change") + { + return LeaseAction::Change; + } + if (leaseAction == "renew") + { + return LeaseAction::Renew; + } + if (leaseAction == "break") + { + return LeaseAction::Break; + } + throw std::runtime_error("Cannot convert " + leaseAction + " to LeaseAction"); + } + + inline std::string CopyStatusTypeToString(const CopyStatusType& copyStatusType) + { + switch (copyStatusType) + { + case CopyStatusType::Pending: + return "pending"; + case CopyStatusType::Success: + return "success"; + case CopyStatusType::Aborted: + return "aborted"; + case CopyStatusType::Failed: + return "failed"; + default: + return std::string(); + } + } + + inline CopyStatusType CopyStatusTypeFromString(const std::string& copyStatusType) + { + if (copyStatusType == "pending") + { + return CopyStatusType::Pending; + } + if (copyStatusType == "success") + { + return CopyStatusType::Success; + } + if (copyStatusType == "aborted") + { + return CopyStatusType::Aborted; + } + if (copyStatusType == "failed") + { + return CopyStatusType::Failed; + } + throw std::runtime_error("Cannot convert " + copyStatusType + " to CopyStatusType"); + } + + inline std::string FileRangeWriteTypeToString(const FileRangeWriteType& fileRangeWriteType) + { + switch (fileRangeWriteType) + { + case FileRangeWriteType::Update: + return "update"; + case FileRangeWriteType::Clear: + return "clear"; + default: + return std::string(); + } + } + + inline FileRangeWriteType FileRangeWriteTypeFromString(const std::string& fileRangeWriteType) + { + if (fileRangeWriteType == "update") + { + return FileRangeWriteType::Update; + } + if (fileRangeWriteType == "clear") + { + return FileRangeWriteType::Clear; + } + throw std::runtime_error("Cannot convert " + fileRangeWriteType + " to FileRangeWriteType"); + } + + class ShareRestClient { public: - struct SetPropertiesOptions - { - StorageServiceProperties ServiceProperties; // The StorageService properties. - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - }; + class Service { + public: + struct SetPropertiesOptions + { + StorageServiceProperties ServiceProperties; // The StorageService properties. + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + }; - static Azure::Core::Response SetProperties( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const SetPropertiesOptions& setPropertiesOptions) - { + static Azure::Core::Response SetProperties( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const SetPropertiesOptions& setPropertiesOptions) + { - std::string xml_body; - { - XmlWriter writer; - StorageServicePropertiesToXml(writer, setPropertiesOptions.ServiceProperties); - writer.Write(XmlNode{XmlNodeType::End}); - xml_body = writer.GetDocument(); + std::string xml_body; + { + XmlWriter writer; + StorageServicePropertiesToXml(writer, setPropertiesOptions.ServiceProperties); + writer.Write(XmlNode{XmlNodeType::End}); + xml_body = writer.GetDocument(); + } + auto body = Azure::Core::Http::MemoryBodyStream( + reinterpret_cast(xml_body.data()), xml_body.length()); + auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Put, url, &body); + request.AddHeader("Content-Length", std::to_string(body.Length())); + request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "service"); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "properties"); + if (setPropertiesOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(setPropertiesOptions.Timeout.GetValue()))); + } + request.AddHeader(Details::c_HeaderVersion, setPropertiesOptions.ApiVersionParameter); + return SetPropertiesParseResult(context, pipeline.Send(context, request)); } - auto body = Azure::Core::Http::MemoryBodyStream( - reinterpret_cast(xml_body.data()), xml_body.length()); - auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Put, url, &body); - request.AddHeader("Content-Length", std::to_string(body.Length())); - request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "service"); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "properties"); - if (setPropertiesOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(setPropertiesOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderVersion, setPropertiesOptions.ApiVersionParameter); - return SetPropertiesParseResult(context, pipeline.Send(context, request)); - } - struct GetPropertiesOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - }; + struct GetPropertiesOptions + { + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + }; - static Azure::Core::Response GetProperties( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const GetPropertiesOptions& getPropertiesOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Get, url); - request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "service"); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "properties"); - if (getPropertiesOptions.Timeout.HasValue()) + static Azure::Core::Response GetProperties( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const GetPropertiesOptions& getPropertiesOptions) { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(getPropertiesOptions.Timeout.GetValue()))); + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Get, url); + request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "service"); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "properties"); + if (getPropertiesOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(getPropertiesOptions.Timeout.GetValue()))); + } + request.AddHeader(Details::c_HeaderVersion, getPropertiesOptions.ApiVersionParameter); + return GetPropertiesParseResult(context, pipeline.Send(context, request)); } - request.AddHeader(Details::c_HeaderVersion, getPropertiesOptions.ApiVersionParameter); - return GetPropertiesParseResult(context, pipeline.Send(context, request)); - } - struct ListSharesSegmentOptions - { - Azure::Core::Nullable Prefix; // Filters the results to return only entries - // whose name begins with the specified prefix. - Azure::Core::Nullable - ContinuationToken; // A string value that identifies the portion of the list to be - // returned with the next list operation. The operation returns a - // marker value within the response body if the list returned was not - // complete. The marker value may then be used in a subsequent call - // to request the next set of list items. The marker value is opaque - // to the client. - Azure::Core::Nullable - MaxResults; // Specifies the maximum number of entries to return. If the request does - // not specify maxresults, or specifies a value greater than 5,000, the - // server will return up to 5,000 items. - Azure::Core::Nullable - ListSharesInclude; // Include this parameter to specify one or more datasets to include - // in the response. - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - }; + struct ListSharesSegmentOptions + { + Azure::Core::Nullable Prefix; // Filters the results to return only entries + // whose name begins with the specified prefix. + Azure::Core::Nullable + ContinuationToken; // A string value that identifies the portion of the list to be + // returned with the next list operation. The operation returns a + // marker value within the response body if the list returned was + // not complete. The marker value may then be used in a subsequent + // call to request the next set of list items. The marker value is + // opaque to the client. + Azure::Core::Nullable + MaxResults; // Specifies the maximum number of entries to return. If the request does + // not specify maxresults, or specifies a value greater than 5,000, the + // server will return up to 5,000 items. + Azure::Core::Nullable + ListSharesInclude; // Include this parameter to specify one or more datasets to + // include in the response. + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + }; - static Azure::Core::Response ListSharesSegment( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const ListSharesSegmentOptions& listSharesSegmentOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Get, url); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "list"); - if (listSharesSegmentOptions.Prefix.HasValue()) + static Azure::Core::Response ListSharesSegment( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const ListSharesSegmentOptions& listSharesSegmentOptions) { - request.GetUrl().AppendQueryParameter( - Details::c_QueryPrefix, - Storage::Details::UrlEncodeQueryParameter( - listSharesSegmentOptions.Prefix.GetValue())); + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Get, url); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "list"); + if (listSharesSegmentOptions.Prefix.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryPrefix, + Storage::Details::UrlEncodeQueryParameter( + listSharesSegmentOptions.Prefix.GetValue())); + } + if (listSharesSegmentOptions.ContinuationToken.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryContinuationToken, + Storage::Details::UrlEncodeQueryParameter( + listSharesSegmentOptions.ContinuationToken.GetValue())); + } + if (listSharesSegmentOptions.MaxResults.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryMaxResults, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(listSharesSegmentOptions.MaxResults.GetValue()))); + } + if (listSharesSegmentOptions.ListSharesInclude.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryListSharesInclude, + Storage::Details::UrlEncodeQueryParameter(ListSharesIncludeTypeToString( + listSharesSegmentOptions.ListSharesInclude.GetValue()))); + } + if (listSharesSegmentOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(listSharesSegmentOptions.Timeout.GetValue()))); + } + request.AddHeader(Details::c_HeaderVersion, listSharesSegmentOptions.ApiVersionParameter); + return ListSharesSegmentParseResult(context, pipeline.Send(context, request)); } - if (listSharesSegmentOptions.ContinuationToken.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryContinuationToken, - Storage::Details::UrlEncodeQueryParameter( - listSharesSegmentOptions.ContinuationToken.GetValue())); - } - if (listSharesSegmentOptions.MaxResults.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryMaxResults, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(listSharesSegmentOptions.MaxResults.GetValue()))); - } - if (listSharesSegmentOptions.ListSharesInclude.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryListSharesInclude, - Storage::Details::UrlEncodeQueryParameter(ListSharesIncludeTypeToString( - listSharesSegmentOptions.ListSharesInclude.GetValue()))); - } - if (listSharesSegmentOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(listSharesSegmentOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderVersion, listSharesSegmentOptions.ApiVersionParameter); - return ListSharesSegmentParseResult(context, pipeline.Send(context, request)); - } - private: - static Azure::Core::Response SetPropertiesParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Accepted) + private: + static Azure::Core::Response SetPropertiesParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) { - // Success (Accepted) - ServiceSetPropertiesResult result; - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Accepted) + { + // Success (Accepted) + ServiceSetPropertiesResult result; + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - static void ShareRetentionPolicyToXml(XmlWriter& writer, const ShareRetentionPolicy& object) - { - writer.Write(XmlNode{XmlNodeType::StartTag, "Enabled"}); - writer.Write(XmlNode{XmlNodeType::Text, nullptr, object.Enabled ? "true" : "false"}); - writer.Write(XmlNode{XmlNodeType::EndTag}); - if (object.Days.HasValue()) + static void ShareRetentionPolicyToXml(XmlWriter& writer, const ShareRetentionPolicy& object) { - writer.Write(XmlNode{XmlNodeType::StartTag, "Days"}); + writer.Write(XmlNode{XmlNodeType::StartTag, "Enabled"}); + writer.Write(XmlNode{XmlNodeType::Text, nullptr, object.Enabled ? "true" : "false"}); + writer.Write(XmlNode{XmlNodeType::EndTag}); + if (object.Days.HasValue()) + { + writer.Write(XmlNode{XmlNodeType::StartTag, "Days"}); + writer.Write( + XmlNode{XmlNodeType::Text, nullptr, std::to_string(object.Days.GetValue()).data()}); + writer.Write(XmlNode{XmlNodeType::EndTag}); + } + } + + static void MetricsToXml(XmlWriter& writer, const Metrics& object) + { + writer.Write(XmlNode{XmlNodeType::StartTag, "Version"}); + writer.Write(XmlNode{XmlNodeType::Text, nullptr, object.Version.data()}); + writer.Write(XmlNode{XmlNodeType::EndTag}); + writer.Write(XmlNode{XmlNodeType::StartTag, "Enabled"}); + writer.Write(XmlNode{XmlNodeType::Text, nullptr, object.Enabled ? "true" : "false"}); + writer.Write(XmlNode{XmlNodeType::EndTag}); + if (object.IncludeApis.HasValue()) + { + writer.Write(XmlNode{XmlNodeType::StartTag, "IncludeAPIs"}); + writer.Write(XmlNode{ + XmlNodeType::Text, nullptr, object.IncludeApis.GetValue() ? "true" : "false"}); + writer.Write(XmlNode{XmlNodeType::EndTag}); + } + writer.Write(XmlNode{XmlNodeType::StartTag, "RetentionPolicy"}); + ShareRetentionPolicyToXml(writer, object.RetentionPolicy); + writer.Write(XmlNode{XmlNodeType::EndTag}); + } + + static void CorsRuleToXml(XmlWriter& writer, const CorsRule& object) + { + writer.Write(XmlNode{XmlNodeType::StartTag, "CorsRule"}); + writer.Write(XmlNode{XmlNodeType::StartTag, "AllowedOrigins"}); + writer.Write(XmlNode{XmlNodeType::Text, nullptr, object.AllowedOrigins.data()}); + writer.Write(XmlNode{XmlNodeType::EndTag}); + writer.Write(XmlNode{XmlNodeType::StartTag, "AllowedMethods"}); + writer.Write(XmlNode{XmlNodeType::Text, nullptr, object.AllowedMethods.data()}); + writer.Write(XmlNode{XmlNodeType::EndTag}); + writer.Write(XmlNode{XmlNodeType::StartTag, "AllowedHeaders"}); + writer.Write(XmlNode{XmlNodeType::Text, nullptr, object.AllowedHeaders.data()}); + writer.Write(XmlNode{XmlNodeType::EndTag}); + writer.Write(XmlNode{XmlNodeType::StartTag, "ExposedHeaders"}); + writer.Write(XmlNode{XmlNodeType::Text, nullptr, object.ExposedHeaders.data()}); + writer.Write(XmlNode{XmlNodeType::EndTag}); + writer.Write(XmlNode{XmlNodeType::StartTag, "MaxAgeInSeconds"}); writer.Write( - XmlNode{XmlNodeType::Text, nullptr, std::to_string(object.Days.GetValue()).data()}); + XmlNode{XmlNodeType::Text, nullptr, std::to_string(object.MaxAgeInSeconds).data()}); + writer.Write(XmlNode{XmlNodeType::EndTag}); writer.Write(XmlNode{XmlNodeType::EndTag}); } - } - static void MetricsToXml(XmlWriter& writer, const Metrics& object) - { - writer.Write(XmlNode{XmlNodeType::StartTag, "Version"}); - writer.Write(XmlNode{XmlNodeType::Text, nullptr, object.Version.data()}); - writer.Write(XmlNode{XmlNodeType::EndTag}); - writer.Write(XmlNode{XmlNodeType::StartTag, "Enabled"}); - writer.Write(XmlNode{XmlNodeType::Text, nullptr, object.Enabled ? "true" : "false"}); - writer.Write(XmlNode{XmlNodeType::EndTag}); - if (object.IncludeApis.HasValue()) + static void SmbMultichannelToXml(XmlWriter& writer, const SmbMultichannel& object) { - writer.Write(XmlNode{XmlNodeType::StartTag, "IncludeAPIs"}); - writer.Write(XmlNode{ - XmlNodeType::Text, nullptr, object.IncludeApis.GetValue() ? "true" : "false"}); + writer.Write(XmlNode{XmlNodeType::StartTag, "Multichannel"}); + writer.Write(XmlNode{XmlNodeType::StartTag, "Enabled"}); + writer.Write(XmlNode{XmlNodeType::Text, nullptr, object.Enabled ? "true" : "false"}); + writer.Write(XmlNode{XmlNodeType::EndTag}); writer.Write(XmlNode{XmlNodeType::EndTag}); } - writer.Write(XmlNode{XmlNodeType::StartTag, "RetentionPolicy"}); - ShareRetentionPolicyToXml(writer, object.RetentionPolicy); - writer.Write(XmlNode{XmlNodeType::EndTag}); - } - static void CorsRuleToXml(XmlWriter& writer, const CorsRule& object) - { - writer.Write(XmlNode{XmlNodeType::StartTag, "CorsRule"}); - writer.Write(XmlNode{XmlNodeType::StartTag, "AllowedOrigins"}); - writer.Write(XmlNode{XmlNodeType::Text, nullptr, object.AllowedOrigins.data()}); - writer.Write(XmlNode{XmlNodeType::EndTag}); - writer.Write(XmlNode{XmlNodeType::StartTag, "AllowedMethods"}); - writer.Write(XmlNode{XmlNodeType::Text, nullptr, object.AllowedMethods.data()}); - writer.Write(XmlNode{XmlNodeType::EndTag}); - writer.Write(XmlNode{XmlNodeType::StartTag, "AllowedHeaders"}); - writer.Write(XmlNode{XmlNodeType::Text, nullptr, object.AllowedHeaders.data()}); - writer.Write(XmlNode{XmlNodeType::EndTag}); - writer.Write(XmlNode{XmlNodeType::StartTag, "ExposedHeaders"}); - writer.Write(XmlNode{XmlNodeType::Text, nullptr, object.ExposedHeaders.data()}); - writer.Write(XmlNode{XmlNodeType::EndTag}); - writer.Write(XmlNode{XmlNodeType::StartTag, "MaxAgeInSeconds"}); - writer.Write( - XmlNode{XmlNodeType::Text, nullptr, std::to_string(object.MaxAgeInSeconds).data()}); - writer.Write(XmlNode{XmlNodeType::EndTag}); - writer.Write(XmlNode{XmlNodeType::EndTag}); - } - - static void SmbMultichannelToXml(XmlWriter& writer, const SmbMultichannel& object) - { - writer.Write(XmlNode{XmlNodeType::StartTag, "Multichannel"}); - writer.Write(XmlNode{XmlNodeType::StartTag, "Enabled"}); - writer.Write(XmlNode{XmlNodeType::Text, nullptr, object.Enabled ? "true" : "false"}); - writer.Write(XmlNode{XmlNodeType::EndTag}); - writer.Write(XmlNode{XmlNodeType::EndTag}); - } - - static void SmbSettingsToXml(XmlWriter& writer, const SmbSettings& object) - { - writer.Write(XmlNode{XmlNodeType::StartTag, "SMB"}); - SmbMultichannelToXml(writer, object.Multichannel); - writer.Write(XmlNode{XmlNodeType::EndTag}); - } - - static void ShareProtocolSettingsToXml(XmlWriter& writer, const ShareProtocolSettings& object) - { - writer.Write(XmlNode{XmlNodeType::StartTag, "ProtocolSettings"}); - SmbSettingsToXml(writer, object.Settings); - writer.Write(XmlNode{XmlNodeType::EndTag}); - } - - static void StorageServicePropertiesToXml( - XmlWriter& writer, - const StorageServiceProperties& object) - { - writer.Write(XmlNode{XmlNodeType::StartTag, "StorageServiceProperties"}); - writer.Write(XmlNode{XmlNodeType::StartTag, "HourMetrics"}); - MetricsToXml(writer, object.HourMetrics); - writer.Write(XmlNode{XmlNodeType::EndTag}); - writer.Write(XmlNode{XmlNodeType::StartTag, "MinuteMetrics"}); - MetricsToXml(writer, object.MinuteMetrics); - writer.Write(XmlNode{XmlNodeType::EndTag}); - if (object.Cors.size() > 0) + static void SmbSettingsToXml(XmlWriter& writer, const SmbSettings& object) { - writer.Write(XmlNode{XmlNodeType::StartTag, "Cors"}); - for (const auto& item : object.Cors) + writer.Write(XmlNode{XmlNodeType::StartTag, "SMB"}); + SmbMultichannelToXml(writer, object.Multichannel); + writer.Write(XmlNode{XmlNodeType::EndTag}); + } + + static void ShareProtocolSettingsToXml( + XmlWriter& writer, + const ShareProtocolSettings& object) + { + writer.Write(XmlNode{XmlNodeType::StartTag, "ProtocolSettings"}); + SmbSettingsToXml(writer, object.Settings); + writer.Write(XmlNode{XmlNodeType::EndTag}); + } + + static void StorageServicePropertiesToXml( + XmlWriter& writer, + const StorageServiceProperties& object) + { + writer.Write(XmlNode{XmlNodeType::StartTag, "StorageServiceProperties"}); + writer.Write(XmlNode{XmlNodeType::StartTag, "HourMetrics"}); + MetricsToXml(writer, object.HourMetrics); + writer.Write(XmlNode{XmlNodeType::EndTag}); + writer.Write(XmlNode{XmlNodeType::StartTag, "MinuteMetrics"}); + MetricsToXml(writer, object.MinuteMetrics); + writer.Write(XmlNode{XmlNodeType::EndTag}); + if (object.Cors.size() > 0) { - CorsRuleToXml(writer, item); + writer.Write(XmlNode{XmlNodeType::StartTag, "Cors"}); + for (const auto& item : object.Cors) + { + CorsRuleToXml(writer, item); + } + writer.Write(XmlNode{XmlNodeType::EndTag}); + } + if (object.Protocol.HasValue()) + { + ShareProtocolSettingsToXml(writer, object.Protocol.GetValue()); } writer.Write(XmlNode{XmlNodeType::EndTag}); } - if (object.Protocol.HasValue()) + static Azure::Core::Response GetPropertiesParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) { - ShareProtocolSettingsToXml(writer, object.Protocol.GetValue()); + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + { + // Success. + const auto& bodyBuffer = response.GetBody(); + auto reader + = XmlReader(reinterpret_cast(bodyBuffer.data()), bodyBuffer.size()); + ServiceGetPropertiesResult result = bodyBuffer.empty() + ? ServiceGetPropertiesResult() + : ServiceGetPropertiesResultFromStorageServiceProperties( + StorageServicePropertiesFromXml(reader)); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } } - writer.Write(XmlNode{XmlNodeType::EndTag}); - } - static Azure::Core::Response GetPropertiesParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) - { - // Success. - const auto& bodyBuffer = response.GetBody(); - auto reader - = XmlReader(reinterpret_cast(bodyBuffer.data()), bodyBuffer.size()); - ServiceGetPropertiesResult result = bodyBuffer.empty() - ? ServiceGetPropertiesResult() - : ServiceGetPropertiesResultFromStorageServiceProperties( - StorageServicePropertiesFromXml(reader)); - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - static ShareRetentionPolicy ShareRetentionPolicyFromXml(XmlReader& reader) - { - auto result = ShareRetentionPolicy(); - enum class XmlTagName + static ShareRetentionPolicy ShareRetentionPolicyFromXml(XmlReader& reader) { - c_Days, - c_Enabled, - c_Unknown, + auto result = ShareRetentionPolicy(); + enum class XmlTagName + { + c_Days, + c_Enabled, + c_Unknown, + }; + std::vector path; + + while (true) + { + auto node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + break; + } + else if (node.Type == XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == XmlNodeType::StartTag) + { + + if (std::strcmp(node.Name, "Days") == 0) + { + path.emplace_back(XmlTagName::c_Days); + } + else if (std::strcmp(node.Name, "Enabled") == 0) + { + path.emplace_back(XmlTagName::c_Enabled); + } + else + { + path.emplace_back(XmlTagName::c_Unknown); + } + } + else if (node.Type == XmlNodeType::Text) + { + if (path.size() == 1 && path[0] == XmlTagName::c_Days) + { + result.Days = std::stoi(node.Value); + } + else if (path.size() == 1 && path[0] == XmlTagName::c_Enabled) + { + result.Enabled = (std::strcmp(node.Value, "true") == 0); + } + } + } + return result; + } + + static Metrics MetricsFromXml(XmlReader& reader) + { + auto result = Metrics(); + enum class XmlTagName + { + c_Enabled, + c_IncludeAPIs, + c_RetentionPolicy, + c_Unknown, + c_Version, + }; + std::vector path; + + while (true) + { + auto node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + break; + } + else if (node.Type == XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == XmlNodeType::StartTag) + { + + if (std::strcmp(node.Name, "Enabled") == 0) + { + path.emplace_back(XmlTagName::c_Enabled); + } + else if (std::strcmp(node.Name, "IncludeAPIs") == 0) + { + path.emplace_back(XmlTagName::c_IncludeAPIs); + } + else if (std::strcmp(node.Name, "RetentionPolicy") == 0) + { + path.emplace_back(XmlTagName::c_RetentionPolicy); + } + else if (std::strcmp(node.Name, "Version") == 0) + { + path.emplace_back(XmlTagName::c_Version); + } + else + { + path.emplace_back(XmlTagName::c_Unknown); + } + + if (path.size() == 1 && path[0] == XmlTagName::c_RetentionPolicy) + { + result.RetentionPolicy = ShareRetentionPolicyFromXml(reader); + path.pop_back(); + } + } + else if (node.Type == XmlNodeType::Text) + { + if (path.size() == 1 && path[0] == XmlTagName::c_Enabled) + { + result.Enabled = (std::strcmp(node.Value, "true") == 0); + } + else if (path.size() == 1 && path[0] == XmlTagName::c_IncludeAPIs) + { + result.IncludeApis = (std::strcmp(node.Value, "true") == 0); + } + else if (path.size() == 1 && path[0] == XmlTagName::c_Version) + { + result.Version = node.Value; + } + } + } + return result; + } + + static CorsRule CorsRuleFromXml(XmlReader& reader) + { + auto result = CorsRule(); + enum class XmlTagName + { + c_AllowedHeaders, + c_AllowedMethods, + c_AllowedOrigins, + c_ExposedHeaders, + c_MaxAgeInSeconds, + c_Unknown, + }; + std::vector path; + + while (true) + { + auto node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + break; + } + else if (node.Type == XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == XmlNodeType::StartTag) + { + + if (std::strcmp(node.Name, "AllowedHeaders") == 0) + { + path.emplace_back(XmlTagName::c_AllowedHeaders); + } + else if (std::strcmp(node.Name, "AllowedMethods") == 0) + { + path.emplace_back(XmlTagName::c_AllowedMethods); + } + else if (std::strcmp(node.Name, "AllowedOrigins") == 0) + { + path.emplace_back(XmlTagName::c_AllowedOrigins); + } + else if (std::strcmp(node.Name, "ExposedHeaders") == 0) + { + path.emplace_back(XmlTagName::c_ExposedHeaders); + } + else if (std::strcmp(node.Name, "MaxAgeInSeconds") == 0) + { + path.emplace_back(XmlTagName::c_MaxAgeInSeconds); + } + else + { + path.emplace_back(XmlTagName::c_Unknown); + } + } + else if (node.Type == XmlNodeType::Text) + { + if (path.size() == 1 && path[0] == XmlTagName::c_AllowedHeaders) + { + result.AllowedHeaders = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::c_AllowedMethods) + { + result.AllowedMethods = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::c_AllowedOrigins) + { + result.AllowedOrigins = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::c_ExposedHeaders) + { + result.ExposedHeaders = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::c_MaxAgeInSeconds) + { + result.MaxAgeInSeconds = std::stoi(node.Value); + } + } + } + return result; + } + + static SmbMultichannel SmbMultichannelFromXml(XmlReader& reader) + { + auto result = SmbMultichannel(); + enum class XmlTagName + { + c_Enabled, + c_Unknown, + }; + std::vector path; + + while (true) + { + auto node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + break; + } + else if (node.Type == XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == XmlNodeType::StartTag) + { + + if (std::strcmp(node.Name, "Enabled") == 0) + { + path.emplace_back(XmlTagName::c_Enabled); + } + else + { + path.emplace_back(XmlTagName::c_Unknown); + } + } + else if (node.Type == XmlNodeType::Text) + { + if (path.size() == 1 && path[0] == XmlTagName::c_Enabled) + { + result.Enabled = (std::strcmp(node.Value, "true") == 0); + } + } + } + return result; + } + + static SmbSettings SmbSettingsFromXml(XmlReader& reader) + { + auto result = SmbSettings(); + enum class XmlTagName + { + c_Multichannel, + c_Unknown, + }; + std::vector path; + + while (true) + { + auto node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + break; + } + else if (node.Type == XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == XmlNodeType::StartTag) + { + + if (std::strcmp(node.Name, "Multichannel") == 0) + { + path.emplace_back(XmlTagName::c_Multichannel); + } + else + { + path.emplace_back(XmlTagName::c_Unknown); + } + + if (path.size() == 1 && path[0] == XmlTagName::c_Multichannel) + { + result.Multichannel = SmbMultichannelFromXml(reader); + path.pop_back(); + } + } + else if (node.Type == XmlNodeType::Text) + { + } + } + return result; + } + + static ShareProtocolSettings ShareProtocolSettingsFromXml(XmlReader& reader) + { + auto result = ShareProtocolSettings(); + enum class XmlTagName + { + c_SMB, + c_Unknown, + }; + std::vector path; + + while (true) + { + auto node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + break; + } + else if (node.Type == XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == XmlNodeType::StartTag) + { + + if (std::strcmp(node.Name, "SMB") == 0) + { + path.emplace_back(XmlTagName::c_SMB); + } + else + { + path.emplace_back(XmlTagName::c_Unknown); + } + + if (path.size() == 1 && path[0] == XmlTagName::c_SMB) + { + result.Settings = SmbSettingsFromXml(reader); + path.pop_back(); + } + } + else if (node.Type == XmlNodeType::Text) + { + } + } + return result; + } + + static StorageServiceProperties StorageServicePropertiesFromXml(XmlReader& reader) + { + auto result = StorageServiceProperties(); + enum class XmlTagName + { + c_Cors, + c_CorsRule, + c_HourMetrics, + c_MinuteMetrics, + c_ProtocolSettings, + c_StorageServiceProperties, + c_Unknown, + }; + std::vector path; + + while (true) + { + auto node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + break; + } + else if (node.Type == XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == XmlNodeType::StartTag) + { + + if (std::strcmp(node.Name, "Cors") == 0) + { + path.emplace_back(XmlTagName::c_Cors); + } + else if (std::strcmp(node.Name, "CorsRule") == 0) + { + path.emplace_back(XmlTagName::c_CorsRule); + } + else if (std::strcmp(node.Name, "HourMetrics") == 0) + { + path.emplace_back(XmlTagName::c_HourMetrics); + } + else if (std::strcmp(node.Name, "MinuteMetrics") == 0) + { + path.emplace_back(XmlTagName::c_MinuteMetrics); + } + else if (std::strcmp(node.Name, "ProtocolSettings") == 0) + { + path.emplace_back(XmlTagName::c_ProtocolSettings); + } + else if (std::strcmp(node.Name, "StorageServiceProperties") == 0) + { + path.emplace_back(XmlTagName::c_StorageServiceProperties); + } + else + { + path.emplace_back(XmlTagName::c_Unknown); + } + + if (path.size() == 2 && path[0] == XmlTagName::c_StorageServiceProperties + && path[1] == XmlTagName::c_HourMetrics) + { + result.HourMetrics = MetricsFromXml(reader); + path.pop_back(); + } + else if ( + path.size() == 2 && path[0] == XmlTagName::c_StorageServiceProperties + && path[1] == XmlTagName::c_MinuteMetrics) + { + result.MinuteMetrics = MetricsFromXml(reader); + path.pop_back(); + } + else if ( + path.size() == 2 && path[0] == XmlTagName::c_StorageServiceProperties + && path[1] == XmlTagName::c_ProtocolSettings) + { + result.Protocol = ShareProtocolSettingsFromXml(reader); + path.pop_back(); + } + else if ( + path.size() == 3 && path[0] == XmlTagName::c_StorageServiceProperties + && path[1] == XmlTagName::c_Cors && path[2] == XmlTagName::c_CorsRule) + { + result.Cors.emplace_back(CorsRuleFromXml(reader)); + path.pop_back(); + } + } + else if (node.Type == XmlNodeType::Text) + { + } + } + return result; + } + + static ServiceGetPropertiesResult ServiceGetPropertiesResultFromStorageServiceProperties( + StorageServiceProperties object) + { + ServiceGetPropertiesResult result; + result.HourMetrics = std::move(object.HourMetrics); + result.MinuteMetrics = std::move(object.MinuteMetrics); + result.Cors = std::move(object.Cors); + result.Protocol = std::move(object.Protocol); + + return result; + } + static Azure::Core::Response ListSharesSegmentParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + { + // Success. + const auto& bodyBuffer = response.GetBody(); + auto reader + = XmlReader(reinterpret_cast(bodyBuffer.data()), bodyBuffer.size()); + ServiceListSharesSegmentResult result = bodyBuffer.empty() + ? ServiceListSharesSegmentResult() + : ServiceListSharesSegmentResultFromListSharesResponse( + ListSharesResponseFromXml(reader)); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static LeaseStatusType LeaseStatusTypeFromXml(XmlReader& reader) + { + auto result = LeaseStatusType::Unknown; + enum class XmlTagName + { + c_LeaseStatus, + c_Unknown, + }; + std::vector path; + + while (true) + { + auto node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + break; + } + else if (node.Type == XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == XmlNodeType::StartTag) + { + + if (std::strcmp(node.Name, "LeaseStatus") == 0) + { + path.emplace_back(XmlTagName::c_LeaseStatus); + } + else + { + path.emplace_back(XmlTagName::c_Unknown); + } + } + else if (node.Type == XmlNodeType::Text) + { + if (path.size() == 1 && path[0] == XmlTagName::c_LeaseStatus) + { + result = LeaseStatusTypeFromString(node.Value); + } + } + } + return result; + } + + static LeaseStateType LeaseStateTypeFromXml(XmlReader& reader) + { + auto result = LeaseStateType::Unknown; + enum class XmlTagName + { + c_LeaseState, + c_Unknown, + }; + std::vector path; + + while (true) + { + auto node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + break; + } + else if (node.Type == XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == XmlNodeType::StartTag) + { + + if (std::strcmp(node.Name, "LeaseState") == 0) + { + path.emplace_back(XmlTagName::c_LeaseState); + } + else + { + path.emplace_back(XmlTagName::c_Unknown); + } + } + else if (node.Type == XmlNodeType::Text) + { + if (path.size() == 1 && path[0] == XmlTagName::c_LeaseState) + { + result = LeaseStateTypeFromString(node.Value); + } + } + } + return result; + } + + static LeaseDurationType LeaseDurationTypeFromXml(XmlReader& reader) + { + auto result = LeaseDurationType::Unknown; + enum class XmlTagName + { + c_LeaseDuration, + c_Unknown, + }; + std::vector path; + + while (true) + { + auto node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + break; + } + else if (node.Type == XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == XmlNodeType::StartTag) + { + + if (std::strcmp(node.Name, "LeaseDuration") == 0) + { + path.emplace_back(XmlTagName::c_LeaseDuration); + } + else + { + path.emplace_back(XmlTagName::c_Unknown); + } + } + else if (node.Type == XmlNodeType::Text) + { + if (path.size() == 1 && path[0] == XmlTagName::c_LeaseDuration) + { + result = LeaseDurationTypeFromString(node.Value); + } + } + } + return result; + } + + static ShareProperties SharePropertiesFromXml(XmlReader& reader) + { + auto result = ShareProperties(); + enum class XmlTagName + { + c_DeletedTime, + c_Etag, + c_LastModified, + c_LeaseDuration, + c_LeaseState, + c_LeaseStatus, + c_NextAllowedQuotaDowngradeTime, + c_ProvisionedEgressMBps, + c_ProvisionedIngressMBps, + c_ProvisionedIops, + c_Quota, + c_RemainingRetentionDays, + c_Unknown, + }; + std::vector path; + + while (true) + { + auto node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + break; + } + else if (node.Type == XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == XmlNodeType::StartTag) + { + + if (std::strcmp(node.Name, "DeletedTime") == 0) + { + path.emplace_back(XmlTagName::c_DeletedTime); + } + else if (std::strcmp(node.Name, "Etag") == 0) + { + path.emplace_back(XmlTagName::c_Etag); + } + else if (std::strcmp(node.Name, "Last-Modified") == 0) + { + path.emplace_back(XmlTagName::c_LastModified); + } + else if (std::strcmp(node.Name, "LeaseDuration") == 0) + { + path.emplace_back(XmlTagName::c_LeaseDuration); + } + else if (std::strcmp(node.Name, "LeaseState") == 0) + { + path.emplace_back(XmlTagName::c_LeaseState); + } + else if (std::strcmp(node.Name, "LeaseStatus") == 0) + { + path.emplace_back(XmlTagName::c_LeaseStatus); + } + else if (std::strcmp(node.Name, "NextAllowedQuotaDowngradeTime") == 0) + { + path.emplace_back(XmlTagName::c_NextAllowedQuotaDowngradeTime); + } + else if (std::strcmp(node.Name, "ProvisionedEgressMBps") == 0) + { + path.emplace_back(XmlTagName::c_ProvisionedEgressMBps); + } + else if (std::strcmp(node.Name, "ProvisionedIngressMBps") == 0) + { + path.emplace_back(XmlTagName::c_ProvisionedIngressMBps); + } + else if (std::strcmp(node.Name, "ProvisionedIops") == 0) + { + path.emplace_back(XmlTagName::c_ProvisionedIops); + } + else if (std::strcmp(node.Name, "Quota") == 0) + { + path.emplace_back(XmlTagName::c_Quota); + } + else if (std::strcmp(node.Name, "RemainingRetentionDays") == 0) + { + path.emplace_back(XmlTagName::c_RemainingRetentionDays); + } + else + { + path.emplace_back(XmlTagName::c_Unknown); + } + + if (path.size() == 1 && path[0] == XmlTagName::c_LeaseStatus) + { + result.LeaseStatus = LeaseStatusTypeFromXml(reader); + path.pop_back(); + } + else if (path.size() == 1 && path[0] == XmlTagName::c_LeaseState) + { + result.LeaseState = LeaseStateTypeFromXml(reader); + path.pop_back(); + } + else if (path.size() == 1 && path[0] == XmlTagName::c_LeaseDuration) + { + result.LeaseDuration = LeaseDurationTypeFromXml(reader); + path.pop_back(); + } + } + else if (node.Type == XmlNodeType::Text) + { + if (path.size() == 1 && path[0] == XmlTagName::c_DeletedTime) + { + result.DeletedTime = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::c_Etag) + { + result.Etag = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::c_LastModified) + { + result.LastModified = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::c_NextAllowedQuotaDowngradeTime) + { + result.NextAllowedQuotaDowngradeTime = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::c_ProvisionedEgressMBps) + { + result.ProvisionedEgressMBps = std::stoi(node.Value); + } + else if (path.size() == 1 && path[0] == XmlTagName::c_ProvisionedIngressMBps) + { + result.ProvisionedIngressMBps = std::stoi(node.Value); + } + else if (path.size() == 1 && path[0] == XmlTagName::c_ProvisionedIops) + { + result.ProvisionedIops = std::stoi(node.Value); + } + else if (path.size() == 1 && path[0] == XmlTagName::c_Quota) + { + result.Quota = std::stoi(node.Value); + } + else if (path.size() == 1 && path[0] == XmlTagName::c_RemainingRetentionDays) + { + result.RemainingRetentionDays = std::stoi(node.Value); + } + } + } + return result; + } + + static std::map MetadataFromXml(XmlReader& reader) + { + std::map result; + int depth = 0; + std::string key; + while (true) + { + auto node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + break; + } + else if (node.Type == XmlNodeType::StartTag) + { + if (depth++ == 0) + { + key = node.Name; + } + } + else if (node.Type == XmlNodeType::EndTag) + { + if (depth-- == 0) + { + break; + } + } + else if (depth == 1 && node.Type == XmlNodeType::Text) + { + result.emplace(std::move(key), std::string(node.Value)); + } + } + return result; + } + + static ShareItem ShareItemFromXml(XmlReader& reader) + { + auto result = ShareItem(); + enum class XmlTagName + { + c_Deleted, + c_Metadata, + c_Name, + c_Properties, + c_Snapshot, + c_Unknown, + c_Version, + }; + std::vector path; + + while (true) + { + auto node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + break; + } + else if (node.Type == XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == XmlNodeType::StartTag) + { + + if (std::strcmp(node.Name, "Deleted") == 0) + { + path.emplace_back(XmlTagName::c_Deleted); + } + else if (std::strcmp(node.Name, "Metadata") == 0) + { + path.emplace_back(XmlTagName::c_Metadata); + } + else if (std::strcmp(node.Name, "Name") == 0) + { + path.emplace_back(XmlTagName::c_Name); + } + else if (std::strcmp(node.Name, "Properties") == 0) + { + path.emplace_back(XmlTagName::c_Properties); + } + else if (std::strcmp(node.Name, "Snapshot") == 0) + { + path.emplace_back(XmlTagName::c_Snapshot); + } + else if (std::strcmp(node.Name, "Version") == 0) + { + path.emplace_back(XmlTagName::c_Version); + } + else + { + path.emplace_back(XmlTagName::c_Unknown); + } + + if (path.size() == 1 && path[0] == XmlTagName::c_Properties) + { + result.Properties = SharePropertiesFromXml(reader); + path.pop_back(); + } + else if (path.size() == 1 && path[0] == XmlTagName::c_Metadata) + { + result.ShareMetadata = MetadataFromXml(reader); + path.pop_back(); + } + } + else if (node.Type == XmlNodeType::Text) + { + if (path.size() == 1 && path[0] == XmlTagName::c_Deleted) + { + result.Deleted = (std::strcmp(node.Value, "true") == 0); + } + else if (path.size() == 1 && path[0] == XmlTagName::c_Name) + { + result.Name = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::c_Snapshot) + { + result.Snapshot = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::c_Version) + { + result.Version = node.Value; + } + } + } + return result; + } + + static ListSharesResponse ListSharesResponseFromXml(XmlReader& reader) + { + auto result = ListSharesResponse(); + enum class XmlTagName + { + c_EnumerationResults, + c_Marker, + c_MaxResults, + c_NextMarker, + c_Prefix, + c_Share, + c_Shares, + c_Unknown, + }; + std::vector path; + + while (true) + { + auto node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + break; + } + else if (node.Type == XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == XmlNodeType::StartTag) + { + + if (std::strcmp(node.Name, "EnumerationResults") == 0) + { + path.emplace_back(XmlTagName::c_EnumerationResults); + } + else if (std::strcmp(node.Name, "Marker") == 0) + { + path.emplace_back(XmlTagName::c_Marker); + } + else if (std::strcmp(node.Name, "MaxResults") == 0) + { + path.emplace_back(XmlTagName::c_MaxResults); + } + else if (std::strcmp(node.Name, "NextMarker") == 0) + { + path.emplace_back(XmlTagName::c_NextMarker); + } + else if (std::strcmp(node.Name, "Prefix") == 0) + { + path.emplace_back(XmlTagName::c_Prefix); + } + else if (std::strcmp(node.Name, "Share") == 0) + { + path.emplace_back(XmlTagName::c_Share); + } + else if (std::strcmp(node.Name, "Shares") == 0) + { + path.emplace_back(XmlTagName::c_Shares); + } + else + { + path.emplace_back(XmlTagName::c_Unknown); + } + if (path.size() == 3 && path[0] == XmlTagName::c_EnumerationResults + && path[1] == XmlTagName::c_Shares && path[2] == XmlTagName::c_Share) + { + result.ShareItems.emplace_back(ShareItemFromXml(reader)); + path.pop_back(); + } + } + else if (node.Type == XmlNodeType::Text) + { + if (path.size() == 2 && path[0] == XmlTagName::c_EnumerationResults + && path[1] == XmlTagName::c_NextMarker) + { + result.ContinuationToken = node.Value; + } + else if ( + path.size() == 2 && path[0] == XmlTagName::c_EnumerationResults + && path[1] == XmlTagName::c_MaxResults) + { + result.MaxResults = std::stoi(node.Value); + } + else if ( + path.size() == 2 && path[0] == XmlTagName::c_EnumerationResults + && path[1] == XmlTagName::c_Prefix) + { + result.Prefix = node.Value; + } + else if ( + path.size() == 2 && path[0] == XmlTagName::c_EnumerationResults + && path[1] == XmlTagName::c_Marker) + { + result.PreviousContinuationToken = node.Value; + } + } + else if (node.Type == XmlNodeType::Attribute) + { + if (path.size() == 1 && path[0] == XmlTagName::c_EnumerationResults + && (std::strcmp(node.Name, "ServiceEndpoint") == 0)) + { + result.ServiceEndpoint = node.Value; + } + } + } + return result; + } + + static ServiceListSharesSegmentResult ServiceListSharesSegmentResultFromListSharesResponse( + ListSharesResponse object) + { + ServiceListSharesSegmentResult result; + result.ServiceEndpoint = std::move(object.ServiceEndpoint); + result.Prefix = std::move(object.Prefix); + result.PreviousContinuationToken = std::move(object.PreviousContinuationToken); + result.MaxResults = object.MaxResults; + result.ShareItems = std::move(object.ShareItems); + result.ContinuationToken = std::move(object.ContinuationToken); + + return result; + } + }; + + class Share { + public: + struct CreateOptions + { + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::map + Metadata; // A name-value pair to associate with a file storage object. + Azure::Core::Nullable + ShareQuota; // Specifies the maximum size of the share, in gigabytes. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. }; - std::vector path; - while (true) + static Azure::Core::Response Create( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const CreateOptions& createOptions) { - auto node = reader.Read(); - if (node.Type == XmlNodeType::End) + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); + request.AddHeader(Details::c_HeaderContentLength, "0"); + request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "share"); + if (createOptions.Timeout.HasValue()) { - break; + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(createOptions.Timeout.GetValue()))); } - else if (node.Type == XmlNodeType::EndTag) + std::set metadataKeys; + for (const auto& pair : createOptions.Metadata) { - if (path.size() > 0) + std::string key = pair.first; + std::transform(key.begin(), key.end(), key.begin(), [](unsigned char c) { + return static_cast(std::tolower(c)); + }); + if (metadataKeys.insert(key).second == false) { - path.pop_back(); - } - else - { - break; + throw std::runtime_error("duplicate keys in metadata"); } + request.AddHeader(Details::c_HeaderMetadata + ("-" + pair.first), pair.second); } - else if (node.Type == XmlNodeType::StartTag) + metadataKeys.clear(); + if (createOptions.ShareQuota.HasValue()) { - - if (std::strcmp(node.Name, "Days") == 0) - { - path.emplace_back(XmlTagName::c_Days); - } - else if (std::strcmp(node.Name, "Enabled") == 0) - { - path.emplace_back(XmlTagName::c_Enabled); - } - else - { - path.emplace_back(XmlTagName::c_Unknown); - } - } - else if (node.Type == XmlNodeType::Text) - { - if (path.size() == 1 && path[0] == XmlTagName::c_Days) - { - result.Days = std::stoi(node.Value); - } - else if (path.size() == 1 && path[0] == XmlTagName::c_Enabled) - { - result.Enabled = (std::strcmp(node.Value, "true") == 0); - } + request.AddHeader( + Details::c_HeaderQuota, std::to_string(createOptions.ShareQuota.GetValue())); } + request.AddHeader(Details::c_HeaderVersion, createOptions.ApiVersionParameter); + return CreateParseResult(context, pipeline.Send(context, request)); } - return result; - } - static Metrics MetricsFromXml(XmlReader& reader) - { - auto result = Metrics(); - enum class XmlTagName + struct GetPropertiesOptions { - c_Enabled, - c_IncludeAPIs, - c_RetentionPolicy, - c_Unknown, - c_Version, + Azure::Core::Nullable + ShareSnapshot; // The snapshot parameter is an opaque DateTime value that, when + // present, specifies the share snapshot to query. + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease + // is active and matches this ID. }; - std::vector path; - while (true) + static Azure::Core::Response GetProperties( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const GetPropertiesOptions& getPropertiesOptions) { - auto node = reader.Read(); - if (node.Type == XmlNodeType::End) + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Get, url); + request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "share"); + if (getPropertiesOptions.ShareSnapshot.HasValue()) { - break; + request.GetUrl().AppendQueryParameter( + Details::c_QueryShareSnapshot, + Storage::Details::UrlEncodeQueryParameter( + getPropertiesOptions.ShareSnapshot.GetValue())); } - else if (node.Type == XmlNodeType::EndTag) + if (getPropertiesOptions.Timeout.HasValue()) { - if (path.size() > 0) - { - path.pop_back(); - } - else - { - break; - } + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(getPropertiesOptions.Timeout.GetValue()))); } - else if (node.Type == XmlNodeType::StartTag) + request.AddHeader(Details::c_HeaderVersion, getPropertiesOptions.ApiVersionParameter); + if (getPropertiesOptions.LeaseIdOptional.HasValue()) { - - if (std::strcmp(node.Name, "Enabled") == 0) - { - path.emplace_back(XmlTagName::c_Enabled); - } - else if (std::strcmp(node.Name, "IncludeAPIs") == 0) - { - path.emplace_back(XmlTagName::c_IncludeAPIs); - } - else if (std::strcmp(node.Name, "RetentionPolicy") == 0) - { - path.emplace_back(XmlTagName::c_RetentionPolicy); - } - else if (std::strcmp(node.Name, "Version") == 0) - { - path.emplace_back(XmlTagName::c_Version); - } - else - { - path.emplace_back(XmlTagName::c_Unknown); - } - - if (path.size() == 1 && path[0] == XmlTagName::c_RetentionPolicy) - { - result.RetentionPolicy = ShareRetentionPolicyFromXml(reader); - path.pop_back(); - } - } - else if (node.Type == XmlNodeType::Text) - { - if (path.size() == 1 && path[0] == XmlTagName::c_Enabled) - { - result.Enabled = (std::strcmp(node.Value, "true") == 0); - } - else if (path.size() == 1 && path[0] == XmlTagName::c_IncludeAPIs) - { - result.IncludeApis = (std::strcmp(node.Value, "true") == 0); - } - else if (path.size() == 1 && path[0] == XmlTagName::c_Version) - { - result.Version = node.Value; - } + request.AddHeader( + Details::c_HeaderLeaseId, getPropertiesOptions.LeaseIdOptional.GetValue()); } + return GetPropertiesParseResult(context, pipeline.Send(context, request)); } - return result; - } - static CorsRule CorsRuleFromXml(XmlReader& reader) - { - auto result = CorsRule(); - enum class XmlTagName + struct DeleteOptions { - c_AllowedHeaders, - c_AllowedMethods, - c_AllowedOrigins, - c_ExposedHeaders, - c_MaxAgeInSeconds, - c_Unknown, + Azure::Core::Nullable + ShareSnapshot; // The snapshot parameter is an opaque DateTime value that, when + // present, specifies the share snapshot to query. + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + XMsDeleteSnapshots; // Specifies the option include to delete the base share and all + // of its snapshots. + Azure::Core::Nullable + LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease + // is active and matches this ID. }; - std::vector path; - while (true) + static Azure::Core::Response Delete( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const DeleteOptions& deleteOptions) { - auto node = reader.Read(); - if (node.Type == XmlNodeType::End) + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Delete, url); + request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "share"); + if (deleteOptions.ShareSnapshot.HasValue()) { - break; + request.GetUrl().AppendQueryParameter( + Details::c_QueryShareSnapshot, + Storage::Details::UrlEncodeQueryParameter(deleteOptions.ShareSnapshot.GetValue())); } - else if (node.Type == XmlNodeType::EndTag) + if (deleteOptions.Timeout.HasValue()) { - if (path.size() > 0) - { - path.pop_back(); - } - else - { - break; - } + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(deleteOptions.Timeout.GetValue()))); } - else if (node.Type == XmlNodeType::StartTag) + request.AddHeader(Details::c_HeaderVersion, deleteOptions.ApiVersionParameter); + if (deleteOptions.XMsDeleteSnapshots.HasValue()) { - - if (std::strcmp(node.Name, "AllowedHeaders") == 0) - { - path.emplace_back(XmlTagName::c_AllowedHeaders); - } - else if (std::strcmp(node.Name, "AllowedMethods") == 0) - { - path.emplace_back(XmlTagName::c_AllowedMethods); - } - else if (std::strcmp(node.Name, "AllowedOrigins") == 0) - { - path.emplace_back(XmlTagName::c_AllowedOrigins); - } - else if (std::strcmp(node.Name, "ExposedHeaders") == 0) - { - path.emplace_back(XmlTagName::c_ExposedHeaders); - } - else if (std::strcmp(node.Name, "MaxAgeInSeconds") == 0) - { - path.emplace_back(XmlTagName::c_MaxAgeInSeconds); - } - else - { - path.emplace_back(XmlTagName::c_Unknown); - } + request.AddHeader( + Details::c_HeaderDeleteSnapshots, + DeleteSnapshotsOptionTypeToString(deleteOptions.XMsDeleteSnapshots.GetValue())); } - else if (node.Type == XmlNodeType::Text) + if (deleteOptions.LeaseIdOptional.HasValue()) { - if (path.size() == 1 && path[0] == XmlTagName::c_AllowedHeaders) - { - result.AllowedHeaders = node.Value; - } - else if (path.size() == 1 && path[0] == XmlTagName::c_AllowedMethods) - { - result.AllowedMethods = node.Value; - } - else if (path.size() == 1 && path[0] == XmlTagName::c_AllowedOrigins) - { - result.AllowedOrigins = node.Value; - } - else if (path.size() == 1 && path[0] == XmlTagName::c_ExposedHeaders) - { - result.ExposedHeaders = node.Value; - } - else if (path.size() == 1 && path[0] == XmlTagName::c_MaxAgeInSeconds) - { - result.MaxAgeInSeconds = std::stoi(node.Value); - } + request.AddHeader(Details::c_HeaderLeaseId, deleteOptions.LeaseIdOptional.GetValue()); } + return DeleteParseResult(context, pipeline.Send(context, request)); } - return result; - } - static SmbMultichannel SmbMultichannelFromXml(XmlReader& reader) - { - auto result = SmbMultichannel(); - enum class XmlTagName + struct AcquireLeaseOptions { - c_Enabled, - c_Unknown, + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + int32_t LeaseDuration + = int32_t(); // Specifies the duration of the lease, in seconds, or negative one (-1) + // for a lease that never expires. A non-infinite lease can be between 15 + // and 60 seconds. A lease duration cannot be changed using renew or + // change. + Azure::Core::Nullable + ProposedLeaseIdOptional; // Proposed lease ID, in a GUID string format. The File + // service returns 400 (Invalid request) if the proposed + // lease ID is not in the correct format. See Guid + // Constructor (String) for a list of valid GUID string + // formats. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + ShareSnapshot; // The snapshot parameter is an opaque DateTime value that, when + // present, specifies the share snapshot to query. + Azure::Core::Nullable + ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character + // limit that is recorded in the analytics logs when storage + // analytics logging is enabled. }; - std::vector path; - while (true) + static Azure::Core::Response AcquireLease( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const AcquireLeaseOptions& acquireLeaseOptions) { - auto node = reader.Read(); - if (node.Type == XmlNodeType::End) + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); + request.AddHeader(Details::c_HeaderContentLength, "0"); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "lease"); + request.AddHeader(Details::c_HeaderAction, "acquire"); + request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "share"); + if (acquireLeaseOptions.Timeout.HasValue()) { - break; + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(acquireLeaseOptions.Timeout.GetValue()))); } - else if (node.Type == XmlNodeType::EndTag) + request.AddHeader( + Details::c_HeaderDuration, std::to_string(acquireLeaseOptions.LeaseDuration)); + if (acquireLeaseOptions.ProposedLeaseIdOptional.HasValue()) { - if (path.size() > 0) - { - path.pop_back(); - } - else - { - break; - } + request.AddHeader( + Details::c_HeaderProposedLeaseId, + acquireLeaseOptions.ProposedLeaseIdOptional.GetValue()); } - else if (node.Type == XmlNodeType::StartTag) + request.AddHeader(Details::c_HeaderVersion, acquireLeaseOptions.ApiVersionParameter); + if (acquireLeaseOptions.ShareSnapshot.HasValue()) { - - if (std::strcmp(node.Name, "Enabled") == 0) - { - path.emplace_back(XmlTagName::c_Enabled); - } - else - { - path.emplace_back(XmlTagName::c_Unknown); - } + request.GetUrl().AppendQueryParameter( + Details::c_QueryShareSnapshot, + Storage::Details::UrlEncodeQueryParameter( + acquireLeaseOptions.ShareSnapshot.GetValue())); } - else if (node.Type == XmlNodeType::Text) + if (acquireLeaseOptions.ClientRequestId.HasValue()) { - if (path.size() == 1 && path[0] == XmlTagName::c_Enabled) - { - result.Enabled = (std::strcmp(node.Value, "true") == 0); - } + request.AddHeader( + Details::c_HeaderRequestId, acquireLeaseOptions.ClientRequestId.GetValue()); } + return AcquireLeaseParseResult(context, pipeline.Send(context, request)); } - return result; - } - static SmbSettings SmbSettingsFromXml(XmlReader& reader) - { - auto result = SmbSettings(); - enum class XmlTagName + struct ReleaseLeaseOptions { - c_Multichannel, - c_Unknown, + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::string LeaseIdRequired; // Specifies the current lease ID on the resource. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + ShareSnapshot; // The snapshot parameter is an opaque DateTime value that, when + // present, specifies the share snapshot to query. + Azure::Core::Nullable + ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character + // limit that is recorded in the analytics logs when storage + // analytics logging is enabled. }; - std::vector path; - while (true) + static Azure::Core::Response ReleaseLease( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const ReleaseLeaseOptions& releaseLeaseOptions) { - auto node = reader.Read(); - if (node.Type == XmlNodeType::End) + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); + request.AddHeader(Details::c_HeaderContentLength, "0"); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "lease"); + request.AddHeader(Details::c_HeaderAction, "release"); + request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "share"); + if (releaseLeaseOptions.Timeout.HasValue()) { - break; + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(releaseLeaseOptions.Timeout.GetValue()))); } - else if (node.Type == XmlNodeType::EndTag) + request.AddHeader(Details::c_HeaderLeaseId, releaseLeaseOptions.LeaseIdRequired); + request.AddHeader(Details::c_HeaderVersion, releaseLeaseOptions.ApiVersionParameter); + if (releaseLeaseOptions.ShareSnapshot.HasValue()) { - if (path.size() > 0) - { - path.pop_back(); - } - else - { - break; - } + request.GetUrl().AppendQueryParameter( + Details::c_QueryShareSnapshot, + Storage::Details::UrlEncodeQueryParameter( + releaseLeaseOptions.ShareSnapshot.GetValue())); } - else if (node.Type == XmlNodeType::StartTag) - { - - if (std::strcmp(node.Name, "Multichannel") == 0) - { - path.emplace_back(XmlTagName::c_Multichannel); - } - else - { - path.emplace_back(XmlTagName::c_Unknown); - } - - if (path.size() == 1 && path[0] == XmlTagName::c_Multichannel) - { - result.Multichannel = SmbMultichannelFromXml(reader); - path.pop_back(); - } - } - else if (node.Type == XmlNodeType::Text) + if (releaseLeaseOptions.ClientRequestId.HasValue()) { + request.AddHeader( + Details::c_HeaderRequestId, releaseLeaseOptions.ClientRequestId.GetValue()); } + return ReleaseLeaseParseResult(context, pipeline.Send(context, request)); } - return result; - } - static ShareProtocolSettings ShareProtocolSettingsFromXml(XmlReader& reader) - { - auto result = ShareProtocolSettings(); - enum class XmlTagName + struct ChangeLeaseOptions { - c_SMB, - c_Unknown, + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::string LeaseIdRequired; // Specifies the current lease ID on the resource. + Azure::Core::Nullable + ProposedLeaseIdOptional; // Proposed lease ID, in a GUID string format. The File + // service returns 400 (Invalid request) if the proposed + // lease ID is not in the correct format. See Guid + // Constructor (String) for a list of valid GUID string + // formats. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + ShareSnapshot; // The snapshot parameter is an opaque DateTime value that, when + // present, specifies the share snapshot to query. + Azure::Core::Nullable + ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character + // limit that is recorded in the analytics logs when storage + // analytics logging is enabled. }; - std::vector path; - while (true) + static Azure::Core::Response ChangeLease( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const ChangeLeaseOptions& changeLeaseOptions) { - auto node = reader.Read(); - if (node.Type == XmlNodeType::End) + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); + request.AddHeader(Details::c_HeaderContentLength, "0"); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "lease"); + request.AddHeader(Details::c_HeaderAction, "change"); + request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "share"); + if (changeLeaseOptions.Timeout.HasValue()) { - break; + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(changeLeaseOptions.Timeout.GetValue()))); } - else if (node.Type == XmlNodeType::EndTag) + request.AddHeader(Details::c_HeaderLeaseId, changeLeaseOptions.LeaseIdRequired); + if (changeLeaseOptions.ProposedLeaseIdOptional.HasValue()) { - if (path.size() > 0) - { - path.pop_back(); - } - else - { - break; - } + request.AddHeader( + Details::c_HeaderProposedLeaseId, + changeLeaseOptions.ProposedLeaseIdOptional.GetValue()); } - else if (node.Type == XmlNodeType::StartTag) + request.AddHeader(Details::c_HeaderVersion, changeLeaseOptions.ApiVersionParameter); + if (changeLeaseOptions.ShareSnapshot.HasValue()) { - - if (std::strcmp(node.Name, "SMB") == 0) - { - path.emplace_back(XmlTagName::c_SMB); - } - else - { - path.emplace_back(XmlTagName::c_Unknown); - } - - if (path.size() == 1 && path[0] == XmlTagName::c_SMB) - { - result.Settings = SmbSettingsFromXml(reader); - path.pop_back(); - } + request.GetUrl().AppendQueryParameter( + Details::c_QueryShareSnapshot, + Storage::Details::UrlEncodeQueryParameter( + changeLeaseOptions.ShareSnapshot.GetValue())); } - else if (node.Type == XmlNodeType::Text) + if (changeLeaseOptions.ClientRequestId.HasValue()) { + request.AddHeader( + Details::c_HeaderRequestId, changeLeaseOptions.ClientRequestId.GetValue()); } + return ChangeLeaseParseResult(context, pipeline.Send(context, request)); } - return result; - } - static StorageServiceProperties StorageServicePropertiesFromXml(XmlReader& reader) - { - auto result = StorageServiceProperties(); - enum class XmlTagName + struct RenewLeaseOptions { - c_Cors, - c_CorsRule, - c_HourMetrics, - c_MinuteMetrics, - c_ProtocolSettings, - c_StorageServiceProperties, - c_Unknown, + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::string LeaseIdRequired; // Specifies the current lease ID on the resource. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + ShareSnapshot; // The snapshot parameter is an opaque DateTime value that, when + // present, specifies the share snapshot to query. + Azure::Core::Nullable + ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character + // limit that is recorded in the analytics logs when storage + // analytics logging is enabled. }; - std::vector path; - while (true) + static Azure::Core::Response RenewLease( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const RenewLeaseOptions& renewLeaseOptions) { - auto node = reader.Read(); - if (node.Type == XmlNodeType::End) + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); + request.AddHeader(Details::c_HeaderContentLength, "0"); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "lease"); + request.AddHeader(Details::c_HeaderAction, "renew"); + request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "share"); + if (renewLeaseOptions.Timeout.HasValue()) { - break; + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(renewLeaseOptions.Timeout.GetValue()))); } - else if (node.Type == XmlNodeType::EndTag) + request.AddHeader(Details::c_HeaderLeaseId, renewLeaseOptions.LeaseIdRequired); + request.AddHeader(Details::c_HeaderVersion, renewLeaseOptions.ApiVersionParameter); + if (renewLeaseOptions.ShareSnapshot.HasValue()) { - if (path.size() > 0) - { - path.pop_back(); - } - else - { - break; - } + request.GetUrl().AppendQueryParameter( + Details::c_QueryShareSnapshot, + Storage::Details::UrlEncodeQueryParameter( + renewLeaseOptions.ShareSnapshot.GetValue())); } - else if (node.Type == XmlNodeType::StartTag) - { - - if (std::strcmp(node.Name, "Cors") == 0) - { - path.emplace_back(XmlTagName::c_Cors); - } - else if (std::strcmp(node.Name, "CorsRule") == 0) - { - path.emplace_back(XmlTagName::c_CorsRule); - } - else if (std::strcmp(node.Name, "HourMetrics") == 0) - { - path.emplace_back(XmlTagName::c_HourMetrics); - } - else if (std::strcmp(node.Name, "MinuteMetrics") == 0) - { - path.emplace_back(XmlTagName::c_MinuteMetrics); - } - else if (std::strcmp(node.Name, "ProtocolSettings") == 0) - { - path.emplace_back(XmlTagName::c_ProtocolSettings); - } - else if (std::strcmp(node.Name, "StorageServiceProperties") == 0) - { - path.emplace_back(XmlTagName::c_StorageServiceProperties); - } - else - { - path.emplace_back(XmlTagName::c_Unknown); - } - - if (path.size() == 2 && path[0] == XmlTagName::c_StorageServiceProperties - && path[1] == XmlTagName::c_HourMetrics) - { - result.HourMetrics = MetricsFromXml(reader); - path.pop_back(); - } - else if ( - path.size() == 2 && path[0] == XmlTagName::c_StorageServiceProperties - && path[1] == XmlTagName::c_MinuteMetrics) - { - result.MinuteMetrics = MetricsFromXml(reader); - path.pop_back(); - } - else if ( - path.size() == 2 && path[0] == XmlTagName::c_StorageServiceProperties - && path[1] == XmlTagName::c_ProtocolSettings) - { - result.Protocol = ShareProtocolSettingsFromXml(reader); - path.pop_back(); - } - else if ( - path.size() == 3 && path[0] == XmlTagName::c_StorageServiceProperties - && path[1] == XmlTagName::c_Cors && path[2] == XmlTagName::c_CorsRule) - { - result.Cors.emplace_back(CorsRuleFromXml(reader)); - path.pop_back(); - } - } - else if (node.Type == XmlNodeType::Text) + if (renewLeaseOptions.ClientRequestId.HasValue()) { + request.AddHeader( + Details::c_HeaderRequestId, renewLeaseOptions.ClientRequestId.GetValue()); } + return RenewLeaseParseResult(context, pipeline.Send(context, request)); } - return result; - } - static ServiceGetPropertiesResult ServiceGetPropertiesResultFromStorageServiceProperties( - StorageServiceProperties object) - { - ServiceGetPropertiesResult result; - result.HourMetrics = std::move(object.HourMetrics); - result.MinuteMetrics = std::move(object.MinuteMetrics); - result.Cors = std::move(object.Cors); - result.Protocol = std::move(object.Protocol); - - return result; - } - static Azure::Core::Response ListSharesSegmentParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + struct BreakLeaseOptions { - // Success. - const auto& bodyBuffer = response.GetBody(); - auto reader - = XmlReader(reinterpret_cast(bodyBuffer.data()), bodyBuffer.size()); - ServiceListSharesSegmentResult result = bodyBuffer.empty() - ? ServiceListSharesSegmentResult() - : ServiceListSharesSegmentResultFromListSharesResponse( - ListSharesResponseFromXml(reader)); - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static LeaseStatusType LeaseStatusTypeFromXml(XmlReader& reader) - { - auto result = LeaseStatusType::Unknown; - enum class XmlTagName - { - c_LeaseStatus, - c_Unknown, + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + Azure::Core::Nullable + LeaseBreakPeriod; // For a break operation, proposed duration the lease should + // continue before it is broken, in seconds, between 0 and 60. This + // break period is only used if it is shorter than the time + // remaining on the lease. If longer, the time remaining on the + // lease is used. A new lease will not be available before the break + // period has expired, but the lease may be held for longer than the + // break period. If this header does not appear with a break + // operation, a fixed-duration lease breaks after the remaining + // lease period elapses, and an infinite lease breaks immediately. + Azure::Core::Nullable + LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease + // is active and matches this ID. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character + // limit that is recorded in the analytics logs when storage + // analytics logging is enabled. + Azure::Core::Nullable + ShareSnapshot; // The snapshot parameter is an opaque DateTime value that, when + // present, specifies the share snapshot to query. }; - std::vector path; - while (true) + static Azure::Core::Response BreakLease( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const BreakLeaseOptions& breakLeaseOptions) { - auto node = reader.Read(); - if (node.Type == XmlNodeType::End) + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); + request.AddHeader(Details::c_HeaderContentLength, "0"); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "lease"); + request.AddHeader(Details::c_HeaderAction, "break"); + request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "share"); + if (breakLeaseOptions.Timeout.HasValue()) { - break; + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(breakLeaseOptions.Timeout.GetValue()))); } - else if (node.Type == XmlNodeType::EndTag) + if (breakLeaseOptions.LeaseBreakPeriod.HasValue()) { - if (path.size() > 0) - { - path.pop_back(); - } - else - { - break; - } + request.AddHeader( + Details::c_HeaderBreakPeriod, + std::to_string(breakLeaseOptions.LeaseBreakPeriod.GetValue())); } - else if (node.Type == XmlNodeType::StartTag) + if (breakLeaseOptions.LeaseIdOptional.HasValue()) { - - if (std::strcmp(node.Name, "LeaseStatus") == 0) - { - path.emplace_back(XmlTagName::c_LeaseStatus); - } - else - { - path.emplace_back(XmlTagName::c_Unknown); - } + request.AddHeader( + Details::c_HeaderLeaseId, breakLeaseOptions.LeaseIdOptional.GetValue()); } - else if (node.Type == XmlNodeType::Text) + request.AddHeader(Details::c_HeaderVersion, breakLeaseOptions.ApiVersionParameter); + if (breakLeaseOptions.ClientRequestId.HasValue()) { - if (path.size() == 1 && path[0] == XmlTagName::c_LeaseStatus) - { - result = LeaseStatusTypeFromString(node.Value); - } + request.AddHeader( + Details::c_HeaderRequestId, breakLeaseOptions.ClientRequestId.GetValue()); } + if (breakLeaseOptions.ShareSnapshot.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryShareSnapshot, + Storage::Details::UrlEncodeQueryParameter( + breakLeaseOptions.ShareSnapshot.GetValue())); + } + return BreakLeaseParseResult(context, pipeline.Send(context, request)); } - return result; - } - static LeaseStateType LeaseStateTypeFromXml(XmlReader& reader) - { - auto result = LeaseStateType::Unknown; - enum class XmlTagName + struct CreateSnapshotOptions { - c_LeaseState, - c_Unknown, + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::map + Metadata; // A name-value pair to associate with a file storage object. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. }; - std::vector path; - while (true) + static Azure::Core::Response CreateSnapshot( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const CreateSnapshotOptions& createSnapshotOptions) { - auto node = reader.Read(); - if (node.Type == XmlNodeType::End) + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); + request.AddHeader(Details::c_HeaderContentLength, "0"); + request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "share"); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "snapshot"); + if (createSnapshotOptions.Timeout.HasValue()) { - break; + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(createSnapshotOptions.Timeout.GetValue()))); } - else if (node.Type == XmlNodeType::EndTag) + std::set metadataKeys; + for (const auto& pair : createSnapshotOptions.Metadata) { - if (path.size() > 0) + std::string key = pair.first; + std::transform(key.begin(), key.end(), key.begin(), [](unsigned char c) { + return static_cast(std::tolower(c)); + }); + if (metadataKeys.insert(key).second == false) { - path.pop_back(); - } - else - { - break; - } - } - else if (node.Type == XmlNodeType::StartTag) - { - - if (std::strcmp(node.Name, "LeaseState") == 0) - { - path.emplace_back(XmlTagName::c_LeaseState); - } - else - { - path.emplace_back(XmlTagName::c_Unknown); - } - } - else if (node.Type == XmlNodeType::Text) - { - if (path.size() == 1 && path[0] == XmlTagName::c_LeaseState) - { - result = LeaseStateTypeFromString(node.Value); + throw std::runtime_error("duplicate keys in metadata"); } + request.AddHeader(Details::c_HeaderMetadata + ("-" + pair.first), pair.second); } + metadataKeys.clear(); + request.AddHeader(Details::c_HeaderVersion, createSnapshotOptions.ApiVersionParameter); + return CreateSnapshotParseResult(context, pipeline.Send(context, request)); } - return result; - } - static LeaseDurationType LeaseDurationTypeFromXml(XmlReader& reader) - { - auto result = LeaseDurationType::Unknown; - enum class XmlTagName + struct CreatePermissionOptions { - c_LeaseDuration, - c_Unknown, + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + SharePermission Permission; // A permission (a security descriptor) at the share level. }; - std::vector path; - while (true) + static Azure::Core::Response CreatePermission( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const CreatePermissionOptions& createPermissionOptions) { - auto node = reader.Read(); - if (node.Type == XmlNodeType::End) - { - break; - } - else if (node.Type == XmlNodeType::EndTag) - { - if (path.size() > 0) - { - path.pop_back(); - } - else - { - break; - } - } - else if (node.Type == XmlNodeType::StartTag) - { - if (std::strcmp(node.Name, "LeaseDuration") == 0) - { - path.emplace_back(XmlTagName::c_LeaseDuration); - } - else - { - path.emplace_back(XmlTagName::c_Unknown); - } - } - else if (node.Type == XmlNodeType::Text) + std::string json_body; { - if (path.size() == 1 && path[0] == XmlTagName::c_LeaseDuration) - { - result = LeaseDurationTypeFromString(node.Value); - } + nlohmann::json json; + SharePermissionToJson(json, createPermissionOptions.Permission); + json_body = json.dump(); } + auto body = Azure::Core::Http::MemoryBodyStream( + reinterpret_cast(json_body.data()), json_body.length()); + auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Put, url, &body); + request.AddHeader("Content-Length", std::to_string(body.Length())); + request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "share"); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "filepermission"); + if (createPermissionOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(createPermissionOptions.Timeout.GetValue()))); + } + request.AddHeader(Details::c_HeaderVersion, createPermissionOptions.ApiVersionParameter); + return CreatePermissionParseResult(context, pipeline.Send(context, request)); } - return result; - } - static ShareProperties SharePropertiesFromXml(XmlReader& reader) - { - auto result = ShareProperties(); - enum class XmlTagName + struct GetPermissionOptions { - c_DeletedTime, - c_Etag, - c_LastModified, - c_LeaseDuration, - c_LeaseState, - c_LeaseStatus, - c_NextAllowedQuotaDowngradeTime, - c_ProvisionedEgressMBps, - c_ProvisionedIngressMBps, - c_ProvisionedIops, - c_Quota, - c_RemainingRetentionDays, - c_Unknown, + std::string + FilePermissionKeyRequired; // Key of the permission to be set for the directory/file. + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. }; - std::vector path; - while (true) + static Azure::Core::Response GetPermission( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const GetPermissionOptions& getPermissionOptions) { - auto node = reader.Read(); - if (node.Type == XmlNodeType::End) + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Get, url); + request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "share"); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "filepermission"); + request.AddHeader( + Details::c_HeaderFilePermissionKey, getPermissionOptions.FilePermissionKeyRequired); + if (getPermissionOptions.Timeout.HasValue()) { - break; - } - else if (node.Type == XmlNodeType::EndTag) - { - if (path.size() > 0) - { - path.pop_back(); - } - else - { - break; - } - } - else if (node.Type == XmlNodeType::StartTag) - { - - if (std::strcmp(node.Name, "DeletedTime") == 0) - { - path.emplace_back(XmlTagName::c_DeletedTime); - } - else if (std::strcmp(node.Name, "Etag") == 0) - { - path.emplace_back(XmlTagName::c_Etag); - } - else if (std::strcmp(node.Name, "Last-Modified") == 0) - { - path.emplace_back(XmlTagName::c_LastModified); - } - else if (std::strcmp(node.Name, "LeaseDuration") == 0) - { - path.emplace_back(XmlTagName::c_LeaseDuration); - } - else if (std::strcmp(node.Name, "LeaseState") == 0) - { - path.emplace_back(XmlTagName::c_LeaseState); - } - else if (std::strcmp(node.Name, "LeaseStatus") == 0) - { - path.emplace_back(XmlTagName::c_LeaseStatus); - } - else if (std::strcmp(node.Name, "NextAllowedQuotaDowngradeTime") == 0) - { - path.emplace_back(XmlTagName::c_NextAllowedQuotaDowngradeTime); - } - else if (std::strcmp(node.Name, "ProvisionedEgressMBps") == 0) - { - path.emplace_back(XmlTagName::c_ProvisionedEgressMBps); - } - else if (std::strcmp(node.Name, "ProvisionedIngressMBps") == 0) - { - path.emplace_back(XmlTagName::c_ProvisionedIngressMBps); - } - else if (std::strcmp(node.Name, "ProvisionedIops") == 0) - { - path.emplace_back(XmlTagName::c_ProvisionedIops); - } - else if (std::strcmp(node.Name, "Quota") == 0) - { - path.emplace_back(XmlTagName::c_Quota); - } - else if (std::strcmp(node.Name, "RemainingRetentionDays") == 0) - { - path.emplace_back(XmlTagName::c_RemainingRetentionDays); - } - else - { - path.emplace_back(XmlTagName::c_Unknown); - } - - if (path.size() == 1 && path[0] == XmlTagName::c_LeaseStatus) - { - result.LeaseStatus = LeaseStatusTypeFromXml(reader); - path.pop_back(); - } - else if (path.size() == 1 && path[0] == XmlTagName::c_LeaseState) - { - result.LeaseState = LeaseStateTypeFromXml(reader); - path.pop_back(); - } - else if (path.size() == 1 && path[0] == XmlTagName::c_LeaseDuration) - { - result.LeaseDuration = LeaseDurationTypeFromXml(reader); - path.pop_back(); - } - } - else if (node.Type == XmlNodeType::Text) - { - if (path.size() == 1 && path[0] == XmlTagName::c_DeletedTime) - { - result.DeletedTime = node.Value; - } - else if (path.size() == 1 && path[0] == XmlTagName::c_Etag) - { - result.Etag = node.Value; - } - else if (path.size() == 1 && path[0] == XmlTagName::c_LastModified) - { - result.LastModified = node.Value; - } - else if (path.size() == 1 && path[0] == XmlTagName::c_NextAllowedQuotaDowngradeTime) - { - result.NextAllowedQuotaDowngradeTime = node.Value; - } - else if (path.size() == 1 && path[0] == XmlTagName::c_ProvisionedEgressMBps) - { - result.ProvisionedEgressMBps = std::stoi(node.Value); - } - else if (path.size() == 1 && path[0] == XmlTagName::c_ProvisionedIngressMBps) - { - result.ProvisionedIngressMBps = std::stoi(node.Value); - } - else if (path.size() == 1 && path[0] == XmlTagName::c_ProvisionedIops) - { - result.ProvisionedIops = std::stoi(node.Value); - } - else if (path.size() == 1 && path[0] == XmlTagName::c_Quota) - { - result.Quota = std::stoi(node.Value); - } - else if (path.size() == 1 && path[0] == XmlTagName::c_RemainingRetentionDays) - { - result.RemainingRetentionDays = std::stoi(node.Value); - } + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(getPermissionOptions.Timeout.GetValue()))); } + request.AddHeader(Details::c_HeaderVersion, getPermissionOptions.ApiVersionParameter); + return GetPermissionParseResult(context, pipeline.Send(context, request)); } - return result; - } - static std::map MetadataFromXml(XmlReader& reader) - { - std::map result; - int depth = 0; - std::string key; - while (true) + struct SetQuotaOptions { - auto node = reader.Read(); - if (node.Type == XmlNodeType::End) - { - break; - } - else if (node.Type == XmlNodeType::StartTag) - { - if (depth++ == 0) - { - key = node.Name; - } - } - else if (node.Type == XmlNodeType::EndTag) - { - if (depth-- == 0) - { - break; - } - } - else if (depth == 1 && node.Type == XmlNodeType::Text) - { - result.emplace(std::move(key), std::string(node.Value)); - } - } - return result; - } - - static ShareItem ShareItemFromXml(XmlReader& reader) - { - auto result = ShareItem(); - enum class XmlTagName - { - c_Deleted, - c_Metadata, - c_Name, - c_Properties, - c_Snapshot, - c_Unknown, - c_Version, + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + ShareQuota; // Specifies the maximum size of the share, in gigabytes. + Azure::Core::Nullable + LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease + // is active and matches this ID. }; - std::vector path; - while (true) + static Azure::Core::Response SetQuota( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const SetQuotaOptions& setQuotaOptions) { - auto node = reader.Read(); - if (node.Type == XmlNodeType::End) + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); + request.AddHeader(Details::c_HeaderContentLength, "0"); + request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "share"); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "properties"); + if (setQuotaOptions.Timeout.HasValue()) { - break; + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(setQuotaOptions.Timeout.GetValue()))); } - else if (node.Type == XmlNodeType::EndTag) + request.AddHeader(Details::c_HeaderVersion, setQuotaOptions.ApiVersionParameter); + if (setQuotaOptions.ShareQuota.HasValue()) { - if (path.size() > 0) - { - path.pop_back(); - } - else - { - break; - } + request.AddHeader( + Details::c_HeaderQuota, std::to_string(setQuotaOptions.ShareQuota.GetValue())); } - else if (node.Type == XmlNodeType::StartTag) + if (setQuotaOptions.LeaseIdOptional.HasValue()) { - - if (std::strcmp(node.Name, "Deleted") == 0) - { - path.emplace_back(XmlTagName::c_Deleted); - } - else if (std::strcmp(node.Name, "Metadata") == 0) - { - path.emplace_back(XmlTagName::c_Metadata); - } - else if (std::strcmp(node.Name, "Name") == 0) - { - path.emplace_back(XmlTagName::c_Name); - } - else if (std::strcmp(node.Name, "Properties") == 0) - { - path.emplace_back(XmlTagName::c_Properties); - } - else if (std::strcmp(node.Name, "Snapshot") == 0) - { - path.emplace_back(XmlTagName::c_Snapshot); - } - else if (std::strcmp(node.Name, "Version") == 0) - { - path.emplace_back(XmlTagName::c_Version); - } - else - { - path.emplace_back(XmlTagName::c_Unknown); - } - - if (path.size() == 1 && path[0] == XmlTagName::c_Properties) - { - result.Properties = SharePropertiesFromXml(reader); - path.pop_back(); - } - else if (path.size() == 1 && path[0] == XmlTagName::c_Metadata) - { - result.ShareMetadata = MetadataFromXml(reader); - path.pop_back(); - } - } - else if (node.Type == XmlNodeType::Text) - { - if (path.size() == 1 && path[0] == XmlTagName::c_Deleted) - { - result.Deleted = (std::strcmp(node.Value, "true") == 0); - } - else if (path.size() == 1 && path[0] == XmlTagName::c_Name) - { - result.Name = node.Value; - } - else if (path.size() == 1 && path[0] == XmlTagName::c_Snapshot) - { - result.Snapshot = node.Value; - } - else if (path.size() == 1 && path[0] == XmlTagName::c_Version) - { - result.Version = node.Value; - } + request.AddHeader(Details::c_HeaderLeaseId, setQuotaOptions.LeaseIdOptional.GetValue()); } + return SetQuotaParseResult(context, pipeline.Send(context, request)); } - return result; - } - static ListSharesResponse ListSharesResponseFromXml(XmlReader& reader) - { - auto result = ListSharesResponse(); - enum class XmlTagName + struct SetMetadataOptions { - c_EnumerationResults, - c_Marker, - c_MaxResults, - c_NextMarker, - c_Prefix, - c_Share, - c_Shares, - c_Unknown, + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::map + Metadata; // A name-value pair to associate with a file storage object. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease + // is active and matches this ID. }; - std::vector path; - while (true) + static Azure::Core::Response SetMetadata( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const SetMetadataOptions& setMetadataOptions) { - auto node = reader.Read(); - if (node.Type == XmlNodeType::End) + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); + request.AddHeader(Details::c_HeaderContentLength, "0"); + request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "share"); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "metadata"); + if (setMetadataOptions.Timeout.HasValue()) { - break; + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(setMetadataOptions.Timeout.GetValue()))); } - else if (node.Type == XmlNodeType::EndTag) + std::set metadataKeys; + for (const auto& pair : setMetadataOptions.Metadata) { - if (path.size() > 0) + std::string key = pair.first; + std::transform(key.begin(), key.end(), key.begin(), [](unsigned char c) { + return static_cast(std::tolower(c)); + }); + if (metadataKeys.insert(key).second == false) { - path.pop_back(); + throw std::runtime_error("duplicate keys in metadata"); } - else + request.AddHeader(Details::c_HeaderMetadata + ("-" + pair.first), pair.second); + } + metadataKeys.clear(); + request.AddHeader(Details::c_HeaderVersion, setMetadataOptions.ApiVersionParameter); + if (setMetadataOptions.LeaseIdOptional.HasValue()) + { + request.AddHeader( + Details::c_HeaderLeaseId, setMetadataOptions.LeaseIdOptional.GetValue()); + } + return SetMetadataParseResult(context, pipeline.Send(context, request)); + } + + struct GetAccessPolicyOptions + { + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease + // is active and matches this ID. + }; + + static Azure::Core::Response GetAccessPolicy( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const GetAccessPolicyOptions& getAccessPolicyOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Get, url); + request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "share"); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "acl"); + if (getAccessPolicyOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(getAccessPolicyOptions.Timeout.GetValue()))); + } + request.AddHeader(Details::c_HeaderVersion, getAccessPolicyOptions.ApiVersionParameter); + if (getAccessPolicyOptions.LeaseIdOptional.HasValue()) + { + request.AddHeader( + Details::c_HeaderLeaseId, getAccessPolicyOptions.LeaseIdOptional.GetValue()); + } + return GetAccessPolicyParseResult(context, pipeline.Send(context, request)); + } + + struct SetAccessPolicyOptions + { + std::vector ShareAcl; // The ACL for the share. + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease + // is active and matches this ID. + }; + + static Azure::Core::Response SetAccessPolicy( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const SetAccessPolicyOptions& setAccessPolicyOptions) + { + + std::string xml_body; + { + XmlWriter writer; + SignedIdentifiersToXml(writer, setAccessPolicyOptions.ShareAcl); + writer.Write(XmlNode{XmlNodeType::End}); + xml_body = writer.GetDocument(); + } + auto body = Azure::Core::Http::MemoryBodyStream( + reinterpret_cast(xml_body.data()), xml_body.length()); + auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Put, url, &body); + request.AddHeader("Content-Length", std::to_string(body.Length())); + request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "share"); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "acl"); + if (setAccessPolicyOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(setAccessPolicyOptions.Timeout.GetValue()))); + } + request.AddHeader(Details::c_HeaderVersion, setAccessPolicyOptions.ApiVersionParameter); + if (setAccessPolicyOptions.LeaseIdOptional.HasValue()) + { + request.AddHeader( + Details::c_HeaderLeaseId, setAccessPolicyOptions.LeaseIdOptional.GetValue()); + } + return SetAccessPolicyParseResult(context, pipeline.Send(context, request)); + } + + struct GetStatisticsOptions + { + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease + // is active and matches this ID. + }; + + static Azure::Core::Response GetStatistics( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const GetStatisticsOptions& getStatisticsOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Get, url); + request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "share"); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "stats"); + if (getStatisticsOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(getStatisticsOptions.Timeout.GetValue()))); + } + request.AddHeader(Details::c_HeaderVersion, getStatisticsOptions.ApiVersionParameter); + if (getStatisticsOptions.LeaseIdOptional.HasValue()) + { + request.AddHeader( + Details::c_HeaderLeaseId, getStatisticsOptions.LeaseIdOptional.GetValue()); + } + return GetStatisticsParseResult(context, pipeline.Send(context, request)); + } + + struct RestoreOptions + { + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character + // limit that is recorded in the analytics logs when storage + // analytics logging is enabled. + Azure::Core::Nullable + DeletedShareName; // Specifies the name of the preivously-deleted share. + Azure::Core::Nullable + DeletedShareVersion; // Specifies the version of the preivously-deleted share. + }; + + static Azure::Core::Response Restore( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const RestoreOptions& restoreOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); + request.AddHeader(Details::c_HeaderContentLength, "0"); + request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "share"); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "undelete"); + if (restoreOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(restoreOptions.Timeout.GetValue()))); + } + request.AddHeader(Details::c_HeaderVersion, restoreOptions.ApiVersionParameter); + if (restoreOptions.ClientRequestId.HasValue()) + { + request.AddHeader( + Details::c_HeaderRequestId, restoreOptions.ClientRequestId.GetValue()); + } + if (restoreOptions.DeletedShareName.HasValue()) + { + request.AddHeader( + Details::c_HeaderDeletedShareName, restoreOptions.DeletedShareName.GetValue()); + } + if (restoreOptions.DeletedShareVersion.HasValue()) + { + request.AddHeader( + Details::c_HeaderDeletedShareVersion, + restoreOptions.DeletedShareVersion.GetValue()); + } + return RestoreParseResult(context, pipeline.Send(context, request)); + } + + private: + static Azure::Core::Response CreateParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Created) + { + // Success, Share created. + ShareCreateResult result; + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Core::Response GetPropertiesParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + { + // Success + ShareGetPropertiesResult result; + + for (auto i = response.GetHeaders().lower_bound(Details::c_HeaderMetadata); + i != response.GetHeaders().end() + && i->first.substr(0, 9) == Details::c_HeaderMetadata; + ++i) { - break; + result.Metadata.emplace(i->first.substr(10), i->second); } - } - else if (node.Type == XmlNodeType::StartTag) - { - - if (std::strcmp(node.Name, "EnumerationResults") == 0) + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + result.Quota = std::stoi(response.GetHeaders().at(Details::c_HeaderQuota)); + if (response.GetHeaders().find(Details::c_HeaderProvisionedIops) + != response.GetHeaders().end()) { - path.emplace_back(XmlTagName::c_EnumerationResults); + result.ProvisionedIops + = std::stoi(response.GetHeaders().at(Details::c_HeaderProvisionedIops)); } - else if (std::strcmp(node.Name, "Marker") == 0) + if (response.GetHeaders().find(Details::c_HeaderProvisionedIngressMBps) + != response.GetHeaders().end()) { - path.emplace_back(XmlTagName::c_Marker); + result.ProvisionedIngressMBps + = std::stoi(response.GetHeaders().at(Details::c_HeaderProvisionedIngressMBps)); } - else if (std::strcmp(node.Name, "MaxResults") == 0) + if (response.GetHeaders().find(Details::c_HeaderProvisionedEgressMBps) + != response.GetHeaders().end()) { - path.emplace_back(XmlTagName::c_MaxResults); + result.ProvisionedEgressMBps + = std::stoi(response.GetHeaders().at(Details::c_HeaderProvisionedEgressMBps)); } - else if (std::strcmp(node.Name, "NextMarker") == 0) + if (response.GetHeaders().find(Details::c_HeaderNextAllowedQuotaDowngradeTime) + != response.GetHeaders().end()) { - path.emplace_back(XmlTagName::c_NextMarker); + result.NextAllowedQuotaDowngradeTime + = response.GetHeaders().at(Details::c_HeaderNextAllowedQuotaDowngradeTime); } - else if (std::strcmp(node.Name, "Prefix") == 0) + if (response.GetHeaders().find(Details::c_HeaderLeaseDuration) + != response.GetHeaders().end()) { - path.emplace_back(XmlTagName::c_Prefix); + result.LeaseDuration = LeaseDurationTypeFromString( + response.GetHeaders().at(Details::c_HeaderLeaseDuration)); } - else if (std::strcmp(node.Name, "Share") == 0) + if (response.GetHeaders().find(Details::c_HeaderLeaseState) + != response.GetHeaders().end()) { - path.emplace_back(XmlTagName::c_Share); + result.LeaseState + = LeaseStateTypeFromString(response.GetHeaders().at(Details::c_HeaderLeaseState)); } - else if (std::strcmp(node.Name, "Shares") == 0) + if (response.GetHeaders().find(Details::c_HeaderLeaseStatus) + != response.GetHeaders().end()) { - path.emplace_back(XmlTagName::c_Shares); + result.LeaseStatus = LeaseStatusTypeFromString( + response.GetHeaders().at(Details::c_HeaderLeaseStatus)); } - else + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Core::Response DeleteParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Accepted) + { + // Accepted + ShareDeleteResult result; + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Core::Response AcquireLeaseParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Created) + { + // The Acquire operation completed successfully. + ShareAcquireLeaseResult result; + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + if (response.GetHeaders().find(Details::c_HeaderLeaseTime) + != response.GetHeaders().end()) { - path.emplace_back(XmlTagName::c_Unknown); + result.LeaseTime = std::stoi(response.GetHeaders().at(Details::c_HeaderLeaseTime)); } - if (path.size() == 3 && path[0] == XmlTagName::c_EnumerationResults - && path[1] == XmlTagName::c_Shares && path[2] == XmlTagName::c_Share) - { - result.ShareItems.emplace_back(ShareItemFromXml(reader)); - path.pop_back(); - } - } - else if (node.Type == XmlNodeType::Text) - { - if (path.size() == 2 && path[0] == XmlTagName::c_EnumerationResults - && path[1] == XmlTagName::c_NextMarker) - { - result.ContinuationToken = node.Value; - } - else if ( - path.size() == 2 && path[0] == XmlTagName::c_EnumerationResults - && path[1] == XmlTagName::c_MaxResults) - { - result.MaxResults = std::stoi(node.Value); - } - else if ( - path.size() == 2 && path[0] == XmlTagName::c_EnumerationResults - && path[1] == XmlTagName::c_Prefix) - { - result.Prefix = node.Value; - } - else if ( - path.size() == 2 && path[0] == XmlTagName::c_EnumerationResults - && path[1] == XmlTagName::c_Marker) - { - result.PreviousContinuationToken = node.Value; - } - } - else if (node.Type == XmlNodeType::Attribute) - { - if (path.size() == 1 && path[0] == XmlTagName::c_EnumerationResults - && (std::strcmp(node.Name, "ServiceEndpoint") == 0)) - { - result.ServiceEndpoint = node.Value; - } - } - } - return result; - } - - static ServiceListSharesSegmentResult ServiceListSharesSegmentResultFromListSharesResponse( - ListSharesResponse object) - { - ServiceListSharesSegmentResult result; - result.ServiceEndpoint = std::move(object.ServiceEndpoint); - result.Prefix = std::move(object.Prefix); - result.PreviousContinuationToken = std::move(object.PreviousContinuationToken); - result.MaxResults = object.MaxResults; - result.ShareItems = std::move(object.ShareItems); - result.ContinuationToken = std::move(object.ContinuationToken); - - return result; - } - }; - - class Share { - public: - struct CreateOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::map - Metadata; // A name-value pair to associate with a file storage object. - Azure::Core::Nullable - ShareQuota; // Specifies the maximum size of the share, in gigabytes. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - }; - - static Azure::Core::Response Create( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const CreateOptions& createOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); - request.AddHeader(Details::c_HeaderContentLength, "0"); - request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "share"); - if (createOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(createOptions.Timeout.GetValue()))); - } - std::set metadataKeys; - for (const auto& pair : createOptions.Metadata) - { - std::string key = pair.first; - std::transform(key.begin(), key.end(), key.begin(), [](unsigned char c) { - return static_cast(std::tolower(c)); - }); - if (metadataKeys.insert(key).second == false) - { - throw std::runtime_error("duplicate keys in metadata"); - } - request.AddHeader(Details::c_HeaderMetadata + ("-" + pair.first), pair.second); - } - metadataKeys.clear(); - if (createOptions.ShareQuota.HasValue()) - { - request.AddHeader( - Details::c_HeaderQuota, std::to_string(createOptions.ShareQuota.GetValue())); - } - request.AddHeader(Details::c_HeaderVersion, createOptions.ApiVersionParameter); - return CreateParseResult(context, pipeline.Send(context, request)); - } - - struct GetPropertiesOptions - { - Azure::Core::Nullable - ShareSnapshot; // The snapshot parameter is an opaque DateTime value that, when present, - // specifies the share snapshot to query. - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease is - // active and matches this ID. - }; - - static Azure::Core::Response GetProperties( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const GetPropertiesOptions& getPropertiesOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Get, url); - request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "share"); - if (getPropertiesOptions.ShareSnapshot.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryShareSnapshot, - Storage::Details::UrlEncodeQueryParameter( - getPropertiesOptions.ShareSnapshot.GetValue())); - } - if (getPropertiesOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(getPropertiesOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderVersion, getPropertiesOptions.ApiVersionParameter); - if (getPropertiesOptions.LeaseIdOptional.HasValue()) - { - request.AddHeader( - Details::c_HeaderLeaseId, getPropertiesOptions.LeaseIdOptional.GetValue()); - } - return GetPropertiesParseResult(context, pipeline.Send(context, request)); - } - - struct DeleteOptions - { - Azure::Core::Nullable - ShareSnapshot; // The snapshot parameter is an opaque DateTime value that, when present, - // specifies the share snapshot to query. - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - XMsDeleteSnapshots; // Specifies the option include to delete the base share and all of - // its snapshots. - Azure::Core::Nullable - LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease is - // active and matches this ID. - }; - - static Azure::Core::Response Delete( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const DeleteOptions& deleteOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Delete, url); - request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "share"); - if (deleteOptions.ShareSnapshot.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryShareSnapshot, - Storage::Details::UrlEncodeQueryParameter(deleteOptions.ShareSnapshot.GetValue())); - } - if (deleteOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(deleteOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderVersion, deleteOptions.ApiVersionParameter); - if (deleteOptions.XMsDeleteSnapshots.HasValue()) - { - request.AddHeader( - Details::c_HeaderDeleteSnapshots, - DeleteSnapshotsOptionTypeToString(deleteOptions.XMsDeleteSnapshots.GetValue())); - } - if (deleteOptions.LeaseIdOptional.HasValue()) - { - request.AddHeader(Details::c_HeaderLeaseId, deleteOptions.LeaseIdOptional.GetValue()); - } - return DeleteParseResult(context, pipeline.Send(context, request)); - } - - struct AcquireLeaseOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - int32_t LeaseDuration - = int32_t(); // Specifies the duration of the lease, in seconds, or negative one (-1) - // for a lease that never expires. A non-infinite lease can be between 15 - // and 60 seconds. A lease duration cannot be changed using renew or - // change. - Azure::Core::Nullable - ProposedLeaseIdOptional; // Proposed lease ID, in a GUID string format. The File service - // returns 400 (Invalid request) if the proposed lease ID is - // not in the correct format. See Guid Constructor (String) for - // a list of valid GUID string formats. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - ShareSnapshot; // The snapshot parameter is an opaque DateTime value that, when present, - // specifies the share snapshot to query. - Azure::Core::Nullable - ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character - // limit that is recorded in the analytics logs when storage analytics - // logging is enabled. - }; - - static Azure::Core::Response AcquireLease( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const AcquireLeaseOptions& acquireLeaseOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); - request.AddHeader(Details::c_HeaderContentLength, "0"); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "lease"); - request.AddHeader(Details::c_HeaderAction, "acquire"); - request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "share"); - if (acquireLeaseOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(acquireLeaseOptions.Timeout.GetValue()))); - } - request.AddHeader( - Details::c_HeaderDuration, std::to_string(acquireLeaseOptions.LeaseDuration)); - if (acquireLeaseOptions.ProposedLeaseIdOptional.HasValue()) - { - request.AddHeader( - Details::c_HeaderProposedLeaseId, - acquireLeaseOptions.ProposedLeaseIdOptional.GetValue()); - } - request.AddHeader(Details::c_HeaderVersion, acquireLeaseOptions.ApiVersionParameter); - if (acquireLeaseOptions.ShareSnapshot.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryShareSnapshot, - Storage::Details::UrlEncodeQueryParameter( - acquireLeaseOptions.ShareSnapshot.GetValue())); - } - if (acquireLeaseOptions.ClientRequestId.HasValue()) - { - request.AddHeader( - Details::c_HeaderRequestId, acquireLeaseOptions.ClientRequestId.GetValue()); - } - return AcquireLeaseParseResult(context, pipeline.Send(context, request)); - } - - struct ReleaseLeaseOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::string LeaseIdRequired; // Specifies the current lease ID on the resource. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - ShareSnapshot; // The snapshot parameter is an opaque DateTime value that, when present, - // specifies the share snapshot to query. - Azure::Core::Nullable - ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character - // limit that is recorded in the analytics logs when storage analytics - // logging is enabled. - }; - - static Azure::Core::Response ReleaseLease( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const ReleaseLeaseOptions& releaseLeaseOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); - request.AddHeader(Details::c_HeaderContentLength, "0"); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "lease"); - request.AddHeader(Details::c_HeaderAction, "release"); - request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "share"); - if (releaseLeaseOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(releaseLeaseOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderLeaseId, releaseLeaseOptions.LeaseIdRequired); - request.AddHeader(Details::c_HeaderVersion, releaseLeaseOptions.ApiVersionParameter); - if (releaseLeaseOptions.ShareSnapshot.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryShareSnapshot, - Storage::Details::UrlEncodeQueryParameter( - releaseLeaseOptions.ShareSnapshot.GetValue())); - } - if (releaseLeaseOptions.ClientRequestId.HasValue()) - { - request.AddHeader( - Details::c_HeaderRequestId, releaseLeaseOptions.ClientRequestId.GetValue()); - } - return ReleaseLeaseParseResult(context, pipeline.Send(context, request)); - } - - struct ChangeLeaseOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::string LeaseIdRequired; // Specifies the current lease ID on the resource. - Azure::Core::Nullable - ProposedLeaseIdOptional; // Proposed lease ID, in a GUID string format. The File service - // returns 400 (Invalid request) if the proposed lease ID is - // not in the correct format. See Guid Constructor (String) for - // a list of valid GUID string formats. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - ShareSnapshot; // The snapshot parameter is an opaque DateTime value that, when present, - // specifies the share snapshot to query. - Azure::Core::Nullable - ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character - // limit that is recorded in the analytics logs when storage analytics - // logging is enabled. - }; - - static Azure::Core::Response ChangeLease( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const ChangeLeaseOptions& changeLeaseOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); - request.AddHeader(Details::c_HeaderContentLength, "0"); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "lease"); - request.AddHeader(Details::c_HeaderAction, "change"); - request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "share"); - if (changeLeaseOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(changeLeaseOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderLeaseId, changeLeaseOptions.LeaseIdRequired); - if (changeLeaseOptions.ProposedLeaseIdOptional.HasValue()) - { - request.AddHeader( - Details::c_HeaderProposedLeaseId, - changeLeaseOptions.ProposedLeaseIdOptional.GetValue()); - } - request.AddHeader(Details::c_HeaderVersion, changeLeaseOptions.ApiVersionParameter); - if (changeLeaseOptions.ShareSnapshot.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryShareSnapshot, - Storage::Details::UrlEncodeQueryParameter( - changeLeaseOptions.ShareSnapshot.GetValue())); - } - if (changeLeaseOptions.ClientRequestId.HasValue()) - { - request.AddHeader( - Details::c_HeaderRequestId, changeLeaseOptions.ClientRequestId.GetValue()); - } - return ChangeLeaseParseResult(context, pipeline.Send(context, request)); - } - - struct RenewLeaseOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::string LeaseIdRequired; // Specifies the current lease ID on the resource. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - ShareSnapshot; // The snapshot parameter is an opaque DateTime value that, when present, - // specifies the share snapshot to query. - Azure::Core::Nullable - ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character - // limit that is recorded in the analytics logs when storage analytics - // logging is enabled. - }; - - static Azure::Core::Response RenewLease( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const RenewLeaseOptions& renewLeaseOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); - request.AddHeader(Details::c_HeaderContentLength, "0"); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "lease"); - request.AddHeader(Details::c_HeaderAction, "renew"); - request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "share"); - if (renewLeaseOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(renewLeaseOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderLeaseId, renewLeaseOptions.LeaseIdRequired); - request.AddHeader(Details::c_HeaderVersion, renewLeaseOptions.ApiVersionParameter); - if (renewLeaseOptions.ShareSnapshot.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryShareSnapshot, - Storage::Details::UrlEncodeQueryParameter( - renewLeaseOptions.ShareSnapshot.GetValue())); - } - if (renewLeaseOptions.ClientRequestId.HasValue()) - { - request.AddHeader( - Details::c_HeaderRequestId, renewLeaseOptions.ClientRequestId.GetValue()); - } - return RenewLeaseParseResult(context, pipeline.Send(context, request)); - } - - struct BreakLeaseOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - Azure::Core::Nullable - LeaseBreakPeriod; // For a break operation, proposed duration the lease should continue - // before it is broken, in seconds, between 0 and 60. This break - // period is only used if it is shorter than the time remaining on the - // lease. If longer, the time remaining on the lease is used. A new - // lease will not be available before the break period has expired, - // but the lease may be held for longer than the break period. If this - // header does not appear with a break operation, a fixed-duration - // lease breaks after the remaining lease period elapses, and an - // infinite lease breaks immediately. - Azure::Core::Nullable - LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease is - // active and matches this ID. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character - // limit that is recorded in the analytics logs when storage analytics - // logging is enabled. - Azure::Core::Nullable - ShareSnapshot; // The snapshot parameter is an opaque DateTime value that, when present, - // specifies the share snapshot to query. - }; - - static Azure::Core::Response BreakLease( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const BreakLeaseOptions& breakLeaseOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); - request.AddHeader(Details::c_HeaderContentLength, "0"); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "lease"); - request.AddHeader(Details::c_HeaderAction, "break"); - request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "share"); - if (breakLeaseOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(breakLeaseOptions.Timeout.GetValue()))); - } - if (breakLeaseOptions.LeaseBreakPeriod.HasValue()) - { - request.AddHeader( - Details::c_HeaderBreakPeriod, - std::to_string(breakLeaseOptions.LeaseBreakPeriod.GetValue())); - } - if (breakLeaseOptions.LeaseIdOptional.HasValue()) - { - request.AddHeader(Details::c_HeaderLeaseId, breakLeaseOptions.LeaseIdOptional.GetValue()); - } - request.AddHeader(Details::c_HeaderVersion, breakLeaseOptions.ApiVersionParameter); - if (breakLeaseOptions.ClientRequestId.HasValue()) - { - request.AddHeader( - Details::c_HeaderRequestId, breakLeaseOptions.ClientRequestId.GetValue()); - } - if (breakLeaseOptions.ShareSnapshot.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryShareSnapshot, - Storage::Details::UrlEncodeQueryParameter( - breakLeaseOptions.ShareSnapshot.GetValue())); - } - return BreakLeaseParseResult(context, pipeline.Send(context, request)); - } - - struct CreateSnapshotOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::map - Metadata; // A name-value pair to associate with a file storage object. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - }; - - static Azure::Core::Response CreateSnapshot( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const CreateSnapshotOptions& createSnapshotOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); - request.AddHeader(Details::c_HeaderContentLength, "0"); - request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "share"); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "snapshot"); - if (createSnapshotOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(createSnapshotOptions.Timeout.GetValue()))); - } - std::set metadataKeys; - for (const auto& pair : createSnapshotOptions.Metadata) - { - std::string key = pair.first; - std::transform(key.begin(), key.end(), key.begin(), [](unsigned char c) { - return static_cast(std::tolower(c)); - }); - if (metadataKeys.insert(key).second == false) - { - throw std::runtime_error("duplicate keys in metadata"); - } - request.AddHeader(Details::c_HeaderMetadata + ("-" + pair.first), pair.second); - } - metadataKeys.clear(); - request.AddHeader(Details::c_HeaderVersion, createSnapshotOptions.ApiVersionParameter); - return CreateSnapshotParseResult(context, pipeline.Send(context, request)); - } - - struct CreatePermissionOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - SharePermission Permission; // A permission (a security descriptor) at the share level. - }; - - static Azure::Core::Response CreatePermission( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const CreatePermissionOptions& createPermissionOptions) - { - - std::string json_body; - { - nlohmann::json json; - SharePermissionToJson(json, createPermissionOptions.Permission); - json_body = json.dump(); - } - auto body = Azure::Core::Http::MemoryBodyStream( - reinterpret_cast(json_body.data()), json_body.length()); - auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Put, url, &body); - request.AddHeader("Content-Length", std::to_string(body.Length())); - request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "share"); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "filepermission"); - if (createPermissionOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(createPermissionOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderVersion, createPermissionOptions.ApiVersionParameter); - return CreatePermissionParseResult(context, pipeline.Send(context, request)); - } - - struct GetPermissionOptions - { - std::string - FilePermissionKeyRequired; // Key of the permission to be set for the directory/file. - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - }; - - static Azure::Core::Response GetPermission( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const GetPermissionOptions& getPermissionOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Get, url); - request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "share"); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "filepermission"); - request.AddHeader( - Details::c_HeaderFilePermissionKey, getPermissionOptions.FilePermissionKeyRequired); - if (getPermissionOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(getPermissionOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderVersion, getPermissionOptions.ApiVersionParameter); - return GetPermissionParseResult(context, pipeline.Send(context, request)); - } - - struct SetQuotaOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - ShareQuota; // Specifies the maximum size of the share, in gigabytes. - Azure::Core::Nullable - LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease is - // active and matches this ID. - }; - - static Azure::Core::Response SetQuota( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const SetQuotaOptions& setQuotaOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); - request.AddHeader(Details::c_HeaderContentLength, "0"); - request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "share"); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "properties"); - if (setQuotaOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(setQuotaOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderVersion, setQuotaOptions.ApiVersionParameter); - if (setQuotaOptions.ShareQuota.HasValue()) - { - request.AddHeader( - Details::c_HeaderQuota, std::to_string(setQuotaOptions.ShareQuota.GetValue())); - } - if (setQuotaOptions.LeaseIdOptional.HasValue()) - { - request.AddHeader(Details::c_HeaderLeaseId, setQuotaOptions.LeaseIdOptional.GetValue()); - } - return SetQuotaParseResult(context, pipeline.Send(context, request)); - } - - struct SetMetadataOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::map - Metadata; // A name-value pair to associate with a file storage object. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease is - // active and matches this ID. - }; - - static Azure::Core::Response SetMetadata( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const SetMetadataOptions& setMetadataOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); - request.AddHeader(Details::c_HeaderContentLength, "0"); - request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "share"); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "metadata"); - if (setMetadataOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(setMetadataOptions.Timeout.GetValue()))); - } - std::set metadataKeys; - for (const auto& pair : setMetadataOptions.Metadata) - { - std::string key = pair.first; - std::transform(key.begin(), key.end(), key.begin(), [](unsigned char c) { - return static_cast(std::tolower(c)); - }); - if (metadataKeys.insert(key).second == false) - { - throw std::runtime_error("duplicate keys in metadata"); - } - request.AddHeader(Details::c_HeaderMetadata + ("-" + pair.first), pair.second); - } - metadataKeys.clear(); - request.AddHeader(Details::c_HeaderVersion, setMetadataOptions.ApiVersionParameter); - if (setMetadataOptions.LeaseIdOptional.HasValue()) - { - request.AddHeader( - Details::c_HeaderLeaseId, setMetadataOptions.LeaseIdOptional.GetValue()); - } - return SetMetadataParseResult(context, pipeline.Send(context, request)); - } - - struct GetAccessPolicyOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease is - // active and matches this ID. - }; - - static Azure::Core::Response GetAccessPolicy( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const GetAccessPolicyOptions& getAccessPolicyOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Get, url); - request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "share"); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "acl"); - if (getAccessPolicyOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(getAccessPolicyOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderVersion, getAccessPolicyOptions.ApiVersionParameter); - if (getAccessPolicyOptions.LeaseIdOptional.HasValue()) - { - request.AddHeader( - Details::c_HeaderLeaseId, getAccessPolicyOptions.LeaseIdOptional.GetValue()); - } - return GetAccessPolicyParseResult(context, pipeline.Send(context, request)); - } - - struct SetAccessPolicyOptions - { - std::vector ShareAcl; // The ACL for the share. - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease is - // active and matches this ID. - }; - - static Azure::Core::Response SetAccessPolicy( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const SetAccessPolicyOptions& setAccessPolicyOptions) - { - - std::string xml_body; - { - XmlWriter writer; - SignedIdentifiersToXml(writer, setAccessPolicyOptions.ShareAcl); - writer.Write(XmlNode{XmlNodeType::End}); - xml_body = writer.GetDocument(); - } - auto body = Azure::Core::Http::MemoryBodyStream( - reinterpret_cast(xml_body.data()), xml_body.length()); - auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Put, url, &body); - request.AddHeader("Content-Length", std::to_string(body.Length())); - request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "share"); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "acl"); - if (setAccessPolicyOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(setAccessPolicyOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderVersion, setAccessPolicyOptions.ApiVersionParameter); - if (setAccessPolicyOptions.LeaseIdOptional.HasValue()) - { - request.AddHeader( - Details::c_HeaderLeaseId, setAccessPolicyOptions.LeaseIdOptional.GetValue()); - } - return SetAccessPolicyParseResult(context, pipeline.Send(context, request)); - } - - struct GetStatisticsOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease is - // active and matches this ID. - }; - - static Azure::Core::Response GetStatistics( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const GetStatisticsOptions& getStatisticsOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Get, url); - request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "share"); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "stats"); - if (getStatisticsOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(getStatisticsOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderVersion, getStatisticsOptions.ApiVersionParameter); - if (getStatisticsOptions.LeaseIdOptional.HasValue()) - { - request.AddHeader( - Details::c_HeaderLeaseId, getStatisticsOptions.LeaseIdOptional.GetValue()); - } - return GetStatisticsParseResult(context, pipeline.Send(context, request)); - } - - struct RestoreOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character - // limit that is recorded in the analytics logs when storage analytics - // logging is enabled. - Azure::Core::Nullable - DeletedShareName; // Specifies the name of the preivously-deleted share. - Azure::Core::Nullable - DeletedShareVersion; // Specifies the version of the preivously-deleted share. - }; - - static Azure::Core::Response Restore( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const RestoreOptions& restoreOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); - request.AddHeader(Details::c_HeaderContentLength, "0"); - request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "share"); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "undelete"); - if (restoreOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(restoreOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderVersion, restoreOptions.ApiVersionParameter); - if (restoreOptions.ClientRequestId.HasValue()) - { - request.AddHeader(Details::c_HeaderRequestId, restoreOptions.ClientRequestId.GetValue()); - } - if (restoreOptions.DeletedShareName.HasValue()) - { - request.AddHeader( - Details::c_HeaderDeletedShareName, restoreOptions.DeletedShareName.GetValue()); - } - if (restoreOptions.DeletedShareVersion.HasValue()) - { - request.AddHeader( - Details::c_HeaderDeletedShareVersion, restoreOptions.DeletedShareVersion.GetValue()); - } - return RestoreParseResult(context, pipeline.Send(context, request)); - } - - private: - static Azure::Core::Response CreateParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Created) - { - // Success, Share created. - ShareCreateResult result; - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response GetPropertiesParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) - { - // Success - ShareGetPropertiesResult result; - - for (auto i = response.GetHeaders().lower_bound(Details::c_HeaderMetadata); - i != response.GetHeaders().end() - && i->first.substr(0, 9) == Details::c_HeaderMetadata; - ++i) - { - result.Metadata.emplace(i->first.substr(10), i->second); - } - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - result.Quota = std::stoi(response.GetHeaders().at(Details::c_HeaderQuota)); - if (response.GetHeaders().find(Details::c_HeaderProvisionedIops) - != response.GetHeaders().end()) - { - result.ProvisionedIops - = std::stoi(response.GetHeaders().at(Details::c_HeaderProvisionedIops)); - } - if (response.GetHeaders().find(Details::c_HeaderProvisionedIngressMBps) - != response.GetHeaders().end()) - { - result.ProvisionedIngressMBps - = std::stoi(response.GetHeaders().at(Details::c_HeaderProvisionedIngressMBps)); - } - if (response.GetHeaders().find(Details::c_HeaderProvisionedEgressMBps) - != response.GetHeaders().end()) - { - result.ProvisionedEgressMBps - = std::stoi(response.GetHeaders().at(Details::c_HeaderProvisionedEgressMBps)); - } - if (response.GetHeaders().find(Details::c_HeaderNextAllowedQuotaDowngradeTime) - != response.GetHeaders().end()) - { - result.NextAllowedQuotaDowngradeTime - = response.GetHeaders().at(Details::c_HeaderNextAllowedQuotaDowngradeTime); - } - if (response.GetHeaders().find(Details::c_HeaderLeaseDuration) - != response.GetHeaders().end()) - { - result.LeaseDuration = LeaseDurationTypeFromString( - response.GetHeaders().at(Details::c_HeaderLeaseDuration)); - } - if (response.GetHeaders().find(Details::c_HeaderLeaseState) - != response.GetHeaders().end()) - { - result.LeaseState - = LeaseStateTypeFromString(response.GetHeaders().at(Details::c_HeaderLeaseState)); - } - if (response.GetHeaders().find(Details::c_HeaderLeaseStatus) - != response.GetHeaders().end()) - { - result.LeaseStatus - = LeaseStatusTypeFromString(response.GetHeaders().at(Details::c_HeaderLeaseStatus)); - } - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response DeleteParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Accepted) - { - // Accepted - ShareDeleteResult result; - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response AcquireLeaseParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Created) - { - // The Acquire operation completed successfully. - ShareAcquireLeaseResult result; - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - if (response.GetHeaders().find(Details::c_HeaderLeaseTime) != response.GetHeaders().end()) - { - result.LeaseTime = std::stoi(response.GetHeaders().at(Details::c_HeaderLeaseTime)); - } - result.LeaseId = response.GetHeaders().at(Details::c_HeaderLeaseId); - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response ReleaseLeaseParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) - { - // The Release operation completed successfully. - ShareReleaseLeaseResult result; - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - if (response.GetHeaders().find(Details::c_HeaderLeaseTime) != response.GetHeaders().end()) - { - result.LeaseTime = std::stoi(response.GetHeaders().at(Details::c_HeaderLeaseTime)); - } - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response ChangeLeaseParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) - { - // The Change operation completed successfully. - ShareChangeLeaseResult result; - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - if (response.GetHeaders().find(Details::c_HeaderLeaseTime) != response.GetHeaders().end()) - { - result.LeaseTime = std::stoi(response.GetHeaders().at(Details::c_HeaderLeaseTime)); - } - result.LeaseId = response.GetHeaders().at(Details::c_HeaderLeaseId); - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response RenewLeaseParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) - { - // The Renew operation completed successfully. - ShareRenewLeaseResult result; - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - if (response.GetHeaders().find(Details::c_HeaderLeaseTime) != response.GetHeaders().end()) - { - result.LeaseTime = std::stoi(response.GetHeaders().at(Details::c_HeaderLeaseTime)); - } - result.LeaseId = response.GetHeaders().at(Details::c_HeaderLeaseId); - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response BreakLeaseParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Accepted) - { - // The Break operation completed successfully. - ShareBreakLeaseResult result; - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - if (response.GetHeaders().find(Details::c_HeaderLeaseTime) != response.GetHeaders().end()) - { - result.LeaseTime = std::stoi(response.GetHeaders().at(Details::c_HeaderLeaseTime)); - } - if (response.GetHeaders().find(Details::c_HeaderLeaseId) != response.GetHeaders().end()) - { result.LeaseId = response.GetHeaders().at(Details::c_HeaderLeaseId); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); } - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response CreateSnapshotParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Created) - { - // Success, Share snapshot created. - ShareCreateSnapshotResult result; - result.Snapshot = response.GetHeaders().at(Details::c_HeaderSnapshot); - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response CreatePermissionParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Created) - { - // Success, Share level permission created. - ShareCreatePermissionResult result; - result.FilePermissionKey = response.GetHeaders().at(Details::c_HeaderFilePermissionKey); - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static void SharePermissionToJson(nlohmann::json& node, const SharePermission& object) - { - node["permission"] = object.Permission; - } - - static Azure::Core::Response GetPermissionParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) - { - // Success - const auto& bodyBuffer = response.GetBody(); - ShareGetPermissionResult result = bodyBuffer.empty() - ? ShareGetPermissionResult() - : ShareGetPermissionResultFromSharePermission( - SharePermissionFromJson(nlohmann::json::parse(bodyBuffer))); - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static SharePermission SharePermissionFromJson(const nlohmann::json& node) - { - SharePermission result; - result.Permission = node["permission"].get(); - return result; - } - - static ShareGetPermissionResult ShareGetPermissionResultFromSharePermission( - SharePermission object) - { - ShareGetPermissionResult result; - result.Permission = std::move(object.Permission); - - return result; - } - static Azure::Core::Response SetQuotaParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) - { - // Success - ShareSetQuotaResult result; - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response SetMetadataParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) - { - // Success - ShareSetMetadataResult result; - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response GetAccessPolicyParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) - { - // Success - const auto& bodyBuffer = response.GetBody(); - auto reader - = XmlReader(reinterpret_cast(bodyBuffer.data()), bodyBuffer.size()); - ShareGetAccessPolicyResult result = bodyBuffer.empty() - ? ShareGetAccessPolicyResult() - : ShareGetAccessPolicyResultFromSignedIdentifiers(SignedIdentifiersFromXml(reader)); - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static AccessPolicy AccessPolicyFromXml(XmlReader& reader) - { - auto result = AccessPolicy(); - enum class XmlTagName - { - c_Expiry, - c_Permission, - c_Start, - c_Unknown, - }; - std::vector path; - - while (true) - { - auto node = reader.Read(); - if (node.Type == XmlNodeType::End) - { - break; - } - else if (node.Type == XmlNodeType::EndTag) - { - if (path.size() > 0) - { - path.pop_back(); - } - else - { - break; - } - } - else if (node.Type == XmlNodeType::StartTag) - { - - if (std::strcmp(node.Name, "Expiry") == 0) - { - path.emplace_back(XmlTagName::c_Expiry); - } - else if (std::strcmp(node.Name, "Permission") == 0) - { - path.emplace_back(XmlTagName::c_Permission); - } - else if (std::strcmp(node.Name, "Start") == 0) - { - path.emplace_back(XmlTagName::c_Start); - } - else - { - path.emplace_back(XmlTagName::c_Unknown); - } - } - else if (node.Type == XmlNodeType::Text) - { - if (path.size() == 1 && path[0] == XmlTagName::c_Expiry) - { - result.Expiry = node.Value; - } - else if (path.size() == 1 && path[0] == XmlTagName::c_Permission) - { - result.Permission = node.Value; - } - else if (path.size() == 1 && path[0] == XmlTagName::c_Start) - { - result.Start = node.Value; - } - } - } - return result; - } - - static SignedIdentifier SignedIdentifierFromXml(XmlReader& reader) - { - auto result = SignedIdentifier(); - enum class XmlTagName - { - c_AccessPolicy, - c_Id, - c_Unknown, - }; - std::vector path; - - while (true) - { - auto node = reader.Read(); - if (node.Type == XmlNodeType::End) - { - break; - } - else if (node.Type == XmlNodeType::EndTag) - { - if (path.size() > 0) - { - path.pop_back(); - } - else - { - break; - } - } - else if (node.Type == XmlNodeType::StartTag) + else { - - if (std::strcmp(node.Name, "AccessPolicy") == 0) - { - path.emplace_back(XmlTagName::c_AccessPolicy); - } - else if (std::strcmp(node.Name, "Id") == 0) - { - path.emplace_back(XmlTagName::c_Id); - } - else - { - path.emplace_back(XmlTagName::c_Unknown); - } - - if (path.size() == 1 && path[0] == XmlTagName::c_AccessPolicy) - { - result.Policy = AccessPolicyFromXml(reader); - path.pop_back(); - } - } - else if (node.Type == XmlNodeType::Text) - { - if (path.size() == 1 && path[0] == XmlTagName::c_Id) - { - result.Id = node.Value; - } + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); } } - return result; - } - - static std::vector SignedIdentifiersFromXml(XmlReader& reader) - { - auto result = std::vector(); - enum class XmlTagName - { - c_SignedIdentifier, - c_SignedIdentifiers, - c_Unknown, - }; - std::vector path; - while (true) + static Azure::Core::Response ReleaseLeaseParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) { - auto node = reader.Read(); - if (node.Type == XmlNodeType::End) + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) { - break; - } - else if (node.Type == XmlNodeType::EndTag) - { - if (path.size() > 0) - { - path.pop_back(); - } - else - { - break; - } - } - else if (node.Type == XmlNodeType::StartTag) - { - - if (std::strcmp(node.Name, "SignedIdentifier") == 0) - { - path.emplace_back(XmlTagName::c_SignedIdentifier); - } - else if (std::strcmp(node.Name, "SignedIdentifiers") == 0) - { - path.emplace_back(XmlTagName::c_SignedIdentifiers); - } - else - { - path.emplace_back(XmlTagName::c_Unknown); - } - - if (path.size() == 2 && path[0] == XmlTagName::c_SignedIdentifiers - && path[1] == XmlTagName::c_SignedIdentifier) + // The Release operation completed successfully. + ShareReleaseLeaseResult result; + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + if (response.GetHeaders().find(Details::c_HeaderLeaseTime) + != response.GetHeaders().end()) { - result.emplace_back(SignedIdentifierFromXml(reader)); - path.pop_back(); + result.LeaseTime = std::stoi(response.GetHeaders().at(Details::c_HeaderLeaseTime)); } + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); } - else if (node.Type == XmlNodeType::Text) + else { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); } } - return result; - } - - static ShareGetAccessPolicyResult ShareGetAccessPolicyResultFromSignedIdentifiers( - std::vector object) - { - ShareGetAccessPolicyResult result; - result.SignedIdentifiers = std::move(object); - - return result; - } - static Azure::Core::Response SetAccessPolicyParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) - { - // Success. - ShareSetAccessPolicyResult result; - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static void AccessPolicyToXml(XmlWriter& writer, const AccessPolicy& object) - { - writer.Write(XmlNode{XmlNodeType::StartTag, "AccessPolicy"}); - writer.Write(XmlNode{XmlNodeType::StartTag, "Start"}); - writer.Write(XmlNode{XmlNodeType::Text, nullptr, object.Start.data()}); - writer.Write(XmlNode{XmlNodeType::EndTag}); - writer.Write(XmlNode{XmlNodeType::StartTag, "Expiry"}); - writer.Write(XmlNode{XmlNodeType::Text, nullptr, object.Expiry.data()}); - writer.Write(XmlNode{XmlNodeType::EndTag}); - writer.Write(XmlNode{XmlNodeType::StartTag, "Permission"}); - writer.Write(XmlNode{XmlNodeType::Text, nullptr, object.Permission.data()}); - writer.Write(XmlNode{XmlNodeType::EndTag}); - writer.Write(XmlNode{XmlNodeType::EndTag}); - } - - static void SignedIdentifierToXml(XmlWriter& writer, const SignedIdentifier& object) - { - writer.Write(XmlNode{XmlNodeType::StartTag, "SignedIdentifier"}); - writer.Write(XmlNode{XmlNodeType::StartTag, "Id"}); - writer.Write(XmlNode{XmlNodeType::Text, nullptr, object.Id.data()}); - writer.Write(XmlNode{XmlNodeType::EndTag}); - AccessPolicyToXml(writer, object.Policy); - writer.Write(XmlNode{XmlNodeType::EndTag}); - } - - static void SignedIdentifiersToXml( - XmlWriter& writer, - const std::vector& object) - { - writer.Write(XmlNode{XmlNodeType::StartTag, "SignedIdentifiers"}); - for (const auto& item : object) - { - SignedIdentifierToXml(writer, item); - } - writer.Write(XmlNode{XmlNodeType::EndTag}); - } - static Azure::Core::Response GetStatisticsParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) - { - // Success - const auto& bodyBuffer = response.GetBody(); - auto reader - = XmlReader(reinterpret_cast(bodyBuffer.data()), bodyBuffer.size()); - ShareGetStatisticsResult result = bodyBuffer.empty() - ? ShareGetStatisticsResult() - : ShareGetStatisticsResultFromShareStats(ShareStatsFromXml(reader)); - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static ShareStats ShareStatsFromXml(XmlReader& reader) - { - auto result = ShareStats(); - enum class XmlTagName - { - c_ShareStats, - c_ShareUsageBytes, - c_Unknown, - }; - std::vector path; - while (true) + static Azure::Core::Response ChangeLeaseParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) { - auto node = reader.Read(); - if (node.Type == XmlNodeType::End) - { - break; - } - else if (node.Type == XmlNodeType::EndTag) - { - if (path.size() > 0) - { - path.pop_back(); - } - else - { - break; - } - } - else if (node.Type == XmlNodeType::StartTag) - { - - if (std::strcmp(node.Name, "ShareStats") == 0) - { - path.emplace_back(XmlTagName::c_ShareStats); - } - else if (std::strcmp(node.Name, "ShareUsageBytes") == 0) - { - path.emplace_back(XmlTagName::c_ShareUsageBytes); - } - else - { - path.emplace_back(XmlTagName::c_Unknown); - } - } - else if (node.Type == XmlNodeType::Text) + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) { - if (path.size() == 2 && path[0] == XmlTagName::c_ShareStats - && path[1] == XmlTagName::c_ShareUsageBytes) + // The Change operation completed successfully. + ShareChangeLeaseResult result; + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + if (response.GetHeaders().find(Details::c_HeaderLeaseTime) + != response.GetHeaders().end()) { - result.ShareUsageBytes = std::stoll(node.Value); + result.LeaseTime = std::stoi(response.GetHeaders().at(Details::c_HeaderLeaseTime)); } - } - } - return result; - } - - static ShareGetStatisticsResult ShareGetStatisticsResultFromShareStats(ShareStats object) - { - ShareGetStatisticsResult result; - result.ShareUsageBytes = object.ShareUsageBytes; - - return result; - } - static Azure::Core::Response RestoreParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Created) - { - // Created - ShareRestoreResult result; - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - }; - - class Directory { - public: - struct CreateOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::map - Metadata; // A name-value pair to associate with a file storage object. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - FilePermission; // If specified the permission (security descriptor) shall be set for - // the directory/file. This header can be used if Permission size is <= - // 8KB, else x-ms-file-permission-key header shall be used. Default - // value: Inherit. If SDDL is specified as input, it must have owner, - // group and dacl. Note: Only one of the x-ms-file-permission or - // x-ms-file-permission-key should be specified. - Azure::Core::Nullable - FilePermissionKey; // Key of the permission to be set for the directory/file. Note: Only - // one of the x-ms-file-permission or x-ms-file-permission-key should - // be specified. - std::string FileAttributes; // If specified, the provided file attributes shall be set. - // Default value: Archive for file and Directory for directory. - // None can also be specified as default. - std::string FileCreationTime; // Creation time for the file/directory. Default value: Now. - std::string - FileLastWriteTime; // Last write time for the file/directory. Default value: Now. - }; - - static Azure::Core::Response Create( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const CreateOptions& createOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); - request.AddHeader(Details::c_HeaderContentLength, "0"); - request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "directory"); - if (createOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(createOptions.Timeout.GetValue()))); - } - std::set metadataKeys; - for (const auto& pair : createOptions.Metadata) - { - std::string key = pair.first; - std::transform(key.begin(), key.end(), key.begin(), [](unsigned char c) { - return static_cast(std::tolower(c)); - }); - if (metadataKeys.insert(key).second == false) - { - throw std::runtime_error("duplicate keys in metadata"); - } - request.AddHeader(Details::c_HeaderMetadata + ("-" + pair.first), pair.second); - } - metadataKeys.clear(); - request.AddHeader(Details::c_HeaderVersion, createOptions.ApiVersionParameter); - if (createOptions.FilePermission.HasValue()) - { - request.AddHeader( - Details::c_HeaderFilePermission, createOptions.FilePermission.GetValue()); - } - if (createOptions.FilePermissionKey.HasValue()) - { - request.AddHeader( - Details::c_HeaderFilePermissionKey, createOptions.FilePermissionKey.GetValue()); - } - request.AddHeader(Details::c_HeaderFileAttributes, createOptions.FileAttributes); - request.AddHeader(Details::c_HeaderFileCreationTime, createOptions.FileCreationTime); - request.AddHeader(Details::c_HeaderFileLastWriteTime, createOptions.FileLastWriteTime); - return CreateParseResult(context, pipeline.Send(context, request)); - } - - struct GetPropertiesOptions - { - Azure::Core::Nullable - ShareSnapshot; // The snapshot parameter is an opaque DateTime value that, when present, - // specifies the share snapshot to query. - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - }; - - static Azure::Core::Response GetProperties( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const GetPropertiesOptions& getPropertiesOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Get, url); - request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "directory"); - if (getPropertiesOptions.ShareSnapshot.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryShareSnapshot, - Storage::Details::UrlEncodeQueryParameter( - getPropertiesOptions.ShareSnapshot.GetValue())); - } - if (getPropertiesOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(getPropertiesOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderVersion, getPropertiesOptions.ApiVersionParameter); - return GetPropertiesParseResult(context, pipeline.Send(context, request)); - } - - struct DeleteOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - }; - - static Azure::Core::Response Delete( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const DeleteOptions& deleteOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Delete, url); - request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "directory"); - if (deleteOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(deleteOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderVersion, deleteOptions.ApiVersionParameter); - return DeleteParseResult(context, pipeline.Send(context, request)); - } - - struct SetPropertiesOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - FilePermission; // If specified the permission (security descriptor) shall be set for - // the directory/file. This header can be used if Permission size is <= - // 8KB, else x-ms-file-permission-key header shall be used. Default - // value: Inherit. If SDDL is specified as input, it must have owner, - // group and dacl. Note: Only one of the x-ms-file-permission or - // x-ms-file-permission-key should be specified. - Azure::Core::Nullable - FilePermissionKey; // Key of the permission to be set for the directory/file. Note: Only - // one of the x-ms-file-permission or x-ms-file-permission-key should - // be specified. - std::string FileAttributes; // If specified, the provided file attributes shall be set. - // Default value: Archive for file and Directory for directory. - // None can also be specified as default. - std::string FileCreationTime; // Creation time for the file/directory. Default value: Now. - std::string - FileLastWriteTime; // Last write time for the file/directory. Default value: Now. - }; - - static Azure::Core::Response SetProperties( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const SetPropertiesOptions& setPropertiesOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); - request.AddHeader(Details::c_HeaderContentLength, "0"); - request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "directory"); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "properties"); - if (setPropertiesOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(setPropertiesOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderVersion, setPropertiesOptions.ApiVersionParameter); - if (setPropertiesOptions.FilePermission.HasValue()) - { - request.AddHeader( - Details::c_HeaderFilePermission, setPropertiesOptions.FilePermission.GetValue()); - } - if (setPropertiesOptions.FilePermissionKey.HasValue()) - { - request.AddHeader( - Details::c_HeaderFilePermissionKey, - setPropertiesOptions.FilePermissionKey.GetValue()); - } - request.AddHeader(Details::c_HeaderFileAttributes, setPropertiesOptions.FileAttributes); - request.AddHeader(Details::c_HeaderFileCreationTime, setPropertiesOptions.FileCreationTime); - request.AddHeader( - Details::c_HeaderFileLastWriteTime, setPropertiesOptions.FileLastWriteTime); - return SetPropertiesParseResult(context, pipeline.Send(context, request)); - } - - struct SetMetadataOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::map - Metadata; // A name-value pair to associate with a file storage object. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - }; - - static Azure::Core::Response SetMetadata( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const SetMetadataOptions& setMetadataOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); - request.AddHeader(Details::c_HeaderContentLength, "0"); - request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "directory"); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "metadata"); - if (setMetadataOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(setMetadataOptions.Timeout.GetValue()))); - } - std::set metadataKeys; - for (const auto& pair : setMetadataOptions.Metadata) - { - std::string key = pair.first; - std::transform(key.begin(), key.end(), key.begin(), [](unsigned char c) { - return static_cast(std::tolower(c)); - }); - if (metadataKeys.insert(key).second == false) - { - throw std::runtime_error("duplicate keys in metadata"); - } - request.AddHeader(Details::c_HeaderMetadata + ("-" + pair.first), pair.second); - } - metadataKeys.clear(); - request.AddHeader(Details::c_HeaderVersion, setMetadataOptions.ApiVersionParameter); - return SetMetadataParseResult(context, pipeline.Send(context, request)); - } - - struct ListFilesAndDirectoriesSegmentOptions - { - Azure::Core::Nullable Prefix; // Filters the results to return only entries - // whose name begins with the specified prefix. - Azure::Core::Nullable - ShareSnapshot; // The snapshot parameter is an opaque DateTime value that, when present, - // specifies the share snapshot to query. - Azure::Core::Nullable - ContinuationToken; // A string value that identifies the portion of the list to be - // returned with the next list operation. The operation returns a - // marker value within the response body if the list returned was not - // complete. The marker value may then be used in a subsequent call - // to request the next set of list items. The marker value is opaque - // to the client. - Azure::Core::Nullable - MaxResults; // Specifies the maximum number of entries to return. If the request does - // not specify maxresults, or specifies a value greater than 5,000, the - // server will return up to 5,000 items. - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - }; - - static Azure::Core::Response - ListFilesAndDirectoriesSegment( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const ListFilesAndDirectoriesSegmentOptions& listFilesAndDirectoriesSegmentOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Get, url); - request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "directory"); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "list"); - if (listFilesAndDirectoriesSegmentOptions.Prefix.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryPrefix, - Storage::Details::UrlEncodeQueryParameter( - listFilesAndDirectoriesSegmentOptions.Prefix.GetValue())); - } - if (listFilesAndDirectoriesSegmentOptions.ShareSnapshot.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryShareSnapshot, - Storage::Details::UrlEncodeQueryParameter( - listFilesAndDirectoriesSegmentOptions.ShareSnapshot.GetValue())); - } - if (listFilesAndDirectoriesSegmentOptions.ContinuationToken.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryContinuationToken, - Storage::Details::UrlEncodeQueryParameter( - listFilesAndDirectoriesSegmentOptions.ContinuationToken.GetValue())); - } - if (listFilesAndDirectoriesSegmentOptions.MaxResults.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryMaxResults, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(listFilesAndDirectoriesSegmentOptions.MaxResults.GetValue()))); - } - if (listFilesAndDirectoriesSegmentOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(listFilesAndDirectoriesSegmentOptions.Timeout.GetValue()))); - } - request.AddHeader( - Details::c_HeaderVersion, listFilesAndDirectoriesSegmentOptions.ApiVersionParameter); - return ListFilesAndDirectoriesSegmentParseResult(context, pipeline.Send(context, request)); - } - - struct ListHandlesOptions - { - Azure::Core::Nullable - ContinuationToken; // A string value that identifies the portion of the list to be - // returned with the next list operation. The operation returns a - // marker value within the response body if the list returned was not - // complete. The marker value may then be used in a subsequent call - // to request the next set of list items. The marker value is opaque - // to the client. - Azure::Core::Nullable - MaxResults; // Specifies the maximum number of entries to return. If the request does - // not specify maxresults, or specifies a value greater than 5,000, the - // server will return up to 5,000 items. - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - Azure::Core::Nullable - ShareSnapshot; // The snapshot parameter is an opaque DateTime value that, when present, - // specifies the share snapshot to query. - Azure::Core::Nullable - Recursive; // Specifies operation should apply to the directory specified in the URI, - // its files, its subdirectories and their files. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - }; - - static Azure::Core::Response ListHandles( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const ListHandlesOptions& listHandlesOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Get, url); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "listhandles"); - if (listHandlesOptions.ContinuationToken.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryContinuationToken, - Storage::Details::UrlEncodeQueryParameter( - listHandlesOptions.ContinuationToken.GetValue())); - } - if (listHandlesOptions.MaxResults.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryMaxResults, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(listHandlesOptions.MaxResults.GetValue()))); - } - if (listHandlesOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(listHandlesOptions.Timeout.GetValue()))); - } - if (listHandlesOptions.ShareSnapshot.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryShareSnapshot, - Storage::Details::UrlEncodeQueryParameter( - listHandlesOptions.ShareSnapshot.GetValue())); - } - if (listHandlesOptions.Recursive.HasValue()) - { - request.AddHeader( - Details::c_HeaderRecursive, - (listHandlesOptions.Recursive.GetValue() ? "true" : "false")); - } - request.AddHeader(Details::c_HeaderVersion, listHandlesOptions.ApiVersionParameter); - return ListHandlesParseResult(context, pipeline.Send(context, request)); - } - - struct ForceCloseHandlesOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - Azure::Core::Nullable - ContinuationToken; // A string value that identifies the portion of the list to be - // returned with the next list operation. The operation returns a - // marker value within the response body if the list returned was not - // complete. The marker value may then be used in a subsequent call - // to request the next set of list items. The marker value is opaque - // to the client. - Azure::Core::Nullable - ShareSnapshot; // The snapshot parameter is an opaque DateTime value that, when present, - // specifies the share snapshot to query. - std::string HandleId; // Specifies handle ID opened on the file or directory to be closed. - // Asterisk (*) is a wildcard that specifies all handles. - Azure::Core::Nullable - Recursive; // Specifies operation should apply to the directory specified in the URI, - // its files, its subdirectories and their files. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - }; - - static Azure::Core::Response ForceCloseHandles( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const ForceCloseHandlesOptions& forceCloseHandlesOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); - request.AddHeader(Details::c_HeaderContentLength, "0"); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "forceclosehandles"); - if (forceCloseHandlesOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(forceCloseHandlesOptions.Timeout.GetValue()))); - } - if (forceCloseHandlesOptions.ContinuationToken.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryContinuationToken, - Storage::Details::UrlEncodeQueryParameter( - forceCloseHandlesOptions.ContinuationToken.GetValue())); - } - if (forceCloseHandlesOptions.ShareSnapshot.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryShareSnapshot, - Storage::Details::UrlEncodeQueryParameter( - forceCloseHandlesOptions.ShareSnapshot.GetValue())); - } - request.AddHeader(Details::c_HeaderHandleId, forceCloseHandlesOptions.HandleId); - if (forceCloseHandlesOptions.Recursive.HasValue()) - { - request.AddHeader( - Details::c_HeaderRecursive, - (forceCloseHandlesOptions.Recursive.GetValue() ? "true" : "false")); - } - request.AddHeader(Details::c_HeaderVersion, forceCloseHandlesOptions.ApiVersionParameter); - return ForceCloseHandlesParseResult(context, pipeline.Send(context, request)); - } - - private: - static Azure::Core::Response CreateParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Created) - { - // Success, Directory created. - DirectoryCreateResult result; - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - result.IsServerEncrypted - = response.GetHeaders().at(Details::c_HeaderRequestIsServerEncrypted) == "true"; - result.FilePermissionKey = response.GetHeaders().at(Details::c_HeaderFilePermissionKey); - result.FileAttributes = response.GetHeaders().at(Details::c_HeaderFileAttributes); - result.FileCreationTime = response.GetHeaders().at(Details::c_HeaderFileCreationTime); - result.FileLastWriteTime = response.GetHeaders().at(Details::c_HeaderFileLastWriteTime); - result.FileChangeTime = response.GetHeaders().at(Details::c_HeaderFileChangeTime); - result.FileId = response.GetHeaders().at(Details::c_HeaderFileId); - result.FileParentId = response.GetHeaders().at(Details::c_HeaderFileParentId); - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response GetPropertiesParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) - { - // Success. - DirectoryGetPropertiesResult result; - - for (auto i = response.GetHeaders().lower_bound(Details::c_HeaderMetadata); - i != response.GetHeaders().end() - && i->first.substr(0, 9) == Details::c_HeaderMetadata; - ++i) - { - result.Metadata.emplace(i->first.substr(10), i->second); - } - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - result.IsServerEncrypted - = response.GetHeaders().at(Details::c_HeaderIsServerEncrypted) == "true"; - result.FileAttributes = response.GetHeaders().at(Details::c_HeaderFileAttributes); - result.FileCreationTime = response.GetHeaders().at(Details::c_HeaderFileCreationTime); - result.FileLastWriteTime = response.GetHeaders().at(Details::c_HeaderFileLastWriteTime); - result.FileChangeTime = response.GetHeaders().at(Details::c_HeaderFileChangeTime); - result.FilePermissionKey = response.GetHeaders().at(Details::c_HeaderFilePermissionKey); - result.FileId = response.GetHeaders().at(Details::c_HeaderFileId); - result.FileParentId = response.GetHeaders().at(Details::c_HeaderFileParentId); - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response DeleteParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Accepted) - { - // Success (Accepted). - DirectoryDeleteResult result; - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response SetPropertiesParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) - { - // Success - DirectorySetPropertiesResult result; - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - result.IsServerEncrypted - = response.GetHeaders().at(Details::c_HeaderRequestIsServerEncrypted) == "true"; - result.FilePermissionKey = response.GetHeaders().at(Details::c_HeaderFilePermissionKey); - result.FileAttributes = response.GetHeaders().at(Details::c_HeaderFileAttributes); - result.FileCreationTime = response.GetHeaders().at(Details::c_HeaderFileCreationTime); - result.FileLastWriteTime = response.GetHeaders().at(Details::c_HeaderFileLastWriteTime); - result.FileChangeTime = response.GetHeaders().at(Details::c_HeaderFileChangeTime); - result.FileId = response.GetHeaders().at(Details::c_HeaderFileId); - result.FileParentId = response.GetHeaders().at(Details::c_HeaderFileParentId); - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response SetMetadataParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) - { - // Success (OK). - DirectorySetMetadataResult result; - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.IsServerEncrypted - = response.GetHeaders().at(Details::c_HeaderRequestIsServerEncrypted) == "true"; - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response - ListFilesAndDirectoriesSegmentParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) - { - // Success. - const auto& bodyBuffer = response.GetBody(); - auto reader - = XmlReader(reinterpret_cast(bodyBuffer.data()), bodyBuffer.size()); - DirectoryListFilesAndDirectoriesSegmentResult result = bodyBuffer.empty() - ? DirectoryListFilesAndDirectoriesSegmentResult() - : DirectoryListFilesAndDirectoriesSegmentResultFromListFilesAndDirectoriesSegmentResponse( - ListFilesAndDirectoriesSegmentResponseFromXml(reader)); - result.HttpHeaders.ContentType = response.GetHeaders().at(Details::c_HeaderContentType); - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static DirectoryItem DirectoryItemFromXml(XmlReader& reader) - { - auto result = DirectoryItem(); - enum class XmlTagName - { - c_Name, - c_Unknown, - }; - std::vector path; - - while (true) - { - auto node = reader.Read(); - if (node.Type == XmlNodeType::End) - { - break; - } - else if (node.Type == XmlNodeType::EndTag) - { - if (path.size() > 0) - { - path.pop_back(); - } - else - { - break; - } - } - else if (node.Type == XmlNodeType::StartTag) - { - - if (std::strcmp(node.Name, "Name") == 0) - { - path.emplace_back(XmlTagName::c_Name); - } - else - { - path.emplace_back(XmlTagName::c_Unknown); - } - } - else if (node.Type == XmlNodeType::Text) - { - if (path.size() == 1 && path[0] == XmlTagName::c_Name) - { - result.Name = node.Value; - } - } - } - return result; - } - - static FileProperty FilePropertyFromXml(XmlReader& reader) - { - auto result = FileProperty(); - enum class XmlTagName - { - c_ContentLength, - c_Unknown, - }; - std::vector path; - - while (true) - { - auto node = reader.Read(); - if (node.Type == XmlNodeType::End) - { - break; - } - else if (node.Type == XmlNodeType::EndTag) - { - if (path.size() > 0) - { - path.pop_back(); - } - else - { - break; - } - } - else if (node.Type == XmlNodeType::StartTag) - { - - if (std::strcmp(node.Name, "Content-Length") == 0) - { - path.emplace_back(XmlTagName::c_ContentLength); - } - else - { - path.emplace_back(XmlTagName::c_Unknown); - } - } - else if (node.Type == XmlNodeType::Text) - { - if (path.size() == 1 && path[0] == XmlTagName::c_ContentLength) - { - result.ContentLength = std::stoll(node.Value); - } - } - } - return result; - } - - static FileItem FileItemFromXml(XmlReader& reader) - { - auto result = FileItem(); - enum class XmlTagName - { - c_Name, - c_Properties, - c_Unknown, - }; - std::vector path; - - while (true) - { - auto node = reader.Read(); - if (node.Type == XmlNodeType::End) - { - break; - } - else if (node.Type == XmlNodeType::EndTag) - { - if (path.size() > 0) - { - path.pop_back(); - } - else - { - break; - } - } - else if (node.Type == XmlNodeType::StartTag) - { - - if (std::strcmp(node.Name, "Name") == 0) - { - path.emplace_back(XmlTagName::c_Name); - } - else if (std::strcmp(node.Name, "Properties") == 0) - { - path.emplace_back(XmlTagName::c_Properties); - } - else - { - path.emplace_back(XmlTagName::c_Unknown); - } - - if (path.size() == 1 && path[0] == XmlTagName::c_Properties) - { - result.Properties = FilePropertyFromXml(reader); - path.pop_back(); - } - } - else if (node.Type == XmlNodeType::Text) - { - if (path.size() == 1 && path[0] == XmlTagName::c_Name) - { - result.Name = node.Value; - } - } - } - return result; - } - - static FilesAndDirectoriesListSegment FilesAndDirectoriesListSegmentFromXml(XmlReader& reader) - { - auto result = FilesAndDirectoriesListSegment(); - enum class XmlTagName - { - c_Directory, - c_File, - c_Unknown, - }; - std::vector path; - - while (true) - { - auto node = reader.Read(); - if (node.Type == XmlNodeType::End) - { - break; - } - else if (node.Type == XmlNodeType::EndTag) - { - if (path.size() > 0) - { - path.pop_back(); - } - else - { - break; - } - } - else if (node.Type == XmlNodeType::StartTag) - { - - if (std::strcmp(node.Name, "Directory") == 0) - { - path.emplace_back(XmlTagName::c_Directory); - } - else if (std::strcmp(node.Name, "File") == 0) - { - path.emplace_back(XmlTagName::c_File); - } - else - { - path.emplace_back(XmlTagName::c_Unknown); - } - if (path.size() == 1 && path[0] == XmlTagName::c_Directory) - { - result.DirectoryItems.emplace_back(DirectoryItemFromXml(reader)); - path.pop_back(); - } - else if (path.size() == 1 && path[0] == XmlTagName::c_File) - { - result.FileItems.emplace_back(FileItemFromXml(reader)); - path.pop_back(); - } - } - else if (node.Type == XmlNodeType::Text) - { - } - } - return result; - } - - static ListFilesAndDirectoriesSegmentResponse ListFilesAndDirectoriesSegmentResponseFromXml( - XmlReader& reader) - { - auto result = ListFilesAndDirectoriesSegmentResponse(); - enum class XmlTagName - { - c_Entries, - c_EnumerationResults, - c_Marker, - c_MaxResults, - c_NextMarker, - c_Prefix, - c_Unknown, - }; - std::vector path; - - while (true) - { - auto node = reader.Read(); - if (node.Type == XmlNodeType::End) - { - break; - } - else if (node.Type == XmlNodeType::EndTag) - { - if (path.size() > 0) - { - path.pop_back(); - } - else - { - break; - } - } - else if (node.Type == XmlNodeType::StartTag) - { - - if (std::strcmp(node.Name, "Entries") == 0) - { - path.emplace_back(XmlTagName::c_Entries); - } - else if (std::strcmp(node.Name, "EnumerationResults") == 0) - { - path.emplace_back(XmlTagName::c_EnumerationResults); - } - else if (std::strcmp(node.Name, "Marker") == 0) - { - path.emplace_back(XmlTagName::c_Marker); - } - else if (std::strcmp(node.Name, "MaxResults") == 0) - { - path.emplace_back(XmlTagName::c_MaxResults); - } - else if (std::strcmp(node.Name, "NextMarker") == 0) - { - path.emplace_back(XmlTagName::c_NextMarker); - } - else if (std::strcmp(node.Name, "Prefix") == 0) - { - path.emplace_back(XmlTagName::c_Prefix); - } - else - { - path.emplace_back(XmlTagName::c_Unknown); - } - - if (path.size() == 2 && path[0] == XmlTagName::c_EnumerationResults - && path[1] == XmlTagName::c_Entries) - { - result.Segment = FilesAndDirectoriesListSegmentFromXml(reader); - path.pop_back(); - } - } - else if (node.Type == XmlNodeType::Text) - { - if (path.size() == 2 && path[0] == XmlTagName::c_EnumerationResults - && path[1] == XmlTagName::c_NextMarker) - { - result.ContinuationToken = node.Value; - } - else if ( - path.size() == 2 && path[0] == XmlTagName::c_EnumerationResults - && path[1] == XmlTagName::c_MaxResults) - { - result.MaxResults = std::stoi(node.Value); - } - else if ( - path.size() == 2 && path[0] == XmlTagName::c_EnumerationResults - && path[1] == XmlTagName::c_Prefix) - { - result.Prefix = node.Value; - } - else if ( - path.size() == 2 && path[0] == XmlTagName::c_EnumerationResults - && path[1] == XmlTagName::c_Marker) - { - result.PreviousContinuationToken = node.Value; - } - } - else if (node.Type == XmlNodeType::Attribute) - { - if (path.size() == 1 && path[0] == XmlTagName::c_EnumerationResults - && (std::strcmp(node.Name, "DirectoryPath") == 0)) - { - result.DirectoryPath = node.Value; - } - else if ( - path.size() == 1 && path[0] == XmlTagName::c_EnumerationResults - && (std::strcmp(node.Name, "ServiceEndpoint") == 0)) - { - result.ServiceEndpoint = node.Value; - } - else if ( - path.size() == 1 && path[0] == XmlTagName::c_EnumerationResults - && (std::strcmp(node.Name, "ShareName") == 0)) - { - result.ShareName = node.Value; - } - else if ( - path.size() == 1 && path[0] == XmlTagName::c_EnumerationResults - && (std::strcmp(node.Name, "ShareSnapshot") == 0)) - { - result.ShareSnapshot = node.Value; - } - } - } - return result; - } - - static DirectoryListFilesAndDirectoriesSegmentResult - DirectoryListFilesAndDirectoriesSegmentResultFromListFilesAndDirectoriesSegmentResponse( - ListFilesAndDirectoriesSegmentResponse object) - { - DirectoryListFilesAndDirectoriesSegmentResult result; - result.ServiceEndpoint = std::move(object.ServiceEndpoint); - result.ShareName = std::move(object.ShareName); - result.ShareSnapshot = std::move(object.ShareSnapshot); - result.DirectoryPath = std::move(object.DirectoryPath); - result.Prefix = std::move(object.Prefix); - result.PreviousContinuationToken = std::move(object.PreviousContinuationToken); - result.MaxResults = object.MaxResults; - result.Segment = std::move(object.Segment); - result.ContinuationToken = std::move(object.ContinuationToken); - - return result; - } - static Azure::Core::Response ListHandlesParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) - { - // Success. - const auto& bodyBuffer = response.GetBody(); - auto reader - = XmlReader(reinterpret_cast(bodyBuffer.data()), bodyBuffer.size()); - DirectoryListHandlesResult result = bodyBuffer.empty() - ? DirectoryListHandlesResult() - : DirectoryListHandlesResultFromListHandlesResponse( - ListHandlesResponseFromXml(reader)); - result.HttpHeaders.ContentType = response.GetHeaders().at(Details::c_HeaderContentType); - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static HandleItem HandleItemFromXml(XmlReader& reader) - { - auto result = HandleItem(); - enum class XmlTagName - { - c_ClientIp, - c_FileId, - c_HandleId, - c_LastReconnectTime, - c_OpenTime, - c_ParentId, - c_Path, - c_SessionId, - c_Unknown, - }; - std::vector path; - - while (true) - { - auto node = reader.Read(); - if (node.Type == XmlNodeType::End) - { - break; - } - else if (node.Type == XmlNodeType::EndTag) - { - if (path.size() > 0) - { - path.pop_back(); - } - else - { - break; - } - } - else if (node.Type == XmlNodeType::StartTag) - { - - if (std::strcmp(node.Name, "ClientIp") == 0) - { - path.emplace_back(XmlTagName::c_ClientIp); - } - else if (std::strcmp(node.Name, "FileId") == 0) - { - path.emplace_back(XmlTagName::c_FileId); - } - else if (std::strcmp(node.Name, "HandleId") == 0) - { - path.emplace_back(XmlTagName::c_HandleId); - } - else if (std::strcmp(node.Name, "LastReconnectTime") == 0) - { - path.emplace_back(XmlTagName::c_LastReconnectTime); - } - else if (std::strcmp(node.Name, "OpenTime") == 0) - { - path.emplace_back(XmlTagName::c_OpenTime); - } - else if (std::strcmp(node.Name, "ParentId") == 0) - { - path.emplace_back(XmlTagName::c_ParentId); - } - else if (std::strcmp(node.Name, "Path") == 0) - { - path.emplace_back(XmlTagName::c_Path); - } - else if (std::strcmp(node.Name, "SessionId") == 0) - { - path.emplace_back(XmlTagName::c_SessionId); - } - else - { - path.emplace_back(XmlTagName::c_Unknown); - } - } - else if (node.Type == XmlNodeType::Text) - { - if (path.size() == 1 && path[0] == XmlTagName::c_ClientIp) - { - result.ClientIp = node.Value; - } - else if (path.size() == 1 && path[0] == XmlTagName::c_FileId) - { - result.FileId = node.Value; - } - else if (path.size() == 1 && path[0] == XmlTagName::c_HandleId) - { - result.HandleId = node.Value; - } - else if (path.size() == 1 && path[0] == XmlTagName::c_LastReconnectTime) - { - result.LastReconnectTime = node.Value; - } - else if (path.size() == 1 && path[0] == XmlTagName::c_OpenTime) - { - result.OpenTime = node.Value; - } - else if (path.size() == 1 && path[0] == XmlTagName::c_ParentId) - { - result.ParentId = node.Value; - } - else if (path.size() == 1 && path[0] == XmlTagName::c_Path) - { - result.Path = node.Value; - } - else if (path.size() == 1 && path[0] == XmlTagName::c_SessionId) - { - result.SessionId = node.Value; - } - } - } - return result; - } - - static ListHandlesResponse ListHandlesResponseFromXml(XmlReader& reader) - { - auto result = ListHandlesResponse(); - enum class XmlTagName - { - c_Entries, - c_EnumerationResults, - c_Handle, - c_NextMarker, - c_Unknown, - }; - std::vector path; - - while (true) - { - auto node = reader.Read(); - if (node.Type == XmlNodeType::End) - { - break; - } - else if (node.Type == XmlNodeType::EndTag) - { - if (path.size() > 0) - { - path.pop_back(); - } - else - { - break; - } - } - else if (node.Type == XmlNodeType::StartTag) - { - - if (std::strcmp(node.Name, "Entries") == 0) - { - path.emplace_back(XmlTagName::c_Entries); - } - else if (std::strcmp(node.Name, "EnumerationResults") == 0) - { - path.emplace_back(XmlTagName::c_EnumerationResults); - } - else if (std::strcmp(node.Name, "Handle") == 0) - { - path.emplace_back(XmlTagName::c_Handle); - } - else if (std::strcmp(node.Name, "NextMarker") == 0) - { - path.emplace_back(XmlTagName::c_NextMarker); - } - else - { - path.emplace_back(XmlTagName::c_Unknown); - } - if (path.size() == 3 && path[0] == XmlTagName::c_EnumerationResults - && path[1] == XmlTagName::c_Entries && path[2] == XmlTagName::c_Handle) - { - result.HandleList.emplace_back(HandleItemFromXml(reader)); - path.pop_back(); - } - } - else if (node.Type == XmlNodeType::Text) - { - if (path.size() == 2 && path[0] == XmlTagName::c_EnumerationResults - && path[1] == XmlTagName::c_NextMarker) - { - result.ContinuationToken = node.Value; - } - } - } - return result; - } - - static DirectoryListHandlesResult DirectoryListHandlesResultFromListHandlesResponse( - ListHandlesResponse object) - { - DirectoryListHandlesResult result; - result.HandleList = std::move(object.HandleList); - result.ContinuationToken = std::move(object.ContinuationToken); - - return result; - } - static Azure::Core::Response ForceCloseHandlesParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) - { - // Success. - DirectoryForceCloseHandlesResult result; - if (response.GetHeaders().find(Details::c_HeaderContinuationToken) - != response.GetHeaders().end()) - { - result.ContinuationToken = response.GetHeaders().at(Details::c_HeaderContinuationToken); - } - result.numberOfHandlesClosed - = std::stoi(response.GetHeaders().at(Details::c_HeaderNumberOfHandlesClosed)); - result.numberOfHandlesFailedToClose - = std::stoi(response.GetHeaders().at(Details::c_HeaderNumberOfHandlesFailedToClose)); - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - }; - - class File { - public: - struct CreateOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - int64_t XMsContentLength; // Specifies the maximum size for the file, up to 4 TB. - Azure::Core::Nullable - FileContentType; // Sets the MIME content type of the file. The default type is - // 'application/octet-stream'. - Azure::Core::Nullable - FileContentEncoding; // Specifies which content encodings have been applied to the file. - Azure::Core::Nullable - FileContentLanguage; // Specifies the natural languages used by this resource. - Azure::Core::Nullable - FileCacheControl; // Sets the file's cache control. The File service stores this value - // but does not use or modify it. - Azure::Core::Nullable FileContentMd5; // Sets the file's MD5 hash. - Azure::Core::Nullable - FileContentDisposition; // Sets the file's Content-Disposition header. - std::map - Metadata; // A name-value pair to associate with a file storage object. - Azure::Core::Nullable - FilePermission; // If specified the permission (security descriptor) shall be set for - // the directory/file. This header can be used if Permission size is <= - // 8KB, else x-ms-file-permission-key header shall be used. Default - // value: Inherit. If SDDL is specified as input, it must have owner, - // group and dacl. Note: Only one of the x-ms-file-permission or - // x-ms-file-permission-key should be specified. - Azure::Core::Nullable - FilePermissionKey; // Key of the permission to be set for the directory/file. Note: Only - // one of the x-ms-file-permission or x-ms-file-permission-key should - // be specified. - std::string FileAttributes; // If specified, the provided file attributes shall be set. - // Default value: Archive for file and Directory for directory. - // None can also be specified as default. - std::string FileCreationTime; // Creation time for the file/directory. Default value: Now. - std::string - FileLastWriteTime; // Last write time for the file/directory. Default value: Now. - Azure::Core::Nullable - LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease is - // active and matches this ID. - }; - - static Azure::Core::Response Create( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const CreateOptions& createOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); - request.AddHeader(Details::c_HeaderContentLength, "0"); - if (createOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(createOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderVersion, createOptions.ApiVersionParameter); - request.AddHeader( - Details::c_HeaderXMsContentLength, std::to_string(createOptions.XMsContentLength)); - request.AddHeader(Details::c_HeaderFileTypeConstant, "file"); - if (createOptions.FileContentType.HasValue()) - { - request.AddHeader( - Details::c_HeaderFileContentType, createOptions.FileContentType.GetValue()); - } - if (createOptions.FileContentEncoding.HasValue()) - { - request.AddHeader( - Details::c_HeaderFileContentEncoding, createOptions.FileContentEncoding.GetValue()); - } - if (createOptions.FileContentLanguage.HasValue()) - { - request.AddHeader( - Details::c_HeaderFileContentLanguage, createOptions.FileContentLanguage.GetValue()); - } - if (createOptions.FileCacheControl.HasValue()) - { - request.AddHeader( - Details::c_HeaderFileCacheControl, createOptions.FileCacheControl.GetValue()); - } - if (createOptions.FileContentMd5.HasValue()) - { - request.AddHeader(Details::c_HeaderContentMd5, createOptions.FileContentMd5.GetValue()); - } - if (createOptions.FileContentDisposition.HasValue()) - { - request.AddHeader( - Details::c_HeaderFileContentDisposition, - createOptions.FileContentDisposition.GetValue()); - } - std::set metadataKeys; - for (const auto& pair : createOptions.Metadata) - { - std::string key = pair.first; - std::transform(key.begin(), key.end(), key.begin(), [](unsigned char c) { - return static_cast(std::tolower(c)); - }); - if (metadataKeys.insert(key).second == false) - { - throw std::runtime_error("duplicate keys in metadata"); - } - request.AddHeader(Details::c_HeaderMetadata + ("-" + pair.first), pair.second); - } - metadataKeys.clear(); - if (createOptions.FilePermission.HasValue()) - { - request.AddHeader( - Details::c_HeaderFilePermission, createOptions.FilePermission.GetValue()); - } - if (createOptions.FilePermissionKey.HasValue()) - { - request.AddHeader( - Details::c_HeaderFilePermissionKey, createOptions.FilePermissionKey.GetValue()); - } - request.AddHeader(Details::c_HeaderFileAttributes, createOptions.FileAttributes); - request.AddHeader(Details::c_HeaderFileCreationTime, createOptions.FileCreationTime); - request.AddHeader(Details::c_HeaderFileLastWriteTime, createOptions.FileLastWriteTime); - if (createOptions.LeaseIdOptional.HasValue()) - { - request.AddHeader(Details::c_HeaderLeaseId, createOptions.LeaseIdOptional.GetValue()); - } - return CreateParseResult(context, pipeline.Send(context, request)); - } - - struct DownloadOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - Range; // Return file data only from the specified byte range. - Azure::Core::Nullable - GetRangeContentMd5; // When this header is set to true and specified together with the - // Range header, the service returns the MD5 hash for the range, as - // long as the range is less than or equal to 4 MB in size. - Azure::Core::Nullable - LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease is - // active and matches this ID. - }; - - static Azure::Core::Response Download( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const DownloadOptions& downloadOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Get, url, true); - if (downloadOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(downloadOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderVersion, downloadOptions.ApiVersionParameter); - if (downloadOptions.Range.HasValue()) - { - request.AddHeader(Details::c_HeaderRange, downloadOptions.Range.GetValue()); - } - if (downloadOptions.GetRangeContentMd5.HasValue()) - { - request.AddHeader( - Details::c_HeaderRangeGetContentMd5, - (downloadOptions.GetRangeContentMd5.GetValue() ? "true" : "false")); - } - if (downloadOptions.LeaseIdOptional.HasValue()) - { - request.AddHeader(Details::c_HeaderLeaseId, downloadOptions.LeaseIdOptional.GetValue()); - } - return DownloadParseResult(context, pipeline.Send(context, request)); - } - - struct GetPropertiesOptions - { - Azure::Core::Nullable - ShareSnapshot; // The snapshot parameter is an opaque DateTime value that, when present, - // specifies the share snapshot to query. - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease is - // active and matches this ID. - }; - - static Azure::Core::Response GetProperties( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const GetPropertiesOptions& getPropertiesOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Head, url); - if (getPropertiesOptions.ShareSnapshot.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryShareSnapshot, - Storage::Details::UrlEncodeQueryParameter( - getPropertiesOptions.ShareSnapshot.GetValue())); - } - if (getPropertiesOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(getPropertiesOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderVersion, getPropertiesOptions.ApiVersionParameter); - if (getPropertiesOptions.LeaseIdOptional.HasValue()) - { - request.AddHeader( - Details::c_HeaderLeaseId, getPropertiesOptions.LeaseIdOptional.GetValue()); - } - return GetPropertiesParseResult(context, pipeline.Send(context, request)); - } - - struct DeleteOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease is - // active and matches this ID. - }; - - static Azure::Core::Response Delete( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const DeleteOptions& deleteOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Delete, url); - if (deleteOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(deleteOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderVersion, deleteOptions.ApiVersionParameter); - if (deleteOptions.LeaseIdOptional.HasValue()) - { - request.AddHeader(Details::c_HeaderLeaseId, deleteOptions.LeaseIdOptional.GetValue()); - } - return DeleteParseResult(context, pipeline.Send(context, request)); - } - - struct SetHttpHeadersOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - XMsContentLength; // Resizes a file to the specified size. If the specified byte value - // is less than the current size of the file, then all ranges above - // the specified byte value are cleared. - Azure::Core::Nullable - FileContentType; // Sets the MIME content type of the file. The default type is - // 'application/octet-stream'. - Azure::Core::Nullable - FileContentEncoding; // Specifies which content encodings have been applied to the file. - Azure::Core::Nullable - FileContentLanguage; // Specifies the natural languages used by this resource. - Azure::Core::Nullable - FileCacheControl; // Sets the file's cache control. The File service stores this value - // but does not use or modify it. - Azure::Core::Nullable FileContentMd5; // Sets the file's MD5 hash. - Azure::Core::Nullable - FileContentDisposition; // Sets the file's Content-Disposition header. - Azure::Core::Nullable - FilePermission; // If specified the permission (security descriptor) shall be set for - // the directory/file. This header can be used if Permission size is <= - // 8KB, else x-ms-file-permission-key header shall be used. Default - // value: Inherit. If SDDL is specified as input, it must have owner, - // group and dacl. Note: Only one of the x-ms-file-permission or - // x-ms-file-permission-key should be specified. - Azure::Core::Nullable - FilePermissionKey; // Key of the permission to be set for the directory/file. Note: Only - // one of the x-ms-file-permission or x-ms-file-permission-key should - // be specified. - std::string FileAttributes; // If specified, the provided file attributes shall be set. - // Default value: Archive for file and Directory for directory. - // None can also be specified as default. - std::string FileCreationTime; // Creation time for the file/directory. Default value: Now. - std::string - FileLastWriteTime; // Last write time for the file/directory. Default value: Now. - Azure::Core::Nullable - LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease is - // active and matches this ID. - }; - - static Azure::Core::Response SetHttpHeaders( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const SetHttpHeadersOptions& setHttpHeadersOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); - request.AddHeader(Details::c_HeaderContentLength, "0"); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "properties"); - if (setHttpHeadersOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(setHttpHeadersOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderVersion, setHttpHeadersOptions.ApiVersionParameter); - if (setHttpHeadersOptions.XMsContentLength.HasValue()) - { - request.AddHeader( - Details::c_HeaderXMsContentLength, - std::to_string(setHttpHeadersOptions.XMsContentLength.GetValue())); - } - if (setHttpHeadersOptions.FileContentType.HasValue()) - { - request.AddHeader( - Details::c_HeaderFileContentType, setHttpHeadersOptions.FileContentType.GetValue()); - } - if (setHttpHeadersOptions.FileContentEncoding.HasValue()) - { - request.AddHeader( - Details::c_HeaderFileContentEncoding, - setHttpHeadersOptions.FileContentEncoding.GetValue()); - } - if (setHttpHeadersOptions.FileContentLanguage.HasValue()) - { - request.AddHeader( - Details::c_HeaderFileContentLanguage, - setHttpHeadersOptions.FileContentLanguage.GetValue()); - } - if (setHttpHeadersOptions.FileCacheControl.HasValue()) - { - request.AddHeader( - Details::c_HeaderFileCacheControl, setHttpHeadersOptions.FileCacheControl.GetValue()); - } - if (setHttpHeadersOptions.FileContentMd5.HasValue()) - { - request.AddHeader( - Details::c_HeaderContentMd5, setHttpHeadersOptions.FileContentMd5.GetValue()); - } - if (setHttpHeadersOptions.FileContentDisposition.HasValue()) - { - request.AddHeader( - Details::c_HeaderFileContentDisposition, - setHttpHeadersOptions.FileContentDisposition.GetValue()); - } - if (setHttpHeadersOptions.FilePermission.HasValue()) - { - request.AddHeader( - Details::c_HeaderFilePermission, setHttpHeadersOptions.FilePermission.GetValue()); - } - if (setHttpHeadersOptions.FilePermissionKey.HasValue()) - { - request.AddHeader( - Details::c_HeaderFilePermissionKey, - setHttpHeadersOptions.FilePermissionKey.GetValue()); - } - request.AddHeader(Details::c_HeaderFileAttributes, setHttpHeadersOptions.FileAttributes); - request.AddHeader( - Details::c_HeaderFileCreationTime, setHttpHeadersOptions.FileCreationTime); - request.AddHeader( - Details::c_HeaderFileLastWriteTime, setHttpHeadersOptions.FileLastWriteTime); - if (setHttpHeadersOptions.LeaseIdOptional.HasValue()) - { - request.AddHeader( - Details::c_HeaderLeaseId, setHttpHeadersOptions.LeaseIdOptional.GetValue()); - } - return SetHttpHeadersParseResult(context, pipeline.Send(context, request)); - } - - struct SetMetadataOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::map - Metadata; // A name-value pair to associate with a file storage object. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease is - // active and matches this ID. - }; - - static Azure::Core::Response SetMetadata( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const SetMetadataOptions& setMetadataOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); - request.AddHeader(Details::c_HeaderContentLength, "0"); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "metadata"); - if (setMetadataOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(setMetadataOptions.Timeout.GetValue()))); - } - std::set metadataKeys; - for (const auto& pair : setMetadataOptions.Metadata) - { - std::string key = pair.first; - std::transform(key.begin(), key.end(), key.begin(), [](unsigned char c) { - return static_cast(std::tolower(c)); - }); - if (metadataKeys.insert(key).second == false) - { - throw std::runtime_error("duplicate keys in metadata"); - } - request.AddHeader(Details::c_HeaderMetadata + ("-" + pair.first), pair.second); - } - metadataKeys.clear(); - request.AddHeader(Details::c_HeaderVersion, setMetadataOptions.ApiVersionParameter); - if (setMetadataOptions.LeaseIdOptional.HasValue()) - { - request.AddHeader( - Details::c_HeaderLeaseId, setMetadataOptions.LeaseIdOptional.GetValue()); - } - return SetMetadataParseResult(context, pipeline.Send(context, request)); - } - - struct AcquireLeaseOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - int32_t LeaseDuration - = int32_t(); // Specifies the duration of the lease, in seconds, or negative one (-1) - // for a lease that never expires. A non-infinite lease can be between 15 - // and 60 seconds. A lease duration cannot be changed using renew or - // change. - Azure::Core::Nullable - ProposedLeaseIdOptional; // Proposed lease ID, in a GUID string format. The File service - // returns 400 (Invalid request) if the proposed lease ID is - // not in the correct format. See Guid Constructor (String) for - // a list of valid GUID string formats. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character - // limit that is recorded in the analytics logs when storage analytics - // logging is enabled. - }; - - static Azure::Core::Response AcquireLease( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const AcquireLeaseOptions& acquireLeaseOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); - request.AddHeader(Details::c_HeaderContentLength, "0"); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "lease"); - request.AddHeader(Details::c_HeaderAction, "acquire"); - if (acquireLeaseOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(acquireLeaseOptions.Timeout.GetValue()))); - } - request.AddHeader( - Details::c_HeaderDuration, std::to_string(acquireLeaseOptions.LeaseDuration)); - if (acquireLeaseOptions.ProposedLeaseIdOptional.HasValue()) - { - request.AddHeader( - Details::c_HeaderProposedLeaseId, - acquireLeaseOptions.ProposedLeaseIdOptional.GetValue()); - } - request.AddHeader(Details::c_HeaderVersion, acquireLeaseOptions.ApiVersionParameter); - if (acquireLeaseOptions.ClientRequestId.HasValue()) - { - request.AddHeader( - Details::c_HeaderRequestId, acquireLeaseOptions.ClientRequestId.GetValue()); - } - return AcquireLeaseParseResult(context, pipeline.Send(context, request)); - } - - struct ReleaseLeaseOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::string LeaseIdRequired; // Specifies the current lease ID on the resource. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character - // limit that is recorded in the analytics logs when storage analytics - // logging is enabled. - }; - - static Azure::Core::Response ReleaseLease( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const ReleaseLeaseOptions& releaseLeaseOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); - request.AddHeader(Details::c_HeaderContentLength, "0"); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "lease"); - request.AddHeader(Details::c_HeaderAction, "release"); - if (releaseLeaseOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(releaseLeaseOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderLeaseId, releaseLeaseOptions.LeaseIdRequired); - request.AddHeader(Details::c_HeaderVersion, releaseLeaseOptions.ApiVersionParameter); - if (releaseLeaseOptions.ClientRequestId.HasValue()) - { - request.AddHeader( - Details::c_HeaderRequestId, releaseLeaseOptions.ClientRequestId.GetValue()); - } - return ReleaseLeaseParseResult(context, pipeline.Send(context, request)); - } - - struct ChangeLeaseOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::string LeaseIdRequired; // Specifies the current lease ID on the resource. - Azure::Core::Nullable - ProposedLeaseIdOptional; // Proposed lease ID, in a GUID string format. The File service - // returns 400 (Invalid request) if the proposed lease ID is - // not in the correct format. See Guid Constructor (String) for - // a list of valid GUID string formats. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character - // limit that is recorded in the analytics logs when storage analytics - // logging is enabled. - }; - - static Azure::Core::Response ChangeLease( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const ChangeLeaseOptions& changeLeaseOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); - request.AddHeader(Details::c_HeaderContentLength, "0"); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "lease"); - request.AddHeader(Details::c_HeaderAction, "change"); - if (changeLeaseOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(changeLeaseOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderLeaseId, changeLeaseOptions.LeaseIdRequired); - if (changeLeaseOptions.ProposedLeaseIdOptional.HasValue()) - { - request.AddHeader( - Details::c_HeaderProposedLeaseId, - changeLeaseOptions.ProposedLeaseIdOptional.GetValue()); - } - request.AddHeader(Details::c_HeaderVersion, changeLeaseOptions.ApiVersionParameter); - if (changeLeaseOptions.ClientRequestId.HasValue()) - { - request.AddHeader( - Details::c_HeaderRequestId, changeLeaseOptions.ClientRequestId.GetValue()); - } - return ChangeLeaseParseResult(context, pipeline.Send(context, request)); - } - - struct BreakLeaseOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - Azure::Core::Nullable - LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease is - // active and matches this ID. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character - // limit that is recorded in the analytics logs when storage analytics - // logging is enabled. - }; - - static Azure::Core::Response BreakLease( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const BreakLeaseOptions& breakLeaseOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); - request.AddHeader(Details::c_HeaderContentLength, "0"); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "lease"); - request.AddHeader(Details::c_HeaderAction, "break"); - if (breakLeaseOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(breakLeaseOptions.Timeout.GetValue()))); - } - if (breakLeaseOptions.LeaseIdOptional.HasValue()) - { - request.AddHeader(Details::c_HeaderLeaseId, breakLeaseOptions.LeaseIdOptional.GetValue()); - } - request.AddHeader(Details::c_HeaderVersion, breakLeaseOptions.ApiVersionParameter); - if (breakLeaseOptions.ClientRequestId.HasValue()) - { - request.AddHeader( - Details::c_HeaderRequestId, breakLeaseOptions.ClientRequestId.GetValue()); - } - return BreakLeaseParseResult(context, pipeline.Send(context, request)); - } - - struct UploadRangeOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::string - XMsRange; // Specifies the range of bytes to be written. Both the start and end of the - // range must be specified. For an update operation, the range can be up to 4 - // MB in size. For a clear operation, the range can be up to the value of the - // file's full size. The File service accepts only a single byte range for the - // Range and 'x-ms-range' headers, and the byte range must be specified in the - // following format: bytes=startByte-endByte. - FileRangeWriteType - XMsWrite; // Specify one of the following options: - Update: Writes the bytes specified - // by the request body into the specified range. The Range and Content-Length - // headers must match to perform the update. - Clear: Clears the specified - // range and releases the space used in storage for that range. To clear a - // range, set the Content-Length header to zero, and set the Range header to a - // value that indicates the range to clear, up to maximum file size. - int64_t ContentLength = int64_t(); // Specifies the number of bytes being transmitted in the - // request body. When the x-ms-write header is set to - // clear, the value of this header must be set to zero. - Azure::Core::Nullable - ContentMd5; // An MD5 hash of the content. This hash is used to verify the integrity of - // the data during transport. When the Content-MD5 header is specified, the - // File service compares the hash of the content that has arrived with the - // header value that was sent. If the two hashes do not match, the operation - // will fail with error code 400 (Bad Request). - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease is - // active and matches this ID. - }; - - static Azure::Core::Response UploadRange( - const Azure::Core::Http::Url& url, - Azure::Core::Http::BodyStream& bodyStream, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const UploadRangeOptions& uploadRangeOptions) - { - Azure::Core::Http::Request request( - Azure::Core::Http::HttpMethod::Put, std::move(url), &bodyStream); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "range"); - if (uploadRangeOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(uploadRangeOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderXMsRange, uploadRangeOptions.XMsRange); - request.AddHeader( - Details::c_HeaderFileRangeWrite, - FileRangeWriteTypeToString(uploadRangeOptions.XMsWrite)); - request.AddHeader( - Details::c_HeaderContentLength, std::to_string(uploadRangeOptions.ContentLength)); - if (uploadRangeOptions.ContentMd5.HasValue()) - { - request.AddHeader(Details::c_HeaderContentMd5, uploadRangeOptions.ContentMd5.GetValue()); - } - request.AddHeader(Details::c_HeaderVersion, uploadRangeOptions.ApiVersionParameter); - if (uploadRangeOptions.LeaseIdOptional.HasValue()) - { - request.AddHeader( - Details::c_HeaderLeaseId, uploadRangeOptions.LeaseIdOptional.GetValue()); - } - return UploadRangeParseResult(context, pipeline.Send(context, request)); - } - - struct UploadRangeFromUrlOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::string TargetRange; // Writes data to the specified byte range in the file. - std::string - CopySource; // Specifies the URL of the source file or blob, up to 2 KB in length. To - // copy a file to another file within the same storage account, you may use - // Shared Key to authenticate the source file. If you are copying a file - // from another storage account, or if you are copying a blob from the same - // storage account or another storage account, then you must authenticate - // the source file or blob using a shared access signature. If the source is - // a public blob, no authentication is required to perform the copy - // operation. A file in a share snapshot can also be specified as a copy - // source. - Azure::Core::Nullable - SourceRange; // Bytes of source data in the specified range. - FileRangeWriteFromUrlType - XMsWrite; // Only update is supported: - Update: Writes the bytes downloaded from the - // source url into the specified range. - int64_t ContentLength = int64_t(); // Specifies the number of bytes being transmitted in the - // request body. When the x-ms-write header is set to - // clear, the value of this header must be set to zero. - Azure::Core::Nullable - SourceContentCrc64; // Specify the crc64 calculated for the range of bytes that must be - // read from the copy source. - Azure::Core::Nullable - SourceIfMatchCrc64; // Specify the crc64 value to operate only on range with a matching - // crc64 checksum. - Azure::Core::Nullable - SourceIfNoneMatchCrc64; // Specify the crc64 value to operate only on range without a - // matching crc64 checksum. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease is - // active and matches this ID. - }; - - static Azure::Core::Response UploadRangeFromUrl( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const UploadRangeFromUrlOptions& uploadRangeFromUrlOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); - request.AddHeader(Details::c_HeaderContentLength, "0"); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "range"); - if (uploadRangeFromUrlOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(uploadRangeFromUrlOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderRange, uploadRangeFromUrlOptions.TargetRange); - request.AddHeader(Details::c_HeaderCopySource, uploadRangeFromUrlOptions.CopySource); - if (uploadRangeFromUrlOptions.SourceRange.HasValue()) - { - request.AddHeader( - Details::c_HeaderSourceRange, uploadRangeFromUrlOptions.SourceRange.GetValue()); - } - request.AddHeader( - Details::c_HeaderFileRangeWriteFromUrl, - FileRangeWriteFromUrlTypeToString(uploadRangeFromUrlOptions.XMsWrite)); - request.AddHeader( - Details::c_HeaderContentLength, - std::to_string(uploadRangeFromUrlOptions.ContentLength)); - if (uploadRangeFromUrlOptions.SourceContentCrc64.HasValue()) - { - request.AddHeader( - Details::c_HeaderSourceContentCrc64, - uploadRangeFromUrlOptions.SourceContentCrc64.GetValue()); - } - if (uploadRangeFromUrlOptions.SourceIfMatchCrc64.HasValue()) - { - request.AddHeader( - Details::c_HeaderSourceIfMatchCrc64, - uploadRangeFromUrlOptions.SourceIfMatchCrc64.GetValue()); - } - if (uploadRangeFromUrlOptions.SourceIfNoneMatchCrc64.HasValue()) - { - request.AddHeader( - Details::c_HeaderSourceIfNoneMatchCrc64, - uploadRangeFromUrlOptions.SourceIfNoneMatchCrc64.GetValue()); - } - request.AddHeader(Details::c_HeaderVersion, uploadRangeFromUrlOptions.ApiVersionParameter); - if (uploadRangeFromUrlOptions.LeaseIdOptional.HasValue()) - { - request.AddHeader( - Details::c_HeaderLeaseId, uploadRangeFromUrlOptions.LeaseIdOptional.GetValue()); - } - return UploadRangeFromUrlParseResult(context, pipeline.Send(context, request)); - } - - struct GetRangeListOptions - { - Azure::Core::Nullable - ShareSnapshot; // The snapshot parameter is an opaque DateTime value that, when present, - // specifies the share snapshot to query. - Azure::Core::Nullable - PrevShareSnapshot; // The previous snapshot parameter is an opaque DateTime value that, - // when present, specifies the previous snapshot. - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - XMsRange; // Specifies the range of bytes over which to list ranges, inclusively. - Azure::Core::Nullable - LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease is - // active and matches this ID. - }; - - static Azure::Core::Response GetRangeList( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const GetRangeListOptions& getRangeListOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Get, url); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "rangelist"); - if (getRangeListOptions.ShareSnapshot.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryShareSnapshot, - Storage::Details::UrlEncodeQueryParameter( - getRangeListOptions.ShareSnapshot.GetValue())); - } - if (getRangeListOptions.PrevShareSnapshot.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryPrevShareSnapshot, - Storage::Details::UrlEncodeQueryParameter( - getRangeListOptions.PrevShareSnapshot.GetValue())); - } - if (getRangeListOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(getRangeListOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderVersion, getRangeListOptions.ApiVersionParameter); - if (getRangeListOptions.XMsRange.HasValue()) - { - request.AddHeader(Details::c_HeaderXMsRange, getRangeListOptions.XMsRange.GetValue()); - } - if (getRangeListOptions.LeaseIdOptional.HasValue()) - { - request.AddHeader( - Details::c_HeaderLeaseId, getRangeListOptions.LeaseIdOptional.GetValue()); - } - return GetRangeListParseResult(context, pipeline.Send(context, request)); - } - - struct StartCopyOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - std::map - Metadata; // A name-value pair to associate with a file storage object. - std::string - CopySource; // Specifies the URL of the source file or blob, up to 2 KB in length. To - // copy a file to another file within the same storage account, you may use - // Shared Key to authenticate the source file. If you are copying a file - // from another storage account, or if you are copying a blob from the same - // storage account or another storage account, then you must authenticate - // the source file or blob using a shared access signature. If the source is - // a public blob, no authentication is required to perform the copy - // operation. A file in a share snapshot can also be specified as a copy - // source. - Azure::Core::Nullable - FilePermission; // If specified the permission (security descriptor) shall be set for - // the directory/file. This header can be used if Permission size is <= - // 8KB, else x-ms-file-permission-key header shall be used. Default - // value: Inherit. If SDDL is specified as input, it must have owner, - // group and dacl. Note: Only one of the x-ms-file-permission or - // x-ms-file-permission-key should be specified. - Azure::Core::Nullable - FilePermissionKey; // Key of the permission to be set for the directory/file. Note: Only - // one of the x-ms-file-permission or x-ms-file-permission-key should - // be specified. - Azure::Core::Nullable - XMsFilePermissionCopyMode; // Specifies the option to copy file security descriptor from - // source file or to set it using the value which is defined - // by the header value of x-ms-file-permission or - // x-ms-file-permission-key. - Azure::Core::Nullable - FileCopyIgnoreReadOnly; // Specifies the option to overwrite the target file if it - // already exists and has read-only attribute set. - Azure::Core::Nullable - FileCopyFileAttributes; // Specifies either the option to copy file attributes from a - // source file(source) to a target file or a list of attributes - // to set on a target file. - Azure::Core::Nullable - FileCopyFileCreationTime; // Specifies either the option to copy file creation time from - // a source file(source) to a target file or a time value in - // ISO 8601 format to set as creation time on a target file. - Azure::Core::Nullable - FileCopyFileLastWriteTime; // Specifies either the option to copy file last write time - // from a source file(source) to a target file or a time - // value in ISO 8601 format to set as last write time on a - // target file. - Azure::Core::Nullable - FileCopySetArchiveAttribute; // Specifies the option to set archive attribute on a - // target file. True means archive attribute will be set on - // a target file despite attribute overrides or a source - // file state. - Azure::Core::Nullable - LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease is - // active and matches this ID. - }; - - static Azure::Core::Response StartCopy( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const StartCopyOptions& startCopyOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); - request.AddHeader(Details::c_HeaderContentLength, "0"); - if (startCopyOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(startCopyOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderVersion, startCopyOptions.ApiVersionParameter); - std::set metadataKeys; - for (const auto& pair : startCopyOptions.Metadata) - { - std::string key = pair.first; - std::transform(key.begin(), key.end(), key.begin(), [](unsigned char c) { - return static_cast(std::tolower(c)); - }); - if (metadataKeys.insert(key).second == false) - { - throw std::runtime_error("duplicate keys in metadata"); - } - request.AddHeader(Details::c_HeaderMetadata + ("-" + pair.first), pair.second); - } - metadataKeys.clear(); - request.AddHeader(Details::c_HeaderCopySource, startCopyOptions.CopySource); - if (startCopyOptions.FilePermission.HasValue()) - { - request.AddHeader( - Details::c_HeaderFilePermission, startCopyOptions.FilePermission.GetValue()); - } - if (startCopyOptions.FilePermissionKey.HasValue()) - { - request.AddHeader( - Details::c_HeaderFilePermissionKey, startCopyOptions.FilePermissionKey.GetValue()); - } - if (startCopyOptions.XMsFilePermissionCopyMode.HasValue()) - { - request.AddHeader( - Details::c_HeaderFilePermissionCopyMode, - PermissionCopyModeTypeToString( - startCopyOptions.XMsFilePermissionCopyMode.GetValue())); - } - if (startCopyOptions.FileCopyIgnoreReadOnly.HasValue()) - { - request.AddHeader( - Details::c_HeaderIgnoreReadOnly, - (startCopyOptions.FileCopyIgnoreReadOnly.GetValue() ? "true" : "false")); - } - if (startCopyOptions.FileCopyFileAttributes.HasValue()) - { - request.AddHeader( - Details::c_HeaderFileAttributes, startCopyOptions.FileCopyFileAttributes.GetValue()); - } - if (startCopyOptions.FileCopyFileCreationTime.HasValue()) - { - request.AddHeader( - Details::c_HeaderFileCreationTime, - startCopyOptions.FileCopyFileCreationTime.GetValue()); - } - if (startCopyOptions.FileCopyFileLastWriteTime.HasValue()) - { - request.AddHeader( - Details::c_HeaderFileLastWriteTime, - startCopyOptions.FileCopyFileLastWriteTime.GetValue()); - } - if (startCopyOptions.FileCopySetArchiveAttribute.HasValue()) - { - request.AddHeader( - Details::c_HeaderSetArchiveAttribute, - (startCopyOptions.FileCopySetArchiveAttribute.GetValue() ? "true" : "false")); - } - if (startCopyOptions.LeaseIdOptional.HasValue()) - { - request.AddHeader(Details::c_HeaderLeaseId, startCopyOptions.LeaseIdOptional.GetValue()); - } - return StartCopyParseResult(context, pipeline.Send(context, request)); - } - - struct AbortCopyOptions - { - std::string CopyId; // The copy identifier provided in the x-ms-copy-id header of the - // original Copy File operation. - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - Azure::Core::Nullable - LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease is - // active and matches this ID. - }; - - static Azure::Core::Response AbortCopy( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const AbortCopyOptions& abortCopyOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); - request.AddHeader(Details::c_HeaderContentLength, "0"); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "copy"); - request.GetUrl().AppendQueryParameter( - Details::c_QueryCopyId, - Storage::Details::UrlEncodeQueryParameter(abortCopyOptions.CopyId)); - if (abortCopyOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(abortCopyOptions.Timeout.GetValue()))); - } - request.AddHeader(Details::c_HeaderCopyActionAbortConstant, "abort"); - request.AddHeader(Details::c_HeaderVersion, abortCopyOptions.ApiVersionParameter); - if (abortCopyOptions.LeaseIdOptional.HasValue()) - { - request.AddHeader(Details::c_HeaderLeaseId, abortCopyOptions.LeaseIdOptional.GetValue()); - } - return AbortCopyParseResult(context, pipeline.Send(context, request)); - } - - struct ListHandlesOptions - { - Azure::Core::Nullable - ContinuationToken; // A string value that identifies the portion of the list to be - // returned with the next list operation. The operation returns a - // marker value within the response body if the list returned was not - // complete. The marker value may then be used in a subsequent call - // to request the next set of list items. The marker value is opaque - // to the client. - Azure::Core::Nullable - MaxResults; // Specifies the maximum number of entries to return. If the request does - // not specify maxresults, or specifies a value greater than 5,000, the - // server will return up to 5,000 items. - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - Azure::Core::Nullable - ShareSnapshot; // The snapshot parameter is an opaque DateTime value that, when present, - // specifies the share snapshot to query. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - }; - - static Azure::Core::Response ListHandles( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const ListHandlesOptions& listHandlesOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Get, url); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "listhandles"); - if (listHandlesOptions.ContinuationToken.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryContinuationToken, - Storage::Details::UrlEncodeQueryParameter( - listHandlesOptions.ContinuationToken.GetValue())); - } - if (listHandlesOptions.MaxResults.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryMaxResults, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(listHandlesOptions.MaxResults.GetValue()))); - } - if (listHandlesOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(listHandlesOptions.Timeout.GetValue()))); - } - if (listHandlesOptions.ShareSnapshot.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryShareSnapshot, - Storage::Details::UrlEncodeQueryParameter( - listHandlesOptions.ShareSnapshot.GetValue())); - } - request.AddHeader(Details::c_HeaderVersion, listHandlesOptions.ApiVersionParameter); - return ListHandlesParseResult(context, pipeline.Send(context, request)); - } - - struct ForceCloseHandlesOptions - { - Azure::Core::Nullable - Timeout; // The timeout parameter is expressed in seconds. For more information, see Setting - // Timeouts for File Service Operations. - Azure::Core::Nullable - ContinuationToken; // A string value that identifies the portion of the list to be - // returned with the next list operation. The operation returns a - // marker value within the response body if the list returned was not - // complete. The marker value may then be used in a subsequent call - // to request the next set of list items. The marker value is opaque - // to the client. - Azure::Core::Nullable - ShareSnapshot; // The snapshot parameter is an opaque DateTime value that, when present, - // specifies the share snapshot to query. - std::string HandleId; // Specifies handle ID opened on the file or directory to be closed. - // Asterisk (*) is a wildcard that specifies all handles. - std::string ApiVersionParameter - = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to use - // for this request. - }; - - static Azure::Core::Response ForceCloseHandles( - const Azure::Core::Http::Url& url, - Azure::Core::Http::HttpPipeline& pipeline, - Azure::Core::Context context, - const ForceCloseHandlesOptions& forceCloseHandlesOptions) - { - Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); - request.AddHeader(Details::c_HeaderContentLength, "0"); - request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "forceclosehandles"); - if (forceCloseHandlesOptions.Timeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryTimeout, - Storage::Details::UrlEncodeQueryParameter( - std::to_string(forceCloseHandlesOptions.Timeout.GetValue()))); - } - if (forceCloseHandlesOptions.ContinuationToken.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryContinuationToken, - Storage::Details::UrlEncodeQueryParameter( - forceCloseHandlesOptions.ContinuationToken.GetValue())); - } - if (forceCloseHandlesOptions.ShareSnapshot.HasValue()) - { - request.GetUrl().AppendQueryParameter( - Details::c_QueryShareSnapshot, - Storage::Details::UrlEncodeQueryParameter( - forceCloseHandlesOptions.ShareSnapshot.GetValue())); - } - request.AddHeader(Details::c_HeaderHandleId, forceCloseHandlesOptions.HandleId); - request.AddHeader(Details::c_HeaderVersion, forceCloseHandlesOptions.ApiVersionParameter); - return ForceCloseHandlesParseResult(context, pipeline.Send(context, request)); - } - - private: - static Azure::Core::Response CreateParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Created) - { - // Success, File created. - FileCreateResult result; - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - result.IsServerEncrypted - = response.GetHeaders().at(Details::c_HeaderRequestIsServerEncrypted) == "true"; - result.FilePermissionKey = response.GetHeaders().at(Details::c_HeaderFilePermissionKey); - result.FileAttributes = response.GetHeaders().at(Details::c_HeaderFileAttributes); - result.FileCreationTime = response.GetHeaders().at(Details::c_HeaderFileCreationTime); - result.FileLastWriteTime = response.GetHeaders().at(Details::c_HeaderFileLastWriteTime); - result.FileChangeTime = response.GetHeaders().at(Details::c_HeaderFileChangeTime); - result.FileId = response.GetHeaders().at(Details::c_HeaderFileId); - result.FileParentId = response.GetHeaders().at(Details::c_HeaderFileParentId); - return Azure::Core::Response(std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response DownloadParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) - { - // Succeeded to read the entire file. - FileDownloadResult result; - result.BodyStream = response.GetBodyStream(); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - - for (auto i = response.GetHeaders().lower_bound(Details::c_HeaderMetadata); - i != response.GetHeaders().end() - && i->first.substr(0, 9) == Details::c_HeaderMetadata; - ++i) - { - result.Metadata.emplace(i->first.substr(10), i->second); - } - result.ContentLength - = std::stoll(response.GetHeaders().at(Details::c_HeaderContentLength)); - result.HttpHeaders.ContentType = response.GetHeaders().at(Details::c_HeaderContentType); - if (response.GetHeaders().find(Details::c_HeaderContentRange) - != response.GetHeaders().end()) - { - result.ContentRange = response.GetHeaders().at(Details::c_HeaderContentRange); - } - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - if (response.GetHeaders().find(Details::c_HeaderTransactionalContentMd5) - != response.GetHeaders().end()) - { - result.TransactionalContentMd5 - = response.GetHeaders().at(Details::c_HeaderTransactionalContentMd5); - } - if (response.GetHeaders().find(Details::c_HeaderContentEncoding) - != response.GetHeaders().end()) - { - result.HttpHeaders.ContentEncoding - = response.GetHeaders().at(Details::c_HeaderContentEncoding); - } - if (response.GetHeaders().find(Details::c_HeaderCacheControl) - != response.GetHeaders().end()) - { - result.HttpHeaders.CacheControl - = response.GetHeaders().at(Details::c_HeaderCacheControl); - } - if (response.GetHeaders().find(Details::c_HeaderContentDisposition) - != response.GetHeaders().end()) - { - result.HttpHeaders.ContentDisposition - = response.GetHeaders().at(Details::c_HeaderContentDisposition); - } - if (response.GetHeaders().find(Details::c_HeaderContentLanguage) - != response.GetHeaders().end()) - { - result.HttpHeaders.ContentLanguage - = response.GetHeaders().at(Details::c_HeaderContentLanguage); - } - result.AcceptRanges = response.GetHeaders().at(Details::c_HeaderAcceptRanges); - if (response.GetHeaders().find(Details::c_HeaderCopyCompletionTime) - != response.GetHeaders().end()) - { - result.CopyCompletionTime - = response.GetHeaders().at(Details::c_HeaderCopyCompletionTime); - } - if (response.GetHeaders().find(Details::c_HeaderCopyStatusDescription) - != response.GetHeaders().end()) - { - result.CopyStatusDescription - = response.GetHeaders().at(Details::c_HeaderCopyStatusDescription); - } - if (response.GetHeaders().find(Details::c_HeaderCopyId) != response.GetHeaders().end()) - { - result.CopyId = response.GetHeaders().at(Details::c_HeaderCopyId); - } - if (response.GetHeaders().find(Details::c_HeaderCopyProgress) - != response.GetHeaders().end()) - { - result.CopyProgress = response.GetHeaders().at(Details::c_HeaderCopyProgress); - } - if (response.GetHeaders().find(Details::c_HeaderCopySource) - != response.GetHeaders().end()) - { - result.CopySource = response.GetHeaders().at(Details::c_HeaderCopySource); - } - if (response.GetHeaders().find(Details::c_HeaderCopyStatus) - != response.GetHeaders().end()) - { - result.CopyStatus - = CopyStatusTypeFromString(response.GetHeaders().at(Details::c_HeaderCopyStatus)); - } - if (response.GetHeaders().find(Details::c_HeaderContentMd5) - != response.GetHeaders().end()) - { - result.HttpHeaders.ContentMd5 = response.GetHeaders().at(Details::c_HeaderContentMd5); - } - if (response.GetHeaders().find(Details::c_HeaderIsServerEncrypted) - != response.GetHeaders().end()) - { - result.IsServerEncrypted - = response.GetHeaders().at(Details::c_HeaderIsServerEncrypted) == "true"; - } - result.FileAttributes = response.GetHeaders().at(Details::c_HeaderFileAttributes); - result.FileCreationTime = response.GetHeaders().at(Details::c_HeaderFileCreationTime); - result.FileLastWriteTime = response.GetHeaders().at(Details::c_HeaderFileLastWriteTime); - result.FileChangeTime = response.GetHeaders().at(Details::c_HeaderFileChangeTime); - result.FilePermissionKey = response.GetHeaders().at(Details::c_HeaderFilePermissionKey); - result.FileId = response.GetHeaders().at(Details::c_HeaderFileId); - result.FileParentId = response.GetHeaders().at(Details::c_HeaderFileParentId); - if (response.GetHeaders().find(Details::c_HeaderLeaseDuration) - != response.GetHeaders().end()) - { - result.LeaseDuration = LeaseDurationTypeFromString( - response.GetHeaders().at(Details::c_HeaderLeaseDuration)); - } - if (response.GetHeaders().find(Details::c_HeaderLeaseState) - != response.GetHeaders().end()) - { - result.LeaseState - = LeaseStateTypeFromString(response.GetHeaders().at(Details::c_HeaderLeaseState)); - } - if (response.GetHeaders().find(Details::c_HeaderLeaseStatus) - != response.GetHeaders().end()) - { - result.LeaseStatus - = LeaseStatusTypeFromString(response.GetHeaders().at(Details::c_HeaderLeaseStatus)); - } - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::PartialContent) - { - // Succeeded to read a specified range of the file. - FileDownloadResult result; - result.BodyStream = response.GetBodyStream(); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - - for (auto i = response.GetHeaders().lower_bound(Details::c_HeaderMetadata); - i != response.GetHeaders().end() - && i->first.substr(0, 9) == Details::c_HeaderMetadata; - ++i) - { - result.Metadata.emplace(i->first.substr(10), i->second); - } - result.ContentLength - = std::stoll(response.GetHeaders().at(Details::c_HeaderContentLength)); - result.HttpHeaders.ContentType = response.GetHeaders().at(Details::c_HeaderContentType); - if (response.GetHeaders().find(Details::c_HeaderContentRange) - != response.GetHeaders().end()) - { - result.ContentRange = response.GetHeaders().at(Details::c_HeaderContentRange); - } - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - if (response.GetHeaders().find(Details::c_HeaderTransactionalContentMd5) - != response.GetHeaders().end()) - { - result.TransactionalContentMd5 - = response.GetHeaders().at(Details::c_HeaderTransactionalContentMd5); - } - if (response.GetHeaders().find(Details::c_HeaderContentEncoding) - != response.GetHeaders().end()) - { - result.HttpHeaders.ContentEncoding - = response.GetHeaders().at(Details::c_HeaderContentEncoding); - } - if (response.GetHeaders().find(Details::c_HeaderCacheControl) - != response.GetHeaders().end()) - { - result.HttpHeaders.CacheControl - = response.GetHeaders().at(Details::c_HeaderCacheControl); - } - if (response.GetHeaders().find(Details::c_HeaderContentDisposition) - != response.GetHeaders().end()) - { - result.HttpHeaders.ContentDisposition - = response.GetHeaders().at(Details::c_HeaderContentDisposition); - } - if (response.GetHeaders().find(Details::c_HeaderContentLanguage) - != response.GetHeaders().end()) - { - result.HttpHeaders.ContentLanguage - = response.GetHeaders().at(Details::c_HeaderContentLanguage); - } - result.AcceptRanges = response.GetHeaders().at(Details::c_HeaderAcceptRanges); - if (response.GetHeaders().find(Details::c_HeaderCopyCompletionTime) - != response.GetHeaders().end()) - { - result.CopyCompletionTime - = response.GetHeaders().at(Details::c_HeaderCopyCompletionTime); - } - if (response.GetHeaders().find(Details::c_HeaderCopyStatusDescription) - != response.GetHeaders().end()) - { - result.CopyStatusDescription - = response.GetHeaders().at(Details::c_HeaderCopyStatusDescription); - } - if (response.GetHeaders().find(Details::c_HeaderCopyId) != response.GetHeaders().end()) - { - result.CopyId = response.GetHeaders().at(Details::c_HeaderCopyId); - } - if (response.GetHeaders().find(Details::c_HeaderCopyProgress) - != response.GetHeaders().end()) - { - result.CopyProgress = response.GetHeaders().at(Details::c_HeaderCopyProgress); - } - if (response.GetHeaders().find(Details::c_HeaderCopySource) - != response.GetHeaders().end()) - { - result.CopySource = response.GetHeaders().at(Details::c_HeaderCopySource); - } - if (response.GetHeaders().find(Details::c_HeaderCopyStatus) - != response.GetHeaders().end()) - { - result.CopyStatus - = CopyStatusTypeFromString(response.GetHeaders().at(Details::c_HeaderCopyStatus)); - } - if (response.GetHeaders().find(Details::c_HeaderContentMd5) - != response.GetHeaders().end()) - { - result.HttpHeaders.ContentMd5 = response.GetHeaders().at(Details::c_HeaderContentMd5); - } - if (response.GetHeaders().find(Details::c_HeaderIsServerEncrypted) - != response.GetHeaders().end()) - { - result.IsServerEncrypted - = response.GetHeaders().at(Details::c_HeaderIsServerEncrypted) == "true"; - } - result.FileAttributes = response.GetHeaders().at(Details::c_HeaderFileAttributes); - result.FileCreationTime = response.GetHeaders().at(Details::c_HeaderFileCreationTime); - result.FileLastWriteTime = response.GetHeaders().at(Details::c_HeaderFileLastWriteTime); - result.FileChangeTime = response.GetHeaders().at(Details::c_HeaderFileChangeTime); - result.FilePermissionKey = response.GetHeaders().at(Details::c_HeaderFilePermissionKey); - result.FileId = response.GetHeaders().at(Details::c_HeaderFileId); - result.FileParentId = response.GetHeaders().at(Details::c_HeaderFileParentId); - if (response.GetHeaders().find(Details::c_HeaderLeaseDuration) - != response.GetHeaders().end()) - { - result.LeaseDuration = LeaseDurationTypeFromString( - response.GetHeaders().at(Details::c_HeaderLeaseDuration)); - } - if (response.GetHeaders().find(Details::c_HeaderLeaseState) - != response.GetHeaders().end()) - { - result.LeaseState - = LeaseStateTypeFromString(response.GetHeaders().at(Details::c_HeaderLeaseState)); - } - if (response.GetHeaders().find(Details::c_HeaderLeaseStatus) - != response.GetHeaders().end()) - { - result.LeaseStatus - = LeaseStatusTypeFromString(response.GetHeaders().at(Details::c_HeaderLeaseStatus)); - } - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response GetPropertiesParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) - { - // Success. - FileGetPropertiesResult result; - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - - for (auto i = response.GetHeaders().lower_bound(Details::c_HeaderMetadata); - i != response.GetHeaders().end() - && i->first.substr(0, 9) == Details::c_HeaderMetadata; - ++i) - { - result.Metadata.emplace(i->first.substr(10), i->second); - } - result.FileType = response.GetHeaders().at(Details::c_HeaderFileType); - result.ContentLength - = std::stoll(response.GetHeaders().at(Details::c_HeaderContentLength)); - if (response.GetHeaders().find(Details::c_HeaderContentType) - != response.GetHeaders().end()) - { - result.HttpHeaders.ContentType = response.GetHeaders().at(Details::c_HeaderContentType); - } - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - if (response.GetHeaders().find(Details::c_HeaderTransactionalContentMd5) - != response.GetHeaders().end()) - { - result.HttpHeaders.ContentMd5 - = response.GetHeaders().at(Details::c_HeaderTransactionalContentMd5); - } - if (response.GetHeaders().find(Details::c_HeaderContentEncoding) - != response.GetHeaders().end()) - { - result.HttpHeaders.ContentEncoding - = response.GetHeaders().at(Details::c_HeaderContentEncoding); - } - if (response.GetHeaders().find(Details::c_HeaderCacheControl) - != response.GetHeaders().end()) - { - result.HttpHeaders.CacheControl - = response.GetHeaders().at(Details::c_HeaderCacheControl); - } - if (response.GetHeaders().find(Details::c_HeaderContentDisposition) - != response.GetHeaders().end()) - { - result.HttpHeaders.ContentDisposition - = response.GetHeaders().at(Details::c_HeaderContentDisposition); - } - if (response.GetHeaders().find(Details::c_HeaderContentLanguage) - != response.GetHeaders().end()) - { - result.HttpHeaders.ContentLanguage - = response.GetHeaders().at(Details::c_HeaderContentLanguage); - } - if (response.GetHeaders().find(Details::c_HeaderCopyCompletionTime) - != response.GetHeaders().end()) - { - result.CopyCompletionTime - = response.GetHeaders().at(Details::c_HeaderCopyCompletionTime); - } - if (response.GetHeaders().find(Details::c_HeaderCopyStatusDescription) - != response.GetHeaders().end()) - { - result.CopyStatusDescription - = response.GetHeaders().at(Details::c_HeaderCopyStatusDescription); - } - if (response.GetHeaders().find(Details::c_HeaderCopyId) != response.GetHeaders().end()) - { - result.CopyId = response.GetHeaders().at(Details::c_HeaderCopyId); - } - if (response.GetHeaders().find(Details::c_HeaderCopyProgress) - != response.GetHeaders().end()) - { - result.CopyProgress = response.GetHeaders().at(Details::c_HeaderCopyProgress); - } - if (response.GetHeaders().find(Details::c_HeaderCopySource) - != response.GetHeaders().end()) - { - result.CopySource = response.GetHeaders().at(Details::c_HeaderCopySource); - } - if (response.GetHeaders().find(Details::c_HeaderCopyStatus) - != response.GetHeaders().end()) - { - result.CopyStatus - = CopyStatusTypeFromString(response.GetHeaders().at(Details::c_HeaderCopyStatus)); - } - if (response.GetHeaders().find(Details::c_HeaderIsServerEncrypted) - != response.GetHeaders().end()) - { - result.IsServerEncrypted - = response.GetHeaders().at(Details::c_HeaderIsServerEncrypted) == "true"; - } - result.FileAttributes = response.GetHeaders().at(Details::c_HeaderFileAttributes); - result.FileCreationTime = response.GetHeaders().at(Details::c_HeaderFileCreationTime); - result.FileLastWriteTime = response.GetHeaders().at(Details::c_HeaderFileLastWriteTime); - result.FileChangeTime = response.GetHeaders().at(Details::c_HeaderFileChangeTime); - result.FilePermissionKey = response.GetHeaders().at(Details::c_HeaderFilePermissionKey); - result.FileId = response.GetHeaders().at(Details::c_HeaderFileId); - result.FileParentId = response.GetHeaders().at(Details::c_HeaderFileParentId); - if (response.GetHeaders().find(Details::c_HeaderLeaseDuration) - != response.GetHeaders().end()) - { - result.LeaseDuration = LeaseDurationTypeFromString( - response.GetHeaders().at(Details::c_HeaderLeaseDuration)); - } - if (response.GetHeaders().find(Details::c_HeaderLeaseState) - != response.GetHeaders().end()) - { - result.LeaseState - = LeaseStateTypeFromString(response.GetHeaders().at(Details::c_HeaderLeaseState)); - } - if (response.GetHeaders().find(Details::c_HeaderLeaseStatus) - != response.GetHeaders().end()) - { - result.LeaseStatus - = LeaseStatusTypeFromString(response.GetHeaders().at(Details::c_HeaderLeaseStatus)); - } - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response DeleteParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Accepted) - { - // Success (Accepted). - FileDeleteResult result; - return Azure::Core::Response(std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response SetHttpHeadersParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) - { - // Success - FileSetHttpHeadersResult result; - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - result.IsServerEncrypted - = response.GetHeaders().at(Details::c_HeaderRequestIsServerEncrypted) == "true"; - result.FilePermissionKey = response.GetHeaders().at(Details::c_HeaderFilePermissionKey); - result.FileAttributes = response.GetHeaders().at(Details::c_HeaderFileAttributes); - result.FileCreationTime = response.GetHeaders().at(Details::c_HeaderFileCreationTime); - result.FileLastWriteTime = response.GetHeaders().at(Details::c_HeaderFileLastWriteTime); - result.FileChangeTime = response.GetHeaders().at(Details::c_HeaderFileChangeTime); - result.FileId = response.GetHeaders().at(Details::c_HeaderFileId); - result.FileParentId = response.GetHeaders().at(Details::c_HeaderFileParentId); - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response SetMetadataParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) - { - // Success (OK). - FileSetMetadataResult result; - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.IsServerEncrypted - = response.GetHeaders().at(Details::c_HeaderRequestIsServerEncrypted) == "true"; - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response AcquireLeaseParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Created) - { - // The Acquire operation completed successfully. - FileAcquireLeaseResult result; - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - result.LeaseId = response.GetHeaders().at(Details::c_HeaderLeaseId); - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response ReleaseLeaseParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) - { - // The Release operation completed successfully. - FileReleaseLeaseResult result; - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response ChangeLeaseParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) - { - // The Change operation completed successfully. - FileChangeLeaseResult result; - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - result.LeaseId = response.GetHeaders().at(Details::c_HeaderLeaseId); - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response BreakLeaseParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Accepted) - { - // The Break operation completed successfully. - FileBreakLeaseResult result; - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - if (response.GetHeaders().find(Details::c_HeaderLeaseId) != response.GetHeaders().end()) - { result.LeaseId = response.GetHeaders().at(Details::c_HeaderLeaseId); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); } - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - static Azure::Core::Response UploadRangeParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Created) + static Azure::Core::Response RenewLeaseParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) { - // Success (Created). - FileUploadRangeResult result; - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - if (response.GetHeaders().find(Details::c_HeaderTransactionalContentMd5) - != response.GetHeaders().end()) + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) { - result.TransactionalContentMd5 - = response.GetHeaders().at(Details::c_HeaderTransactionalContentMd5); + // The Renew operation completed successfully. + ShareRenewLeaseResult result; + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + if (response.GetHeaders().find(Details::c_HeaderLeaseTime) + != response.GetHeaders().end()) + { + result.LeaseTime = std::stoi(response.GetHeaders().at(Details::c_HeaderLeaseTime)); + } + result.LeaseId = response.GetHeaders().at(Details::c_HeaderLeaseId); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); } - if (response.GetHeaders().find(Details::c_HeaderRequestIsServerEncrypted) - != response.GetHeaders().end()) + else { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Core::Response BreakLeaseParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Accepted) + { + // The Break operation completed successfully. + ShareBreakLeaseResult result; + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + if (response.GetHeaders().find(Details::c_HeaderLeaseTime) + != response.GetHeaders().end()) + { + result.LeaseTime = std::stoi(response.GetHeaders().at(Details::c_HeaderLeaseTime)); + } + if (response.GetHeaders().find(Details::c_HeaderLeaseId) != response.GetHeaders().end()) + { + result.LeaseId = response.GetHeaders().at(Details::c_HeaderLeaseId); + } + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Core::Response CreateSnapshotParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Created) + { + // Success, Share snapshot created. + ShareCreateSnapshotResult result; + result.Snapshot = response.GetHeaders().at(Details::c_HeaderSnapshot); + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Core::Response CreatePermissionParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Created) + { + // Success, Share level permission created. + ShareCreatePermissionResult result; + result.FilePermissionKey = response.GetHeaders().at(Details::c_HeaderFilePermissionKey); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static void SharePermissionToJson(nlohmann::json& node, const SharePermission& object) + { + node["permission"] = object.Permission; + } + + static Azure::Core::Response GetPermissionParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + { + // Success + const auto& bodyBuffer = response.GetBody(); + ShareGetPermissionResult result = bodyBuffer.empty() + ? ShareGetPermissionResult() + : ShareGetPermissionResultFromSharePermission( + SharePermissionFromJson(nlohmann::json::parse(bodyBuffer))); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static SharePermission SharePermissionFromJson(const nlohmann::json& node) + { + SharePermission result; + result.Permission = node["permission"].get(); + return result; + } + + static ShareGetPermissionResult ShareGetPermissionResultFromSharePermission( + SharePermission object) + { + ShareGetPermissionResult result; + result.Permission = std::move(object.Permission); + + return result; + } + static Azure::Core::Response SetQuotaParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + { + // Success + ShareSetQuotaResult result; + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Core::Response SetMetadataParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + { + // Success + ShareSetMetadataResult result; + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Core::Response GetAccessPolicyParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + { + // Success + const auto& bodyBuffer = response.GetBody(); + auto reader + = XmlReader(reinterpret_cast(bodyBuffer.data()), bodyBuffer.size()); + ShareGetAccessPolicyResult result = bodyBuffer.empty() + ? ShareGetAccessPolicyResult() + : ShareGetAccessPolicyResultFromSignedIdentifiers(SignedIdentifiersFromXml(reader)); + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static AccessPolicy AccessPolicyFromXml(XmlReader& reader) + { + auto result = AccessPolicy(); + enum class XmlTagName + { + c_Expiry, + c_Permission, + c_Start, + c_Unknown, + }; + std::vector path; + + while (true) + { + auto node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + break; + } + else if (node.Type == XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == XmlNodeType::StartTag) + { + + if (std::strcmp(node.Name, "Expiry") == 0) + { + path.emplace_back(XmlTagName::c_Expiry); + } + else if (std::strcmp(node.Name, "Permission") == 0) + { + path.emplace_back(XmlTagName::c_Permission); + } + else if (std::strcmp(node.Name, "Start") == 0) + { + path.emplace_back(XmlTagName::c_Start); + } + else + { + path.emplace_back(XmlTagName::c_Unknown); + } + } + else if (node.Type == XmlNodeType::Text) + { + if (path.size() == 1 && path[0] == XmlTagName::c_Expiry) + { + result.Expiry = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::c_Permission) + { + result.Permission = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::c_Start) + { + result.Start = node.Value; + } + } + } + return result; + } + + static SignedIdentifier SignedIdentifierFromXml(XmlReader& reader) + { + auto result = SignedIdentifier(); + enum class XmlTagName + { + c_AccessPolicy, + c_Id, + c_Unknown, + }; + std::vector path; + + while (true) + { + auto node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + break; + } + else if (node.Type == XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == XmlNodeType::StartTag) + { + + if (std::strcmp(node.Name, "AccessPolicy") == 0) + { + path.emplace_back(XmlTagName::c_AccessPolicy); + } + else if (std::strcmp(node.Name, "Id") == 0) + { + path.emplace_back(XmlTagName::c_Id); + } + else + { + path.emplace_back(XmlTagName::c_Unknown); + } + + if (path.size() == 1 && path[0] == XmlTagName::c_AccessPolicy) + { + result.Policy = AccessPolicyFromXml(reader); + path.pop_back(); + } + } + else if (node.Type == XmlNodeType::Text) + { + if (path.size() == 1 && path[0] == XmlTagName::c_Id) + { + result.Id = node.Value; + } + } + } + return result; + } + + static std::vector SignedIdentifiersFromXml(XmlReader& reader) + { + auto result = std::vector(); + enum class XmlTagName + { + c_SignedIdentifier, + c_SignedIdentifiers, + c_Unknown, + }; + std::vector path; + + while (true) + { + auto node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + break; + } + else if (node.Type == XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == XmlNodeType::StartTag) + { + + if (std::strcmp(node.Name, "SignedIdentifier") == 0) + { + path.emplace_back(XmlTagName::c_SignedIdentifier); + } + else if (std::strcmp(node.Name, "SignedIdentifiers") == 0) + { + path.emplace_back(XmlTagName::c_SignedIdentifiers); + } + else + { + path.emplace_back(XmlTagName::c_Unknown); + } + + if (path.size() == 2 && path[0] == XmlTagName::c_SignedIdentifiers + && path[1] == XmlTagName::c_SignedIdentifier) + { + result.emplace_back(SignedIdentifierFromXml(reader)); + path.pop_back(); + } + } + else if (node.Type == XmlNodeType::Text) + { + } + } + return result; + } + + static ShareGetAccessPolicyResult ShareGetAccessPolicyResultFromSignedIdentifiers( + std::vector object) + { + ShareGetAccessPolicyResult result; + result.SignedIdentifiers = std::move(object); + + return result; + } + static Azure::Core::Response SetAccessPolicyParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + { + // Success. + ShareSetAccessPolicyResult result; + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static void AccessPolicyToXml(XmlWriter& writer, const AccessPolicy& object) + { + writer.Write(XmlNode{XmlNodeType::StartTag, "AccessPolicy"}); + writer.Write(XmlNode{XmlNodeType::StartTag, "Start"}); + writer.Write(XmlNode{XmlNodeType::Text, nullptr, object.Start.data()}); + writer.Write(XmlNode{XmlNodeType::EndTag}); + writer.Write(XmlNode{XmlNodeType::StartTag, "Expiry"}); + writer.Write(XmlNode{XmlNodeType::Text, nullptr, object.Expiry.data()}); + writer.Write(XmlNode{XmlNodeType::EndTag}); + writer.Write(XmlNode{XmlNodeType::StartTag, "Permission"}); + writer.Write(XmlNode{XmlNodeType::Text, nullptr, object.Permission.data()}); + writer.Write(XmlNode{XmlNodeType::EndTag}); + writer.Write(XmlNode{XmlNodeType::EndTag}); + } + + static void SignedIdentifierToXml(XmlWriter& writer, const SignedIdentifier& object) + { + writer.Write(XmlNode{XmlNodeType::StartTag, "SignedIdentifier"}); + writer.Write(XmlNode{XmlNodeType::StartTag, "Id"}); + writer.Write(XmlNode{XmlNodeType::Text, nullptr, object.Id.data()}); + writer.Write(XmlNode{XmlNodeType::EndTag}); + AccessPolicyToXml(writer, object.Policy); + writer.Write(XmlNode{XmlNodeType::EndTag}); + } + + static void SignedIdentifiersToXml( + XmlWriter& writer, + const std::vector& object) + { + writer.Write(XmlNode{XmlNodeType::StartTag, "SignedIdentifiers"}); + for (const auto& item : object) + { + SignedIdentifierToXml(writer, item); + } + writer.Write(XmlNode{XmlNodeType::EndTag}); + } + static Azure::Core::Response GetStatisticsParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + { + // Success + const auto& bodyBuffer = response.GetBody(); + auto reader + = XmlReader(reinterpret_cast(bodyBuffer.data()), bodyBuffer.size()); + ShareGetStatisticsResult result = bodyBuffer.empty() + ? ShareGetStatisticsResult() + : ShareGetStatisticsResultFromShareStats(ShareStatsFromXml(reader)); + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static ShareStats ShareStatsFromXml(XmlReader& reader) + { + auto result = ShareStats(); + enum class XmlTagName + { + c_ShareStats, + c_ShareUsageBytes, + c_Unknown, + }; + std::vector path; + + while (true) + { + auto node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + break; + } + else if (node.Type == XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == XmlNodeType::StartTag) + { + + if (std::strcmp(node.Name, "ShareStats") == 0) + { + path.emplace_back(XmlTagName::c_ShareStats); + } + else if (std::strcmp(node.Name, "ShareUsageBytes") == 0) + { + path.emplace_back(XmlTagName::c_ShareUsageBytes); + } + else + { + path.emplace_back(XmlTagName::c_Unknown); + } + } + else if (node.Type == XmlNodeType::Text) + { + if (path.size() == 2 && path[0] == XmlTagName::c_ShareStats + && path[1] == XmlTagName::c_ShareUsageBytes) + { + result.ShareUsageBytes = std::stoll(node.Value); + } + } + } + return result; + } + + static ShareGetStatisticsResult ShareGetStatisticsResultFromShareStats(ShareStats object) + { + ShareGetStatisticsResult result; + result.ShareUsageBytes = object.ShareUsageBytes; + + return result; + } + static Azure::Core::Response RestoreParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Created) + { + // Created + ShareRestoreResult result; + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + }; + + class Directory { + public: + struct CreateOptions + { + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::map + Metadata; // A name-value pair to associate with a file storage object. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + FilePermission; // If specified the permission (security descriptor) shall be set for + // the directory/file. This header can be used if Permission size is + // <= 8KB, else x-ms-file-permission-key header shall be used. Default + // value: Inherit. If SDDL is specified as input, it must have owner, + // group and dacl. Note: Only one of the x-ms-file-permission or + // x-ms-file-permission-key should be specified. + Azure::Core::Nullable + FilePermissionKey; // Key of the permission to be set for the directory/file. Note: + // Only one of the x-ms-file-permission or x-ms-file-permission-key + // should be specified. + std::string FileAttributes; // If specified, the provided file attributes shall be set. + // Default value: Archive for file and Directory for + // directory. None can also be specified as default. + std::string FileCreationTime; // Creation time for the file/directory. Default value: Now. + std::string + FileLastWriteTime; // Last write time for the file/directory. Default value: Now. + }; + + static Azure::Core::Response Create( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const CreateOptions& createOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); + request.AddHeader(Details::c_HeaderContentLength, "0"); + request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "directory"); + if (createOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(createOptions.Timeout.GetValue()))); + } + std::set metadataKeys; + for (const auto& pair : createOptions.Metadata) + { + std::string key = pair.first; + std::transform(key.begin(), key.end(), key.begin(), [](unsigned char c) { + return static_cast(std::tolower(c)); + }); + if (metadataKeys.insert(key).second == false) + { + throw std::runtime_error("duplicate keys in metadata"); + } + request.AddHeader(Details::c_HeaderMetadata + ("-" + pair.first), pair.second); + } + metadataKeys.clear(); + request.AddHeader(Details::c_HeaderVersion, createOptions.ApiVersionParameter); + if (createOptions.FilePermission.HasValue()) + { + request.AddHeader( + Details::c_HeaderFilePermission, createOptions.FilePermission.GetValue()); + } + if (createOptions.FilePermissionKey.HasValue()) + { + request.AddHeader( + Details::c_HeaderFilePermissionKey, createOptions.FilePermissionKey.GetValue()); + } + request.AddHeader(Details::c_HeaderFileAttributes, createOptions.FileAttributes); + request.AddHeader(Details::c_HeaderFileCreationTime, createOptions.FileCreationTime); + request.AddHeader(Details::c_HeaderFileLastWriteTime, createOptions.FileLastWriteTime); + return CreateParseResult(context, pipeline.Send(context, request)); + } + + struct GetPropertiesOptions + { + Azure::Core::Nullable + ShareSnapshot; // The snapshot parameter is an opaque DateTime value that, when + // present, specifies the share snapshot to query. + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + }; + + static Azure::Core::Response GetProperties( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const GetPropertiesOptions& getPropertiesOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Get, url); + request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "directory"); + if (getPropertiesOptions.ShareSnapshot.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryShareSnapshot, + Storage::Details::UrlEncodeQueryParameter( + getPropertiesOptions.ShareSnapshot.GetValue())); + } + if (getPropertiesOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(getPropertiesOptions.Timeout.GetValue()))); + } + request.AddHeader(Details::c_HeaderVersion, getPropertiesOptions.ApiVersionParameter); + return GetPropertiesParseResult(context, pipeline.Send(context, request)); + } + + struct DeleteOptions + { + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + }; + + static Azure::Core::Response Delete( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const DeleteOptions& deleteOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Delete, url); + request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "directory"); + if (deleteOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(deleteOptions.Timeout.GetValue()))); + } + request.AddHeader(Details::c_HeaderVersion, deleteOptions.ApiVersionParameter); + return DeleteParseResult(context, pipeline.Send(context, request)); + } + + struct SetPropertiesOptions + { + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + FilePermission; // If specified the permission (security descriptor) shall be set for + // the directory/file. This header can be used if Permission size is + // <= 8KB, else x-ms-file-permission-key header shall be used. Default + // value: Inherit. If SDDL is specified as input, it must have owner, + // group and dacl. Note: Only one of the x-ms-file-permission or + // x-ms-file-permission-key should be specified. + Azure::Core::Nullable + FilePermissionKey; // Key of the permission to be set for the directory/file. Note: + // Only one of the x-ms-file-permission or x-ms-file-permission-key + // should be specified. + std::string FileAttributes; // If specified, the provided file attributes shall be set. + // Default value: Archive for file and Directory for + // directory. None can also be specified as default. + std::string FileCreationTime; // Creation time for the file/directory. Default value: Now. + std::string + FileLastWriteTime; // Last write time for the file/directory. Default value: Now. + }; + + static Azure::Core::Response SetProperties( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const SetPropertiesOptions& setPropertiesOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); + request.AddHeader(Details::c_HeaderContentLength, "0"); + request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "directory"); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "properties"); + if (setPropertiesOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(setPropertiesOptions.Timeout.GetValue()))); + } + request.AddHeader(Details::c_HeaderVersion, setPropertiesOptions.ApiVersionParameter); + if (setPropertiesOptions.FilePermission.HasValue()) + { + request.AddHeader( + Details::c_HeaderFilePermission, setPropertiesOptions.FilePermission.GetValue()); + } + if (setPropertiesOptions.FilePermissionKey.HasValue()) + { + request.AddHeader( + Details::c_HeaderFilePermissionKey, + setPropertiesOptions.FilePermissionKey.GetValue()); + } + request.AddHeader(Details::c_HeaderFileAttributes, setPropertiesOptions.FileAttributes); + request.AddHeader( + Details::c_HeaderFileCreationTime, setPropertiesOptions.FileCreationTime); + request.AddHeader( + Details::c_HeaderFileLastWriteTime, setPropertiesOptions.FileLastWriteTime); + return SetPropertiesParseResult(context, pipeline.Send(context, request)); + } + + struct SetMetadataOptions + { + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::map + Metadata; // A name-value pair to associate with a file storage object. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + }; + + static Azure::Core::Response SetMetadata( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const SetMetadataOptions& setMetadataOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); + request.AddHeader(Details::c_HeaderContentLength, "0"); + request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "directory"); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "metadata"); + if (setMetadataOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(setMetadataOptions.Timeout.GetValue()))); + } + std::set metadataKeys; + for (const auto& pair : setMetadataOptions.Metadata) + { + std::string key = pair.first; + std::transform(key.begin(), key.end(), key.begin(), [](unsigned char c) { + return static_cast(std::tolower(c)); + }); + if (metadataKeys.insert(key).second == false) + { + throw std::runtime_error("duplicate keys in metadata"); + } + request.AddHeader(Details::c_HeaderMetadata + ("-" + pair.first), pair.second); + } + metadataKeys.clear(); + request.AddHeader(Details::c_HeaderVersion, setMetadataOptions.ApiVersionParameter); + return SetMetadataParseResult(context, pipeline.Send(context, request)); + } + + struct ListFilesAndDirectoriesSegmentOptions + { + Azure::Core::Nullable Prefix; // Filters the results to return only entries + // whose name begins with the specified prefix. + Azure::Core::Nullable + ShareSnapshot; // The snapshot parameter is an opaque DateTime value that, when + // present, specifies the share snapshot to query. + Azure::Core::Nullable + ContinuationToken; // A string value that identifies the portion of the list to be + // returned with the next list operation. The operation returns a + // marker value within the response body if the list returned was + // not complete. The marker value may then be used in a subsequent + // call to request the next set of list items. The marker value is + // opaque to the client. + Azure::Core::Nullable + MaxResults; // Specifies the maximum number of entries to return. If the request does + // not specify maxresults, or specifies a value greater than 5,000, the + // server will return up to 5,000 items. + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + }; + + static Azure::Core::Response + ListFilesAndDirectoriesSegment( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const ListFilesAndDirectoriesSegmentOptions& listFilesAndDirectoriesSegmentOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Get, url); + request.GetUrl().AppendQueryParameter(Details::c_QueryRestype, "directory"); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "list"); + if (listFilesAndDirectoriesSegmentOptions.Prefix.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryPrefix, + Storage::Details::UrlEncodeQueryParameter( + listFilesAndDirectoriesSegmentOptions.Prefix.GetValue())); + } + if (listFilesAndDirectoriesSegmentOptions.ShareSnapshot.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryShareSnapshot, + Storage::Details::UrlEncodeQueryParameter( + listFilesAndDirectoriesSegmentOptions.ShareSnapshot.GetValue())); + } + if (listFilesAndDirectoriesSegmentOptions.ContinuationToken.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryContinuationToken, + Storage::Details::UrlEncodeQueryParameter( + listFilesAndDirectoriesSegmentOptions.ContinuationToken.GetValue())); + } + if (listFilesAndDirectoriesSegmentOptions.MaxResults.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryMaxResults, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(listFilesAndDirectoriesSegmentOptions.MaxResults.GetValue()))); + } + if (listFilesAndDirectoriesSegmentOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(listFilesAndDirectoriesSegmentOptions.Timeout.GetValue()))); + } + request.AddHeader( + Details::c_HeaderVersion, listFilesAndDirectoriesSegmentOptions.ApiVersionParameter); + return ListFilesAndDirectoriesSegmentParseResult( + context, pipeline.Send(context, request)); + } + + struct ListHandlesOptions + { + Azure::Core::Nullable + ContinuationToken; // A string value that identifies the portion of the list to be + // returned with the next list operation. The operation returns a + // marker value within the response body if the list returned was + // not complete. The marker value may then be used in a subsequent + // call to request the next set of list items. The marker value is + // opaque to the client. + Azure::Core::Nullable + MaxResults; // Specifies the maximum number of entries to return. If the request does + // not specify maxresults, or specifies a value greater than 5,000, the + // server will return up to 5,000 items. + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + Azure::Core::Nullable + ShareSnapshot; // The snapshot parameter is an opaque DateTime value that, when + // present, specifies the share snapshot to query. + Azure::Core::Nullable + Recursive; // Specifies operation should apply to the directory specified in the URI, + // its files, its subdirectories and their files. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + }; + + static Azure::Core::Response ListHandles( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const ListHandlesOptions& listHandlesOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Get, url); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "listhandles"); + if (listHandlesOptions.ContinuationToken.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryContinuationToken, + Storage::Details::UrlEncodeQueryParameter( + listHandlesOptions.ContinuationToken.GetValue())); + } + if (listHandlesOptions.MaxResults.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryMaxResults, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(listHandlesOptions.MaxResults.GetValue()))); + } + if (listHandlesOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(listHandlesOptions.Timeout.GetValue()))); + } + if (listHandlesOptions.ShareSnapshot.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryShareSnapshot, + Storage::Details::UrlEncodeQueryParameter( + listHandlesOptions.ShareSnapshot.GetValue())); + } + if (listHandlesOptions.Recursive.HasValue()) + { + request.AddHeader( + Details::c_HeaderRecursive, + (listHandlesOptions.Recursive.GetValue() ? "true" : "false")); + } + request.AddHeader(Details::c_HeaderVersion, listHandlesOptions.ApiVersionParameter); + return ListHandlesParseResult(context, pipeline.Send(context, request)); + } + + struct ForceCloseHandlesOptions + { + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + Azure::Core::Nullable + ContinuationToken; // A string value that identifies the portion of the list to be + // returned with the next list operation. The operation returns a + // marker value within the response body if the list returned was + // not complete. The marker value may then be used in a subsequent + // call to request the next set of list items. The marker value is + // opaque to the client. + Azure::Core::Nullable + ShareSnapshot; // The snapshot parameter is an opaque DateTime value that, when + // present, specifies the share snapshot to query. + std::string HandleId; // Specifies handle ID opened on the file or directory to be closed. + // Asterisk (*) is a wildcard that specifies all handles. + Azure::Core::Nullable + Recursive; // Specifies operation should apply to the directory specified in the URI, + // its files, its subdirectories and their files. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + }; + + static Azure::Core::Response ForceCloseHandles( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const ForceCloseHandlesOptions& forceCloseHandlesOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); + request.AddHeader(Details::c_HeaderContentLength, "0"); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "forceclosehandles"); + if (forceCloseHandlesOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(forceCloseHandlesOptions.Timeout.GetValue()))); + } + if (forceCloseHandlesOptions.ContinuationToken.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryContinuationToken, + Storage::Details::UrlEncodeQueryParameter( + forceCloseHandlesOptions.ContinuationToken.GetValue())); + } + if (forceCloseHandlesOptions.ShareSnapshot.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryShareSnapshot, + Storage::Details::UrlEncodeQueryParameter( + forceCloseHandlesOptions.ShareSnapshot.GetValue())); + } + request.AddHeader(Details::c_HeaderHandleId, forceCloseHandlesOptions.HandleId); + if (forceCloseHandlesOptions.Recursive.HasValue()) + { + request.AddHeader( + Details::c_HeaderRecursive, + (forceCloseHandlesOptions.Recursive.GetValue() ? "true" : "false")); + } + request.AddHeader(Details::c_HeaderVersion, forceCloseHandlesOptions.ApiVersionParameter); + return ForceCloseHandlesParseResult(context, pipeline.Send(context, request)); + } + + private: + static Azure::Core::Response CreateParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Created) + { + // Success, Directory created. + DirectoryCreateResult result; + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); result.IsServerEncrypted = response.GetHeaders().at(Details::c_HeaderRequestIsServerEncrypted) == "true"; + result.FilePermissionKey = response.GetHeaders().at(Details::c_HeaderFilePermissionKey); + result.FileAttributes = response.GetHeaders().at(Details::c_HeaderFileAttributes); + result.FileCreationTime = response.GetHeaders().at(Details::c_HeaderFileCreationTime); + result.FileLastWriteTime = response.GetHeaders().at(Details::c_HeaderFileLastWriteTime); + result.FileChangeTime = response.GetHeaders().at(Details::c_HeaderFileChangeTime); + result.FileId = response.GetHeaders().at(Details::c_HeaderFileId); + result.FileParentId = response.GetHeaders().at(Details::c_HeaderFileParentId); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); } - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response UploadRangeFromUrlParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Created) - { - // Success (Created). - FileUploadRangeFromUrlResult result; - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - result.XMsContentCrc64 = response.GetHeaders().at(Details::c_HeaderXMsContentCrc64); - result.IsServerEncrypted - = response.GetHeaders().at(Details::c_HeaderRequestIsServerEncrypted) == "true"; - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response GetRangeListParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) - { - // Success. - const auto& bodyBuffer = response.GetBody(); - auto reader - = XmlReader(reinterpret_cast(bodyBuffer.data()), bodyBuffer.size()); - FileGetRangeListResult result = bodyBuffer.empty() - ? FileGetRangeListResult() - : FileGetRangeListResultFromShareFileRangeList(ShareFileRangeListFromXml(reader)); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.FileContentLength - = std::stoll(response.GetHeaders().at(Details::c_HeaderXMsContentLength)); - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static FileRange FileRangeFromXml(XmlReader& reader) - { - auto result = FileRange(); - enum class XmlTagName - { - c_End, - c_Start, - c_Unknown, - }; - std::vector path; - - while (true) - { - auto node = reader.Read(); - if (node.Type == XmlNodeType::End) + else { - break; + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); } - else if (node.Type == XmlNodeType::EndTag) + } + + static Azure::Core::Response GetPropertiesParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) { - if (path.size() > 0) + // Success. + DirectoryGetPropertiesResult result; + + for (auto i = response.GetHeaders().lower_bound(Details::c_HeaderMetadata); + i != response.GetHeaders().end() + && i->first.substr(0, 9) == Details::c_HeaderMetadata; + ++i) { - path.pop_back(); + result.Metadata.emplace(i->first.substr(10), i->second); } - else + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + result.IsServerEncrypted + = response.GetHeaders().at(Details::c_HeaderIsServerEncrypted) == "true"; + result.FileAttributes = response.GetHeaders().at(Details::c_HeaderFileAttributes); + result.FileCreationTime = response.GetHeaders().at(Details::c_HeaderFileCreationTime); + result.FileLastWriteTime = response.GetHeaders().at(Details::c_HeaderFileLastWriteTime); + result.FileChangeTime = response.GetHeaders().at(Details::c_HeaderFileChangeTime); + result.FilePermissionKey = response.GetHeaders().at(Details::c_HeaderFilePermissionKey); + result.FileId = response.GetHeaders().at(Details::c_HeaderFileId); + result.FileParentId = response.GetHeaders().at(Details::c_HeaderFileParentId); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Core::Response DeleteParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Accepted) + { + // Success (Accepted). + DirectoryDeleteResult result; + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Core::Response SetPropertiesParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + { + // Success + DirectorySetPropertiesResult result; + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + result.IsServerEncrypted + = response.GetHeaders().at(Details::c_HeaderRequestIsServerEncrypted) == "true"; + result.FilePermissionKey = response.GetHeaders().at(Details::c_HeaderFilePermissionKey); + result.FileAttributes = response.GetHeaders().at(Details::c_HeaderFileAttributes); + result.FileCreationTime = response.GetHeaders().at(Details::c_HeaderFileCreationTime); + result.FileLastWriteTime = response.GetHeaders().at(Details::c_HeaderFileLastWriteTime); + result.FileChangeTime = response.GetHeaders().at(Details::c_HeaderFileChangeTime); + result.FileId = response.GetHeaders().at(Details::c_HeaderFileId); + result.FileParentId = response.GetHeaders().at(Details::c_HeaderFileParentId); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Core::Response SetMetadataParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + { + // Success (OK). + DirectorySetMetadataResult result; + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.IsServerEncrypted + = response.GetHeaders().at(Details::c_HeaderRequestIsServerEncrypted) == "true"; + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Core::Response + ListFilesAndDirectoriesSegmentParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + { + // Success. + const auto& bodyBuffer = response.GetBody(); + auto reader + = XmlReader(reinterpret_cast(bodyBuffer.data()), bodyBuffer.size()); + DirectoryListFilesAndDirectoriesSegmentResult result = bodyBuffer.empty() + ? DirectoryListFilesAndDirectoriesSegmentResult() + : DirectoryListFilesAndDirectoriesSegmentResultFromListFilesAndDirectoriesSegmentResponse( + ListFilesAndDirectoriesSegmentResponseFromXml(reader)); + result.HttpHeaders.ContentType = response.GetHeaders().at(Details::c_HeaderContentType); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static DirectoryItem DirectoryItemFromXml(XmlReader& reader) + { + auto result = DirectoryItem(); + enum class XmlTagName + { + c_Name, + c_Unknown, + }; + std::vector path; + + while (true) + { + auto node = reader.Read(); + if (node.Type == XmlNodeType::End) { break; } - } - else if (node.Type == XmlNodeType::StartTag) - { + else if (node.Type == XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == XmlNodeType::StartTag) + { - if (std::strcmp(node.Name, "End") == 0) - { - path.emplace_back(XmlTagName::c_End); + if (std::strcmp(node.Name, "Name") == 0) + { + path.emplace_back(XmlTagName::c_Name); + } + else + { + path.emplace_back(XmlTagName::c_Unknown); + } } - else if (std::strcmp(node.Name, "Start") == 0) + else if (node.Type == XmlNodeType::Text) { - path.emplace_back(XmlTagName::c_Start); - } - else - { - path.emplace_back(XmlTagName::c_Unknown); - } - } - else if (node.Type == XmlNodeType::Text) - { - if (path.size() == 1 && path[0] == XmlTagName::c_End) - { - result.End = std::stoll(node.Value); - } - else if (path.size() == 1 && path[0] == XmlTagName::c_Start) - { - result.Start = std::stoll(node.Value); + if (path.size() == 1 && path[0] == XmlTagName::c_Name) + { + result.Name = node.Value; + } } } + return result; } - return result; - } - static ClearRange ClearRangeFromXml(XmlReader& reader) - { - auto result = ClearRange(); - enum class XmlTagName + static FileProperty FilePropertyFromXml(XmlReader& reader) { - c_End, - c_Start, - c_Unknown, - }; - std::vector path; + auto result = FileProperty(); + enum class XmlTagName + { + c_ContentLength, + c_Unknown, + }; + std::vector path; - while (true) - { - auto node = reader.Read(); - if (node.Type == XmlNodeType::End) + while (true) { - break; - } - else if (node.Type == XmlNodeType::EndTag) - { - if (path.size() > 0) - { - path.pop_back(); - } - else + auto node = reader.Read(); + if (node.Type == XmlNodeType::End) { break; } - } - else if (node.Type == XmlNodeType::StartTag) - { + else if (node.Type == XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == XmlNodeType::StartTag) + { - if (std::strcmp(node.Name, "End") == 0) - { - path.emplace_back(XmlTagName::c_End); + if (std::strcmp(node.Name, "Content-Length") == 0) + { + path.emplace_back(XmlTagName::c_ContentLength); + } + else + { + path.emplace_back(XmlTagName::c_Unknown); + } } - else if (std::strcmp(node.Name, "Start") == 0) + else if (node.Type == XmlNodeType::Text) { - path.emplace_back(XmlTagName::c_Start); - } - else - { - path.emplace_back(XmlTagName::c_Unknown); - } - } - else if (node.Type == XmlNodeType::Text) - { - if (path.size() == 1 && path[0] == XmlTagName::c_End) - { - result.End = std::stoll(node.Value); - } - else if (path.size() == 1 && path[0] == XmlTagName::c_Start) - { - result.Start = std::stoll(node.Value); + if (path.size() == 1 && path[0] == XmlTagName::c_ContentLength) + { + result.ContentLength = std::stoll(node.Value); + } } } + return result; } - return result; - } - static ShareFileRangeList ShareFileRangeListFromXml(XmlReader& reader) - { - auto result = ShareFileRangeList(); - enum class XmlTagName + static FileItem FileItemFromXml(XmlReader& reader) { - c_ClearRange, - c_Range, - c_Ranges, - c_Unknown, - }; - std::vector path; + auto result = FileItem(); + enum class XmlTagName + { + c_Name, + c_Properties, + c_Unknown, + }; + std::vector path; - while (true) - { - auto node = reader.Read(); - if (node.Type == XmlNodeType::End) + while (true) { - break; - } - else if (node.Type == XmlNodeType::EndTag) - { - if (path.size() > 0) - { - path.pop_back(); - } - else + auto node = reader.Read(); + if (node.Type == XmlNodeType::End) { break; } - } - else if (node.Type == XmlNodeType::StartTag) - { + else if (node.Type == XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == XmlNodeType::StartTag) + { - if (std::strcmp(node.Name, "ClearRange") == 0) - { - path.emplace_back(XmlTagName::c_ClearRange); + if (std::strcmp(node.Name, "Name") == 0) + { + path.emplace_back(XmlTagName::c_Name); + } + else if (std::strcmp(node.Name, "Properties") == 0) + { + path.emplace_back(XmlTagName::c_Properties); + } + else + { + path.emplace_back(XmlTagName::c_Unknown); + } + + if (path.size() == 1 && path[0] == XmlTagName::c_Properties) + { + result.Properties = FilePropertyFromXml(reader); + path.pop_back(); + } } - else if (std::strcmp(node.Name, "Range") == 0) + else if (node.Type == XmlNodeType::Text) { - path.emplace_back(XmlTagName::c_Range); - } - else if (std::strcmp(node.Name, "Ranges") == 0) - { - path.emplace_back(XmlTagName::c_Ranges); - } - else - { - path.emplace_back(XmlTagName::c_Unknown); - } - if (path.size() == 2 && path[0] == XmlTagName::c_Ranges - && path[1] == XmlTagName::c_Range) - { - result.Ranges.emplace_back(FileRangeFromXml(reader)); - path.pop_back(); - } - else if ( - path.size() == 2 && path[0] == XmlTagName::c_Ranges - && path[1] == XmlTagName::c_ClearRange) - { - result.ClearRanges.emplace_back(ClearRangeFromXml(reader)); - path.pop_back(); + if (path.size() == 1 && path[0] == XmlTagName::c_Name) + { + result.Name = node.Value; + } } } - else if (node.Type == XmlNodeType::Text) + return result; + } + + static FilesAndDirectoriesListSegment FilesAndDirectoriesListSegmentFromXml( + XmlReader& reader) + { + auto result = FilesAndDirectoriesListSegment(); + enum class XmlTagName { - } - } - return result; - } + c_Directory, + c_File, + c_Unknown, + }; + std::vector path; - static FileGetRangeListResult FileGetRangeListResultFromShareFileRangeList( - ShareFileRangeList object) - { - FileGetRangeListResult result; - result.Ranges = std::move(object.Ranges); - result.ClearRanges = std::move(object.ClearRanges); - - return result; - } - static Azure::Core::Response StartCopyParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Accepted) - { - // The copy file has been accepted with the specified copy status. - FileStartCopyResult result; - result.ETag = response.GetHeaders().at(Details::c_HeaderETag); - result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); - if (response.GetHeaders().find(Details::c_HeaderCopyId) != response.GetHeaders().end()) + while (true) { - result.CopyId = response.GetHeaders().at(Details::c_HeaderCopyId); - } - if (response.GetHeaders().find(Details::c_HeaderCopyStatus) - != response.GetHeaders().end()) - { - result.CopyStatus - = CopyStatusTypeFromString(response.GetHeaders().at(Details::c_HeaderCopyStatus)); - } - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response AbortCopyParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::NoContent) - { - // The delete request was accepted and the file will be deleted. - FileAbortCopyResult result; - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static Azure::Core::Response ListHandlesParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) - { - // Success. - const auto& bodyBuffer = response.GetBody(); - auto reader - = XmlReader(reinterpret_cast(bodyBuffer.data()), bodyBuffer.size()); - FileListHandlesResult result = bodyBuffer.empty() - ? FileListHandlesResult() - : FileListHandlesResultFromListHandlesResponse(ListHandlesResponseFromXml(reader)); - result.HttpHeaders.ContentType = response.GetHeaders().at(Details::c_HeaderContentType); - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - - static HandleItem HandleItemFromXml(XmlReader& reader) - { - auto result = HandleItem(); - enum class XmlTagName - { - c_ClientIp, - c_FileId, - c_HandleId, - c_LastReconnectTime, - c_OpenTime, - c_ParentId, - c_Path, - c_SessionId, - c_Unknown, - }; - std::vector path; - - while (true) - { - auto node = reader.Read(); - if (node.Type == XmlNodeType::End) - { - break; - } - else if (node.Type == XmlNodeType::EndTag) - { - if (path.size() > 0) - { - path.pop_back(); - } - else + auto node = reader.Read(); + if (node.Type == XmlNodeType::End) { break; } - } - else if (node.Type == XmlNodeType::StartTag) - { + else if (node.Type == XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == XmlNodeType::StartTag) + { - if (std::strcmp(node.Name, "ClientIp") == 0) - { - path.emplace_back(XmlTagName::c_ClientIp); + if (std::strcmp(node.Name, "Directory") == 0) + { + path.emplace_back(XmlTagName::c_Directory); + } + else if (std::strcmp(node.Name, "File") == 0) + { + path.emplace_back(XmlTagName::c_File); + } + else + { + path.emplace_back(XmlTagName::c_Unknown); + } + if (path.size() == 1 && path[0] == XmlTagName::c_Directory) + { + result.DirectoryItems.emplace_back(DirectoryItemFromXml(reader)); + path.pop_back(); + } + else if (path.size() == 1 && path[0] == XmlTagName::c_File) + { + result.FileItems.emplace_back(FileItemFromXml(reader)); + path.pop_back(); + } } - else if (std::strcmp(node.Name, "FileId") == 0) + else if (node.Type == XmlNodeType::Text) { - path.emplace_back(XmlTagName::c_FileId); - } - else if (std::strcmp(node.Name, "HandleId") == 0) - { - path.emplace_back(XmlTagName::c_HandleId); - } - else if (std::strcmp(node.Name, "LastReconnectTime") == 0) - { - path.emplace_back(XmlTagName::c_LastReconnectTime); - } - else if (std::strcmp(node.Name, "OpenTime") == 0) - { - path.emplace_back(XmlTagName::c_OpenTime); - } - else if (std::strcmp(node.Name, "ParentId") == 0) - { - path.emplace_back(XmlTagName::c_ParentId); - } - else if (std::strcmp(node.Name, "Path") == 0) - { - path.emplace_back(XmlTagName::c_Path); - } - else if (std::strcmp(node.Name, "SessionId") == 0) - { - path.emplace_back(XmlTagName::c_SessionId); - } - else - { - path.emplace_back(XmlTagName::c_Unknown); - } - } - else if (node.Type == XmlNodeType::Text) - { - if (path.size() == 1 && path[0] == XmlTagName::c_ClientIp) - { - result.ClientIp = node.Value; - } - else if (path.size() == 1 && path[0] == XmlTagName::c_FileId) - { - result.FileId = node.Value; - } - else if (path.size() == 1 && path[0] == XmlTagName::c_HandleId) - { - result.HandleId = node.Value; - } - else if (path.size() == 1 && path[0] == XmlTagName::c_LastReconnectTime) - { - result.LastReconnectTime = node.Value; - } - else if (path.size() == 1 && path[0] == XmlTagName::c_OpenTime) - { - result.OpenTime = node.Value; - } - else if (path.size() == 1 && path[0] == XmlTagName::c_ParentId) - { - result.ParentId = node.Value; - } - else if (path.size() == 1 && path[0] == XmlTagName::c_Path) - { - result.Path = node.Value; - } - else if (path.size() == 1 && path[0] == XmlTagName::c_SessionId) - { - result.SessionId = node.Value; } } + return result; } - return result; - } - static ListHandlesResponse ListHandlesResponseFromXml(XmlReader& reader) - { - auto result = ListHandlesResponse(); - enum class XmlTagName + static ListFilesAndDirectoriesSegmentResponse ListFilesAndDirectoriesSegmentResponseFromXml( + XmlReader& reader) { - c_Entries, - c_EnumerationResults, - c_Handle, - c_NextMarker, - c_Unknown, - }; - std::vector path; + auto result = ListFilesAndDirectoriesSegmentResponse(); + enum class XmlTagName + { + c_Entries, + c_EnumerationResults, + c_Marker, + c_MaxResults, + c_NextMarker, + c_Prefix, + c_Unknown, + }; + std::vector path; - while (true) - { - auto node = reader.Read(); - if (node.Type == XmlNodeType::End) + while (true) { - break; - } - else if (node.Type == XmlNodeType::EndTag) - { - if (path.size() > 0) - { - path.pop_back(); - } - else + auto node = reader.Read(); + if (node.Type == XmlNodeType::End) { break; } - } - else if (node.Type == XmlNodeType::StartTag) - { + else if (node.Type == XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == XmlNodeType::StartTag) + { - if (std::strcmp(node.Name, "Entries") == 0) - { - path.emplace_back(XmlTagName::c_Entries); + if (std::strcmp(node.Name, "Entries") == 0) + { + path.emplace_back(XmlTagName::c_Entries); + } + else if (std::strcmp(node.Name, "EnumerationResults") == 0) + { + path.emplace_back(XmlTagName::c_EnumerationResults); + } + else if (std::strcmp(node.Name, "Marker") == 0) + { + path.emplace_back(XmlTagName::c_Marker); + } + else if (std::strcmp(node.Name, "MaxResults") == 0) + { + path.emplace_back(XmlTagName::c_MaxResults); + } + else if (std::strcmp(node.Name, "NextMarker") == 0) + { + path.emplace_back(XmlTagName::c_NextMarker); + } + else if (std::strcmp(node.Name, "Prefix") == 0) + { + path.emplace_back(XmlTagName::c_Prefix); + } + else + { + path.emplace_back(XmlTagName::c_Unknown); + } + + if (path.size() == 2 && path[0] == XmlTagName::c_EnumerationResults + && path[1] == XmlTagName::c_Entries) + { + result.Segment = FilesAndDirectoriesListSegmentFromXml(reader); + path.pop_back(); + } } - else if (std::strcmp(node.Name, "EnumerationResults") == 0) + else if (node.Type == XmlNodeType::Text) { - path.emplace_back(XmlTagName::c_EnumerationResults); + if (path.size() == 2 && path[0] == XmlTagName::c_EnumerationResults + && path[1] == XmlTagName::c_NextMarker) + { + result.ContinuationToken = node.Value; + } + else if ( + path.size() == 2 && path[0] == XmlTagName::c_EnumerationResults + && path[1] == XmlTagName::c_MaxResults) + { + result.MaxResults = std::stoi(node.Value); + } + else if ( + path.size() == 2 && path[0] == XmlTagName::c_EnumerationResults + && path[1] == XmlTagName::c_Prefix) + { + result.Prefix = node.Value; + } + else if ( + path.size() == 2 && path[0] == XmlTagName::c_EnumerationResults + && path[1] == XmlTagName::c_Marker) + { + result.PreviousContinuationToken = node.Value; + } } - else if (std::strcmp(node.Name, "Handle") == 0) + else if (node.Type == XmlNodeType::Attribute) { - path.emplace_back(XmlTagName::c_Handle); - } - else if (std::strcmp(node.Name, "NextMarker") == 0) - { - path.emplace_back(XmlTagName::c_NextMarker); - } - else - { - path.emplace_back(XmlTagName::c_Unknown); - } - if (path.size() == 3 && path[0] == XmlTagName::c_EnumerationResults - && path[1] == XmlTagName::c_Entries && path[2] == XmlTagName::c_Handle) - { - result.HandleList.emplace_back(HandleItemFromXml(reader)); - path.pop_back(); - } - } - else if (node.Type == XmlNodeType::Text) - { - if (path.size() == 2 && path[0] == XmlTagName::c_EnumerationResults - && path[1] == XmlTagName::c_NextMarker) - { - result.ContinuationToken = node.Value; + if (path.size() == 1 && path[0] == XmlTagName::c_EnumerationResults + && (std::strcmp(node.Name, "DirectoryPath") == 0)) + { + result.DirectoryPath = node.Value; + } + else if ( + path.size() == 1 && path[0] == XmlTagName::c_EnumerationResults + && (std::strcmp(node.Name, "ServiceEndpoint") == 0)) + { + result.ServiceEndpoint = node.Value; + } + else if ( + path.size() == 1 && path[0] == XmlTagName::c_EnumerationResults + && (std::strcmp(node.Name, "ShareName") == 0)) + { + result.ShareName = node.Value; + } + else if ( + path.size() == 1 && path[0] == XmlTagName::c_EnumerationResults + && (std::strcmp(node.Name, "ShareSnapshot") == 0)) + { + result.ShareSnapshot = node.Value; + } } } + return result; } - return result; - } - static FileListHandlesResult FileListHandlesResultFromListHandlesResponse( - ListHandlesResponse object) - { - FileListHandlesResult result; - result.HandleList = std::move(object.HandleList); - result.ContinuationToken = std::move(object.ContinuationToken); - - return result; - } - static Azure::Core::Response ForceCloseHandlesParseResult( - Azure::Core::Context context, - std::unique_ptr responsePtr) - { - auto& response = *responsePtr; - if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + static DirectoryListFilesAndDirectoriesSegmentResult + DirectoryListFilesAndDirectoriesSegmentResultFromListFilesAndDirectoriesSegmentResponse( + ListFilesAndDirectoriesSegmentResponse object) { - // Success. - FileForceCloseHandlesResult result; - if (response.GetHeaders().find(Details::c_HeaderContinuationToken) - != response.GetHeaders().end()) - { - result.ContinuationToken = response.GetHeaders().at(Details::c_HeaderContinuationToken); - } - result.numberOfHandlesClosed - = std::stoi(response.GetHeaders().at(Details::c_HeaderNumberOfHandlesClosed)); - result.numberOfHandlesFailedToClose - = std::stoi(response.GetHeaders().at(Details::c_HeaderNumberOfHandlesFailedToClose)); - return Azure::Core::Response( - std::move(result), std::move(responsePtr)); - } - else - { - unused(context); - throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); - } - } - }; + DirectoryListFilesAndDirectoriesSegmentResult result; + result.ServiceEndpoint = std::move(object.ServiceEndpoint); + result.ShareName = std::move(object.ShareName); + result.ShareSnapshot = std::move(object.ShareSnapshot); + result.DirectoryPath = std::move(object.DirectoryPath); + result.Prefix = std::move(object.Prefix); + result.PreviousContinuationToken = std::move(object.PreviousContinuationToken); + result.MaxResults = object.MaxResults; + result.Segment = std::move(object.Segment); + result.ContinuationToken = std::move(object.ContinuationToken); - }; // class ShareRestClient + return result; + } + static Azure::Core::Response ListHandlesParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + { + // Success. + const auto& bodyBuffer = response.GetBody(); + auto reader + = XmlReader(reinterpret_cast(bodyBuffer.data()), bodyBuffer.size()); + DirectoryListHandlesResult result = bodyBuffer.empty() + ? DirectoryListHandlesResult() + : DirectoryListHandlesResultFromListHandlesResponse( + ListHandlesResponseFromXml(reader)); + result.HttpHeaders.ContentType = response.GetHeaders().at(Details::c_HeaderContentType); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static HandleItem HandleItemFromXml(XmlReader& reader) + { + auto result = HandleItem(); + enum class XmlTagName + { + c_ClientIp, + c_FileId, + c_HandleId, + c_LastReconnectTime, + c_OpenTime, + c_ParentId, + c_Path, + c_SessionId, + c_Unknown, + }; + std::vector path; + + while (true) + { + auto node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + break; + } + else if (node.Type == XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == XmlNodeType::StartTag) + { + + if (std::strcmp(node.Name, "ClientIp") == 0) + { + path.emplace_back(XmlTagName::c_ClientIp); + } + else if (std::strcmp(node.Name, "FileId") == 0) + { + path.emplace_back(XmlTagName::c_FileId); + } + else if (std::strcmp(node.Name, "HandleId") == 0) + { + path.emplace_back(XmlTagName::c_HandleId); + } + else if (std::strcmp(node.Name, "LastReconnectTime") == 0) + { + path.emplace_back(XmlTagName::c_LastReconnectTime); + } + else if (std::strcmp(node.Name, "OpenTime") == 0) + { + path.emplace_back(XmlTagName::c_OpenTime); + } + else if (std::strcmp(node.Name, "ParentId") == 0) + { + path.emplace_back(XmlTagName::c_ParentId); + } + else if (std::strcmp(node.Name, "Path") == 0) + { + path.emplace_back(XmlTagName::c_Path); + } + else if (std::strcmp(node.Name, "SessionId") == 0) + { + path.emplace_back(XmlTagName::c_SessionId); + } + else + { + path.emplace_back(XmlTagName::c_Unknown); + } + } + else if (node.Type == XmlNodeType::Text) + { + if (path.size() == 1 && path[0] == XmlTagName::c_ClientIp) + { + result.ClientIp = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::c_FileId) + { + result.FileId = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::c_HandleId) + { + result.HandleId = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::c_LastReconnectTime) + { + result.LastReconnectTime = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::c_OpenTime) + { + result.OpenTime = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::c_ParentId) + { + result.ParentId = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::c_Path) + { + result.Path = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::c_SessionId) + { + result.SessionId = node.Value; + } + } + } + return result; + } + + static ListHandlesResponse ListHandlesResponseFromXml(XmlReader& reader) + { + auto result = ListHandlesResponse(); + enum class XmlTagName + { + c_Entries, + c_EnumerationResults, + c_Handle, + c_NextMarker, + c_Unknown, + }; + std::vector path; + + while (true) + { + auto node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + break; + } + else if (node.Type == XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == XmlNodeType::StartTag) + { + + if (std::strcmp(node.Name, "Entries") == 0) + { + path.emplace_back(XmlTagName::c_Entries); + } + else if (std::strcmp(node.Name, "EnumerationResults") == 0) + { + path.emplace_back(XmlTagName::c_EnumerationResults); + } + else if (std::strcmp(node.Name, "Handle") == 0) + { + path.emplace_back(XmlTagName::c_Handle); + } + else if (std::strcmp(node.Name, "NextMarker") == 0) + { + path.emplace_back(XmlTagName::c_NextMarker); + } + else + { + path.emplace_back(XmlTagName::c_Unknown); + } + if (path.size() == 3 && path[0] == XmlTagName::c_EnumerationResults + && path[1] == XmlTagName::c_Entries && path[2] == XmlTagName::c_Handle) + { + result.HandleList.emplace_back(HandleItemFromXml(reader)); + path.pop_back(); + } + } + else if (node.Type == XmlNodeType::Text) + { + if (path.size() == 2 && path[0] == XmlTagName::c_EnumerationResults + && path[1] == XmlTagName::c_NextMarker) + { + result.ContinuationToken = node.Value; + } + } + } + return result; + } + + static DirectoryListHandlesResult DirectoryListHandlesResultFromListHandlesResponse( + ListHandlesResponse object) + { + DirectoryListHandlesResult result; + result.HandleList = std::move(object.HandleList); + result.ContinuationToken = std::move(object.ContinuationToken); + + return result; + } + static Azure::Core::Response ForceCloseHandlesParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + { + // Success. + DirectoryForceCloseHandlesResult result; + if (response.GetHeaders().find(Details::c_HeaderContinuationToken) + != response.GetHeaders().end()) + { + result.ContinuationToken + = response.GetHeaders().at(Details::c_HeaderContinuationToken); + } + result.numberOfHandlesClosed + = std::stoi(response.GetHeaders().at(Details::c_HeaderNumberOfHandlesClosed)); + result.numberOfHandlesFailedToClose = std::stoi( + response.GetHeaders().at(Details::c_HeaderNumberOfHandlesFailedToClose)); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + }; + + class File { + public: + struct CreateOptions + { + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + int64_t XMsContentLength; // Specifies the maximum size for the file, up to 4 TB. + Azure::Core::Nullable + FileContentType; // Sets the MIME content type of the file. The default type is + // 'application/octet-stream'. + Azure::Core::Nullable + FileContentEncoding; // Specifies which content encodings have been applied to the + // file. + Azure::Core::Nullable + FileContentLanguage; // Specifies the natural languages used by this resource. + Azure::Core::Nullable + FileCacheControl; // Sets the file's cache control. The File service stores this value + // but does not use or modify it. + Azure::Core::Nullable FileContentMd5; // Sets the file's MD5 hash. + Azure::Core::Nullable + FileContentDisposition; // Sets the file's Content-Disposition header. + std::map + Metadata; // A name-value pair to associate with a file storage object. + Azure::Core::Nullable + FilePermission; // If specified the permission (security descriptor) shall be set for + // the directory/file. This header can be used if Permission size is + // <= 8KB, else x-ms-file-permission-key header shall be used. Default + // value: Inherit. If SDDL is specified as input, it must have owner, + // group and dacl. Note: Only one of the x-ms-file-permission or + // x-ms-file-permission-key should be specified. + Azure::Core::Nullable + FilePermissionKey; // Key of the permission to be set for the directory/file. Note: + // Only one of the x-ms-file-permission or x-ms-file-permission-key + // should be specified. + std::string FileAttributes; // If specified, the provided file attributes shall be set. + // Default value: Archive for file and Directory for + // directory. None can also be specified as default. + std::string FileCreationTime; // Creation time for the file/directory. Default value: Now. + std::string + FileLastWriteTime; // Last write time for the file/directory. Default value: Now. + Azure::Core::Nullable + LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease + // is active and matches this ID. + }; + + static Azure::Core::Response Create( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const CreateOptions& createOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); + request.AddHeader(Details::c_HeaderContentLength, "0"); + if (createOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(createOptions.Timeout.GetValue()))); + } + request.AddHeader(Details::c_HeaderVersion, createOptions.ApiVersionParameter); + request.AddHeader( + Details::c_HeaderXMsContentLength, std::to_string(createOptions.XMsContentLength)); + request.AddHeader(Details::c_HeaderFileTypeConstant, "file"); + if (createOptions.FileContentType.HasValue()) + { + request.AddHeader( + Details::c_HeaderFileContentType, createOptions.FileContentType.GetValue()); + } + if (createOptions.FileContentEncoding.HasValue()) + { + request.AddHeader( + Details::c_HeaderFileContentEncoding, createOptions.FileContentEncoding.GetValue()); + } + if (createOptions.FileContentLanguage.HasValue()) + { + request.AddHeader( + Details::c_HeaderFileContentLanguage, createOptions.FileContentLanguage.GetValue()); + } + if (createOptions.FileCacheControl.HasValue()) + { + request.AddHeader( + Details::c_HeaderFileCacheControl, createOptions.FileCacheControl.GetValue()); + } + if (createOptions.FileContentMd5.HasValue()) + { + request.AddHeader(Details::c_HeaderContentMd5, createOptions.FileContentMd5.GetValue()); + } + if (createOptions.FileContentDisposition.HasValue()) + { + request.AddHeader( + Details::c_HeaderFileContentDisposition, + createOptions.FileContentDisposition.GetValue()); + } + std::set metadataKeys; + for (const auto& pair : createOptions.Metadata) + { + std::string key = pair.first; + std::transform(key.begin(), key.end(), key.begin(), [](unsigned char c) { + return static_cast(std::tolower(c)); + }); + if (metadataKeys.insert(key).second == false) + { + throw std::runtime_error("duplicate keys in metadata"); + } + request.AddHeader(Details::c_HeaderMetadata + ("-" + pair.first), pair.second); + } + metadataKeys.clear(); + if (createOptions.FilePermission.HasValue()) + { + request.AddHeader( + Details::c_HeaderFilePermission, createOptions.FilePermission.GetValue()); + } + if (createOptions.FilePermissionKey.HasValue()) + { + request.AddHeader( + Details::c_HeaderFilePermissionKey, createOptions.FilePermissionKey.GetValue()); + } + request.AddHeader(Details::c_HeaderFileAttributes, createOptions.FileAttributes); + request.AddHeader(Details::c_HeaderFileCreationTime, createOptions.FileCreationTime); + request.AddHeader(Details::c_HeaderFileLastWriteTime, createOptions.FileLastWriteTime); + if (createOptions.LeaseIdOptional.HasValue()) + { + request.AddHeader(Details::c_HeaderLeaseId, createOptions.LeaseIdOptional.GetValue()); + } + return CreateParseResult(context, pipeline.Send(context, request)); + } + + struct DownloadOptions + { + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + Range; // Return file data only from the specified byte range. + Azure::Core::Nullable + GetRangeContentMd5; // When this header is set to true and specified together with the + // Range header, the service returns the MD5 hash for the range, + // as long as the range is less than or equal to 4 MB in size. + Azure::Core::Nullable + LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease + // is active and matches this ID. + }; + + static Azure::Core::Response Download( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const DownloadOptions& downloadOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Get, url, true); + if (downloadOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(downloadOptions.Timeout.GetValue()))); + } + request.AddHeader(Details::c_HeaderVersion, downloadOptions.ApiVersionParameter); + if (downloadOptions.Range.HasValue()) + { + request.AddHeader(Details::c_HeaderRange, downloadOptions.Range.GetValue()); + } + if (downloadOptions.GetRangeContentMd5.HasValue()) + { + request.AddHeader( + Details::c_HeaderRangeGetContentMd5, + (downloadOptions.GetRangeContentMd5.GetValue() ? "true" : "false")); + } + if (downloadOptions.LeaseIdOptional.HasValue()) + { + request.AddHeader(Details::c_HeaderLeaseId, downloadOptions.LeaseIdOptional.GetValue()); + } + return DownloadParseResult(context, pipeline.Send(context, request)); + } + + struct GetPropertiesOptions + { + Azure::Core::Nullable + ShareSnapshot; // The snapshot parameter is an opaque DateTime value that, when + // present, specifies the share snapshot to query. + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease + // is active and matches this ID. + }; + + static Azure::Core::Response GetProperties( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const GetPropertiesOptions& getPropertiesOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Head, url); + if (getPropertiesOptions.ShareSnapshot.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryShareSnapshot, + Storage::Details::UrlEncodeQueryParameter( + getPropertiesOptions.ShareSnapshot.GetValue())); + } + if (getPropertiesOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(getPropertiesOptions.Timeout.GetValue()))); + } + request.AddHeader(Details::c_HeaderVersion, getPropertiesOptions.ApiVersionParameter); + if (getPropertiesOptions.LeaseIdOptional.HasValue()) + { + request.AddHeader( + Details::c_HeaderLeaseId, getPropertiesOptions.LeaseIdOptional.GetValue()); + } + return GetPropertiesParseResult(context, pipeline.Send(context, request)); + } + + struct DeleteOptions + { + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease + // is active and matches this ID. + }; + + static Azure::Core::Response Delete( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const DeleteOptions& deleteOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Delete, url); + if (deleteOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(deleteOptions.Timeout.GetValue()))); + } + request.AddHeader(Details::c_HeaderVersion, deleteOptions.ApiVersionParameter); + if (deleteOptions.LeaseIdOptional.HasValue()) + { + request.AddHeader(Details::c_HeaderLeaseId, deleteOptions.LeaseIdOptional.GetValue()); + } + return DeleteParseResult(context, pipeline.Send(context, request)); + } + + struct SetHttpHeadersOptions + { + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + XMsContentLength; // Resizes a file to the specified size. If the specified byte value + // is less than the current size of the file, then all ranges above + // the specified byte value are cleared. + Azure::Core::Nullable + FileContentType; // Sets the MIME content type of the file. The default type is + // 'application/octet-stream'. + Azure::Core::Nullable + FileContentEncoding; // Specifies which content encodings have been applied to the + // file. + Azure::Core::Nullable + FileContentLanguage; // Specifies the natural languages used by this resource. + Azure::Core::Nullable + FileCacheControl; // Sets the file's cache control. The File service stores this value + // but does not use or modify it. + Azure::Core::Nullable FileContentMd5; // Sets the file's MD5 hash. + Azure::Core::Nullable + FileContentDisposition; // Sets the file's Content-Disposition header. + Azure::Core::Nullable + FilePermission; // If specified the permission (security descriptor) shall be set for + // the directory/file. This header can be used if Permission size is + // <= 8KB, else x-ms-file-permission-key header shall be used. Default + // value: Inherit. If SDDL is specified as input, it must have owner, + // group and dacl. Note: Only one of the x-ms-file-permission or + // x-ms-file-permission-key should be specified. + Azure::Core::Nullable + FilePermissionKey; // Key of the permission to be set for the directory/file. Note: + // Only one of the x-ms-file-permission or x-ms-file-permission-key + // should be specified. + std::string FileAttributes; // If specified, the provided file attributes shall be set. + // Default value: Archive for file and Directory for + // directory. None can also be specified as default. + std::string FileCreationTime; // Creation time for the file/directory. Default value: Now. + std::string + FileLastWriteTime; // Last write time for the file/directory. Default value: Now. + Azure::Core::Nullable + LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease + // is active and matches this ID. + }; + + static Azure::Core::Response SetHttpHeaders( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const SetHttpHeadersOptions& setHttpHeadersOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); + request.AddHeader(Details::c_HeaderContentLength, "0"); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "properties"); + if (setHttpHeadersOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(setHttpHeadersOptions.Timeout.GetValue()))); + } + request.AddHeader(Details::c_HeaderVersion, setHttpHeadersOptions.ApiVersionParameter); + if (setHttpHeadersOptions.XMsContentLength.HasValue()) + { + request.AddHeader( + Details::c_HeaderXMsContentLength, + std::to_string(setHttpHeadersOptions.XMsContentLength.GetValue())); + } + if (setHttpHeadersOptions.FileContentType.HasValue()) + { + request.AddHeader( + Details::c_HeaderFileContentType, setHttpHeadersOptions.FileContentType.GetValue()); + } + if (setHttpHeadersOptions.FileContentEncoding.HasValue()) + { + request.AddHeader( + Details::c_HeaderFileContentEncoding, + setHttpHeadersOptions.FileContentEncoding.GetValue()); + } + if (setHttpHeadersOptions.FileContentLanguage.HasValue()) + { + request.AddHeader( + Details::c_HeaderFileContentLanguage, + setHttpHeadersOptions.FileContentLanguage.GetValue()); + } + if (setHttpHeadersOptions.FileCacheControl.HasValue()) + { + request.AddHeader( + Details::c_HeaderFileCacheControl, + setHttpHeadersOptions.FileCacheControl.GetValue()); + } + if (setHttpHeadersOptions.FileContentMd5.HasValue()) + { + request.AddHeader( + Details::c_HeaderContentMd5, setHttpHeadersOptions.FileContentMd5.GetValue()); + } + if (setHttpHeadersOptions.FileContentDisposition.HasValue()) + { + request.AddHeader( + Details::c_HeaderFileContentDisposition, + setHttpHeadersOptions.FileContentDisposition.GetValue()); + } + if (setHttpHeadersOptions.FilePermission.HasValue()) + { + request.AddHeader( + Details::c_HeaderFilePermission, setHttpHeadersOptions.FilePermission.GetValue()); + } + if (setHttpHeadersOptions.FilePermissionKey.HasValue()) + { + request.AddHeader( + Details::c_HeaderFilePermissionKey, + setHttpHeadersOptions.FilePermissionKey.GetValue()); + } + request.AddHeader(Details::c_HeaderFileAttributes, setHttpHeadersOptions.FileAttributes); + request.AddHeader( + Details::c_HeaderFileCreationTime, setHttpHeadersOptions.FileCreationTime); + request.AddHeader( + Details::c_HeaderFileLastWriteTime, setHttpHeadersOptions.FileLastWriteTime); + if (setHttpHeadersOptions.LeaseIdOptional.HasValue()) + { + request.AddHeader( + Details::c_HeaderLeaseId, setHttpHeadersOptions.LeaseIdOptional.GetValue()); + } + return SetHttpHeadersParseResult(context, pipeline.Send(context, request)); + } + + struct SetMetadataOptions + { + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::map + Metadata; // A name-value pair to associate with a file storage object. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease + // is active and matches this ID. + }; + + static Azure::Core::Response SetMetadata( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const SetMetadataOptions& setMetadataOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); + request.AddHeader(Details::c_HeaderContentLength, "0"); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "metadata"); + if (setMetadataOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(setMetadataOptions.Timeout.GetValue()))); + } + std::set metadataKeys; + for (const auto& pair : setMetadataOptions.Metadata) + { + std::string key = pair.first; + std::transform(key.begin(), key.end(), key.begin(), [](unsigned char c) { + return static_cast(std::tolower(c)); + }); + if (metadataKeys.insert(key).second == false) + { + throw std::runtime_error("duplicate keys in metadata"); + } + request.AddHeader(Details::c_HeaderMetadata + ("-" + pair.first), pair.second); + } + metadataKeys.clear(); + request.AddHeader(Details::c_HeaderVersion, setMetadataOptions.ApiVersionParameter); + if (setMetadataOptions.LeaseIdOptional.HasValue()) + { + request.AddHeader( + Details::c_HeaderLeaseId, setMetadataOptions.LeaseIdOptional.GetValue()); + } + return SetMetadataParseResult(context, pipeline.Send(context, request)); + } + + struct AcquireLeaseOptions + { + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + int32_t LeaseDuration + = int32_t(); // Specifies the duration of the lease, in seconds, or negative one (-1) + // for a lease that never expires. A non-infinite lease can be between 15 + // and 60 seconds. A lease duration cannot be changed using renew or + // change. + Azure::Core::Nullable + ProposedLeaseIdOptional; // Proposed lease ID, in a GUID string format. The File + // service returns 400 (Invalid request) if the proposed + // lease ID is not in the correct format. See Guid + // Constructor (String) for a list of valid GUID string + // formats. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character + // limit that is recorded in the analytics logs when storage + // analytics logging is enabled. + }; + + static Azure::Core::Response AcquireLease( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const AcquireLeaseOptions& acquireLeaseOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); + request.AddHeader(Details::c_HeaderContentLength, "0"); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "lease"); + request.AddHeader(Details::c_HeaderAction, "acquire"); + if (acquireLeaseOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(acquireLeaseOptions.Timeout.GetValue()))); + } + request.AddHeader( + Details::c_HeaderDuration, std::to_string(acquireLeaseOptions.LeaseDuration)); + if (acquireLeaseOptions.ProposedLeaseIdOptional.HasValue()) + { + request.AddHeader( + Details::c_HeaderProposedLeaseId, + acquireLeaseOptions.ProposedLeaseIdOptional.GetValue()); + } + request.AddHeader(Details::c_HeaderVersion, acquireLeaseOptions.ApiVersionParameter); + if (acquireLeaseOptions.ClientRequestId.HasValue()) + { + request.AddHeader( + Details::c_HeaderRequestId, acquireLeaseOptions.ClientRequestId.GetValue()); + } + return AcquireLeaseParseResult(context, pipeline.Send(context, request)); + } + + struct ReleaseLeaseOptions + { + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::string LeaseIdRequired; // Specifies the current lease ID on the resource. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character + // limit that is recorded in the analytics logs when storage + // analytics logging is enabled. + }; + + static Azure::Core::Response ReleaseLease( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const ReleaseLeaseOptions& releaseLeaseOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); + request.AddHeader(Details::c_HeaderContentLength, "0"); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "lease"); + request.AddHeader(Details::c_HeaderAction, "release"); + if (releaseLeaseOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(releaseLeaseOptions.Timeout.GetValue()))); + } + request.AddHeader(Details::c_HeaderLeaseId, releaseLeaseOptions.LeaseIdRequired); + request.AddHeader(Details::c_HeaderVersion, releaseLeaseOptions.ApiVersionParameter); + if (releaseLeaseOptions.ClientRequestId.HasValue()) + { + request.AddHeader( + Details::c_HeaderRequestId, releaseLeaseOptions.ClientRequestId.GetValue()); + } + return ReleaseLeaseParseResult(context, pipeline.Send(context, request)); + } + + struct ChangeLeaseOptions + { + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::string LeaseIdRequired; // Specifies the current lease ID on the resource. + Azure::Core::Nullable + ProposedLeaseIdOptional; // Proposed lease ID, in a GUID string format. The File + // service returns 400 (Invalid request) if the proposed + // lease ID is not in the correct format. See Guid + // Constructor (String) for a list of valid GUID string + // formats. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character + // limit that is recorded in the analytics logs when storage + // analytics logging is enabled. + }; + + static Azure::Core::Response ChangeLease( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const ChangeLeaseOptions& changeLeaseOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); + request.AddHeader(Details::c_HeaderContentLength, "0"); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "lease"); + request.AddHeader(Details::c_HeaderAction, "change"); + if (changeLeaseOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(changeLeaseOptions.Timeout.GetValue()))); + } + request.AddHeader(Details::c_HeaderLeaseId, changeLeaseOptions.LeaseIdRequired); + if (changeLeaseOptions.ProposedLeaseIdOptional.HasValue()) + { + request.AddHeader( + Details::c_HeaderProposedLeaseId, + changeLeaseOptions.ProposedLeaseIdOptional.GetValue()); + } + request.AddHeader(Details::c_HeaderVersion, changeLeaseOptions.ApiVersionParameter); + if (changeLeaseOptions.ClientRequestId.HasValue()) + { + request.AddHeader( + Details::c_HeaderRequestId, changeLeaseOptions.ClientRequestId.GetValue()); + } + return ChangeLeaseParseResult(context, pipeline.Send(context, request)); + } + + struct BreakLeaseOptions + { + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + Azure::Core::Nullable + LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease + // is active and matches this ID. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + ClientRequestId; // Provides a client-generated, opaque value with a 1 KB character + // limit that is recorded in the analytics logs when storage + // analytics logging is enabled. + }; + + static Azure::Core::Response BreakLease( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const BreakLeaseOptions& breakLeaseOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); + request.AddHeader(Details::c_HeaderContentLength, "0"); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "lease"); + request.AddHeader(Details::c_HeaderAction, "break"); + if (breakLeaseOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(breakLeaseOptions.Timeout.GetValue()))); + } + if (breakLeaseOptions.LeaseIdOptional.HasValue()) + { + request.AddHeader( + Details::c_HeaderLeaseId, breakLeaseOptions.LeaseIdOptional.GetValue()); + } + request.AddHeader(Details::c_HeaderVersion, breakLeaseOptions.ApiVersionParameter); + if (breakLeaseOptions.ClientRequestId.HasValue()) + { + request.AddHeader( + Details::c_HeaderRequestId, breakLeaseOptions.ClientRequestId.GetValue()); + } + return BreakLeaseParseResult(context, pipeline.Send(context, request)); + } + + struct UploadRangeOptions + { + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::string + XMsRange; // Specifies the range of bytes to be written. Both the start and end of the + // range must be specified. For an update operation, the range can be up to + // 4 MB in size. For a clear operation, the range can be up to the value of + // the file's full size. The File service accepts only a single byte range + // for the Range and 'x-ms-range' headers, and the byte range must be + // specified in the following format: bytes=startByte-endByte. + FileRangeWriteType + XMsWrite; // Specify one of the following options: - Update: Writes the bytes + // specified by the request body into the specified range. The Range and + // Content-Length headers must match to perform the update. - Clear: Clears + // the specified range and releases the space used in storage for that + // range. To clear a range, set the Content-Length header to zero, and set + // the Range header to a value that indicates the range to clear, up to + // maximum file size. + int64_t ContentLength + = int64_t(); // Specifies the number of bytes being transmitted in the request body. + // When the x-ms-write header is set to clear, the value of this header + // must be set to zero. + Azure::Core::Nullable + ContentMd5; // An MD5 hash of the content. This hash is used to verify the integrity + // of the data during transport. When the Content-MD5 header is specified, + // the File service compares the hash of the content that has arrived with + // the header value that was sent. If the two hashes do not match, the + // operation will fail with error code 400 (Bad Request). + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease + // is active and matches this ID. + }; + + static Azure::Core::Response UploadRange( + const Azure::Core::Http::Url& url, + Azure::Core::Http::BodyStream& bodyStream, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const UploadRangeOptions& uploadRangeOptions) + { + Azure::Core::Http::Request request( + Azure::Core::Http::HttpMethod::Put, std::move(url), &bodyStream); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "range"); + if (uploadRangeOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(uploadRangeOptions.Timeout.GetValue()))); + } + request.AddHeader(Details::c_HeaderXMsRange, uploadRangeOptions.XMsRange); + request.AddHeader( + Details::c_HeaderFileRangeWrite, + FileRangeWriteTypeToString(uploadRangeOptions.XMsWrite)); + request.AddHeader( + Details::c_HeaderContentLength, std::to_string(uploadRangeOptions.ContentLength)); + if (uploadRangeOptions.ContentMd5.HasValue()) + { + request.AddHeader( + Details::c_HeaderContentMd5, uploadRangeOptions.ContentMd5.GetValue()); + } + request.AddHeader(Details::c_HeaderVersion, uploadRangeOptions.ApiVersionParameter); + if (uploadRangeOptions.LeaseIdOptional.HasValue()) + { + request.AddHeader( + Details::c_HeaderLeaseId, uploadRangeOptions.LeaseIdOptional.GetValue()); + } + return UploadRangeParseResult(context, pipeline.Send(context, request)); + } + + struct UploadRangeFromUrlOptions + { + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::string TargetRange; // Writes data to the specified byte range in the file. + std::string + CopySource; // Specifies the URL of the source file or blob, up to 2 KB in length. To + // copy a file to another file within the same storage account, you may + // use Shared Key to authenticate the source file. If you are copying a + // file from another storage account, or if you are copying a blob from + // the same storage account or another storage account, then you must + // authenticate the source file or blob using a shared access signature. + // If the source is a public blob, no authentication is required to + // perform the copy operation. A file in a share snapshot can also be + // specified as a copy source. + Azure::Core::Nullable + SourceRange; // Bytes of source data in the specified range. + FileRangeWriteFromUrlType + XMsWrite; // Only update is supported: - Update: Writes the bytes downloaded from the + // source url into the specified range. + int64_t ContentLength + = int64_t(); // Specifies the number of bytes being transmitted in the request body. + // When the x-ms-write header is set to clear, the value of this header + // must be set to zero. + Azure::Core::Nullable + SourceContentCrc64; // Specify the crc64 calculated for the range of bytes that must + // be read from the copy source. + Azure::Core::Nullable + SourceIfMatchCrc64; // Specify the crc64 value to operate only on range with a + // matching crc64 checksum. + Azure::Core::Nullable + SourceIfNoneMatchCrc64; // Specify the crc64 value to operate only on range without a + // matching crc64 checksum. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease + // is active and matches this ID. + }; + + static Azure::Core::Response UploadRangeFromUrl( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const UploadRangeFromUrlOptions& uploadRangeFromUrlOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); + request.AddHeader(Details::c_HeaderContentLength, "0"); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "range"); + if (uploadRangeFromUrlOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(uploadRangeFromUrlOptions.Timeout.GetValue()))); + } + request.AddHeader(Details::c_HeaderRange, uploadRangeFromUrlOptions.TargetRange); + request.AddHeader(Details::c_HeaderCopySource, uploadRangeFromUrlOptions.CopySource); + if (uploadRangeFromUrlOptions.SourceRange.HasValue()) + { + request.AddHeader( + Details::c_HeaderSourceRange, uploadRangeFromUrlOptions.SourceRange.GetValue()); + } + request.AddHeader( + Details::c_HeaderFileRangeWriteFromUrl, + FileRangeWriteFromUrlTypeToString(uploadRangeFromUrlOptions.XMsWrite)); + request.AddHeader( + Details::c_HeaderContentLength, + std::to_string(uploadRangeFromUrlOptions.ContentLength)); + if (uploadRangeFromUrlOptions.SourceContentCrc64.HasValue()) + { + request.AddHeader( + Details::c_HeaderSourceContentCrc64, + uploadRangeFromUrlOptions.SourceContentCrc64.GetValue()); + } + if (uploadRangeFromUrlOptions.SourceIfMatchCrc64.HasValue()) + { + request.AddHeader( + Details::c_HeaderSourceIfMatchCrc64, + uploadRangeFromUrlOptions.SourceIfMatchCrc64.GetValue()); + } + if (uploadRangeFromUrlOptions.SourceIfNoneMatchCrc64.HasValue()) + { + request.AddHeader( + Details::c_HeaderSourceIfNoneMatchCrc64, + uploadRangeFromUrlOptions.SourceIfNoneMatchCrc64.GetValue()); + } + request.AddHeader( + Details::c_HeaderVersion, uploadRangeFromUrlOptions.ApiVersionParameter); + if (uploadRangeFromUrlOptions.LeaseIdOptional.HasValue()) + { + request.AddHeader( + Details::c_HeaderLeaseId, uploadRangeFromUrlOptions.LeaseIdOptional.GetValue()); + } + return UploadRangeFromUrlParseResult(context, pipeline.Send(context, request)); + } + + struct GetRangeListOptions + { + Azure::Core::Nullable + ShareSnapshot; // The snapshot parameter is an opaque DateTime value that, when + // present, specifies the share snapshot to query. + Azure::Core::Nullable + PrevShareSnapshot; // The previous snapshot parameter is an opaque DateTime value + // that, when present, specifies the previous snapshot. + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + XMsRange; // Specifies the range of bytes over which to list ranges, inclusively. + Azure::Core::Nullable + LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease + // is active and matches this ID. + }; + + static Azure::Core::Response GetRangeList( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const GetRangeListOptions& getRangeListOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Get, url); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "rangelist"); + if (getRangeListOptions.ShareSnapshot.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryShareSnapshot, + Storage::Details::UrlEncodeQueryParameter( + getRangeListOptions.ShareSnapshot.GetValue())); + } + if (getRangeListOptions.PrevShareSnapshot.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryPrevShareSnapshot, + Storage::Details::UrlEncodeQueryParameter( + getRangeListOptions.PrevShareSnapshot.GetValue())); + } + if (getRangeListOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(getRangeListOptions.Timeout.GetValue()))); + } + request.AddHeader(Details::c_HeaderVersion, getRangeListOptions.ApiVersionParameter); + if (getRangeListOptions.XMsRange.HasValue()) + { + request.AddHeader(Details::c_HeaderXMsRange, getRangeListOptions.XMsRange.GetValue()); + } + if (getRangeListOptions.LeaseIdOptional.HasValue()) + { + request.AddHeader( + Details::c_HeaderLeaseId, getRangeListOptions.LeaseIdOptional.GetValue()); + } + return GetRangeListParseResult(context, pipeline.Send(context, request)); + } + + struct StartCopyOptions + { + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + std::map + Metadata; // A name-value pair to associate with a file storage object. + std::string + CopySource; // Specifies the URL of the source file or blob, up to 2 KB in length. To + // copy a file to another file within the same storage account, you may + // use Shared Key to authenticate the source file. If you are copying a + // file from another storage account, or if you are copying a blob from + // the same storage account or another storage account, then you must + // authenticate the source file or blob using a shared access signature. + // If the source is a public blob, no authentication is required to + // perform the copy operation. A file in a share snapshot can also be + // specified as a copy source. + Azure::Core::Nullable + FilePermission; // If specified the permission (security descriptor) shall be set for + // the directory/file. This header can be used if Permission size is + // <= 8KB, else x-ms-file-permission-key header shall be used. Default + // value: Inherit. If SDDL is specified as input, it must have owner, + // group and dacl. Note: Only one of the x-ms-file-permission or + // x-ms-file-permission-key should be specified. + Azure::Core::Nullable + FilePermissionKey; // Key of the permission to be set for the directory/file. Note: + // Only one of the x-ms-file-permission or x-ms-file-permission-key + // should be specified. + Azure::Core::Nullable + XMsFilePermissionCopyMode; // Specifies the option to copy file security descriptor + // from source file or to set it using the value which is + // defined by the header value of x-ms-file-permission or + // x-ms-file-permission-key. + Azure::Core::Nullable + FileCopyIgnoreReadOnly; // Specifies the option to overwrite the target file if it + // already exists and has read-only attribute set. + Azure::Core::Nullable + FileCopyFileAttributes; // Specifies either the option to copy file attributes from a + // source file(source) to a target file or a list of + // attributes to set on a target file. + Azure::Core::Nullable + FileCopyFileCreationTime; // Specifies either the option to copy file creation time + // from a source file(source) to a target file or a time + // value in ISO 8601 format to set as creation time on a + // target file. + Azure::Core::Nullable + FileCopyFileLastWriteTime; // Specifies either the option to copy file last write time + // from a source file(source) to a target file or a time + // value in ISO 8601 format to set as last write time on a + // target file. + Azure::Core::Nullable + FileCopySetArchiveAttribute; // Specifies the option to set archive attribute on a + // target file. True means archive attribute will be set + // on a target file despite attribute overrides or a + // source file state. + Azure::Core::Nullable + LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease + // is active and matches this ID. + }; + + static Azure::Core::Response StartCopy( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const StartCopyOptions& startCopyOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); + request.AddHeader(Details::c_HeaderContentLength, "0"); + if (startCopyOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(startCopyOptions.Timeout.GetValue()))); + } + request.AddHeader(Details::c_HeaderVersion, startCopyOptions.ApiVersionParameter); + std::set metadataKeys; + for (const auto& pair : startCopyOptions.Metadata) + { + std::string key = pair.first; + std::transform(key.begin(), key.end(), key.begin(), [](unsigned char c) { + return static_cast(std::tolower(c)); + }); + if (metadataKeys.insert(key).second == false) + { + throw std::runtime_error("duplicate keys in metadata"); + } + request.AddHeader(Details::c_HeaderMetadata + ("-" + pair.first), pair.second); + } + metadataKeys.clear(); + request.AddHeader(Details::c_HeaderCopySource, startCopyOptions.CopySource); + if (startCopyOptions.FilePermission.HasValue()) + { + request.AddHeader( + Details::c_HeaderFilePermission, startCopyOptions.FilePermission.GetValue()); + } + if (startCopyOptions.FilePermissionKey.HasValue()) + { + request.AddHeader( + Details::c_HeaderFilePermissionKey, startCopyOptions.FilePermissionKey.GetValue()); + } + if (startCopyOptions.XMsFilePermissionCopyMode.HasValue()) + { + request.AddHeader( + Details::c_HeaderFilePermissionCopyMode, + PermissionCopyModeTypeToString( + startCopyOptions.XMsFilePermissionCopyMode.GetValue())); + } + if (startCopyOptions.FileCopyIgnoreReadOnly.HasValue()) + { + request.AddHeader( + Details::c_HeaderIgnoreReadOnly, + (startCopyOptions.FileCopyIgnoreReadOnly.GetValue() ? "true" : "false")); + } + if (startCopyOptions.FileCopyFileAttributes.HasValue()) + { + request.AddHeader( + Details::c_HeaderFileAttributes, + startCopyOptions.FileCopyFileAttributes.GetValue()); + } + if (startCopyOptions.FileCopyFileCreationTime.HasValue()) + { + request.AddHeader( + Details::c_HeaderFileCreationTime, + startCopyOptions.FileCopyFileCreationTime.GetValue()); + } + if (startCopyOptions.FileCopyFileLastWriteTime.HasValue()) + { + request.AddHeader( + Details::c_HeaderFileLastWriteTime, + startCopyOptions.FileCopyFileLastWriteTime.GetValue()); + } + if (startCopyOptions.FileCopySetArchiveAttribute.HasValue()) + { + request.AddHeader( + Details::c_HeaderSetArchiveAttribute, + (startCopyOptions.FileCopySetArchiveAttribute.GetValue() ? "true" : "false")); + } + if (startCopyOptions.LeaseIdOptional.HasValue()) + { + request.AddHeader( + Details::c_HeaderLeaseId, startCopyOptions.LeaseIdOptional.GetValue()); + } + return StartCopyParseResult(context, pipeline.Send(context, request)); + } + + struct AbortCopyOptions + { + std::string CopyId; // The copy identifier provided in the x-ms-copy-id header of the + // original Copy File operation. + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + Azure::Core::Nullable + LeaseIdOptional; // If specified, the operation only succeeds if the resource's lease + // is active and matches this ID. + }; + + static Azure::Core::Response AbortCopy( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const AbortCopyOptions& abortCopyOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); + request.AddHeader(Details::c_HeaderContentLength, "0"); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "copy"); + request.GetUrl().AppendQueryParameter( + Details::c_QueryCopyId, + Storage::Details::UrlEncodeQueryParameter(abortCopyOptions.CopyId)); + if (abortCopyOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(abortCopyOptions.Timeout.GetValue()))); + } + request.AddHeader(Details::c_HeaderCopyActionAbortConstant, "abort"); + request.AddHeader(Details::c_HeaderVersion, abortCopyOptions.ApiVersionParameter); + if (abortCopyOptions.LeaseIdOptional.HasValue()) + { + request.AddHeader( + Details::c_HeaderLeaseId, abortCopyOptions.LeaseIdOptional.GetValue()); + } + return AbortCopyParseResult(context, pipeline.Send(context, request)); + } + + struct ListHandlesOptions + { + Azure::Core::Nullable + ContinuationToken; // A string value that identifies the portion of the list to be + // returned with the next list operation. The operation returns a + // marker value within the response body if the list returned was + // not complete. The marker value may then be used in a subsequent + // call to request the next set of list items. The marker value is + // opaque to the client. + Azure::Core::Nullable + MaxResults; // Specifies the maximum number of entries to return. If the request does + // not specify maxresults, or specifies a value greater than 5,000, the + // server will return up to 5,000 items. + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + Azure::Core::Nullable + ShareSnapshot; // The snapshot parameter is an opaque DateTime value that, when + // present, specifies the share snapshot to query. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + }; + + static Azure::Core::Response ListHandles( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const ListHandlesOptions& listHandlesOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Get, url); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "listhandles"); + if (listHandlesOptions.ContinuationToken.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryContinuationToken, + Storage::Details::UrlEncodeQueryParameter( + listHandlesOptions.ContinuationToken.GetValue())); + } + if (listHandlesOptions.MaxResults.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryMaxResults, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(listHandlesOptions.MaxResults.GetValue()))); + } + if (listHandlesOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(listHandlesOptions.Timeout.GetValue()))); + } + if (listHandlesOptions.ShareSnapshot.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryShareSnapshot, + Storage::Details::UrlEncodeQueryParameter( + listHandlesOptions.ShareSnapshot.GetValue())); + } + request.AddHeader(Details::c_HeaderVersion, listHandlesOptions.ApiVersionParameter); + return ListHandlesParseResult(context, pipeline.Send(context, request)); + } + + struct ForceCloseHandlesOptions + { + Azure::Core::Nullable + Timeout; // The timeout parameter is expressed in seconds. + // For more information, see Setting + // Timeouts for File Service Operations. + Azure::Core::Nullable + ContinuationToken; // A string value that identifies the portion of the list to be + // returned with the next list operation. The operation returns a + // marker value within the response body if the list returned was + // not complete. The marker value may then be used in a subsequent + // call to request the next set of list items. The marker value is + // opaque to the client. + Azure::Core::Nullable + ShareSnapshot; // The snapshot parameter is an opaque DateTime value that, when + // present, specifies the share snapshot to query. + std::string HandleId; // Specifies handle ID opened on the file or directory to be closed. + // Asterisk (*) is a wildcard that specifies all handles. + std::string ApiVersionParameter + = Details::c_DefaultServiceApiVersion; // Specifies the version of the operation to + // use for this request. + }; + + static Azure::Core::Response ForceCloseHandles( + const Azure::Core::Http::Url& url, + Azure::Core::Http::HttpPipeline& pipeline, + Azure::Core::Context context, + const ForceCloseHandlesOptions& forceCloseHandlesOptions) + { + Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url); + request.AddHeader(Details::c_HeaderContentLength, "0"); + request.GetUrl().AppendQueryParameter(Details::c_QueryComp, "forceclosehandles"); + if (forceCloseHandlesOptions.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryTimeout, + Storage::Details::UrlEncodeQueryParameter( + std::to_string(forceCloseHandlesOptions.Timeout.GetValue()))); + } + if (forceCloseHandlesOptions.ContinuationToken.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryContinuationToken, + Storage::Details::UrlEncodeQueryParameter( + forceCloseHandlesOptions.ContinuationToken.GetValue())); + } + if (forceCloseHandlesOptions.ShareSnapshot.HasValue()) + { + request.GetUrl().AppendQueryParameter( + Details::c_QueryShareSnapshot, + Storage::Details::UrlEncodeQueryParameter( + forceCloseHandlesOptions.ShareSnapshot.GetValue())); + } + request.AddHeader(Details::c_HeaderHandleId, forceCloseHandlesOptions.HandleId); + request.AddHeader(Details::c_HeaderVersion, forceCloseHandlesOptions.ApiVersionParameter); + return ForceCloseHandlesParseResult(context, pipeline.Send(context, request)); + } + + private: + static Azure::Core::Response CreateParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Created) + { + // Success, File created. + FileCreateResult result; + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + result.IsServerEncrypted + = response.GetHeaders().at(Details::c_HeaderRequestIsServerEncrypted) == "true"; + result.FilePermissionKey = response.GetHeaders().at(Details::c_HeaderFilePermissionKey); + result.FileAttributes = response.GetHeaders().at(Details::c_HeaderFileAttributes); + result.FileCreationTime = response.GetHeaders().at(Details::c_HeaderFileCreationTime); + result.FileLastWriteTime = response.GetHeaders().at(Details::c_HeaderFileLastWriteTime); + result.FileChangeTime = response.GetHeaders().at(Details::c_HeaderFileChangeTime); + result.FileId = response.GetHeaders().at(Details::c_HeaderFileId); + result.FileParentId = response.GetHeaders().at(Details::c_HeaderFileParentId); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Core::Response DownloadParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + { + // Succeeded to read the entire file. + FileDownloadResult result; + result.BodyStream = response.GetBodyStream(); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + + for (auto i = response.GetHeaders().lower_bound(Details::c_HeaderMetadata); + i != response.GetHeaders().end() + && i->first.substr(0, 9) == Details::c_HeaderMetadata; + ++i) + { + result.Metadata.emplace(i->first.substr(10), i->second); + } + result.ContentLength + = std::stoll(response.GetHeaders().at(Details::c_HeaderContentLength)); + result.HttpHeaders.ContentType = response.GetHeaders().at(Details::c_HeaderContentType); + if (response.GetHeaders().find(Details::c_HeaderContentRange) + != response.GetHeaders().end()) + { + result.ContentRange = response.GetHeaders().at(Details::c_HeaderContentRange); + } + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + if (response.GetHeaders().find(Details::c_HeaderTransactionalContentMd5) + != response.GetHeaders().end()) + { + result.TransactionalContentMd5 + = response.GetHeaders().at(Details::c_HeaderTransactionalContentMd5); + } + if (response.GetHeaders().find(Details::c_HeaderContentEncoding) + != response.GetHeaders().end()) + { + result.HttpHeaders.ContentEncoding + = response.GetHeaders().at(Details::c_HeaderContentEncoding); + } + if (response.GetHeaders().find(Details::c_HeaderCacheControl) + != response.GetHeaders().end()) + { + result.HttpHeaders.CacheControl + = response.GetHeaders().at(Details::c_HeaderCacheControl); + } + if (response.GetHeaders().find(Details::c_HeaderContentDisposition) + != response.GetHeaders().end()) + { + result.HttpHeaders.ContentDisposition + = response.GetHeaders().at(Details::c_HeaderContentDisposition); + } + if (response.GetHeaders().find(Details::c_HeaderContentLanguage) + != response.GetHeaders().end()) + { + result.HttpHeaders.ContentLanguage + = response.GetHeaders().at(Details::c_HeaderContentLanguage); + } + result.AcceptRanges = response.GetHeaders().at(Details::c_HeaderAcceptRanges); + if (response.GetHeaders().find(Details::c_HeaderCopyCompletionTime) + != response.GetHeaders().end()) + { + result.CopyCompletionTime + = response.GetHeaders().at(Details::c_HeaderCopyCompletionTime); + } + if (response.GetHeaders().find(Details::c_HeaderCopyStatusDescription) + != response.GetHeaders().end()) + { + result.CopyStatusDescription + = response.GetHeaders().at(Details::c_HeaderCopyStatusDescription); + } + if (response.GetHeaders().find(Details::c_HeaderCopyId) != response.GetHeaders().end()) + { + result.CopyId = response.GetHeaders().at(Details::c_HeaderCopyId); + } + if (response.GetHeaders().find(Details::c_HeaderCopyProgress) + != response.GetHeaders().end()) + { + result.CopyProgress = response.GetHeaders().at(Details::c_HeaderCopyProgress); + } + if (response.GetHeaders().find(Details::c_HeaderCopySource) + != response.GetHeaders().end()) + { + result.CopySource = response.GetHeaders().at(Details::c_HeaderCopySource); + } + if (response.GetHeaders().find(Details::c_HeaderCopyStatus) + != response.GetHeaders().end()) + { + result.CopyStatus + = CopyStatusTypeFromString(response.GetHeaders().at(Details::c_HeaderCopyStatus)); + } + if (response.GetHeaders().find(Details::c_HeaderContentMd5) + != response.GetHeaders().end()) + { + result.HttpHeaders.ContentMd5 = response.GetHeaders().at(Details::c_HeaderContentMd5); + } + if (response.GetHeaders().find(Details::c_HeaderIsServerEncrypted) + != response.GetHeaders().end()) + { + result.IsServerEncrypted + = response.GetHeaders().at(Details::c_HeaderIsServerEncrypted) == "true"; + } + result.FileAttributes = response.GetHeaders().at(Details::c_HeaderFileAttributes); + result.FileCreationTime = response.GetHeaders().at(Details::c_HeaderFileCreationTime); + result.FileLastWriteTime = response.GetHeaders().at(Details::c_HeaderFileLastWriteTime); + result.FileChangeTime = response.GetHeaders().at(Details::c_HeaderFileChangeTime); + result.FilePermissionKey = response.GetHeaders().at(Details::c_HeaderFilePermissionKey); + result.FileId = response.GetHeaders().at(Details::c_HeaderFileId); + result.FileParentId = response.GetHeaders().at(Details::c_HeaderFileParentId); + if (response.GetHeaders().find(Details::c_HeaderLeaseDuration) + != response.GetHeaders().end()) + { + result.LeaseDuration = LeaseDurationTypeFromString( + response.GetHeaders().at(Details::c_HeaderLeaseDuration)); + } + if (response.GetHeaders().find(Details::c_HeaderLeaseState) + != response.GetHeaders().end()) + { + result.LeaseState + = LeaseStateTypeFromString(response.GetHeaders().at(Details::c_HeaderLeaseState)); + } + if (response.GetHeaders().find(Details::c_HeaderLeaseStatus) + != response.GetHeaders().end()) + { + result.LeaseStatus = LeaseStatusTypeFromString( + response.GetHeaders().at(Details::c_HeaderLeaseStatus)); + } + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::PartialContent) + { + // Succeeded to read a specified range of the file. + FileDownloadResult result; + result.BodyStream = response.GetBodyStream(); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + + for (auto i = response.GetHeaders().lower_bound(Details::c_HeaderMetadata); + i != response.GetHeaders().end() + && i->first.substr(0, 9) == Details::c_HeaderMetadata; + ++i) + { + result.Metadata.emplace(i->first.substr(10), i->second); + } + result.ContentLength + = std::stoll(response.GetHeaders().at(Details::c_HeaderContentLength)); + result.HttpHeaders.ContentType = response.GetHeaders().at(Details::c_HeaderContentType); + if (response.GetHeaders().find(Details::c_HeaderContentRange) + != response.GetHeaders().end()) + { + result.ContentRange = response.GetHeaders().at(Details::c_HeaderContentRange); + } + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + if (response.GetHeaders().find(Details::c_HeaderTransactionalContentMd5) + != response.GetHeaders().end()) + { + result.TransactionalContentMd5 + = response.GetHeaders().at(Details::c_HeaderTransactionalContentMd5); + } + if (response.GetHeaders().find(Details::c_HeaderContentEncoding) + != response.GetHeaders().end()) + { + result.HttpHeaders.ContentEncoding + = response.GetHeaders().at(Details::c_HeaderContentEncoding); + } + if (response.GetHeaders().find(Details::c_HeaderCacheControl) + != response.GetHeaders().end()) + { + result.HttpHeaders.CacheControl + = response.GetHeaders().at(Details::c_HeaderCacheControl); + } + if (response.GetHeaders().find(Details::c_HeaderContentDisposition) + != response.GetHeaders().end()) + { + result.HttpHeaders.ContentDisposition + = response.GetHeaders().at(Details::c_HeaderContentDisposition); + } + if (response.GetHeaders().find(Details::c_HeaderContentLanguage) + != response.GetHeaders().end()) + { + result.HttpHeaders.ContentLanguage + = response.GetHeaders().at(Details::c_HeaderContentLanguage); + } + result.AcceptRanges = response.GetHeaders().at(Details::c_HeaderAcceptRanges); + if (response.GetHeaders().find(Details::c_HeaderCopyCompletionTime) + != response.GetHeaders().end()) + { + result.CopyCompletionTime + = response.GetHeaders().at(Details::c_HeaderCopyCompletionTime); + } + if (response.GetHeaders().find(Details::c_HeaderCopyStatusDescription) + != response.GetHeaders().end()) + { + result.CopyStatusDescription + = response.GetHeaders().at(Details::c_HeaderCopyStatusDescription); + } + if (response.GetHeaders().find(Details::c_HeaderCopyId) != response.GetHeaders().end()) + { + result.CopyId = response.GetHeaders().at(Details::c_HeaderCopyId); + } + if (response.GetHeaders().find(Details::c_HeaderCopyProgress) + != response.GetHeaders().end()) + { + result.CopyProgress = response.GetHeaders().at(Details::c_HeaderCopyProgress); + } + if (response.GetHeaders().find(Details::c_HeaderCopySource) + != response.GetHeaders().end()) + { + result.CopySource = response.GetHeaders().at(Details::c_HeaderCopySource); + } + if (response.GetHeaders().find(Details::c_HeaderCopyStatus) + != response.GetHeaders().end()) + { + result.CopyStatus + = CopyStatusTypeFromString(response.GetHeaders().at(Details::c_HeaderCopyStatus)); + } + if (response.GetHeaders().find(Details::c_HeaderContentMd5) + != response.GetHeaders().end()) + { + result.HttpHeaders.ContentMd5 = response.GetHeaders().at(Details::c_HeaderContentMd5); + } + if (response.GetHeaders().find(Details::c_HeaderIsServerEncrypted) + != response.GetHeaders().end()) + { + result.IsServerEncrypted + = response.GetHeaders().at(Details::c_HeaderIsServerEncrypted) == "true"; + } + result.FileAttributes = response.GetHeaders().at(Details::c_HeaderFileAttributes); + result.FileCreationTime = response.GetHeaders().at(Details::c_HeaderFileCreationTime); + result.FileLastWriteTime = response.GetHeaders().at(Details::c_HeaderFileLastWriteTime); + result.FileChangeTime = response.GetHeaders().at(Details::c_HeaderFileChangeTime); + result.FilePermissionKey = response.GetHeaders().at(Details::c_HeaderFilePermissionKey); + result.FileId = response.GetHeaders().at(Details::c_HeaderFileId); + result.FileParentId = response.GetHeaders().at(Details::c_HeaderFileParentId); + if (response.GetHeaders().find(Details::c_HeaderLeaseDuration) + != response.GetHeaders().end()) + { + result.LeaseDuration = LeaseDurationTypeFromString( + response.GetHeaders().at(Details::c_HeaderLeaseDuration)); + } + if (response.GetHeaders().find(Details::c_HeaderLeaseState) + != response.GetHeaders().end()) + { + result.LeaseState + = LeaseStateTypeFromString(response.GetHeaders().at(Details::c_HeaderLeaseState)); + } + if (response.GetHeaders().find(Details::c_HeaderLeaseStatus) + != response.GetHeaders().end()) + { + result.LeaseStatus = LeaseStatusTypeFromString( + response.GetHeaders().at(Details::c_HeaderLeaseStatus)); + } + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Core::Response GetPropertiesParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + { + // Success. + FileGetPropertiesResult result; + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + + for (auto i = response.GetHeaders().lower_bound(Details::c_HeaderMetadata); + i != response.GetHeaders().end() + && i->first.substr(0, 9) == Details::c_HeaderMetadata; + ++i) + { + result.Metadata.emplace(i->first.substr(10), i->second); + } + result.FileType = response.GetHeaders().at(Details::c_HeaderFileType); + result.ContentLength + = std::stoll(response.GetHeaders().at(Details::c_HeaderContentLength)); + if (response.GetHeaders().find(Details::c_HeaderContentType) + != response.GetHeaders().end()) + { + result.HttpHeaders.ContentType + = response.GetHeaders().at(Details::c_HeaderContentType); + } + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + if (response.GetHeaders().find(Details::c_HeaderTransactionalContentMd5) + != response.GetHeaders().end()) + { + result.HttpHeaders.ContentMd5 + = response.GetHeaders().at(Details::c_HeaderTransactionalContentMd5); + } + if (response.GetHeaders().find(Details::c_HeaderContentEncoding) + != response.GetHeaders().end()) + { + result.HttpHeaders.ContentEncoding + = response.GetHeaders().at(Details::c_HeaderContentEncoding); + } + if (response.GetHeaders().find(Details::c_HeaderCacheControl) + != response.GetHeaders().end()) + { + result.HttpHeaders.CacheControl + = response.GetHeaders().at(Details::c_HeaderCacheControl); + } + if (response.GetHeaders().find(Details::c_HeaderContentDisposition) + != response.GetHeaders().end()) + { + result.HttpHeaders.ContentDisposition + = response.GetHeaders().at(Details::c_HeaderContentDisposition); + } + if (response.GetHeaders().find(Details::c_HeaderContentLanguage) + != response.GetHeaders().end()) + { + result.HttpHeaders.ContentLanguage + = response.GetHeaders().at(Details::c_HeaderContentLanguage); + } + if (response.GetHeaders().find(Details::c_HeaderCopyCompletionTime) + != response.GetHeaders().end()) + { + result.CopyCompletionTime + = response.GetHeaders().at(Details::c_HeaderCopyCompletionTime); + } + if (response.GetHeaders().find(Details::c_HeaderCopyStatusDescription) + != response.GetHeaders().end()) + { + result.CopyStatusDescription + = response.GetHeaders().at(Details::c_HeaderCopyStatusDescription); + } + if (response.GetHeaders().find(Details::c_HeaderCopyId) != response.GetHeaders().end()) + { + result.CopyId = response.GetHeaders().at(Details::c_HeaderCopyId); + } + if (response.GetHeaders().find(Details::c_HeaderCopyProgress) + != response.GetHeaders().end()) + { + result.CopyProgress = response.GetHeaders().at(Details::c_HeaderCopyProgress); + } + if (response.GetHeaders().find(Details::c_HeaderCopySource) + != response.GetHeaders().end()) + { + result.CopySource = response.GetHeaders().at(Details::c_HeaderCopySource); + } + if (response.GetHeaders().find(Details::c_HeaderCopyStatus) + != response.GetHeaders().end()) + { + result.CopyStatus + = CopyStatusTypeFromString(response.GetHeaders().at(Details::c_HeaderCopyStatus)); + } + if (response.GetHeaders().find(Details::c_HeaderIsServerEncrypted) + != response.GetHeaders().end()) + { + result.IsServerEncrypted + = response.GetHeaders().at(Details::c_HeaderIsServerEncrypted) == "true"; + } + result.FileAttributes = response.GetHeaders().at(Details::c_HeaderFileAttributes); + result.FileCreationTime = response.GetHeaders().at(Details::c_HeaderFileCreationTime); + result.FileLastWriteTime = response.GetHeaders().at(Details::c_HeaderFileLastWriteTime); + result.FileChangeTime = response.GetHeaders().at(Details::c_HeaderFileChangeTime); + result.FilePermissionKey = response.GetHeaders().at(Details::c_HeaderFilePermissionKey); + result.FileId = response.GetHeaders().at(Details::c_HeaderFileId); + result.FileParentId = response.GetHeaders().at(Details::c_HeaderFileParentId); + if (response.GetHeaders().find(Details::c_HeaderLeaseDuration) + != response.GetHeaders().end()) + { + result.LeaseDuration = LeaseDurationTypeFromString( + response.GetHeaders().at(Details::c_HeaderLeaseDuration)); + } + if (response.GetHeaders().find(Details::c_HeaderLeaseState) + != response.GetHeaders().end()) + { + result.LeaseState + = LeaseStateTypeFromString(response.GetHeaders().at(Details::c_HeaderLeaseState)); + } + if (response.GetHeaders().find(Details::c_HeaderLeaseStatus) + != response.GetHeaders().end()) + { + result.LeaseStatus = LeaseStatusTypeFromString( + response.GetHeaders().at(Details::c_HeaderLeaseStatus)); + } + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Core::Response DeleteParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Accepted) + { + // Success (Accepted). + FileDeleteResult result; + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Core::Response SetHttpHeadersParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + { + // Success + FileSetHttpHeadersResult result; + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + result.IsServerEncrypted + = response.GetHeaders().at(Details::c_HeaderRequestIsServerEncrypted) == "true"; + result.FilePermissionKey = response.GetHeaders().at(Details::c_HeaderFilePermissionKey); + result.FileAttributes = response.GetHeaders().at(Details::c_HeaderFileAttributes); + result.FileCreationTime = response.GetHeaders().at(Details::c_HeaderFileCreationTime); + result.FileLastWriteTime = response.GetHeaders().at(Details::c_HeaderFileLastWriteTime); + result.FileChangeTime = response.GetHeaders().at(Details::c_HeaderFileChangeTime); + result.FileId = response.GetHeaders().at(Details::c_HeaderFileId); + result.FileParentId = response.GetHeaders().at(Details::c_HeaderFileParentId); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Core::Response SetMetadataParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + { + // Success (OK). + FileSetMetadataResult result; + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.IsServerEncrypted + = response.GetHeaders().at(Details::c_HeaderRequestIsServerEncrypted) == "true"; + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Core::Response AcquireLeaseParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Created) + { + // The Acquire operation completed successfully. + FileAcquireLeaseResult result; + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + result.LeaseId = response.GetHeaders().at(Details::c_HeaderLeaseId); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Core::Response ReleaseLeaseParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + { + // The Release operation completed successfully. + FileReleaseLeaseResult result; + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Core::Response ChangeLeaseParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + { + // The Change operation completed successfully. + FileChangeLeaseResult result; + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + result.LeaseId = response.GetHeaders().at(Details::c_HeaderLeaseId); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Core::Response BreakLeaseParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Accepted) + { + // The Break operation completed successfully. + FileBreakLeaseResult result; + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + if (response.GetHeaders().find(Details::c_HeaderLeaseId) != response.GetHeaders().end()) + { + result.LeaseId = response.GetHeaders().at(Details::c_HeaderLeaseId); + } + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Core::Response UploadRangeParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Created) + { + // Success (Created). + FileUploadRangeResult result; + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + if (response.GetHeaders().find(Details::c_HeaderTransactionalContentMd5) + != response.GetHeaders().end()) + { + result.TransactionalContentMd5 + = response.GetHeaders().at(Details::c_HeaderTransactionalContentMd5); + } + if (response.GetHeaders().find(Details::c_HeaderRequestIsServerEncrypted) + != response.GetHeaders().end()) + { + result.IsServerEncrypted + = response.GetHeaders().at(Details::c_HeaderRequestIsServerEncrypted) == "true"; + } + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Core::Response UploadRangeFromUrlParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Created) + { + // Success (Created). + FileUploadRangeFromUrlResult result; + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + result.XMsContentCrc64 = response.GetHeaders().at(Details::c_HeaderXMsContentCrc64); + result.IsServerEncrypted + = response.GetHeaders().at(Details::c_HeaderRequestIsServerEncrypted) == "true"; + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Core::Response GetRangeListParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + { + // Success. + const auto& bodyBuffer = response.GetBody(); + auto reader + = XmlReader(reinterpret_cast(bodyBuffer.data()), bodyBuffer.size()); + FileGetRangeListResult result = bodyBuffer.empty() + ? FileGetRangeListResult() + : FileGetRangeListResultFromShareFileRangeList(ShareFileRangeListFromXml(reader)); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.FileContentLength + = std::stoll(response.GetHeaders().at(Details::c_HeaderXMsContentLength)); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static FileRange FileRangeFromXml(XmlReader& reader) + { + auto result = FileRange(); + enum class XmlTagName + { + c_End, + c_Start, + c_Unknown, + }; + std::vector path; + + while (true) + { + auto node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + break; + } + else if (node.Type == XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == XmlNodeType::StartTag) + { + + if (std::strcmp(node.Name, "End") == 0) + { + path.emplace_back(XmlTagName::c_End); + } + else if (std::strcmp(node.Name, "Start") == 0) + { + path.emplace_back(XmlTagName::c_Start); + } + else + { + path.emplace_back(XmlTagName::c_Unknown); + } + } + else if (node.Type == XmlNodeType::Text) + { + if (path.size() == 1 && path[0] == XmlTagName::c_End) + { + result.End = std::stoll(node.Value); + } + else if (path.size() == 1 && path[0] == XmlTagName::c_Start) + { + result.Start = std::stoll(node.Value); + } + } + } + return result; + } + + static ClearRange ClearRangeFromXml(XmlReader& reader) + { + auto result = ClearRange(); + enum class XmlTagName + { + c_End, + c_Start, + c_Unknown, + }; + std::vector path; + + while (true) + { + auto node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + break; + } + else if (node.Type == XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == XmlNodeType::StartTag) + { + + if (std::strcmp(node.Name, "End") == 0) + { + path.emplace_back(XmlTagName::c_End); + } + else if (std::strcmp(node.Name, "Start") == 0) + { + path.emplace_back(XmlTagName::c_Start); + } + else + { + path.emplace_back(XmlTagName::c_Unknown); + } + } + else if (node.Type == XmlNodeType::Text) + { + if (path.size() == 1 && path[0] == XmlTagName::c_End) + { + result.End = std::stoll(node.Value); + } + else if (path.size() == 1 && path[0] == XmlTagName::c_Start) + { + result.Start = std::stoll(node.Value); + } + } + } + return result; + } + + static ShareFileRangeList ShareFileRangeListFromXml(XmlReader& reader) + { + auto result = ShareFileRangeList(); + enum class XmlTagName + { + c_ClearRange, + c_Range, + c_Ranges, + c_Unknown, + }; + std::vector path; + + while (true) + { + auto node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + break; + } + else if (node.Type == XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == XmlNodeType::StartTag) + { + + if (std::strcmp(node.Name, "ClearRange") == 0) + { + path.emplace_back(XmlTagName::c_ClearRange); + } + else if (std::strcmp(node.Name, "Range") == 0) + { + path.emplace_back(XmlTagName::c_Range); + } + else if (std::strcmp(node.Name, "Ranges") == 0) + { + path.emplace_back(XmlTagName::c_Ranges); + } + else + { + path.emplace_back(XmlTagName::c_Unknown); + } + if (path.size() == 2 && path[0] == XmlTagName::c_Ranges + && path[1] == XmlTagName::c_Range) + { + result.Ranges.emplace_back(FileRangeFromXml(reader)); + path.pop_back(); + } + else if ( + path.size() == 2 && path[0] == XmlTagName::c_Ranges + && path[1] == XmlTagName::c_ClearRange) + { + result.ClearRanges.emplace_back(ClearRangeFromXml(reader)); + path.pop_back(); + } + } + else if (node.Type == XmlNodeType::Text) + { + } + } + return result; + } + + static FileGetRangeListResult FileGetRangeListResultFromShareFileRangeList( + ShareFileRangeList object) + { + FileGetRangeListResult result; + result.Ranges = std::move(object.Ranges); + result.ClearRanges = std::move(object.ClearRanges); + + return result; + } + static Azure::Core::Response StartCopyParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Accepted) + { + // The copy file has been accepted with the specified copy status. + FileStartCopyResult result; + result.ETag = response.GetHeaders().at(Details::c_HeaderETag); + result.LastModified = response.GetHeaders().at(Details::c_HeaderLastModified); + if (response.GetHeaders().find(Details::c_HeaderCopyId) != response.GetHeaders().end()) + { + result.CopyId = response.GetHeaders().at(Details::c_HeaderCopyId); + } + if (response.GetHeaders().find(Details::c_HeaderCopyStatus) + != response.GetHeaders().end()) + { + result.CopyStatus + = CopyStatusTypeFromString(response.GetHeaders().at(Details::c_HeaderCopyStatus)); + } + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Core::Response AbortCopyParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::NoContent) + { + // The delete request was accepted and the file will be deleted. + FileAbortCopyResult result; + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static Azure::Core::Response ListHandlesParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + { + // Success. + const auto& bodyBuffer = response.GetBody(); + auto reader + = XmlReader(reinterpret_cast(bodyBuffer.data()), bodyBuffer.size()); + FileListHandlesResult result = bodyBuffer.empty() + ? FileListHandlesResult() + : FileListHandlesResultFromListHandlesResponse(ListHandlesResponseFromXml(reader)); + result.HttpHeaders.ContentType = response.GetHeaders().at(Details::c_HeaderContentType); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + + static HandleItem HandleItemFromXml(XmlReader& reader) + { + auto result = HandleItem(); + enum class XmlTagName + { + c_ClientIp, + c_FileId, + c_HandleId, + c_LastReconnectTime, + c_OpenTime, + c_ParentId, + c_Path, + c_SessionId, + c_Unknown, + }; + std::vector path; + + while (true) + { + auto node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + break; + } + else if (node.Type == XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == XmlNodeType::StartTag) + { + + if (std::strcmp(node.Name, "ClientIp") == 0) + { + path.emplace_back(XmlTagName::c_ClientIp); + } + else if (std::strcmp(node.Name, "FileId") == 0) + { + path.emplace_back(XmlTagName::c_FileId); + } + else if (std::strcmp(node.Name, "HandleId") == 0) + { + path.emplace_back(XmlTagName::c_HandleId); + } + else if (std::strcmp(node.Name, "LastReconnectTime") == 0) + { + path.emplace_back(XmlTagName::c_LastReconnectTime); + } + else if (std::strcmp(node.Name, "OpenTime") == 0) + { + path.emplace_back(XmlTagName::c_OpenTime); + } + else if (std::strcmp(node.Name, "ParentId") == 0) + { + path.emplace_back(XmlTagName::c_ParentId); + } + else if (std::strcmp(node.Name, "Path") == 0) + { + path.emplace_back(XmlTagName::c_Path); + } + else if (std::strcmp(node.Name, "SessionId") == 0) + { + path.emplace_back(XmlTagName::c_SessionId); + } + else + { + path.emplace_back(XmlTagName::c_Unknown); + } + } + else if (node.Type == XmlNodeType::Text) + { + if (path.size() == 1 && path[0] == XmlTagName::c_ClientIp) + { + result.ClientIp = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::c_FileId) + { + result.FileId = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::c_HandleId) + { + result.HandleId = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::c_LastReconnectTime) + { + result.LastReconnectTime = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::c_OpenTime) + { + result.OpenTime = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::c_ParentId) + { + result.ParentId = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::c_Path) + { + result.Path = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::c_SessionId) + { + result.SessionId = node.Value; + } + } + } + return result; + } + + static ListHandlesResponse ListHandlesResponseFromXml(XmlReader& reader) + { + auto result = ListHandlesResponse(); + enum class XmlTagName + { + c_Entries, + c_EnumerationResults, + c_Handle, + c_NextMarker, + c_Unknown, + }; + std::vector path; + + while (true) + { + auto node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + break; + } + else if (node.Type == XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == XmlNodeType::StartTag) + { + + if (std::strcmp(node.Name, "Entries") == 0) + { + path.emplace_back(XmlTagName::c_Entries); + } + else if (std::strcmp(node.Name, "EnumerationResults") == 0) + { + path.emplace_back(XmlTagName::c_EnumerationResults); + } + else if (std::strcmp(node.Name, "Handle") == 0) + { + path.emplace_back(XmlTagName::c_Handle); + } + else if (std::strcmp(node.Name, "NextMarker") == 0) + { + path.emplace_back(XmlTagName::c_NextMarker); + } + else + { + path.emplace_back(XmlTagName::c_Unknown); + } + if (path.size() == 3 && path[0] == XmlTagName::c_EnumerationResults + && path[1] == XmlTagName::c_Entries && path[2] == XmlTagName::c_Handle) + { + result.HandleList.emplace_back(HandleItemFromXml(reader)); + path.pop_back(); + } + } + else if (node.Type == XmlNodeType::Text) + { + if (path.size() == 2 && path[0] == XmlTagName::c_EnumerationResults + && path[1] == XmlTagName::c_NextMarker) + { + result.ContinuationToken = node.Value; + } + } + } + return result; + } + + static FileListHandlesResult FileListHandlesResultFromListHandlesResponse( + ListHandlesResponse object) + { + FileListHandlesResult result; + result.HandleList = std::move(object.HandleList); + result.ContinuationToken = std::move(object.ContinuationToken); + + return result; + } + static Azure::Core::Response ForceCloseHandlesParseResult( + Azure::Core::Context context, + std::unique_ptr responsePtr) + { + auto& response = *responsePtr; + if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok) + { + // Success. + FileForceCloseHandlesResult result; + if (response.GetHeaders().find(Details::c_HeaderContinuationToken) + != response.GetHeaders().end()) + { + result.ContinuationToken + = response.GetHeaders().at(Details::c_HeaderContinuationToken); + } + result.numberOfHandlesClosed + = std::stoi(response.GetHeaders().at(Details::c_HeaderNumberOfHandlesClosed)); + result.numberOfHandlesFailedToClose = std::stoi( + response.GetHeaders().at(Details::c_HeaderNumberOfHandlesFailedToClose)); + return Azure::Core::Response( + std::move(result), std::move(responsePtr)); + } + else + { + unused(context); + throw Azure::Storage::StorageError::CreateFromResponse(std::move(responsePtr)); + } + } + }; + + }; // class ShareRestClient + + } // namespace Details }}}} // namespace Azure::Storage::Files::Shares diff --git a/sdk/storage/azure-storage-files-shares/src/share_client.cpp b/sdk/storage/azure-storage-files-shares/src/share_client.cpp index df8d90794..e1877b0e0 100644 --- a/sdk/storage/azure-storage-files-shares/src/share_client.cpp +++ b/sdk/storage/azure-storage-files-shares/src/share_client.cpp @@ -142,39 +142,39 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { Azure::Core::Response ShareClient::Create( const CreateShareOptions& options) const { - auto protocolLayerOptions = ShareRestClient::Share::CreateOptions(); + auto protocolLayerOptions = Details::ShareRestClient::Share::CreateOptions(); protocolLayerOptions.Metadata = options.Metadata; protocolLayerOptions.ShareQuota = options.ShareQuota; - return ShareRestClient::Share::Create( + return Details::ShareRestClient::Share::Create( m_shareUri, *m_pipeline, options.Context, protocolLayerOptions); } Azure::Core::Response ShareClient::Delete( const DeleteShareOptions& options) const { - auto protocolLayerOptions = ShareRestClient::Share::DeleteOptions(); + auto protocolLayerOptions = Details::ShareRestClient::Share::DeleteOptions(); if (options.IncludeSnapshots.HasValue() and options.IncludeSnapshots.GetValue()) { protocolLayerOptions.XMsDeleteSnapshots = DeleteSnapshotsOptionType::Include; } - return ShareRestClient::Share::Delete( + return Details::ShareRestClient::Share::Delete( m_shareUri, *m_pipeline, options.Context, protocolLayerOptions); } Azure::Core::Response ShareClient::CreateSnapshot( const CreateShareSnapshotOptions& options) const { - auto protocolLayerOptions = ShareRestClient::Share::CreateSnapshotOptions(); + auto protocolLayerOptions = Details::ShareRestClient::Share::CreateSnapshotOptions(); protocolLayerOptions.Metadata = options.Metadata; - return ShareRestClient::Share::CreateSnapshot( + return Details::ShareRestClient::Share::CreateSnapshot( m_shareUri, *m_pipeline, options.Context, protocolLayerOptions); } Azure::Core::Response ShareClient::GetProperties( const GetSharePropertiesOptions& options) const { - auto protocolLayerOptions = ShareRestClient::Share::GetPropertiesOptions(); - return ShareRestClient::Share::GetProperties( + auto protocolLayerOptions = Details::ShareRestClient::Share::GetPropertiesOptions(); + return Details::ShareRestClient::Share::GetProperties( m_shareUri, *m_pipeline, options.Context, protocolLayerOptions); } @@ -182,9 +182,9 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { int32_t quota, const SetShareQuotaOptions& options) const { - auto protocolLayerOptions = ShareRestClient::Share::SetQuotaOptions(); + auto protocolLayerOptions = Details::ShareRestClient::Share::SetQuotaOptions(); protocolLayerOptions.ShareQuota = quota; - return ShareRestClient::Share::SetQuota( + return Details::ShareRestClient::Share::SetQuota( m_shareUri, *m_pipeline, options.Context, protocolLayerOptions); } @@ -192,17 +192,17 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { std::map metadata, const SetShareMetadataOptions& options) const { - auto protocolLayerOptions = ShareRestClient::Share::SetMetadataOptions(); + auto protocolLayerOptions = Details::ShareRestClient::Share::SetMetadataOptions(); protocolLayerOptions.Metadata = metadata; - return ShareRestClient::Share::SetMetadata( + return Details::ShareRestClient::Share::SetMetadata( m_shareUri, *m_pipeline, options.Context, protocolLayerOptions); } Azure::Core::Response ShareClient::GetAccessPolicy( const GetShareAccessPolicyOptions& options) const { - auto protocolLayerOptions = ShareRestClient::Share::GetAccessPolicyOptions(); - return ShareRestClient::Share::GetAccessPolicy( + auto protocolLayerOptions = Details::ShareRestClient::Share::GetAccessPolicyOptions(); + return Details::ShareRestClient::Share::GetAccessPolicy( m_shareUri, *m_pipeline, options.Context, protocolLayerOptions); } @@ -210,17 +210,17 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { const std::vector& accessPolicy, const SetShareAccessPolicyOptions& options) const { - auto protocolLayerOptions = ShareRestClient::Share::SetAccessPolicyOptions(); + auto protocolLayerOptions = Details::ShareRestClient::Share::SetAccessPolicyOptions(); protocolLayerOptions.ShareAcl = accessPolicy; - return ShareRestClient::Share::SetAccessPolicy( + return Details::ShareRestClient::Share::SetAccessPolicy( m_shareUri, *m_pipeline, options.Context, protocolLayerOptions); } Azure::Core::Response ShareClient::GetStatistics( const GetShareStatsOptions& options) const { - auto protocolLayerOptions = ShareRestClient::Share::GetStatisticsOptions(); - return ShareRestClient::Share::GetStatistics( + auto protocolLayerOptions = Details::ShareRestClient::Share::GetStatisticsOptions(); + return Details::ShareRestClient::Share::GetStatistics( m_shareUri, *m_pipeline, options.Context, protocolLayerOptions); } @@ -228,9 +228,9 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { const std::string& permission, const CreateSharePermissionOptions& options) const { - auto protocolLayerOptions = ShareRestClient::Share::CreatePermissionOptions(); + auto protocolLayerOptions = Details::ShareRestClient::Share::CreatePermissionOptions(); protocolLayerOptions.Permission.Permission = permission; - return ShareRestClient::Share::CreatePermission( + return Details::ShareRestClient::Share::CreatePermission( m_shareUri, *m_pipeline, options.Context, protocolLayerOptions); } @@ -238,9 +238,9 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { const std::string& permissionKey, const GetSharePermissionOptions& options) const { - auto protocolLayerOptions = ShareRestClient::Share::GetPermissionOptions(); + auto protocolLayerOptions = Details::ShareRestClient::Share::GetPermissionOptions(); protocolLayerOptions.FilePermissionKeyRequired = permissionKey; - return ShareRestClient::Share::GetPermission( + return Details::ShareRestClient::Share::GetPermission( m_shareUri, *m_pipeline, options.Context, protocolLayerOptions); } @@ -248,11 +248,12 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { ShareClient::ListFilesAndDirectoriesSegment( const ListFilesAndDirectoriesSegmentOptions& options) const { - auto protocolLayerOptions = ShareRestClient::Directory::ListFilesAndDirectoriesSegmentOptions(); + auto protocolLayerOptions + = Details::ShareRestClient::Directory::ListFilesAndDirectoriesSegmentOptions(); protocolLayerOptions.Prefix = options.Prefix; protocolLayerOptions.ContinuationToken = options.ContinuationToken; protocolLayerOptions.MaxResults = options.MaxResults; - auto result = ShareRestClient::Directory::ListFilesAndDirectoriesSegment( + auto result = Details::ShareRestClient::Directory::ListFilesAndDirectoriesSegment( m_shareUri, *m_pipeline, options.Context, protocolLayerOptions); ListFilesAndDirectoriesSegmentResult ret; ret.ServiceEndpoint = std::move(result->ServiceEndpoint); @@ -275,10 +276,10 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { int32_t duration, const AcquireShareLeaseOptions& options) const { - ShareRestClient::Share::AcquireLeaseOptions protocolLayerOptions; + Details::ShareRestClient::Share::AcquireLeaseOptions protocolLayerOptions; protocolLayerOptions.ProposedLeaseIdOptional = proposedLeaseId; protocolLayerOptions.LeaseDuration = duration; - return ShareRestClient::Share::AcquireLease( + return Details::ShareRestClient::Share::AcquireLease( m_shareUri, *m_pipeline, options.Context, protocolLayerOptions); } @@ -287,10 +288,10 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { const std::string& proposedLeaseId, const ChangeShareLeaseOptions& options) const { - ShareRestClient::Share::ChangeLeaseOptions protocolLayerOptions; + Details::ShareRestClient::Share::ChangeLeaseOptions protocolLayerOptions; protocolLayerOptions.LeaseIdRequired = leaseId; protocolLayerOptions.ProposedLeaseIdOptional = proposedLeaseId; - return ShareRestClient::Share::ChangeLease( + return Details::ShareRestClient::Share::ChangeLease( m_shareUri, *m_pipeline, options.Context, protocolLayerOptions); } @@ -298,18 +299,18 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { const std::string& leaseId, const ReleaseShareLeaseOptions& options) const { - ShareRestClient::Share::ReleaseLeaseOptions protocolLayerOptions; + Details::ShareRestClient::Share::ReleaseLeaseOptions protocolLayerOptions; protocolLayerOptions.LeaseIdRequired = leaseId; - return ShareRestClient::Share::ReleaseLease( + return Details::ShareRestClient::Share::ReleaseLease( m_shareUri, *m_pipeline, options.Context, protocolLayerOptions); } Azure::Core::Response ShareClient::BreakLease( const BreakShareLeaseOptions& options) const { - ShareRestClient::Share::BreakLeaseOptions protocolLayerOptions; + Details::ShareRestClient::Share::BreakLeaseOptions protocolLayerOptions; protocolLayerOptions.LeaseBreakPeriod = options.BreakPeriod; - return ShareRestClient::Share::BreakLease( + return Details::ShareRestClient::Share::BreakLease( m_shareUri, *m_pipeline, options.Context, protocolLayerOptions); } @@ -317,9 +318,9 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { const std::string& leaseId, const RenewShareLeaseOptions& options) const { - ShareRestClient::Share::RenewLeaseOptions protocolLayerOptions; + Details::ShareRestClient::Share::RenewLeaseOptions protocolLayerOptions; protocolLayerOptions.LeaseIdRequired = leaseId; - return ShareRestClient::Share::RenewLease( + return Details::ShareRestClient::Share::RenewLease( m_shareUri, *m_pipeline, options.Context, protocolLayerOptions); } diff --git a/sdk/storage/azure-storage-files-shares/src/share_directory_client.cpp b/sdk/storage/azure-storage-files-shares/src/share_directory_client.cpp index 5c2ebb2cb..110ec9dd6 100644 --- a/sdk/storage/azure-storage-files-shares/src/share_directory_client.cpp +++ b/sdk/storage/azure-storage-files-shares/src/share_directory_client.cpp @@ -145,7 +145,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { Azure::Core::Response DirectoryClient::Create( const CreateDirectoryOptions& options) const { - auto protocolLayerOptions = ShareRestClient::Directory::CreateOptions(); + auto protocolLayerOptions = Details::ShareRestClient::Directory::CreateOptions(); protocolLayerOptions.Metadata = options.Metadata; protocolLayerOptions.FileAttributes = FileAttributesToString(options.SmbProperties.Attributes); if (protocolLayerOptions.FileAttributes.empty()) @@ -180,23 +180,23 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { protocolLayerOptions.FilePermission = std::string(c_FileInheritPermission); } - return ShareRestClient::Directory::Create( + return Details::ShareRestClient::Directory::Create( m_shareDirectoryUri, *m_pipeline, options.Context, protocolLayerOptions); } Azure::Core::Response DirectoryClient::Delete( const DeleteDirectoryOptions& options) const { - auto protocolLayerOptions = ShareRestClient::Directory::DeleteOptions(); - return ShareRestClient::Directory::Delete( + auto protocolLayerOptions = Details::ShareRestClient::Directory::DeleteOptions(); + return Details::ShareRestClient::Directory::Delete( m_shareDirectoryUri, *m_pipeline, options.Context, protocolLayerOptions); } Azure::Core::Response DirectoryClient::GetProperties( const GetDirectoryPropertiesOptions& options) const { - auto protocolLayerOptions = ShareRestClient::Directory::GetPropertiesOptions(); - return ShareRestClient::Directory::GetProperties( + auto protocolLayerOptions = Details::ShareRestClient::Directory::GetPropertiesOptions(); + return Details::ShareRestClient::Directory::GetProperties( m_shareDirectoryUri, *m_pipeline, options.Context, protocolLayerOptions); } @@ -204,7 +204,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { FileShareSmbProperties smbProperties, const SetDirectoryPropertiesOptions& options) const { - auto protocolLayerOptions = ShareRestClient::Directory::SetPropertiesOptions(); + auto protocolLayerOptions = Details::ShareRestClient::Directory::SetPropertiesOptions(); protocolLayerOptions.FileAttributes = FileAttributesToString(smbProperties.Attributes); if (smbProperties.CreationTime.HasValue()) { @@ -234,7 +234,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { protocolLayerOptions.FilePermission = std::string(c_FileInheritPermission); } - return ShareRestClient::Directory::SetProperties( + return Details::ShareRestClient::Directory::SetProperties( m_shareDirectoryUri, *m_pipeline, options.Context, protocolLayerOptions); } @@ -242,9 +242,9 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { const std::map& metadata, const SetDirectoryMetadataOptions& options) const { - auto protocolLayerOptions = ShareRestClient::Directory::SetMetadataOptions(); + auto protocolLayerOptions = Details::ShareRestClient::Directory::SetMetadataOptions(); protocolLayerOptions.Metadata = metadata; - return ShareRestClient::Directory::SetMetadata( + return Details::ShareRestClient::Directory::SetMetadata( m_shareDirectoryUri, *m_pipeline, options.Context, protocolLayerOptions); } @@ -252,11 +252,12 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { DirectoryClient::ListFilesAndDirectoriesSegment( const ListFilesAndDirectoriesSegmentOptions& options) const { - auto protocolLayerOptions = ShareRestClient::Directory::ListFilesAndDirectoriesSegmentOptions(); + auto protocolLayerOptions + = Details::ShareRestClient::Directory::ListFilesAndDirectoriesSegmentOptions(); protocolLayerOptions.Prefix = options.Prefix; protocolLayerOptions.ContinuationToken = options.ContinuationToken; protocolLayerOptions.MaxResults = options.MaxResults; - auto result = ShareRestClient::Directory::ListFilesAndDirectoriesSegment( + auto result = Details::ShareRestClient::Directory::ListFilesAndDirectoriesSegment( m_shareDirectoryUri, *m_pipeline, options.Context, protocolLayerOptions); ListFilesAndDirectoriesSegmentResult ret; ret.ServiceEndpoint = std::move(result->ServiceEndpoint); @@ -277,11 +278,11 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { Azure::Core::Response DirectoryClient::ListHandlesSegment( const ListDirectoryHandlesSegmentOptions& options) const { - auto protocolLayerOptions = ShareRestClient::Directory::ListHandlesOptions(); + auto protocolLayerOptions = Details::ShareRestClient::Directory::ListHandlesOptions(); protocolLayerOptions.ContinuationToken = options.ContinuationToken; protocolLayerOptions.MaxResults = options.MaxResults; protocolLayerOptions.Recursive = options.Recursive; - auto result = ShareRestClient::Directory::ListHandles( + auto result = Details::ShareRestClient::Directory::ListHandles( m_shareDirectoryUri, *m_pipeline, options.Context, protocolLayerOptions); ListDirectoryHandlesSegmentResult ret; ret.ContinuationToken = std::move(result->ContinuationToken); @@ -295,9 +296,9 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { const std::string& handleId, const ForceCloseDirectoryHandleOptions& options) const { - auto protocolLayerOptions = ShareRestClient::File::ForceCloseHandlesOptions(); + auto protocolLayerOptions = Details::ShareRestClient::File::ForceCloseHandlesOptions(); protocolLayerOptions.HandleId = handleId; - auto result = ShareRestClient::File::ForceCloseHandles( + auto result = Details::ShareRestClient::File::ForceCloseHandles( m_shareDirectoryUri, *m_pipeline, options.Context, protocolLayerOptions); return Azure::Core::Response( ForceCloseDirectoryHandleResult(), result.ExtractRawResponse()); @@ -306,11 +307,11 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { Azure::Core::Response DirectoryClient::ForceCloseAllHandles( const ForceCloseAllDirectoryHandlesOptions& options) const { - auto protocolLayerOptions = ShareRestClient::Directory::ForceCloseHandlesOptions(); + auto protocolLayerOptions = Details::ShareRestClient::Directory::ForceCloseHandlesOptions(); protocolLayerOptions.HandleId = c_FileAllHandles; protocolLayerOptions.ContinuationToken = options.ContinuationToken; protocolLayerOptions.Recursive = options.Recursive; - return ShareRestClient::Directory::ForceCloseHandles( + return Details::ShareRestClient::Directory::ForceCloseHandles( m_shareDirectoryUri, *m_pipeline, options.Context, protocolLayerOptions); } diff --git a/sdk/storage/azure-storage-files-shares/src/share_file_client.cpp b/sdk/storage/azure-storage-files-shares/src/share_file_client.cpp index bad2c4313..ec77af89c 100644 --- a/sdk/storage/azure-storage-files-shares/src/share_file_client.cpp +++ b/sdk/storage/azure-storage-files-shares/src/share_file_client.cpp @@ -133,7 +133,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { int64_t fileSize, const CreateFileOptions& options) const { - auto protocolLayerOptions = ShareRestClient::File::CreateOptions(); + auto protocolLayerOptions = Details::ShareRestClient::File::CreateOptions(); protocolLayerOptions.Metadata = options.Metadata; protocolLayerOptions.FileAttributes = FileAttributesToString(options.SmbProperties.Attributes); if (protocolLayerOptions.FileAttributes.empty()) @@ -194,22 +194,22 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { protocolLayerOptions.FileContentMd5 = options.HttpHeaders.ContentMd5; } protocolLayerOptions.LeaseIdOptional = options.AccessConditions.LeaseId; - return ShareRestClient::File::Create( + return Details::ShareRestClient::File::Create( m_shareFileUri, *m_pipeline, options.Context, protocolLayerOptions); } Azure::Core::Response FileClient::Delete(const DeleteFileOptions& options) const { - auto protocolLayerOptions = ShareRestClient::File::DeleteOptions(); + auto protocolLayerOptions = Details::ShareRestClient::File::DeleteOptions(); protocolLayerOptions.LeaseIdOptional = options.AccessConditions.LeaseId; - return ShareRestClient::File::Delete( + return Details::ShareRestClient::File::Delete( m_shareFileUri, *m_pipeline, options.Context, protocolLayerOptions); } Azure::Core::Response FileClient::Download( const DownloadFileOptions& options) const { - auto protocolLayerOptions = ShareRestClient::File::DownloadOptions(); + auto protocolLayerOptions = Details::ShareRestClient::File::DownloadOptions(); if (options.Offset.HasValue()) { if (options.Length.HasValue()) @@ -227,7 +227,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { protocolLayerOptions.GetRangeContentMd5 = options.GetRangeContentMd5; protocolLayerOptions.LeaseIdOptional = options.AccessConditions.LeaseId; - auto downloadResponse = ShareRestClient::File::Download( + auto downloadResponse = Details::ShareRestClient::File::Download( m_shareFileUri, *m_pipeline, options.Context, protocolLayerOptions); { @@ -269,7 +269,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { std::string copySource, const StartCopyFileOptions& options) const { - auto protocolLayerOptions = ShareRestClient::File::StartCopyOptions(); + auto protocolLayerOptions = Details::ShareRestClient::File::StartCopyOptions(); protocolLayerOptions.Metadata = options.Metadata; protocolLayerOptions.CopySource = std::move(copySource); protocolLayerOptions.FileCopyFileAttributes @@ -319,7 +319,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { protocolLayerOptions.FileCopyIgnoreReadOnly = options.IgnoreReadOnly; protocolLayerOptions.FileCopySetArchiveAttribute = options.SetArchiveAttribute; protocolLayerOptions.LeaseIdOptional = options.AccessConditions.LeaseId; - return ShareRestClient::File::StartCopy( + return Details::ShareRestClient::File::StartCopy( m_shareFileUri, *m_pipeline, options.Context, protocolLayerOptions); } @@ -327,19 +327,19 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { std::string copyId, const AbortCopyFileOptions& options) const { - auto protocolLayerOptions = ShareRestClient::File::AbortCopyOptions(); + auto protocolLayerOptions = Details::ShareRestClient::File::AbortCopyOptions(); protocolLayerOptions.CopyId = std::move(copyId); protocolLayerOptions.LeaseIdOptional = options.AccessConditions.LeaseId; - return ShareRestClient::File::AbortCopy( + return Details::ShareRestClient::File::AbortCopy( m_shareFileUri, *m_pipeline, options.Context, protocolLayerOptions); } Azure::Core::Response FileClient::GetProperties( const GetFilePropertiesOptions& options) const { - auto protocolLayerOptions = ShareRestClient::File::GetPropertiesOptions(); + auto protocolLayerOptions = Details::ShareRestClient::File::GetPropertiesOptions(); protocolLayerOptions.LeaseIdOptional = options.AccessConditions.LeaseId; - return ShareRestClient::File::GetProperties( + return Details::ShareRestClient::File::GetProperties( m_shareFileUri, *m_pipeline, options.Context, protocolLayerOptions); } @@ -348,7 +348,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { FileShareSmbProperties smbProperties, const SetFilePropertiesOptions& options) const { - auto protocolLayerOptions = ShareRestClient::File::SetHttpHeadersOptions(); + auto protocolLayerOptions = Details::ShareRestClient::File::SetHttpHeadersOptions(); protocolLayerOptions.FileAttributes = FileAttributesToString(smbProperties.Attributes); if (smbProperties.CreationTime.HasValue()) { @@ -402,7 +402,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { protocolLayerOptions.FileContentDisposition = httpHeaders.ContentDisposition; } - return ShareRestClient::File::SetHttpHeaders( + return Details::ShareRestClient::File::SetHttpHeaders( m_shareFileUri, *m_pipeline, options.Context, protocolLayerOptions); } @@ -410,10 +410,10 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { const std::map& metadata, const SetFileMetadataOptions& options) const { - auto protocolLayerOptions = ShareRestClient::File::SetMetadataOptions(); + auto protocolLayerOptions = Details::ShareRestClient::File::SetMetadataOptions(); protocolLayerOptions.Metadata = metadata; protocolLayerOptions.LeaseIdOptional = options.AccessConditions.LeaseId; - return ShareRestClient::File::SetMetadata( + return Details::ShareRestClient::File::SetMetadata( m_shareFileUri, *m_pipeline, options.Context, protocolLayerOptions); } @@ -422,14 +422,14 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { Azure::Core::Http::BodyStream* content, const UploadFileRangeOptions& options) const { - auto protocolLayerOptions = ShareRestClient::File::UploadRangeOptions(); + auto protocolLayerOptions = Details::ShareRestClient::File::UploadRangeOptions(); protocolLayerOptions.XMsWrite = FileRangeWriteType::Update; protocolLayerOptions.ContentLength = content->Length(); protocolLayerOptions.XMsRange = std::string("bytes=") + std::to_string(offset) + std::string("-") + std::to_string(offset + content->Length() - 1); protocolLayerOptions.ContentMd5 = options.TransactionalMd5; protocolLayerOptions.LeaseIdOptional = options.AccessConditions.LeaseId; - return ShareRestClient::File::UploadRange( + return Details::ShareRestClient::File::UploadRange( m_shareFileUri, *content, *m_pipeline, options.Context, protocolLayerOptions); } @@ -438,14 +438,14 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { int64_t length, const ClearFileRangeOptions& options) const { - auto protocolLayerOptions = ShareRestClient::File::UploadRangeOptions(); + auto protocolLayerOptions = Details::ShareRestClient::File::UploadRangeOptions(); protocolLayerOptions.XMsWrite = FileRangeWriteType::Clear; protocolLayerOptions.ContentLength = 0; protocolLayerOptions.XMsRange = std::string("bytes=") + std::to_string(offset) + std::string("-") + std::to_string(offset + length - 1); protocolLayerOptions.LeaseIdOptional = options.AccessConditions.LeaseId; - return ShareRestClient::File::UploadRange( + return Details::ShareRestClient::File::UploadRange( m_shareFileUri, *Azure::Core::Http::NullBodyStream::GetNullBodyStream(), *m_pipeline, @@ -456,7 +456,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { Azure::Core::Response FileClient::GetRangeList( const GetFileRangeListOptions& options) const { - auto protocolLayerOptions = ShareRestClient::File::GetRangeListOptions(); + auto protocolLayerOptions = Details::ShareRestClient::File::GetRangeListOptions(); if (options.Offset.HasValue()) { if (options.Length.HasValue()) @@ -474,17 +474,17 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { protocolLayerOptions.PrevShareSnapshot = options.PrevShareSnapshot; protocolLayerOptions.LeaseIdOptional = options.AccessConditions.LeaseId; - return ShareRestClient::File::GetRangeList( + return Details::ShareRestClient::File::GetRangeList( m_shareFileUri, *m_pipeline, options.Context, protocolLayerOptions); } Azure::Core::Response FileClient::ListHandlesSegment( const ListFileHandlesSegmentOptions& options) const { - auto protocolLayerOptions = ShareRestClient::File::ListHandlesOptions(); + auto protocolLayerOptions = Details::ShareRestClient::File::ListHandlesOptions(); protocolLayerOptions.ContinuationToken = options.ContinuationToken; protocolLayerOptions.MaxResults = options.MaxResults; - auto result = ShareRestClient::File::ListHandles( + auto result = Details::ShareRestClient::File::ListHandles( m_shareFileUri, *m_pipeline, options.Context, protocolLayerOptions); ListFileHandlesSegmentResult ret; ret.ContinuationToken = std::move(result->ContinuationToken); @@ -498,9 +498,9 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { const std::string& handleId, const ForceCloseFileHandleOptions& options) const { - auto protocolLayerOptions = ShareRestClient::File::ForceCloseHandlesOptions(); + auto protocolLayerOptions = Details::ShareRestClient::File::ForceCloseHandlesOptions(); protocolLayerOptions.HandleId = handleId; - auto result = ShareRestClient::File::ForceCloseHandles( + auto result = Details::ShareRestClient::File::ForceCloseHandles( m_shareFileUri, *m_pipeline, options.Context, protocolLayerOptions); return Azure::Core::Response( ForceCloseFileHandleResult(), result.ExtractRawResponse()); @@ -509,10 +509,10 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { Azure::Core::Response FileClient::ForceCloseAllHandles( const ForceCloseAllFileHandlesOptions& options) const { - auto protocolLayerOptions = ShareRestClient::File::ForceCloseHandlesOptions(); + auto protocolLayerOptions = Details::ShareRestClient::File::ForceCloseHandlesOptions(); protocolLayerOptions.HandleId = c_FileAllHandles; protocolLayerOptions.ContinuationToken = options.ContinuationToken; - return ShareRestClient::File::ForceCloseHandles( + return Details::ShareRestClient::File::ForceCloseHandles( m_shareFileUri, *m_pipeline, options.Context, protocolLayerOptions); } @@ -520,10 +520,10 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { const std::string& proposedLeaseId, const AcquireFileLeaseOptions& options) const { - ShareRestClient::File::AcquireLeaseOptions protocolLayerOptions; + Details::ShareRestClient::File::AcquireLeaseOptions protocolLayerOptions; protocolLayerOptions.ProposedLeaseIdOptional = proposedLeaseId; protocolLayerOptions.LeaseDuration = -1; - return ShareRestClient::File::AcquireLease( + return Details::ShareRestClient::File::AcquireLease( m_shareFileUri, *m_pipeline, options.Context, protocolLayerOptions); } @@ -532,10 +532,10 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { const std::string& proposedLeaseId, const ChangeFileLeaseOptions& options) const { - ShareRestClient::File::ChangeLeaseOptions protocolLayerOptions; + Details::ShareRestClient::File::ChangeLeaseOptions protocolLayerOptions; protocolLayerOptions.LeaseIdRequired = leaseId; protocolLayerOptions.ProposedLeaseIdOptional = proposedLeaseId; - return ShareRestClient::File::ChangeLease( + return Details::ShareRestClient::File::ChangeLease( m_shareFileUri, *m_pipeline, options.Context, protocolLayerOptions); } @@ -543,17 +543,17 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { const std::string& leaseId, const ReleaseFileLeaseOptions& options) const { - ShareRestClient::File::ReleaseLeaseOptions protocolLayerOptions; + Details::ShareRestClient::File::ReleaseLeaseOptions protocolLayerOptions; protocolLayerOptions.LeaseIdRequired = leaseId; - return ShareRestClient::File::ReleaseLease( + return Details::ShareRestClient::File::ReleaseLease( m_shareFileUri, *m_pipeline, options.Context, protocolLayerOptions); } Azure::Core::Response FileClient::BreakLease( const BreakFileLeaseOptions& options) const { - ShareRestClient::File::BreakLeaseOptions protocolLayerOptions; - return ShareRestClient::File::BreakLease( + Details::ShareRestClient::File::BreakLeaseOptions protocolLayerOptions; + return Details::ShareRestClient::File::BreakLease( m_shareFileUri, *m_pipeline, options.Context, protocolLayerOptions); } @@ -812,7 +812,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { std::size_t bufferSize, const UploadFileFromOptions& options) const { - ShareRestClient::File::CreateOptions protocolLayerOptions; + Details::ShareRestClient::File::CreateOptions protocolLayerOptions; protocolLayerOptions.XMsContentLength = bufferSize; protocolLayerOptions.FileAttributes = FileAttributesToString(options.SmbProperties.Attributes); if (protocolLayerOptions.FileAttributes.empty()) @@ -873,7 +873,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { protocolLayerOptions.FileContentMd5 = options.HttpHeaders.ContentMd5; } protocolLayerOptions.Metadata = options.Metadata; - auto createResult = ShareRestClient::File::Create( + auto createResult = Details::ShareRestClient::File::Create( m_shareFileUri, *m_pipeline, options.Context, protocolLayerOptions); int64_t chunkSize = options.ChunkSize.HasValue() ? options.ChunkSize.GetValue() @@ -903,7 +903,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { Storage::Details::FileReader fileReader(file); - ShareRestClient::File::CreateOptions protocolLayerOptions; + Details::ShareRestClient::File::CreateOptions protocolLayerOptions; protocolLayerOptions.XMsContentLength = fileReader.GetFileSize(); protocolLayerOptions.FileAttributes = FileAttributesToString(options.SmbProperties.Attributes); if (protocolLayerOptions.FileAttributes.empty()) @@ -964,7 +964,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { protocolLayerOptions.FileContentMd5 = options.HttpHeaders.ContentMd5; } protocolLayerOptions.Metadata = options.Metadata; - auto createResult = ShareRestClient::File::Create( + auto createResult = Details::ShareRestClient::File::Create( m_shareFileUri, *m_pipeline, options.Context, protocolLayerOptions); int64_t chunkSize = options.ChunkSize.HasValue() ? options.ChunkSize.GetValue() diff --git a/sdk/storage/azure-storage-files-shares/src/share_service_client.cpp b/sdk/storage/azure-storage-files-shares/src/share_service_client.cpp index 0beee600b..128c28f56 100644 --- a/sdk/storage/azure-storage-files-shares/src/share_service_client.cpp +++ b/sdk/storage/azure-storage-files-shares/src/share_service_client.cpp @@ -115,12 +115,12 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { Azure::Core::Response ServiceClient::ListSharesSegment( const ListSharesSegmentOptions& options) const { - auto protocolLayerOptions = ShareRestClient::Service::ListSharesSegmentOptions(); + auto protocolLayerOptions = Details::ShareRestClient::Service::ListSharesSegmentOptions(); protocolLayerOptions.ListSharesInclude = options.ListSharesInclude; protocolLayerOptions.ContinuationToken = options.ContinuationToken; protocolLayerOptions.MaxResults = options.MaxResults; protocolLayerOptions.Prefix = options.Prefix; - return ShareRestClient::Service::ListSharesSegment( + return Details::ShareRestClient::Service::ListSharesSegment( m_serviceUri, *m_pipeline, options.Context, protocolLayerOptions); } @@ -128,17 +128,17 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { StorageServiceProperties properties, const SetServicePropertiesOptions& options) const { - auto protocolLayerOptions = ShareRestClient::Service::SetPropertiesOptions(); + auto protocolLayerOptions = Details::ShareRestClient::Service::SetPropertiesOptions(); protocolLayerOptions.ServiceProperties = std::move(properties); - return ShareRestClient::Service::SetProperties( + return Details::ShareRestClient::Service::SetProperties( m_serviceUri, *m_pipeline, options.Context, protocolLayerOptions); } Azure::Core::Response ServiceClient::GetProperties( const GetServicePropertiesOptions& options) const { - auto protocolLayerOptions = ShareRestClient::Service::GetPropertiesOptions(); - auto result = ShareRestClient::Service::GetProperties( + auto protocolLayerOptions = Details::ShareRestClient::Service::GetPropertiesOptions(); + auto result = Details::ShareRestClient::Service::GetProperties( m_serviceUri, *m_pipeline, options.Context, protocolLayerOptions); StorageServiceProperties ret; ret.Cors = std::move(result->Cors);