Add more APIs in storage sdk (#169)
* Add xml serializer/deserializer * Add blob service client, add undelete, set access tier, start copy, abort copy, create snapshot, stage block from uri * add support for conditional headers * support range download * Change the helper functions order to alphabetical so that we always get the same result in different environemnts. * use c++ casting * Add support for append blob and page blob * remove redundant ; added by auto-generator * Remove BlobType in BlockBlob::Upload * Rename blob_client_options.hpp->blob_options.hpp * Remove API version in request options
This commit is contained in:
parent
f604a1dd00
commit
4366159c50
@ -16,12 +16,15 @@ set (AZURE_STORAGE_BLOB_HEADER
|
||||
inc/common/common_headers_request_policy.hpp
|
||||
inc/common/shared_key_policy.hpp
|
||||
inc/common/crypt.hpp
|
||||
inc/common/xml_wrapper.hpp
|
||||
inc/blobs/blob.hpp
|
||||
inc/blobs/blob_service_client.hpp
|
||||
inc/blobs/blob_container_client.hpp
|
||||
inc/blobs/blob_client.hpp
|
||||
inc/blobs/block_blob_client.hpp
|
||||
inc/blobs/blob_container_client.hpp
|
||||
inc/blobs/blob_client_options.hpp
|
||||
inc/blobs/blob_container_client_options.hpp
|
||||
inc/blobs/page_blob_client.hpp
|
||||
inc/blobs/append_blob_client.hpp
|
||||
inc/blobs/blob_options.hpp
|
||||
inc/blobs/internal/protocol/blob_rest_client.hpp
|
||||
)
|
||||
|
||||
@ -31,14 +34,18 @@ set (AZURE_STORAGE_DATALAKE_HEADER
|
||||
)
|
||||
|
||||
set (AZURE_STORAGE_BLOB_SOURCE
|
||||
src/blobs/blob_client.cpp
|
||||
src/blobs/block_blob_client.cpp
|
||||
src/blobs/blob_container_client.cpp
|
||||
src/common/storage_credential.cpp
|
||||
src/common/storage_url_builder.cpp
|
||||
src/common/common_headers_request_policy.cpp
|
||||
src/common/shared_key_policy.cpp
|
||||
src/common/crypt.cpp
|
||||
src/common/xml_wrapper.cpp
|
||||
src/blobs/blob_service_client.cpp
|
||||
src/blobs/blob_container_client.cpp
|
||||
src/blobs/blob_client.cpp
|
||||
src/blobs/block_blob_client.cpp
|
||||
src/blobs/page_blob_client.cpp
|
||||
src/blobs/append_blob_client.cpp
|
||||
)
|
||||
|
||||
set (AZURE_STORAGE_DATALAKE_SOURCE
|
||||
|
||||
54
sdk/storage/inc/blobs/append_blob_client.hpp
Normal file
54
sdk/storage/inc/blobs/append_blob_client.hpp
Normal file
@ -0,0 +1,54 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "blob_options.hpp"
|
||||
#include "blobs/blob_client.hpp"
|
||||
#include "common/storage_credential.hpp"
|
||||
#include "internal/protocol/blob_rest_client.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Azure { namespace Storage { namespace Blobs {
|
||||
|
||||
class AppendBlobClient : public BlobClient {
|
||||
public:
|
||||
// connection string
|
||||
static AppendBlobClient CreateFromConnectionString(
|
||||
const std::string& connectionString,
|
||||
const std::string& containerName,
|
||||
const std::string& blobName,
|
||||
const AppendBlobClientOptions& options = AppendBlobClientOptions());
|
||||
|
||||
// shared key auth
|
||||
explicit AppendBlobClient(
|
||||
const std::string& blobUri,
|
||||
std::shared_ptr<SharedKeyCredential> credential,
|
||||
const AppendBlobClientOptions& options = AppendBlobClientOptions());
|
||||
|
||||
// token auth
|
||||
explicit AppendBlobClient(
|
||||
const std::string& blobUri,
|
||||
std::shared_ptr<TokenCredential> credential,
|
||||
const AppendBlobClientOptions& options = AppendBlobClientOptions());
|
||||
|
||||
// anonymous/SAS/customized pipeline auth
|
||||
explicit AppendBlobClient(
|
||||
const std::string& blobUri,
|
||||
const AppendBlobClientOptions& options = AppendBlobClientOptions());
|
||||
|
||||
AppendBlobClient WithSnapshot(const std::string& snapshot) const;
|
||||
|
||||
BlobContentInfo Create(const CreateAppendBlobOptions& options = CreateAppendBlobOptions());
|
||||
|
||||
BlobAppendInfo AppendBlock(
|
||||
// TODO: We don't have BodyStream for now.
|
||||
std::vector<uint8_t> content,
|
||||
const AppendBlockOptions& options = AppendBlockOptions());
|
||||
|
||||
private:
|
||||
explicit AppendBlobClient(BlobClient blobClient);
|
||||
};
|
||||
|
||||
}}} // namespace Azure::Storage::Blobs
|
||||
@ -3,6 +3,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "blobs/append_blob_client.hpp"
|
||||
#include "blobs/blob_client.hpp"
|
||||
#include "blobs/blob_container_client.hpp"
|
||||
#include "blobs/blob_service_client.hpp"
|
||||
#include "blobs/block_blob_client.hpp"
|
||||
#include "blobs/page_blob_client.hpp"
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "blob_client_options.hpp"
|
||||
#include "blob_options.hpp"
|
||||
#include "common/storage_credential.hpp"
|
||||
#include "common/storage_url_builder.hpp"
|
||||
#include "internal/protocol/blob_rest_client.hpp"
|
||||
@ -40,21 +40,39 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
const std::string& blobUri,
|
||||
const BlobClientOptions& options = BlobClientOptions());
|
||||
|
||||
BlobClient WithSnapshot(const std::string& snapshot);
|
||||
BlobClient WithSnapshot(const std::string& snapshot) const;
|
||||
|
||||
BlobProperties GetProperties(
|
||||
const GetBlobPropertiesOptions& options = GetBlobPropertiesOptions());
|
||||
const GetBlobPropertiesOptions& options = GetBlobPropertiesOptions()) const;
|
||||
|
||||
BlobInfo SetHttpHeaders(const SetBlobHttpHeadersOptions& options = SetBlobHttpHeadersOptions());
|
||||
BlobInfo SetHttpHeaders(
|
||||
const SetBlobHttpHeadersOptions& options = SetBlobHttpHeadersOptions()) const;
|
||||
|
||||
BlobInfo SetMetadata(
|
||||
std::map<std::string, std::string> metadata,
|
||||
const SetBlobMetadataOptions& options = SetBlobMetadataOptions());
|
||||
const SetBlobMetadataOptions& options = SetBlobMetadataOptions()) const;
|
||||
|
||||
BasicResponse SetAccessTier(
|
||||
AccessTier Tier,
|
||||
const SetAccessTierOptions& options = SetAccessTierOptions()) const;
|
||||
|
||||
BlobCopyInfo StartCopyFromUri(
|
||||
const std::string& sourceUri,
|
||||
const StartCopyFromUriOptions& options = StartCopyFromUriOptions()) const;
|
||||
|
||||
BasicResponse AbortCopyFromUri(
|
||||
const std::string& copyId,
|
||||
const AbortCopyFromUriOptions& options = AbortCopyFromUriOptions()) const;
|
||||
|
||||
FlattenedDownloadProperties Download(
|
||||
const DownloadBlobOptions& options = DownloadBlobOptions());
|
||||
const DownloadBlobOptions& options = DownloadBlobOptions()) const;
|
||||
|
||||
BasicResponse Delete(const DeleteBlobOptions& options = DeleteBlobOptions());
|
||||
BlobSnapshotInfo CreateSnapshot(
|
||||
const CreateSnapshotOptions& options = CreateSnapshotOptions()) const;
|
||||
|
||||
BasicResponse Delete(const DeleteBlobOptions& options = DeleteBlobOptions()) const;
|
||||
|
||||
BasicResponse Undelete(const UndeleteBlobOptions& options = UndeleteBlobOptions()) const;
|
||||
|
||||
protected:
|
||||
UrlBuilder m_blobUrl;
|
||||
|
||||
@ -1,88 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "internal/protocol/blob_rest_client.hpp"
|
||||
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace Azure { namespace Storage { namespace Blobs {
|
||||
|
||||
struct BlobClientOptions
|
||||
{
|
||||
std::vector<std::unique_ptr<Azure::Core::Http::HttpPolicy>> policies;
|
||||
};
|
||||
|
||||
struct BlockBlobClientOptions : public BlobClientOptions
|
||||
{
|
||||
};
|
||||
|
||||
struct GetBlobPropertiesOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
};
|
||||
|
||||
struct SetBlobHttpHeadersOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
std::string ContentType;
|
||||
std::string ContentEncoding;
|
||||
std::string ContentLanguage;
|
||||
std::string ContentMD5;
|
||||
std::string CacheControl;
|
||||
std::string ContentDisposition;
|
||||
};
|
||||
|
||||
struct SetBlobMetadataOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
};
|
||||
|
||||
struct DownloadBlobOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
uint64_t Offset = std::numeric_limits<uint64_t>::max();
|
||||
uint64_t Length = 0;
|
||||
};
|
||||
|
||||
struct DeleteBlobOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
DeleteSnapshotsOption DeleteSnapshots = DeleteSnapshotsOption::None;
|
||||
};
|
||||
|
||||
struct UploadBlobOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
std::string ContentMD5;
|
||||
std::string ContentCRC64;
|
||||
BlobHttpHeaders Properties;
|
||||
std::map<std::string, std::string> Metadata;
|
||||
AccessTier Tier = AccessTier::Unknown;
|
||||
};
|
||||
|
||||
struct StageBlockOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
std::string ContentMD5;
|
||||
std::string ContentCRC64;
|
||||
};
|
||||
|
||||
struct CommitBlockListOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
BlobHttpHeaders Properties;
|
||||
std::map<std::string, std::string> Metadata;
|
||||
AccessTier Tier = AccessTier::Unknown;
|
||||
};
|
||||
|
||||
struct GetBlockListOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
BlockListTypeOption ListType = BlockListTypeOption::All;
|
||||
};
|
||||
|
||||
}}} // namespace Azure::Storage::Blobs
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "blob_container_client_options.hpp"
|
||||
#include "blob_options.hpp"
|
||||
#include "blobs/blob_client.hpp"
|
||||
#include "common/storage_credential.hpp"
|
||||
#include "common/storage_url_builder.hpp"
|
||||
@ -40,21 +40,23 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
const std::string& containerUri,
|
||||
const BlobContainerClientOptions& options = BlobContainerClientOptions());
|
||||
|
||||
BlobClient GetBlobClient(const std::string& blobName);
|
||||
BlobClient GetBlobClient(const std::string& blobName) const;
|
||||
|
||||
BlobContainerInfo Create(
|
||||
const CreateBlobContainerOptions& options = CreateBlobContainerOptions());
|
||||
const CreateBlobContainerOptions& options = CreateBlobContainerOptions()) const;
|
||||
|
||||
BasicResponse Delete(const DeleteBlobContainerOptions& options = DeleteBlobContainerOptions());
|
||||
BasicResponse Delete(
|
||||
const DeleteBlobContainerOptions& options = DeleteBlobContainerOptions()) const;
|
||||
|
||||
BlobContainerProperties GetProperties(
|
||||
const GetBlobContainerPropertiesOptions& options = GetBlobContainerPropertiesOptions());
|
||||
const GetBlobContainerPropertiesOptions& options
|
||||
= GetBlobContainerPropertiesOptions()) const;
|
||||
|
||||
BlobContainerInfo SetMetadata(
|
||||
std::map<std::string, std::string> metadata,
|
||||
SetBlobContainerMetadataOptions options = SetBlobContainerMetadataOptions());
|
||||
SetBlobContainerMetadataOptions options = SetBlobContainerMetadataOptions()) const;
|
||||
|
||||
BlobsFlatSegment ListBlobs(const ListBlobsOptions& options = ListBlobsOptions());
|
||||
BlobsFlatSegment ListBlobs(const ListBlobsOptions& options = ListBlobsOptions()) const;
|
||||
|
||||
private:
|
||||
UrlBuilder m_ContainerUri;
|
||||
|
||||
@ -1,51 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "internal/protocol/blob_rest_client.hpp"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace Azure { namespace Storage { namespace Blobs {
|
||||
|
||||
struct BlobContainerClientOptions
|
||||
{
|
||||
std::vector<std::unique_ptr<Azure::Core::Http::HttpPolicy>> policies;
|
||||
};
|
||||
|
||||
struct CreateBlobContainerOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
PublicAccessType AccessType = PublicAccessType::Private;
|
||||
std::map<std::string, std::string> Metadata;
|
||||
};
|
||||
|
||||
struct DeleteBlobContainerOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
};
|
||||
|
||||
struct GetBlobContainerPropertiesOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
};
|
||||
|
||||
struct SetBlobContainerMetadataOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
};
|
||||
|
||||
struct ListBlobsOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
std::string Prefix;
|
||||
std::string Delimiter;
|
||||
std::string Marker;
|
||||
int MaxResults = 0;
|
||||
std::vector<ListBlobsIncludeItem> Include;
|
||||
};
|
||||
|
||||
}}} // namespace Azure::Storage::Blobs
|
||||
353
sdk/storage/inc/blobs/blob_options.hpp
Normal file
353
sdk/storage/inc/blobs/blob_options.hpp
Normal file
@ -0,0 +1,353 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "internal/protocol/blob_rest_client.hpp"
|
||||
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace Azure { namespace Storage { namespace Blobs {
|
||||
|
||||
struct BlobServiceClientOptions
|
||||
{
|
||||
std::vector<std::unique_ptr<Azure::Core::Http::HttpPolicy>> policies;
|
||||
};
|
||||
|
||||
struct ListBlobContainersOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
std::string Prefix;
|
||||
std::string Marker;
|
||||
int MaxResults = 0;
|
||||
std::vector<ListBlobContainersIncludeOption> Include;
|
||||
};
|
||||
|
||||
struct GetUserDelegationKeyOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
std::string StartsOn;
|
||||
};
|
||||
|
||||
struct BlobContainerClientOptions
|
||||
{
|
||||
std::vector<std::unique_ptr<Azure::Core::Http::HttpPolicy>> policies;
|
||||
};
|
||||
|
||||
struct CreateBlobContainerOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
PublicAccessType AccessType = PublicAccessType::Private;
|
||||
std::map<std::string, std::string> Metadata;
|
||||
};
|
||||
|
||||
struct DeleteBlobContainerOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
std::string IfModifiedSince;
|
||||
std::string IfUnmodifiedSince;
|
||||
};
|
||||
|
||||
struct GetBlobContainerPropertiesOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
};
|
||||
|
||||
struct SetBlobContainerMetadataOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
std::string IfModifiedSince;
|
||||
};
|
||||
|
||||
struct ListBlobsOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
std::string Prefix;
|
||||
std::string Delimiter;
|
||||
std::string Marker;
|
||||
int MaxResults = 0;
|
||||
std::vector<ListBlobsIncludeItem> Include;
|
||||
};
|
||||
|
||||
struct BlobClientOptions
|
||||
{
|
||||
std::vector<std::unique_ptr<Azure::Core::Http::HttpPolicy>> policies;
|
||||
};
|
||||
|
||||
struct BlockBlobClientOptions : public BlobClientOptions
|
||||
{
|
||||
};
|
||||
|
||||
struct AppendBlobClientOptions : public BlobClientOptions
|
||||
{
|
||||
};
|
||||
|
||||
struct PageBlobClientOptions : public BlobClientOptions
|
||||
{
|
||||
};
|
||||
|
||||
struct GetBlobPropertiesOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
std::string IfModifiedSince;
|
||||
std::string IfUnmodifiedSince;
|
||||
std::string IfMatch;
|
||||
std::string IfNoneMatch;
|
||||
};
|
||||
|
||||
struct SetBlobHttpHeadersOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
std::string ContentType;
|
||||
std::string ContentEncoding;
|
||||
std::string ContentLanguage;
|
||||
std::string ContentMD5;
|
||||
std::string CacheControl;
|
||||
std::string ContentDisposition;
|
||||
std::string IfModifiedSince;
|
||||
std::string IfUnmodifiedSince;
|
||||
std::string IfMatch;
|
||||
std::string IfNoneMatch;
|
||||
};
|
||||
|
||||
struct SetBlobMetadataOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
std::string IfModifiedSince;
|
||||
std::string IfUnmodifiedSince;
|
||||
std::string IfMatch;
|
||||
std::string IfNoneMatch;
|
||||
};
|
||||
|
||||
struct SetAccessTierOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
Blobs::RehydratePriority RehydratePriority = Blobs::RehydratePriority::Unknown;
|
||||
};
|
||||
|
||||
struct StartCopyFromUriOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
std::map<std::string, std::string> Metadata;
|
||||
std::string LeaseId;
|
||||
std::string SourceLeaseId;
|
||||
AccessTier Tier = AccessTier::Unknown;
|
||||
Blobs::RehydratePriority RehydratePriority = Blobs::RehydratePriority::Unknown;
|
||||
std::string IfModifiedSince;
|
||||
std::string IfUnmodifiedSince;
|
||||
std::string IfMatch;
|
||||
std::string IfNoneMatch;
|
||||
std::string SourceIfModifiedSince;
|
||||
std::string SourceIfUnmodifiedSince;
|
||||
std::string SourceIfMatch;
|
||||
std::string SourceIfNoneMatch;
|
||||
};
|
||||
|
||||
struct AbortCopyFromUriOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
std::string LeaseId;
|
||||
};
|
||||
|
||||
struct DownloadBlobOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
uint64_t Offset = std::numeric_limits<uint64_t>::max(); // max means the whole blob
|
||||
uint64_t Length = 0; // 0 means till the end
|
||||
std::string IfModifiedSince;
|
||||
std::string IfUnmodifiedSince;
|
||||
std::string IfMatch;
|
||||
std::string IfNoneMatch;
|
||||
};
|
||||
|
||||
struct CreateSnapshotOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
std::map<std::string, std::string> Metadata;
|
||||
std::string LeaseId;
|
||||
std::string IfModifiedSince;
|
||||
std::string IfUnmodifiedSince;
|
||||
std::string IfMatch;
|
||||
std::string IfNoneMatch;
|
||||
};
|
||||
|
||||
struct DeleteBlobOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
DeleteSnapshotsOption DeleteSnapshots = DeleteSnapshotsOption::None;
|
||||
std::string IfModifiedSince;
|
||||
std::string IfUnmodifiedSince;
|
||||
std::string IfMatch;
|
||||
std::string IfNoneMatch;
|
||||
};
|
||||
|
||||
struct UndeleteBlobOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
};
|
||||
|
||||
struct UploadBlobOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
std::string ContentMD5;
|
||||
std::string ContentCRC64;
|
||||
BlobHttpHeaders Properties;
|
||||
std::map<std::string, std::string> Metadata;
|
||||
AccessTier Tier = AccessTier::Unknown;
|
||||
std::string IfModifiedSince;
|
||||
std::string IfUnmodifiedSince;
|
||||
std::string IfMatch;
|
||||
std::string IfNoneMatch;
|
||||
};
|
||||
|
||||
struct StageBlockOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
std::string ContentMD5;
|
||||
std::string ContentCRC64;
|
||||
};
|
||||
|
||||
struct StageBlockFromUriOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
uint64_t SourceOffset = std::numeric_limits<uint64_t>::max();
|
||||
uint64_t SourceLength = 0;
|
||||
std::string ContentMD5;
|
||||
std::string ContentCRC64;
|
||||
std::string LeaseId;
|
||||
std::string SourceIfModifiedSince;
|
||||
std::string SourceIfUnmodifiedSince;
|
||||
std::string SourceIfMatch;
|
||||
std::string SourceIfNoneMatch;
|
||||
};
|
||||
|
||||
struct CommitBlockListOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
BlobHttpHeaders Properties;
|
||||
std::map<std::string, std::string> Metadata;
|
||||
AccessTier Tier = AccessTier::Unknown;
|
||||
std::string IfModifiedSince;
|
||||
std::string IfUnmodifiedSince;
|
||||
std::string IfMatch;
|
||||
std::string IfNoneMatch;
|
||||
};
|
||||
|
||||
struct GetBlockListOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
BlockListTypeOption ListType = BlockListTypeOption::All;
|
||||
std::string IfModifiedSince;
|
||||
std::string IfUnmodifiedSince;
|
||||
std::string IfMatch;
|
||||
std::string IfNoneMatch;
|
||||
};
|
||||
|
||||
struct CreateAppendBlobOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
BlobHttpHeaders Properties;
|
||||
std::map<std::string, std::string> Metadata;
|
||||
AccessTier Tier = AccessTier::Unknown;
|
||||
std::string IfModifiedSince;
|
||||
std::string IfUnmodifiedSince;
|
||||
std::string IfMatch;
|
||||
std::string IfNoneMatch;
|
||||
};
|
||||
|
||||
struct AppendBlockOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
std::string ContentMD5;
|
||||
std::string ContentCRC64;
|
||||
std::string LeaseId;
|
||||
uint64_t MaxSize = std::numeric_limits<uint64_t>::max();
|
||||
uint64_t AppendPosition = std::numeric_limits<uint64_t>::max();
|
||||
std::string IfModifiedSince;
|
||||
std::string IfUnmodifiedSince;
|
||||
std::string IfMatch;
|
||||
std::string IfNoneMatch;
|
||||
};
|
||||
|
||||
struct CreatePageBlobOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
uint64_t SequenceNumber = 0;
|
||||
BlobHttpHeaders Properties;
|
||||
std::map<std::string, std::string> Metadata;
|
||||
AccessTier Tier = AccessTier::Unknown;
|
||||
std::string IfModifiedSince;
|
||||
std::string IfUnmodifiedSince;
|
||||
std::string IfMatch;
|
||||
std::string IfNoneMatch;
|
||||
};
|
||||
|
||||
struct UploadPagesOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
std::string ContentMD5;
|
||||
std::string ContentCRC64;
|
||||
std::string LeaseId;
|
||||
std::string IfModifiedSince;
|
||||
std::string IfUnmodifiedSince;
|
||||
std::string IfMatch;
|
||||
std::string IfNoneMatch;
|
||||
};
|
||||
|
||||
struct UploadPagesFromUriOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
std::string ContentMD5;
|
||||
std::string ContentCRC64;
|
||||
std::string LeaseId;
|
||||
std::string IfModifiedSince;
|
||||
std::string IfUnmodifiedSince;
|
||||
std::string IfMatch;
|
||||
std::string IfNoneMatch;
|
||||
};
|
||||
|
||||
struct ClearPagesOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
std::string LeaseId;
|
||||
std::string IfModifiedSince;
|
||||
std::string IfUnmodifiedSince;
|
||||
std::string IfMatch;
|
||||
std::string IfNoneMatch;
|
||||
};
|
||||
|
||||
struct ResizePageBlobOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
std::string IfModifiedSince;
|
||||
std::string IfUnmodifiedSince;
|
||||
std::string IfMatch;
|
||||
std::string IfNoneMatch;
|
||||
};
|
||||
|
||||
struct GetPageRangesOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
std::string PreviousSnapshot;
|
||||
std::string PreviousSnapshotUrl;
|
||||
uint64_t Offset = 0;
|
||||
uint64_t Length = 0;
|
||||
std::string LeaseId;
|
||||
std::string IfModifiedSince;
|
||||
std::string IfUnmodifiedSince;
|
||||
std::string IfMatch;
|
||||
std::string IfNoneMatch;
|
||||
};
|
||||
|
||||
struct IncrementalCopyPageBlobOptions
|
||||
{
|
||||
Azure::Core::Context Context;
|
||||
std::string IfModifiedSince;
|
||||
std::string IfUnmodifiedSince;
|
||||
std::string IfMatch;
|
||||
std::string IfNoneMatch;
|
||||
};
|
||||
|
||||
}}} // namespace Azure::Storage::Blobs
|
||||
51
sdk/storage/inc/blobs/blob_service_client.hpp
Normal file
51
sdk/storage/inc/blobs/blob_service_client.hpp
Normal file
@ -0,0 +1,51 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "blob_options.hpp"
|
||||
#include "common/storage_credential.hpp"
|
||||
#include "common/storage_url_builder.hpp"
|
||||
#include "internal/protocol/blob_rest_client.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace Azure { namespace Storage { namespace Blobs {
|
||||
|
||||
class BlobServiceClient {
|
||||
public:
|
||||
// connection string
|
||||
static BlobServiceClient CreateFromConnectionString(
|
||||
const std::string& connectionString,
|
||||
const BlobServiceClientOptions& options = BlobServiceClientOptions());
|
||||
|
||||
// shared key auth
|
||||
explicit BlobServiceClient(
|
||||
const std::string& serviceUri,
|
||||
std::shared_ptr<SharedKeyCredential> credential,
|
||||
const BlobServiceClientOptions& options = BlobServiceClientOptions());
|
||||
|
||||
// token auth
|
||||
explicit BlobServiceClient(
|
||||
const std::string& serviceUri,
|
||||
std::shared_ptr<TokenCredential> credential,
|
||||
const BlobServiceClientOptions& options = BlobServiceClientOptions());
|
||||
|
||||
// anonymous/SAS/customized pipeline auth
|
||||
explicit BlobServiceClient(
|
||||
const std::string& serviceUri,
|
||||
const BlobServiceClientOptions& options = BlobServiceClientOptions());
|
||||
|
||||
ListContainersSegment ListBlobContainersSegment(
|
||||
const ListBlobContainersOptions& options = ListBlobContainersOptions()) const;
|
||||
|
||||
UserDelegationKey GetUserDelegationKey(
|
||||
const std::string& expiresOn,
|
||||
const GetUserDelegationKeyOptions& options = GetUserDelegationKeyOptions()) const;
|
||||
|
||||
protected:
|
||||
UrlBuilder m_serviceUrl;
|
||||
std::shared_ptr<Azure::Core::Http::HttpPipeline> m_pipeline;
|
||||
};
|
||||
}}} // namespace Azure::Storage::Blobs
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "blob_client_options.hpp"
|
||||
#include "blob_options.hpp"
|
||||
#include "blobs/blob_client.hpp"
|
||||
#include "common/storage_credential.hpp"
|
||||
#include "internal/protocol/blob_rest_client.hpp"
|
||||
@ -39,24 +39,30 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
const std::string& blobUri,
|
||||
const BlockBlobClientOptions& options = BlockBlobClientOptions());
|
||||
|
||||
BlockBlobClient WithSnapshot(const std::string& snapshot);
|
||||
BlockBlobClient WithSnapshot(const std::string& snapshot) const;
|
||||
|
||||
BlobContentInfo Upload(
|
||||
// TODO: We don't have BodyStream for now.
|
||||
std::vector<uint8_t> content,
|
||||
const UploadBlobOptions& options = UploadBlobOptions());
|
||||
const UploadBlobOptions& options = UploadBlobOptions()) const;
|
||||
|
||||
BlockInfo StageBlock(
|
||||
const std::string& blockId,
|
||||
// TODO: We don't have BodyStream for now.
|
||||
std::vector<uint8_t> content,
|
||||
const StageBlockOptions& options = StageBlockOptions());
|
||||
const StageBlockOptions& options = StageBlockOptions()) const;
|
||||
|
||||
BlockInfo StageBlockFromUri(
|
||||
const std::string& blockId,
|
||||
const std::string& sourceUri,
|
||||
const StageBlockFromUriOptions& options = StageBlockFromUriOptions()) const;
|
||||
|
||||
BlobContentInfo CommitBlockList(
|
||||
const std::vector<std::pair<BlockType, std::string>>& blockIds,
|
||||
const CommitBlockListOptions& options = CommitBlockListOptions());
|
||||
const CommitBlockListOptions& options = CommitBlockListOptions()) const;
|
||||
|
||||
BlobBlockListInfo GetBlockList(const GetBlockListOptions& options = GetBlockListOptions());
|
||||
BlobBlockListInfo GetBlockList(
|
||||
const GetBlockListOptions& options = GetBlockListOptions()) const;
|
||||
|
||||
private:
|
||||
explicit BlockBlobClient(BlobClient blobClient);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
79
sdk/storage/inc/blobs/page_blob_client.hpp
Normal file
79
sdk/storage/inc/blobs/page_blob_client.hpp
Normal file
@ -0,0 +1,79 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "blob_options.hpp"
|
||||
#include "blobs/blob_client.hpp"
|
||||
#include "common/storage_credential.hpp"
|
||||
#include "internal/protocol/blob_rest_client.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Azure { namespace Storage { namespace Blobs {
|
||||
|
||||
class PageBlobClient : public BlobClient {
|
||||
public:
|
||||
// connection string
|
||||
static PageBlobClient CreateFromConnectionString(
|
||||
const std::string& connectionString,
|
||||
const std::string& containerName,
|
||||
const std::string& blobName,
|
||||
const PageBlobClientOptions& options = PageBlobClientOptions());
|
||||
|
||||
// shared key auth
|
||||
explicit PageBlobClient(
|
||||
const std::string& blobUri,
|
||||
std::shared_ptr<SharedKeyCredential> credential,
|
||||
const PageBlobClientOptions& options = PageBlobClientOptions());
|
||||
|
||||
// token auth
|
||||
explicit PageBlobClient(
|
||||
const std::string& blobUri,
|
||||
std::shared_ptr<TokenCredential> credential,
|
||||
const PageBlobClientOptions& options = PageBlobClientOptions());
|
||||
|
||||
// anonymous/SAS/customized pipeline auth
|
||||
explicit PageBlobClient(
|
||||
const std::string& blobUri,
|
||||
const PageBlobClientOptions& options = PageBlobClientOptions());
|
||||
|
||||
PageBlobClient WithSnapshot(const std::string& snapshot) const;
|
||||
|
||||
BlobContentInfo Create(
|
||||
uint64_t blobContentLength,
|
||||
const CreatePageBlobOptions& options = CreatePageBlobOptions());
|
||||
|
||||
PageInfo UploadPages(
|
||||
// TODO: We don't have BodyStream for now.
|
||||
std::vector<uint8_t> content,
|
||||
uint64_t offset,
|
||||
const UploadPagesOptions& options = UploadPagesOptions());
|
||||
|
||||
PageInfo UploadPagesFromUri(
|
||||
std::string sourceUri,
|
||||
uint64_t sourceOffset,
|
||||
uint64_t sourceLength,
|
||||
uint64_t destinationoffset,
|
||||
const UploadPagesFromUriOptions& options = UploadPagesFromUriOptions());
|
||||
|
||||
PageInfo ClearPages(
|
||||
uint64_t offset,
|
||||
uint64_t length,
|
||||
const ClearPagesOptions& options = ClearPagesOptions());
|
||||
|
||||
PageBlobInfo Resize(
|
||||
uint64_t blobContentLength,
|
||||
const ResizePageBlobOptions& options = ResizePageBlobOptions());
|
||||
|
||||
PageRangesInfo GetPageRanges(const GetPageRangesOptions& options = GetPageRangesOptions());
|
||||
|
||||
BlobCopyInfo StartCopyIncremental(
|
||||
const std::string& sourceUri,
|
||||
const IncrementalCopyPageBlobOptions& options = IncrementalCopyPageBlobOptions());
|
||||
|
||||
private:
|
||||
explicit PageBlobClient(BlobClient blobClient);
|
||||
};
|
||||
|
||||
}}} // namespace Azure::Storage::Blobs
|
||||
62
sdk/storage/inc/common/xml_wrapper.hpp
Normal file
62
sdk/storage/inc/common/xml_wrapper.hpp
Normal file
@ -0,0 +1,62 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
struct _xmlTextReader;
|
||||
struct _xmlTextWriter;
|
||||
struct _xmlBuffer;
|
||||
|
||||
namespace Azure { namespace Storage {
|
||||
|
||||
enum class XmlNodeType
|
||||
{
|
||||
StartTag,
|
||||
EndTag,
|
||||
SelfClosingTag,
|
||||
Text,
|
||||
Attribute,
|
||||
End,
|
||||
};
|
||||
|
||||
struct XmlNode
|
||||
{
|
||||
explicit XmlNode(XmlNodeType type, const char* name = nullptr, const char* value = nullptr)
|
||||
: Type(type), Name(name), Value(value)
|
||||
{
|
||||
}
|
||||
XmlNodeType Type;
|
||||
const char* Name;
|
||||
const char* Value;
|
||||
};
|
||||
|
||||
class XmlReader {
|
||||
public:
|
||||
explicit XmlReader(const char* data, std::size_t length);
|
||||
~XmlReader();
|
||||
|
||||
XmlNode Read();
|
||||
|
||||
private:
|
||||
_xmlTextReader* m_reader = nullptr;
|
||||
bool m_readingAttributes = false;
|
||||
};
|
||||
|
||||
class XmlWriter {
|
||||
public:
|
||||
explicit XmlWriter();
|
||||
~XmlWriter();
|
||||
|
||||
void Write(XmlNode node);
|
||||
|
||||
std::string GetDocument();
|
||||
|
||||
private:
|
||||
_xmlBuffer* m_buffer = nullptr;
|
||||
_xmlTextWriter* m_writer = nullptr;
|
||||
};
|
||||
|
||||
}} // namespace Azure::Storage
|
||||
93
sdk/storage/src/blobs/append_blob_client.cpp
Normal file
93
sdk/storage/src/blobs/append_blob_client.cpp
Normal file
@ -0,0 +1,93 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include "blobs/append_blob_client.hpp"
|
||||
|
||||
#include "common/storage_common.hpp"
|
||||
|
||||
namespace Azure { namespace Storage { namespace Blobs {
|
||||
|
||||
AppendBlobClient AppendBlobClient::CreateFromConnectionString(
|
||||
const std::string& connectionString,
|
||||
const std::string& containerName,
|
||||
const std::string& blobName,
|
||||
const AppendBlobClientOptions& options)
|
||||
{
|
||||
AppendBlobClient newClient(
|
||||
BlobClient::CreateFromConnectionString(connectionString, containerName, blobName, options));
|
||||
return newClient;
|
||||
}
|
||||
|
||||
AppendBlobClient::AppendBlobClient(
|
||||
const std::string& blobUri,
|
||||
std::shared_ptr<SharedKeyCredential> credential,
|
||||
const AppendBlobClientOptions& options)
|
||||
: BlobClient(blobUri, std::move(credential), options)
|
||||
{
|
||||
}
|
||||
|
||||
AppendBlobClient::AppendBlobClient(
|
||||
const std::string& blobUri,
|
||||
std::shared_ptr<TokenCredential> credential,
|
||||
const AppendBlobClientOptions& options)
|
||||
: BlobClient(blobUri, std::move(credential), options)
|
||||
{
|
||||
}
|
||||
|
||||
AppendBlobClient::AppendBlobClient(
|
||||
const std::string& blobUri,
|
||||
const AppendBlobClientOptions& options)
|
||||
: BlobClient(blobUri, options)
|
||||
{
|
||||
}
|
||||
|
||||
AppendBlobClient::AppendBlobClient(BlobClient blobClient) : BlobClient(std::move(blobClient)) {}
|
||||
|
||||
AppendBlobClient AppendBlobClient::WithSnapshot(const std::string& snapshot) const
|
||||
{
|
||||
AppendBlobClient newClient(*this);
|
||||
if (snapshot.empty())
|
||||
{
|
||||
newClient.m_blobUrl.RemoveQuery("snapshot");
|
||||
}
|
||||
else
|
||||
{
|
||||
newClient.m_blobUrl.AppendQuery("snapshot", snapshot);
|
||||
}
|
||||
return newClient;
|
||||
}
|
||||
|
||||
BlobContentInfo AppendBlobClient::Create(const CreateAppendBlobOptions& options)
|
||||
{
|
||||
BlobRestClient::AppendBlob::CreateOptions protocolLayerOptions;
|
||||
protocolLayerOptions.Properties = options.Properties;
|
||||
protocolLayerOptions.Metadata = options.Metadata;
|
||||
protocolLayerOptions.Tier = options.Tier;
|
||||
protocolLayerOptions.IfModifiedSince = options.IfModifiedSince;
|
||||
protocolLayerOptions.IfUnmodifiedSince = options.IfUnmodifiedSince;
|
||||
protocolLayerOptions.IfMatch = options.IfMatch;
|
||||
protocolLayerOptions.IfNoneMatch = options.IfNoneMatch;
|
||||
return BlobRestClient::AppendBlob::Create(
|
||||
options.Context, *m_pipeline, m_blobUrl.to_string(), protocolLayerOptions);
|
||||
}
|
||||
|
||||
BlobAppendInfo AppendBlobClient::AppendBlock(
|
||||
std::vector<uint8_t> content,
|
||||
const AppendBlockOptions& options)
|
||||
{
|
||||
BlobRestClient::AppendBlob::AppendBlockOptions protocolLayerOptions;
|
||||
protocolLayerOptions.BodyBuffer = &content;
|
||||
protocolLayerOptions.ContentMD5 = options.ContentMD5;
|
||||
protocolLayerOptions.ContentCRC64 = options.ContentCRC64;
|
||||
protocolLayerOptions.LeaseId = options.LeaseId;
|
||||
protocolLayerOptions.MaxSize = options.MaxSize;
|
||||
protocolLayerOptions.AppendPosition = options.AppendPosition;
|
||||
protocolLayerOptions.IfModifiedSince = options.IfModifiedSince;
|
||||
protocolLayerOptions.IfUnmodifiedSince = options.IfUnmodifiedSince;
|
||||
protocolLayerOptions.IfMatch = options.IfMatch;
|
||||
protocolLayerOptions.IfNoneMatch = options.IfNoneMatch;
|
||||
return BlobRestClient::AppendBlob::AppendBlock(
|
||||
options.Context, *m_pipeline, m_blobUrl.to_string(), protocolLayerOptions);
|
||||
}
|
||||
|
||||
}}} // namespace Azure::Storage::Blobs
|
||||
@ -123,48 +123,62 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
m_pipeline = std::make_shared<Azure::Core::Http::HttpPipeline>(policies);
|
||||
}
|
||||
|
||||
BlobClient BlobClient::WithSnapshot(const std::string& snapshot)
|
||||
BlobClient BlobClient::WithSnapshot(const std::string& snapshot) const
|
||||
{
|
||||
BlobClient newClient(*this);
|
||||
if (snapshot.empty())
|
||||
{
|
||||
m_blobUrl.RemoveQuery("snapshot");
|
||||
newClient.m_blobUrl.RemoveQuery("snapshot");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_blobUrl.AppendQuery("snapshot", snapshot);
|
||||
newClient.m_blobUrl.AppendQuery("snapshot", snapshot);
|
||||
}
|
||||
return newClient;
|
||||
}
|
||||
|
||||
FlattenedDownloadProperties BlobClient::Download(const DownloadBlobOptions& options)
|
||||
FlattenedDownloadProperties BlobClient::Download(const DownloadBlobOptions& options) const
|
||||
{
|
||||
BlobRestClient::Blob::DownloadOptions protocolLayerOptions;
|
||||
if (options.Offset != std::numeric_limits<decltype(options.Offset)>::max())
|
||||
{
|
||||
protocolLayerOptions.Range
|
||||
= std::make_pair(options.Offset, options.Offset + options.Length - 1);
|
||||
if (options.Length == 0)
|
||||
{
|
||||
protocolLayerOptions.Range
|
||||
= std::make_pair(options.Offset, std::numeric_limits<decltype(options.Offset)>::max());
|
||||
}
|
||||
else
|
||||
{
|
||||
protocolLayerOptions.Range
|
||||
= std::make_pair(options.Offset, options.Offset + options.Length - 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
protocolLayerOptions.Range
|
||||
= std::make_pair(std::numeric_limits<uint64_t>::max(), uint64_t(0));
|
||||
}
|
||||
protocolLayerOptions.IfModifiedSince = options.IfModifiedSince;
|
||||
protocolLayerOptions.IfUnmodifiedSince = options.IfUnmodifiedSince;
|
||||
protocolLayerOptions.IfMatch = options.IfMatch;
|
||||
protocolLayerOptions.IfNoneMatch = options.IfNoneMatch;
|
||||
|
||||
return BlobRestClient::Blob::Download(
|
||||
options.Context, *m_pipeline, m_blobUrl.to_string(), protocolLayerOptions);
|
||||
}
|
||||
|
||||
BlobProperties BlobClient::GetProperties(const GetBlobPropertiesOptions& options)
|
||||
BlobProperties BlobClient::GetProperties(const GetBlobPropertiesOptions& options) const
|
||||
{
|
||||
unused(options);
|
||||
|
||||
BlobRestClient::Blob::GetPropertiesOptions protocolLayerOptions;
|
||||
protocolLayerOptions.IfModifiedSince = options.IfModifiedSince;
|
||||
protocolLayerOptions.IfUnmodifiedSince = options.IfUnmodifiedSince;
|
||||
protocolLayerOptions.IfMatch = options.IfMatch;
|
||||
protocolLayerOptions.IfNoneMatch = options.IfNoneMatch;
|
||||
return BlobRestClient::Blob::GetProperties(
|
||||
options.Context, *m_pipeline, m_blobUrl.to_string(), protocolLayerOptions);
|
||||
}
|
||||
|
||||
BlobInfo BlobClient::SetHttpHeaders(const SetBlobHttpHeadersOptions& options)
|
||||
BlobInfo BlobClient::SetHttpHeaders(const SetBlobHttpHeadersOptions& options) const
|
||||
{
|
||||
BlobRestClient::Blob::SetHttpHeadersOptions protocolLayerOptions;
|
||||
protocolLayerOptions.ContentType = options.ContentType;
|
||||
@ -173,27 +187,102 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
protocolLayerOptions.ContentMD5 = options.ContentMD5;
|
||||
protocolLayerOptions.CacheControl = options.CacheControl;
|
||||
protocolLayerOptions.ContentDisposition = options.ContentDisposition;
|
||||
protocolLayerOptions.IfModifiedSince = options.IfModifiedSince;
|
||||
protocolLayerOptions.IfUnmodifiedSince = options.IfUnmodifiedSince;
|
||||
protocolLayerOptions.IfMatch = options.IfMatch;
|
||||
protocolLayerOptions.IfNoneMatch = options.IfNoneMatch;
|
||||
return BlobRestClient::Blob::SetHttpHeaders(
|
||||
options.Context, *m_pipeline, m_blobUrl.to_string(), protocolLayerOptions);
|
||||
}
|
||||
|
||||
BlobInfo BlobClient::SetMetadata(
|
||||
std::map<std::string, std::string> metadata,
|
||||
const SetBlobMetadataOptions& options)
|
||||
const SetBlobMetadataOptions& options) const
|
||||
{
|
||||
unused(options);
|
||||
BlobRestClient::Blob::SetMetadataOptions protocolLayerOptions;
|
||||
protocolLayerOptions.Metadata = std::move(metadata);
|
||||
protocolLayerOptions.IfModifiedSince = options.IfModifiedSince;
|
||||
protocolLayerOptions.IfUnmodifiedSince = options.IfUnmodifiedSince;
|
||||
protocolLayerOptions.IfMatch = options.IfMatch;
|
||||
protocolLayerOptions.IfNoneMatch = options.IfNoneMatch;
|
||||
return BlobRestClient::Blob::SetMetadata(
|
||||
options.Context, *m_pipeline, m_blobUrl.to_string(), protocolLayerOptions);
|
||||
}
|
||||
|
||||
BasicResponse BlobClient::Delete(const DeleteBlobOptions& options)
|
||||
BasicResponse BlobClient::SetAccessTier(AccessTier Tier, const SetAccessTierOptions& options)
|
||||
const
|
||||
{
|
||||
BlobRestClient::Blob::SetAccessTierOptions protocolLayerOptions;
|
||||
protocolLayerOptions.Tier = Tier;
|
||||
protocolLayerOptions.RehydratePriority = options.RehydratePriority;
|
||||
return BlobRestClient::Blob::SetAccessTier(
|
||||
options.Context, *m_pipeline, m_blobUrl.to_string(), protocolLayerOptions);
|
||||
}
|
||||
|
||||
BlobCopyInfo BlobClient::StartCopyFromUri(
|
||||
const std::string& sourceUri,
|
||||
const StartCopyFromUriOptions& options) const
|
||||
{
|
||||
BlobRestClient::Blob::StartCopyFromUriOptions protocolLayerOptions;
|
||||
protocolLayerOptions.Metadata = options.Metadata;
|
||||
protocolLayerOptions.SourceUri = sourceUri;
|
||||
protocolLayerOptions.LeaseId = options.LeaseId;
|
||||
protocolLayerOptions.SourceLeaseId = options.SourceLeaseId;
|
||||
protocolLayerOptions.Tier = options.Tier;
|
||||
protocolLayerOptions.RehydratePriority = options.RehydratePriority;
|
||||
protocolLayerOptions.IfModifiedSince = options.IfModifiedSince;
|
||||
protocolLayerOptions.IfUnmodifiedSince = options.IfUnmodifiedSince;
|
||||
protocolLayerOptions.IfMatch = options.IfMatch;
|
||||
protocolLayerOptions.IfNoneMatch = options.IfNoneMatch;
|
||||
protocolLayerOptions.SourceIfModifiedSince = options.SourceIfModifiedSince;
|
||||
protocolLayerOptions.SourceIfUnmodifiedSince = options.IfUnmodifiedSince;
|
||||
protocolLayerOptions.SourceIfMatch = options.SourceIfMatch;
|
||||
protocolLayerOptions.SourceIfNoneMatch = options.SourceIfNoneMatch;
|
||||
return BlobRestClient::Blob::StartCopyFromUri(
|
||||
options.Context, *m_pipeline, m_blobUrl.to_string(), protocolLayerOptions);
|
||||
}
|
||||
|
||||
BasicResponse BlobClient::AbortCopyFromUri(
|
||||
const std::string& copyId,
|
||||
const AbortCopyFromUriOptions& options) const
|
||||
{
|
||||
BlobRestClient::Blob::AbortCopyFromUriOptions protocolLayerOptions;
|
||||
protocolLayerOptions.CopyId = copyId;
|
||||
protocolLayerOptions.LeaseId = options.LeaseId;
|
||||
return BlobRestClient::Blob::AbortCopyFromUri(
|
||||
options.Context, *m_pipeline, m_blobUrl.to_string(), protocolLayerOptions);
|
||||
}
|
||||
|
||||
BlobSnapshotInfo BlobClient::CreateSnapshot(const CreateSnapshotOptions& options) const
|
||||
{
|
||||
BlobRestClient::Blob::CreateSnapshotOptions protocolLayerOptions;
|
||||
protocolLayerOptions.Metadata = options.Metadata;
|
||||
protocolLayerOptions.LeaseId = options.LeaseId;
|
||||
protocolLayerOptions.IfModifiedSince = options.IfModifiedSince;
|
||||
protocolLayerOptions.IfUnmodifiedSince = options.IfUnmodifiedSince;
|
||||
protocolLayerOptions.IfMatch = options.IfMatch;
|
||||
protocolLayerOptions.IfNoneMatch = options.IfNoneMatch;
|
||||
return BlobRestClient::Blob::CreateSnapshot(
|
||||
options.Context, *m_pipeline, m_blobUrl.to_string(), protocolLayerOptions);
|
||||
}
|
||||
|
||||
BasicResponse BlobClient::Delete(const DeleteBlobOptions& options) const
|
||||
{
|
||||
BlobRestClient::Blob::DeleteOptions protocolLayerOptions;
|
||||
protocolLayerOptions.DeleteSnapshots = options.DeleteSnapshots;
|
||||
protocolLayerOptions.IfModifiedSince = options.IfModifiedSince;
|
||||
protocolLayerOptions.IfUnmodifiedSince = options.IfUnmodifiedSince;
|
||||
protocolLayerOptions.IfMatch = options.IfMatch;
|
||||
protocolLayerOptions.IfNoneMatch = options.IfNoneMatch;
|
||||
return BlobRestClient::Blob::Delete(
|
||||
options.Context, *m_pipeline, m_blobUrl.to_string(), protocolLayerOptions);
|
||||
}
|
||||
|
||||
BasicResponse BlobClient::Undelete(const UndeleteBlobOptions& options) const
|
||||
{
|
||||
BlobRestClient::Blob::UndeleteOptions protocolLayerOptions;
|
||||
return BlobRestClient::Blob::Undelete(
|
||||
options.Context, *m_pipeline, m_blobUrl.to_string(), protocolLayerOptions);
|
||||
}
|
||||
|
||||
}}} // namespace Azure::Storage::Blobs
|
||||
|
||||
@ -123,7 +123,7 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
m_pipeline = std::make_shared<Azure::Core::Http::HttpPipeline>(policies);
|
||||
}
|
||||
|
||||
BlobContainerInfo BlobContainerClient::Create(const CreateBlobContainerOptions& options)
|
||||
BlobContainerInfo BlobContainerClient::Create(const CreateBlobContainerOptions& options) const
|
||||
{
|
||||
BlobRestClient::Container::CreateOptions protocolLayerOptions;
|
||||
protocolLayerOptions.AccessType = options.AccessType;
|
||||
@ -132,16 +132,17 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
options.Context, *m_pipeline, m_ContainerUri.to_string(), protocolLayerOptions);
|
||||
}
|
||||
|
||||
BasicResponse BlobContainerClient::Delete(const DeleteBlobContainerOptions& options)
|
||||
BasicResponse BlobContainerClient::Delete(const DeleteBlobContainerOptions& options) const
|
||||
{
|
||||
unused(options);
|
||||
BlobRestClient::Container::DeleteOptions protocolLayerOptions;
|
||||
protocolLayerOptions.IfModifiedSince = options.IfModifiedSince;
|
||||
protocolLayerOptions.IfUnmodifiedSince = options.IfUnmodifiedSince;
|
||||
return BlobRestClient::Container::Delete(
|
||||
options.Context, *m_pipeline, m_ContainerUri.to_string(), protocolLayerOptions);
|
||||
}
|
||||
|
||||
BlobContainerProperties BlobContainerClient::GetProperties(
|
||||
const GetBlobContainerPropertiesOptions& options)
|
||||
const GetBlobContainerPropertiesOptions& options) const
|
||||
{
|
||||
unused(options);
|
||||
BlobRestClient::Container::GetPropertiesOptions protocolLayerOptions;
|
||||
@ -151,16 +152,16 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
|
||||
BlobContainerInfo BlobContainerClient::SetMetadata(
|
||||
std::map<std::string, std::string> metadata,
|
||||
SetBlobContainerMetadataOptions options)
|
||||
SetBlobContainerMetadataOptions options) const
|
||||
{
|
||||
unused(options);
|
||||
BlobRestClient::Container::SetMetadataOptions protocolLayerOptions;
|
||||
protocolLayerOptions.Metadata = metadata;
|
||||
protocolLayerOptions.IfModifiedSince = options.IfModifiedSince;
|
||||
return BlobRestClient::Container::SetMetadata(
|
||||
options.Context, *m_pipeline, m_ContainerUri.to_string(), protocolLayerOptions);
|
||||
}
|
||||
|
||||
BlobsFlatSegment BlobContainerClient::ListBlobs(const ListBlobsOptions& options)
|
||||
BlobsFlatSegment BlobContainerClient::ListBlobs(const ListBlobsOptions& options) const
|
||||
{
|
||||
BlobRestClient::Container::ListBlobsOptions protocolLayerOptions;
|
||||
protocolLayerOptions.Prefix = options.Prefix;
|
||||
|
||||
154
sdk/storage/src/blobs/blob_service_client.cpp
Normal file
154
sdk/storage/src/blobs/blob_service_client.cpp
Normal file
@ -0,0 +1,154 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include "blobs/blob_service_client.hpp"
|
||||
|
||||
#include "common/common_headers_request_policy.hpp"
|
||||
#include "common/shared_key_policy.hpp"
|
||||
#include "common/storage_common.hpp"
|
||||
#include "http/curl/curl.hpp"
|
||||
|
||||
namespace Azure { namespace Storage { namespace Blobs {
|
||||
|
||||
BlobServiceClient BlobServiceClient::CreateFromConnectionString(
|
||||
const std::string& connectionString,
|
||||
const BlobServiceClientOptions& options)
|
||||
{
|
||||
auto parsedConnectionString = ParseConnectionString(connectionString);
|
||||
|
||||
std::string accountName;
|
||||
std::string accountKey;
|
||||
std::string blobEndpoint;
|
||||
std::string EndpointSuffix;
|
||||
std::string defaultEndpointsProtocol = ".core.windows.net";
|
||||
|
||||
auto ite = parsedConnectionString.find("AccountName");
|
||||
if (ite != parsedConnectionString.end())
|
||||
{
|
||||
accountName = ite->second;
|
||||
}
|
||||
ite = parsedConnectionString.find("AccountKey");
|
||||
if (ite != parsedConnectionString.end())
|
||||
{
|
||||
accountKey = ite->second;
|
||||
}
|
||||
ite = parsedConnectionString.find("BlobEndpoint");
|
||||
if (ite != parsedConnectionString.end())
|
||||
{
|
||||
blobEndpoint = ite->second;
|
||||
}
|
||||
ite = parsedConnectionString.find("EndpointSuffix");
|
||||
if (ite != parsedConnectionString.end())
|
||||
{
|
||||
EndpointSuffix = ite->second;
|
||||
}
|
||||
ite = parsedConnectionString.find("DefaultEndpointsProtocol");
|
||||
if (ite != parsedConnectionString.end())
|
||||
{
|
||||
defaultEndpointsProtocol = ite->second;
|
||||
}
|
||||
|
||||
UrlBuilder builder;
|
||||
builder.SetScheme(defaultEndpointsProtocol);
|
||||
if (!blobEndpoint.empty())
|
||||
{
|
||||
builder = UrlBuilder(blobEndpoint);
|
||||
}
|
||||
else if (!accountName.empty())
|
||||
{
|
||||
builder.SetHost(accountName + ".blob." + EndpointSuffix);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("invalid connection string");
|
||||
}
|
||||
|
||||
auto credential = std::make_shared<SharedKeyCredential>(accountName, accountKey);
|
||||
|
||||
return BlobServiceClient(builder.to_string(), credential, options);
|
||||
}
|
||||
|
||||
BlobServiceClient::BlobServiceClient(
|
||||
const std::string& serviceUri,
|
||||
std::shared_ptr<SharedKeyCredential> credential,
|
||||
const BlobServiceClientOptions& options)
|
||||
: m_serviceUrl(serviceUri)
|
||||
{
|
||||
std::vector<std::unique_ptr<Azure::Core::Http::HttpPolicy>> policies;
|
||||
for (const auto& p : options.policies)
|
||||
{
|
||||
policies.emplace_back(std::unique_ptr<Azure::Core::Http::HttpPolicy>(p->Clone()));
|
||||
}
|
||||
policies.emplace_back(std::make_unique<CommonHeadersRequestPolicy>());
|
||||
policies.emplace_back(std::make_unique<SharedKeyPolicy>(credential));
|
||||
policies.emplace_back(std::make_unique<Azure::Core::Http::TransportPolicy>(
|
||||
std::make_shared<Azure::Core::Http::CurlTransport>()));
|
||||
m_pipeline = std::make_shared<Azure::Core::Http::HttpPipeline>(policies);
|
||||
}
|
||||
|
||||
BlobServiceClient::BlobServiceClient(
|
||||
const std::string& serviceUri,
|
||||
std::shared_ptr<TokenCredential> credential,
|
||||
const BlobServiceClientOptions& options)
|
||||
: m_serviceUrl(serviceUri)
|
||||
{
|
||||
std::vector<std::unique_ptr<Azure::Core::Http::HttpPolicy>> policies;
|
||||
for (const auto& p : options.policies)
|
||||
{
|
||||
policies.emplace_back(std::unique_ptr<Azure::Core::Http::HttpPolicy>(p->Clone()));
|
||||
}
|
||||
policies.emplace_back(std::make_unique<CommonHeadersRequestPolicy>());
|
||||
// not implemented yet
|
||||
unused(credential);
|
||||
policies.emplace_back(std::make_unique<Azure::Core::Http::TransportPolicy>(
|
||||
std::make_shared<Azure::Core::Http::CurlTransport>()));
|
||||
m_pipeline = std::make_shared<Azure::Core::Http::HttpPipeline>(policies);
|
||||
}
|
||||
|
||||
BlobServiceClient::BlobServiceClient(
|
||||
const std::string& serviceUri,
|
||||
const BlobServiceClientOptions& options)
|
||||
: m_serviceUrl(serviceUri)
|
||||
{
|
||||
std::vector<std::unique_ptr<Azure::Core::Http::HttpPolicy>> policies;
|
||||
for (const auto& p : options.policies)
|
||||
{
|
||||
policies.emplace_back(std::unique_ptr<Azure::Core::Http::HttpPolicy>(p->Clone()));
|
||||
}
|
||||
policies.emplace_back(std::make_unique<CommonHeadersRequestPolicy>());
|
||||
policies.emplace_back(std::make_unique<Azure::Core::Http::TransportPolicy>(
|
||||
std::make_shared<Azure::Core::Http::CurlTransport>()));
|
||||
m_pipeline = std::make_shared<Azure::Core::Http::HttpPipeline>(policies);
|
||||
}
|
||||
|
||||
ListContainersSegment BlobServiceClient::ListBlobContainersSegment(
|
||||
const ListBlobContainersOptions& options) const
|
||||
{
|
||||
BlobRestClient::Service::ListBlobContainersOptions protocolLayerOptions;
|
||||
protocolLayerOptions.Prefix = options.Prefix;
|
||||
protocolLayerOptions.Marker = options.Marker;
|
||||
protocolLayerOptions.MaxResults = options.MaxResults;
|
||||
protocolLayerOptions.IncludeMetadata = ListBlobContainersIncludeOption::None;
|
||||
for (auto i : options.Include)
|
||||
{
|
||||
if (i == ListBlobContainersIncludeOption::Metadata)
|
||||
{
|
||||
protocolLayerOptions.IncludeMetadata = i;
|
||||
}
|
||||
}
|
||||
return BlobRestClient::Service::ListBlobContainers(
|
||||
options.Context, *m_pipeline, m_serviceUrl.to_string(), protocolLayerOptions);
|
||||
}
|
||||
|
||||
UserDelegationKey BlobServiceClient::GetUserDelegationKey(
|
||||
const std::string& expiresOn,
|
||||
const GetUserDelegationKeyOptions& options) const
|
||||
{
|
||||
BlobRestClient::Service::GetUserDelegationKeyOptions protocolLayerOptions;
|
||||
protocolLayerOptions.StartsOn = options.StartsOn;
|
||||
protocolLayerOptions.ExpiresOn = expiresOn;
|
||||
return BlobRestClient::Service::GetUserDelegationKey(
|
||||
options.Context, *m_pipeline, m_serviceUrl.to_string(), protocolLayerOptions);
|
||||
}
|
||||
|
||||
}}} // namespace Azure::Storage::Blobs
|
||||
@ -43,7 +43,7 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
|
||||
BlockBlobClient::BlockBlobClient(BlobClient blobClient) : BlobClient(std::move(blobClient)) {}
|
||||
|
||||
BlockBlobClient BlockBlobClient::WithSnapshot(const std::string& snapshot)
|
||||
BlockBlobClient BlockBlobClient::WithSnapshot(const std::string& snapshot) const
|
||||
{
|
||||
BlockBlobClient newClient(*this);
|
||||
if (snapshot.empty())
|
||||
@ -60,16 +60,19 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
BlobContentInfo BlockBlobClient::Upload(
|
||||
// TODO: We don't have BodyStream for now.
|
||||
std::vector<uint8_t> content,
|
||||
const UploadBlobOptions& options)
|
||||
const UploadBlobOptions& options) const
|
||||
{
|
||||
BlobRestClient::BlockBlob::UploadOptions protocolLayerOptions;
|
||||
protocolLayerOptions.BodyBuffer = &content;
|
||||
protocolLayerOptions.ContentMD5 = options.ContentMD5;
|
||||
protocolLayerOptions.ContentCRC64 = options.ContentCRC64;
|
||||
protocolLayerOptions.BlobType = BlobType::BlockBlob;
|
||||
protocolLayerOptions.Properties = options.Properties;
|
||||
protocolLayerOptions.Metadata = options.Metadata;
|
||||
protocolLayerOptions.Tier = options.Tier;
|
||||
protocolLayerOptions.IfModifiedSince = options.IfModifiedSince;
|
||||
protocolLayerOptions.IfUnmodifiedSince = options.IfUnmodifiedSince;
|
||||
protocolLayerOptions.IfMatch = options.IfMatch;
|
||||
protocolLayerOptions.IfNoneMatch = options.IfNoneMatch;
|
||||
return BlobRestClient::BlockBlob::Upload(
|
||||
options.Context, *m_pipeline, m_blobUrl.to_string(), protocolLayerOptions);
|
||||
}
|
||||
@ -78,7 +81,7 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
const std::string& blockId,
|
||||
// TODO: We don't have BodyStream for now.
|
||||
std::vector<uint8_t> content,
|
||||
const StageBlockOptions& options)
|
||||
const StageBlockOptions& options) const
|
||||
{
|
||||
BlobRestClient::BlockBlob::StageBlockOptions protocolLayerOptions;
|
||||
protocolLayerOptions.BodyBuffer = &content;
|
||||
@ -89,23 +92,68 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
options.Context, *m_pipeline, m_blobUrl.to_string(), protocolLayerOptions);
|
||||
}
|
||||
|
||||
BlockInfo BlockBlobClient::StageBlockFromUri(
|
||||
const std::string& blockId,
|
||||
const std::string& sourceUri,
|
||||
const StageBlockFromUriOptions& options) const
|
||||
{
|
||||
BlobRestClient::BlockBlob::StageBlockFromUriOptions protocolLayerOptions;
|
||||
protocolLayerOptions.BlockId = blockId;
|
||||
protocolLayerOptions.SourceUri = sourceUri;
|
||||
if (options.SourceOffset != std::numeric_limits<decltype(options.SourceOffset)>::max())
|
||||
{
|
||||
if (options.SourceLength == 0)
|
||||
{
|
||||
protocolLayerOptions.SourceRange = std::make_pair(
|
||||
options.SourceOffset, std::numeric_limits<decltype(options.SourceOffset)>::max());
|
||||
}
|
||||
else
|
||||
{
|
||||
protocolLayerOptions.SourceRange
|
||||
= std::make_pair(options.SourceOffset, options.SourceOffset + options.SourceLength - 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
protocolLayerOptions.SourceRange
|
||||
= std::make_pair(std::numeric_limits<uint64_t>::max(), uint64_t(0));
|
||||
}
|
||||
protocolLayerOptions.ContentMD5 = options.ContentMD5;
|
||||
protocolLayerOptions.ContentCRC64 = options.ContentCRC64;
|
||||
protocolLayerOptions.LeaseId = options.LeaseId;
|
||||
protocolLayerOptions.SourceIfModifiedSince = options.SourceIfModifiedSince;
|
||||
protocolLayerOptions.SourceIfUnmodifiedSince = options.SourceIfUnmodifiedSince;
|
||||
protocolLayerOptions.SourceIfMatch = options.SourceIfMatch;
|
||||
protocolLayerOptions.SourceIfNoneMatch = options.SourceIfNoneMatch;
|
||||
return BlobRestClient::BlockBlob::StageBlockFromUri(
|
||||
options.Context, *m_pipeline, m_blobUrl.to_string(), protocolLayerOptions);
|
||||
}
|
||||
|
||||
BlobContentInfo BlockBlobClient::CommitBlockList(
|
||||
const std::vector<std::pair<BlockType, std::string>>& blockIds,
|
||||
const CommitBlockListOptions& options)
|
||||
const CommitBlockListOptions& options) const
|
||||
{
|
||||
BlobRestClient::BlockBlob::CommitBlockListOptions protocolLayerOptions;
|
||||
protocolLayerOptions.BlockList = blockIds;
|
||||
protocolLayerOptions.Properties = options.Properties;
|
||||
protocolLayerOptions.Metadata = options.Metadata;
|
||||
protocolLayerOptions.Tier = options.Tier;
|
||||
protocolLayerOptions.IfModifiedSince = options.IfModifiedSince;
|
||||
protocolLayerOptions.IfUnmodifiedSince = options.IfUnmodifiedSince;
|
||||
protocolLayerOptions.IfMatch = options.IfMatch;
|
||||
protocolLayerOptions.IfNoneMatch = options.IfNoneMatch;
|
||||
return BlobRestClient::BlockBlob::CommitBlockList(
|
||||
options.Context, *m_pipeline, m_blobUrl.to_string(), protocolLayerOptions);
|
||||
}
|
||||
|
||||
BlobBlockListInfo BlockBlobClient::GetBlockList(const GetBlockListOptions& options)
|
||||
BlobBlockListInfo BlockBlobClient::GetBlockList(const GetBlockListOptions& options) const
|
||||
{
|
||||
BlobRestClient::BlockBlob::GetBlockListOptions protocolLayerOptions;
|
||||
protocolLayerOptions.ListType = options.ListType;
|
||||
protocolLayerOptions.IfModifiedSince = options.IfModifiedSince;
|
||||
protocolLayerOptions.IfUnmodifiedSince = options.IfUnmodifiedSince;
|
||||
protocolLayerOptions.IfMatch = options.IfMatch;
|
||||
protocolLayerOptions.IfNoneMatch = options.IfNoneMatch;
|
||||
return BlobRestClient::BlockBlob::GetBlockList(
|
||||
options.Context, *m_pipeline, m_blobUrl.to_string(), protocolLayerOptions);
|
||||
}
|
||||
|
||||
178
sdk/storage/src/blobs/page_blob_client.cpp
Normal file
178
sdk/storage/src/blobs/page_blob_client.cpp
Normal file
@ -0,0 +1,178 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include "blobs/page_blob_client.hpp"
|
||||
|
||||
#include "common/storage_common.hpp"
|
||||
|
||||
namespace Azure { namespace Storage { namespace Blobs {
|
||||
|
||||
PageBlobClient PageBlobClient::CreateFromConnectionString(
|
||||
const std::string& connectionString,
|
||||
const std::string& containerName,
|
||||
const std::string& blobName,
|
||||
const PageBlobClientOptions& options)
|
||||
{
|
||||
PageBlobClient newClient(
|
||||
BlobClient::CreateFromConnectionString(connectionString, containerName, blobName, options));
|
||||
return newClient;
|
||||
}
|
||||
|
||||
PageBlobClient::PageBlobClient(
|
||||
const std::string& blobUri,
|
||||
std::shared_ptr<SharedKeyCredential> credential,
|
||||
const PageBlobClientOptions& options)
|
||||
: BlobClient(blobUri, std::move(credential), options)
|
||||
{
|
||||
}
|
||||
|
||||
PageBlobClient::PageBlobClient(
|
||||
const std::string& blobUri,
|
||||
std::shared_ptr<TokenCredential> credential,
|
||||
const PageBlobClientOptions& options)
|
||||
: BlobClient(blobUri, std::move(credential), options)
|
||||
{
|
||||
}
|
||||
|
||||
PageBlobClient::PageBlobClient(const std::string& blobUri, const PageBlobClientOptions& options)
|
||||
: BlobClient(blobUri, options)
|
||||
{
|
||||
}
|
||||
|
||||
PageBlobClient::PageBlobClient(BlobClient blobClient) : BlobClient(std::move(blobClient)) {}
|
||||
|
||||
PageBlobClient PageBlobClient::WithSnapshot(const std::string& snapshot) const
|
||||
{
|
||||
PageBlobClient newClient(*this);
|
||||
if (snapshot.empty())
|
||||
{
|
||||
newClient.m_blobUrl.RemoveQuery("snapshot");
|
||||
}
|
||||
else
|
||||
{
|
||||
newClient.m_blobUrl.AppendQuery("snapshot", snapshot);
|
||||
}
|
||||
return newClient;
|
||||
}
|
||||
|
||||
BlobContentInfo PageBlobClient::Create(
|
||||
uint64_t blobContentLength,
|
||||
const CreatePageBlobOptions& options)
|
||||
{
|
||||
BlobRestClient::PageBlob::CreateOptions protocolLayerOptions;
|
||||
protocolLayerOptions.BlobContentLength = blobContentLength;
|
||||
protocolLayerOptions.SequenceNumber = options.SequenceNumber;
|
||||
protocolLayerOptions.Properties = options.Properties;
|
||||
protocolLayerOptions.Metadata = options.Metadata;
|
||||
protocolLayerOptions.Tier = options.Tier;
|
||||
protocolLayerOptions.IfModifiedSince = options.IfModifiedSince;
|
||||
protocolLayerOptions.IfUnmodifiedSince = options.IfUnmodifiedSince;
|
||||
protocolLayerOptions.IfMatch = options.IfMatch;
|
||||
protocolLayerOptions.IfNoneMatch = options.IfNoneMatch;
|
||||
return BlobRestClient::PageBlob::Create(
|
||||
options.Context, *m_pipeline, m_blobUrl.to_string(), protocolLayerOptions);
|
||||
}
|
||||
|
||||
PageInfo PageBlobClient::UploadPages(
|
||||
std::vector<uint8_t> content,
|
||||
uint64_t offset,
|
||||
const UploadPagesOptions& options)
|
||||
{
|
||||
BlobRestClient::PageBlob::UploadPagesOptions protocolLayerOptions;
|
||||
protocolLayerOptions.BodyBuffer = &content;
|
||||
protocolLayerOptions.Range = std::make_pair(offset, offset + content.size() - 1);
|
||||
protocolLayerOptions.ContentMD5 = options.ContentMD5;
|
||||
protocolLayerOptions.ContentCRC64 = options.ContentCRC64;
|
||||
protocolLayerOptions.LeaseId = options.LeaseId;
|
||||
protocolLayerOptions.IfModifiedSince = options.IfModifiedSince;
|
||||
protocolLayerOptions.IfUnmodifiedSince = options.IfUnmodifiedSince;
|
||||
protocolLayerOptions.IfMatch = options.IfMatch;
|
||||
protocolLayerOptions.IfNoneMatch = options.IfNoneMatch;
|
||||
return BlobRestClient::PageBlob::UploadPages(
|
||||
options.Context, *m_pipeline, m_blobUrl.to_string(), protocolLayerOptions);
|
||||
}
|
||||
|
||||
PageInfo PageBlobClient::UploadPagesFromUri(
|
||||
std::string sourceUri,
|
||||
uint64_t sourceOffset,
|
||||
uint64_t sourceLength,
|
||||
uint64_t destinationoffset,
|
||||
const UploadPagesFromUriOptions& options)
|
||||
{
|
||||
BlobRestClient::PageBlob::UploadPagesFromUriOptions protocolLayerOptions;
|
||||
protocolLayerOptions.SourceUri = sourceUri;
|
||||
protocolLayerOptions.SourceRange
|
||||
= std::make_pair(sourceOffset, sourceOffset + sourceLength - 1);
|
||||
protocolLayerOptions.Range
|
||||
= std::make_pair(destinationoffset, destinationoffset + sourceLength - 1);
|
||||
protocolLayerOptions.ContentMD5 = options.ContentMD5;
|
||||
protocolLayerOptions.ContentCRC64 = options.ContentCRC64;
|
||||
protocolLayerOptions.LeaseId = options.LeaseId;
|
||||
protocolLayerOptions.IfModifiedSince = options.IfModifiedSince;
|
||||
protocolLayerOptions.IfUnmodifiedSince = options.IfUnmodifiedSince;
|
||||
protocolLayerOptions.IfMatch = options.IfMatch;
|
||||
protocolLayerOptions.IfNoneMatch = options.IfNoneMatch;
|
||||
return BlobRestClient::PageBlob::UploadPagesFromUri(
|
||||
options.Context, *m_pipeline, m_blobUrl.to_string(), protocolLayerOptions);
|
||||
}
|
||||
|
||||
PageInfo PageBlobClient::ClearPages(
|
||||
uint64_t offset,
|
||||
uint64_t length,
|
||||
const ClearPagesOptions& options)
|
||||
{
|
||||
BlobRestClient::PageBlob::ClearPagesOptions protocolLayerOptions;
|
||||
protocolLayerOptions.Range = std::make_pair(offset, offset + length - 1);
|
||||
protocolLayerOptions.LeaseId = options.LeaseId;
|
||||
protocolLayerOptions.IfModifiedSince = options.IfModifiedSince;
|
||||
protocolLayerOptions.IfUnmodifiedSince = options.IfUnmodifiedSince;
|
||||
protocolLayerOptions.IfMatch = options.IfMatch;
|
||||
protocolLayerOptions.IfNoneMatch = options.IfNoneMatch;
|
||||
return BlobRestClient::PageBlob::ClearPages(
|
||||
options.Context, *m_pipeline, m_blobUrl.to_string(), protocolLayerOptions);
|
||||
}
|
||||
|
||||
PageBlobInfo PageBlobClient::Resize(
|
||||
uint64_t blobContentLength,
|
||||
const ResizePageBlobOptions& options)
|
||||
{
|
||||
BlobRestClient::PageBlob::ResizeOptions protocolLayerOptions;
|
||||
protocolLayerOptions.BlobContentLength = blobContentLength;
|
||||
protocolLayerOptions.IfModifiedSince = options.IfModifiedSince;
|
||||
protocolLayerOptions.IfUnmodifiedSince = options.IfUnmodifiedSince;
|
||||
protocolLayerOptions.IfMatch = options.IfMatch;
|
||||
protocolLayerOptions.IfNoneMatch = options.IfNoneMatch;
|
||||
return BlobRestClient::PageBlob::Resize(
|
||||
options.Context, *m_pipeline, m_blobUrl.to_string(), protocolLayerOptions);
|
||||
}
|
||||
|
||||
PageRangesInfo PageBlobClient::GetPageRanges(const GetPageRangesOptions& options)
|
||||
{
|
||||
BlobRestClient::PageBlob::GetPageRangesOptions protocolLayerOptions;
|
||||
protocolLayerOptions.PreviousSnapshot = options.PreviousSnapshot;
|
||||
protocolLayerOptions.PreviousSnapshotUrl = options.PreviousSnapshotUrl;
|
||||
protocolLayerOptions.Range
|
||||
= std::make_pair(options.Offset, options.Offset + options.Length - 1);
|
||||
protocolLayerOptions.IfModifiedSince = options.IfModifiedSince;
|
||||
protocolLayerOptions.IfUnmodifiedSince = options.IfUnmodifiedSince;
|
||||
protocolLayerOptions.IfMatch = options.IfMatch;
|
||||
protocolLayerOptions.IfNoneMatch = options.IfNoneMatch;
|
||||
return BlobRestClient::PageBlob::GetPageRanges(
|
||||
options.Context, *m_pipeline, m_blobUrl.to_string(), protocolLayerOptions);
|
||||
}
|
||||
|
||||
BlobCopyInfo PageBlobClient::StartCopyIncremental(
|
||||
const std::string& sourceUri,
|
||||
const IncrementalCopyPageBlobOptions& options)
|
||||
{
|
||||
BlobRestClient::PageBlob::CopyIncrementalOptions protocolLayerOptions;
|
||||
protocolLayerOptions.CopySource = sourceUri;
|
||||
protocolLayerOptions.IfModifiedSince = options.IfModifiedSince;
|
||||
protocolLayerOptions.IfUnmodifiedSince = options.IfUnmodifiedSince;
|
||||
protocolLayerOptions.IfMatch = options.IfMatch;
|
||||
protocolLayerOptions.IfNoneMatch = options.IfNoneMatch;
|
||||
return BlobRestClient::PageBlob::CopyIncremental(
|
||||
options.Context, *m_pipeline, m_blobUrl.to_string(), protocolLayerOptions);
|
||||
}
|
||||
|
||||
}}} // namespace Azure::Storage::Blobs
|
||||
@ -31,7 +31,7 @@ namespace Azure { namespace Storage {
|
||||
AlgorithmProviderInstance()
|
||||
{
|
||||
NTSTATUS status = BCryptOpenAlgorithmProvider(
|
||||
&Handle, BCRYPT_SHA256_ALGORITHM, NULL, BCRYPT_ALG_HANDLE_HMAC_FLAG);
|
||||
&Handle, BCRYPT_SHA256_ALGORITHM, nullptr, BCRYPT_ALG_HANDLE_HMAC_FLAG);
|
||||
if (!BCRYPT_SUCCESS(status))
|
||||
{
|
||||
throw std::runtime_error("BCryptOpenAlgorithmProvider failed");
|
||||
@ -41,7 +41,7 @@ namespace Azure { namespace Storage {
|
||||
status = BCryptGetProperty(
|
||||
Handle,
|
||||
BCRYPT_OBJECT_LENGTH,
|
||||
(PBYTE)&objectLength,
|
||||
reinterpret_cast<PBYTE>(&objectLength),
|
||||
sizeof(objectLength),
|
||||
&dataLength,
|
||||
0);
|
||||
@ -52,7 +52,12 @@ namespace Azure { namespace Storage {
|
||||
ContextSize = objectLength;
|
||||
DWORD hashLength = 0;
|
||||
status = BCryptGetProperty(
|
||||
Handle, BCRYPT_HASH_LENGTH, (PBYTE)&hashLength, sizeof(hashLength), &dataLength, 0);
|
||||
Handle,
|
||||
BCRYPT_HASH_LENGTH,
|
||||
reinterpret_cast<PBYTE>(&hashLength),
|
||||
sizeof(hashLength),
|
||||
&dataLength,
|
||||
0);
|
||||
if (!BCRYPT_SUCCESS(status))
|
||||
{
|
||||
throw std::runtime_error("BCryptGetProperty failed");
|
||||
@ -72,17 +77,21 @@ namespace Azure { namespace Storage {
|
||||
NTSTATUS status = BCryptCreateHash(
|
||||
AlgorithmProvider.Handle,
|
||||
&hashHandle,
|
||||
(PUCHAR)context.data(),
|
||||
(ULONG)context.size(),
|
||||
(PUCHAR)key.data(),
|
||||
(ULONG)key.length(),
|
||||
reinterpret_cast<PUCHAR>(&context[0]),
|
||||
static_cast<ULONG>(context.size()),
|
||||
reinterpret_cast<PUCHAR>(const_cast<char*>(&key[0])),
|
||||
static_cast<ULONG>(key.length()),
|
||||
0);
|
||||
if (!BCRYPT_SUCCESS(status))
|
||||
{
|
||||
throw std::runtime_error("BCryptCreateHash failed");
|
||||
}
|
||||
|
||||
status = BCryptHashData(hashHandle, (PBYTE)text.data(), (ULONG)text.length(), 0);
|
||||
status = BCryptHashData(
|
||||
hashHandle,
|
||||
reinterpret_cast<PBYTE>(const_cast<char*>(&text[0])),
|
||||
static_cast<ULONG>(text.length()),
|
||||
0);
|
||||
if (!BCRYPT_SUCCESS(status))
|
||||
{
|
||||
throw std::runtime_error("BCryptHashData failed");
|
||||
@ -90,7 +99,8 @@ namespace Azure { namespace Storage {
|
||||
|
||||
std::string hash;
|
||||
hash.resize(AlgorithmProvider.HashLength);
|
||||
status = BCryptFinishHash(hashHandle, (PUCHAR)hash.data(), (ULONG)hash.length(), 0);
|
||||
status = BCryptFinishHash(
|
||||
hashHandle, reinterpret_cast<PUCHAR>(&hash[0]), static_cast<ULONG>(hash.length()), 0);
|
||||
if (!BCRYPT_SUCCESS(status))
|
||||
{
|
||||
throw std::runtime_error("BCryptFinishHash failed");
|
||||
@ -105,15 +115,15 @@ namespace Azure { namespace Storage {
|
||||
{
|
||||
std::string encoded;
|
||||
// According to RFC 4648, the encoded length should be ceiling(n / 3) * 4
|
||||
DWORD encodedLength = DWORD((text.length() + 2) / 3 * 4);
|
||||
DWORD encodedLength = static_cast<DWORD>((text.length() + 2) / 3 * 4);
|
||||
encoded.resize(encodedLength);
|
||||
|
||||
CryptBinaryToStringA(
|
||||
(BYTE*)text.data(),
|
||||
(DWORD)text.length(),
|
||||
reinterpret_cast<const BYTE*>(text.data()),
|
||||
static_cast<DWORD>(text.length()),
|
||||
CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF,
|
||||
(LPSTR)encoded.data(),
|
||||
(DWORD*)&encodedLength);
|
||||
static_cast<LPSTR>(&encoded[0]),
|
||||
&encodedLength);
|
||||
|
||||
return encoded;
|
||||
}
|
||||
@ -128,12 +138,12 @@ namespace Azure { namespace Storage {
|
||||
|
||||
CryptStringToBinaryA(
|
||||
text.data(),
|
||||
(DWORD)text.length(),
|
||||
static_cast<DWORD>(text.length()),
|
||||
CRYPT_STRING_BASE64 | CRYPT_STRING_STRICT,
|
||||
(BYTE*)decoded.data(),
|
||||
reinterpret_cast<BYTE*>(&decoded[0]),
|
||||
&decodedLength,
|
||||
NULL,
|
||||
NULL);
|
||||
nullptr,
|
||||
nullptr);
|
||||
decoded.resize(decodedLength);
|
||||
return decoded;
|
||||
}
|
||||
@ -147,10 +157,10 @@ namespace Azure { namespace Storage {
|
||||
HMAC(
|
||||
EVP_sha256(),
|
||||
key.data(),
|
||||
(int)key.length(),
|
||||
(const unsigned char*)text.data(),
|
||||
static_cast<int>(key.length()),
|
||||
reinterpret_cast<const unsigned char*>(text.data()),
|
||||
text.length(),
|
||||
(unsigned char*)&hash[0],
|
||||
reinterpret_cast<unsigned char*>(&hash[0]),
|
||||
&hashLength);
|
||||
|
||||
return std::string(hash, hashLength);
|
||||
@ -161,7 +171,7 @@ namespace Azure { namespace Storage {
|
||||
BIO* bio = BIO_new(BIO_s_mem());
|
||||
bio = BIO_push(BIO_new(BIO_f_base64()), bio);
|
||||
BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
|
||||
BIO_write(bio, text.data(), (int)text.length());
|
||||
BIO_write(bio, text.data(), static_cast<int>(text.length()));
|
||||
BIO_flush(bio);
|
||||
BUF_MEM* bufferPtr;
|
||||
BIO_get_mem_ptr(bio, &bufferPtr);
|
||||
@ -182,7 +192,7 @@ namespace Azure { namespace Storage {
|
||||
BIO* bio = BIO_new_mem_buf(text.data(), -1);
|
||||
bio = BIO_push(BIO_new(BIO_f_base64()), bio);
|
||||
BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
|
||||
int decodedLength = BIO_read(bio, &decoded[0], (int)text.length());
|
||||
int decodedLength = BIO_read(bio, &decoded[0], static_cast<int>(text.length()));
|
||||
BIO_free_all(bio);
|
||||
|
||||
decoded.resize(decodedLength);
|
||||
|
||||
177
sdk/storage/src/common/xml_wrapper.cpp
Normal file
177
sdk/storage/src/common/xml_wrapper.cpp
Normal file
@ -0,0 +1,177 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include "common/xml_wrapper.hpp"
|
||||
|
||||
#include "libxml/xmlreader.h"
|
||||
#include "libxml/xmlwriter.h"
|
||||
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace Azure { namespace Storage {
|
||||
|
||||
struct XmlGlobalInitializer
|
||||
{
|
||||
XmlGlobalInitializer() { xmlInitParser(); }
|
||||
~XmlGlobalInitializer() { xmlCleanupParser(); }
|
||||
};
|
||||
|
||||
static void XmlGlobalInitialize() { static XmlGlobalInitializer globalInitializer; }
|
||||
|
||||
XmlReader::XmlReader(const char* data, std::size_t length)
|
||||
{
|
||||
XmlGlobalInitialize();
|
||||
|
||||
if (length > static_cast<std::size_t>(std::numeric_limits<int>::max()))
|
||||
{
|
||||
throw std::runtime_error("xml data too big");
|
||||
}
|
||||
|
||||
m_reader = xmlReaderForMemory(data, static_cast<int>(length), nullptr, nullptr, 0);
|
||||
if (!m_reader)
|
||||
{
|
||||
throw std::runtime_error("failed to parse xml");
|
||||
}
|
||||
}
|
||||
|
||||
XmlReader::~XmlReader() { xmlFreeTextReader(m_reader); }
|
||||
|
||||
XmlNode XmlReader::Read()
|
||||
{
|
||||
if (m_readingAttributes)
|
||||
{
|
||||
int ret = xmlTextReaderMoveToNextAttribute(m_reader);
|
||||
if (ret == 1)
|
||||
{
|
||||
const char* name = reinterpret_cast<const char*>(xmlTextReaderName(m_reader));
|
||||
const char* value = reinterpret_cast<const char*>(xmlTextReaderValue(m_reader));
|
||||
return XmlNode{XmlNodeType::Attribute, name, value};
|
||||
}
|
||||
else if (ret == 0)
|
||||
{
|
||||
m_readingAttributes = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("failed to parse xml");
|
||||
}
|
||||
}
|
||||
|
||||
int ret = xmlTextReaderRead(m_reader);
|
||||
if (ret == 0)
|
||||
{
|
||||
return XmlNode{XmlNodeType::End};
|
||||
}
|
||||
if (ret != 1)
|
||||
{
|
||||
throw std::runtime_error("failed to parse xml");
|
||||
}
|
||||
|
||||
int type = xmlTextReaderNodeType(m_reader);
|
||||
bool is_empty = xmlTextReaderIsEmptyElement(m_reader) == 1;
|
||||
bool has_value = xmlTextReaderHasValue(m_reader) == 1;
|
||||
bool has_attributes = xmlTextReaderHasAttributes(m_reader) == 1;
|
||||
|
||||
const char* name = reinterpret_cast<const char*>(xmlTextReaderName(m_reader));
|
||||
const char* value = reinterpret_cast<const char*>(xmlTextReaderValue(m_reader));
|
||||
|
||||
if (has_attributes)
|
||||
{
|
||||
m_readingAttributes = true;
|
||||
}
|
||||
|
||||
if (type == XML_READER_TYPE_ELEMENT && is_empty)
|
||||
{
|
||||
return XmlNode{XmlNodeType::SelfClosingTag, name};
|
||||
}
|
||||
else if (type == XML_READER_TYPE_ELEMENT)
|
||||
{
|
||||
return XmlNode{XmlNodeType::StartTag, name};
|
||||
}
|
||||
else if (type == XML_READER_TYPE_END_ELEMENT)
|
||||
{
|
||||
return XmlNode{XmlNodeType::EndTag, name};
|
||||
}
|
||||
else if (type == XML_READER_TYPE_TEXT)
|
||||
{
|
||||
if (has_value)
|
||||
{
|
||||
return XmlNode{XmlNodeType::Text, nullptr, value};
|
||||
}
|
||||
}
|
||||
else if (type == XML_READER_TYPE_SIGNIFICANT_WHITESPACE)
|
||||
{
|
||||
// silently ignore
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("unknown type " + std::to_string(type) + " while parsing xml");
|
||||
}
|
||||
|
||||
return Read();
|
||||
}
|
||||
|
||||
XmlWriter::XmlWriter()
|
||||
{
|
||||
XmlGlobalInitialize();
|
||||
m_buffer = xmlBufferCreate();
|
||||
m_writer = xmlNewTextWriterMemory(m_buffer, 0);
|
||||
xmlTextWriterStartDocument(m_writer, nullptr, nullptr, nullptr);
|
||||
}
|
||||
|
||||
XmlWriter::~XmlWriter()
|
||||
{
|
||||
xmlFreeTextWriter(m_writer);
|
||||
xmlBufferFree(m_buffer);
|
||||
}
|
||||
|
||||
void XmlWriter::Write(XmlNode node)
|
||||
{
|
||||
if (node.Type == XmlNodeType::StartTag)
|
||||
{
|
||||
if (!node.Value)
|
||||
{
|
||||
xmlTextWriterStartElement(m_writer, BAD_CAST(node.Name));
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlTextWriterWriteElement(m_writer, BAD_CAST(node.Name), BAD_CAST(node.Value));
|
||||
}
|
||||
}
|
||||
else if (node.Type == XmlNodeType::EndTag)
|
||||
{
|
||||
xmlTextWriterEndElement(m_writer);
|
||||
}
|
||||
else if (node.Type == XmlNodeType::SelfClosingTag)
|
||||
{
|
||||
xmlTextWriterStartElement(m_writer, BAD_CAST(node.Name));
|
||||
xmlTextWriterEndElement(m_writer);
|
||||
}
|
||||
else if (node.Type == XmlNodeType::Text)
|
||||
{
|
||||
xmlTextWriterWriteString(m_writer, BAD_CAST(node.Value));
|
||||
}
|
||||
else if (node.Type == XmlNodeType::Attribute)
|
||||
{
|
||||
xmlTextWriterWriteAttribute(m_writer, BAD_CAST(node.Name), BAD_CAST(node.Value));
|
||||
}
|
||||
else if (node.Type == XmlNodeType::End)
|
||||
{
|
||||
xmlTextWriterEndDocument(m_writer);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error(
|
||||
"unsupported XmlNode type "
|
||||
+ std::to_string(static_cast<std::underlying_type<XmlNodeType>::type>(node.Type)));
|
||||
}
|
||||
}
|
||||
|
||||
std::string XmlWriter::GetDocument()
|
||||
{
|
||||
xmlTextWriterFlush(m_writer);
|
||||
return std::string(reinterpret_cast<const char*>(m_buffer->content), m_buffer->use);
|
||||
}
|
||||
|
||||
}} // namespace Azure::Storage
|
||||
Loading…
Reference in New Issue
Block a user