diff --git a/BreakingChanges.txt b/BreakingChanges.txt index 860f3247..4a5d704b 100644 --- a/BreakingChanges.txt +++ b/BreakingChanges.txt @@ -1,6 +1,10 @@ Azure Storage Client Library for C++ History of Breaking Changes +Breaking Changes in v2.0: +- Changed behavior to stop stripping out query parameters passed in with the resource URI. Some query parameters such as comp, restype, snapshot and api-version will still be removed. +- Deprecated cloud_blob::start_copy_from_blob and cloud_blob::start_copy_from_blob_async. Use cloud_blob::start_copy instead. + Breaking Changes in v1.0: - Changed return value type of cloud_blob_client::list_blobs_segmented, cloud_blob_container::list_blobs_segmented and cloud_blob_directory::list_blobs_segmented methods from blob_result_segment to list_blob_item_segment - Removed type blob_result_segment diff --git a/Changelog.txt b/Changelog.txt index ba14b540..35760df1 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -1,6 +1,14 @@ Azure Storage Client Library for C++ History of Changes +Changes in v2.0: +- Default REST API version is 2015-02-21 +- Added cloud_append_blob class, which supports the new blob type: append blob. +- Added support of ranged-based for-loop for result_iterator class +- Changed behavior to stop stripping out query parameters passed in with the resource URI. Some query parameters such as comp, restype, snapshot and api-version will still be removed. +- Deprecated cloud_blob::start_copy_from_blob and cloud_blob::start_copy_from_blob_async. Use cloud_blob::start_copy instead. +- Fixed the bug that cloud_table::execute(const table_operation&) method doesn't respect cloud_table_client::default_request_options. + Changes in v1.0: - Changed return value type of cloud_blob_client::list_blobs_segmented, cloud_blob_container::list_blobs_segmented and cloud_blob_directory::list_blobs_segmented methods from blob_result_segment to list_blob_item_segment - Removed type blob_result_segment diff --git a/Microsoft.WindowsAzure.Storage.autopkg b/Microsoft.WindowsAzure.Storage.autopkg index 9bcaefbe..749cea49 100644 --- a/Microsoft.WindowsAzure.Storage.autopkg +++ b/Microsoft.WindowsAzure.Storage.autopkg @@ -1,7 +1,7 @@ nuget { nuspec { id = wastorage; - version: 1.0.0; + version: 2.0.0; title: Microsoft Azure Storage Client Library for C++; authors: {Microsoft Corporation}; owners: {Microsoft Corporation}; @@ -87,4 +87,4 @@ nuget { bin: ${SDK_2013}\x64\Release\wastorage.dll; } } -} \ No newline at end of file +} diff --git a/Microsoft.WindowsAzure.Storage/CMakeLists.txt b/Microsoft.WindowsAzure.Storage/CMakeLists.txt index a1c6b914..01b17a3b 100644 --- a/Microsoft.WindowsAzure.Storage/CMakeLists.txt +++ b/Microsoft.WindowsAzure.Storage/CMakeLists.txt @@ -61,7 +61,7 @@ set(AZURESTORAGE_LIBRARY azurestorage) set(AZURESTORAGE_LIBRARIES ${AZURESTORAGE_LIBRARY} ${CASABLANCA_LIBRARIES} ${Boost_LIBRARIES} ${Boost_FRAMEWORK} ${OPENSSL_LIBRARIES} ${LibXML++_LIBRARIES} ${UUID_LIBRARIES} ${Glibmm_LIBRARIES}) # Set version numbers centralized -set (AZURESTORAGE_VERSION_MAJOR 1) +set (AZURESTORAGE_VERSION_MAJOR 2) set (AZURESTORAGE_VERSION_MINOR 0) set (AZURESTORAGE_VERSION_REVISION 0) diff --git a/Microsoft.WindowsAzure.Storage/Microsoft.WindowsAzure.Storage.v120.vcxproj b/Microsoft.WindowsAzure.Storage/Microsoft.WindowsAzure.Storage.v120.vcxproj index 68de533b..369544f2 100644 --- a/Microsoft.WindowsAzure.Storage/Microsoft.WindowsAzure.Storage.v120.vcxproj +++ b/Microsoft.WindowsAzure.Storage/Microsoft.WindowsAzure.Storage.v120.vcxproj @@ -97,88 +97,68 @@ $(ProjectDir)$(PlatformToolset)\$(Platform)\$(Configuration)\ $(PlatformToolset)\$(Platform)\$(Configuration)\ - + Use - Level4 - Disabled - WASTORAGE_DLL;WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true - true /we4100 /Zm150 %(AdditionalOptions) /bigobj true includes + true + false Windows true rpcrt4.lib;xmllite.lib;bcrypt.lib;%(AdditionalDependencies) + + + + + Level4 + Disabled + WASTORAGE_DLL;WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + + true - Use Level4 Disabled WASTORAGE_DLL;WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - true - true - /we4100 /Zm150 %(AdditionalOptions) /bigobj - true - includes - Windows - true - rpcrt4.lib;xmllite.lib;bcrypt.lib;%(AdditionalDependencies) true Level3 - Use MaxSpeed true true WASTORAGE_DLL;WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - true false - true - /we4100 /Zm150 %(AdditionalOptions) /bigobj - true - includes - Windows - true true true - rpcrt4.lib;xmllite.lib;bcrypt.lib;%(AdditionalDependencies) Level3 - Use MaxSpeed true true WASTORAGE_DLL;WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - true false - true - /we4100 /Zm150 %(AdditionalOptions) /bigobj - true - includes - Windows - true true true - rpcrt4.lib;xmllite.lib;bcrypt.lib;%(AdditionalDependencies) @@ -213,6 +193,7 @@ + diff --git a/Microsoft.WindowsAzure.Storage/Microsoft.WindowsAzure.Storage.v120.vcxproj.filters b/Microsoft.WindowsAzure.Storage/Microsoft.WindowsAzure.Storage.v120.vcxproj.filters index 5c61d0db..2ff2ec4b 100644 --- a/Microsoft.WindowsAzure.Storage/Microsoft.WindowsAzure.Storage.v120.vcxproj.filters +++ b/Microsoft.WindowsAzure.Storage/Microsoft.WindowsAzure.Storage.v120.vcxproj.filters @@ -233,6 +233,9 @@ Source Files + + Source Files + diff --git a/Microsoft.WindowsAzure.Storage/Microsoft.WindowsAzure.Storage.vcxproj b/Microsoft.WindowsAzure.Storage/Microsoft.WindowsAzure.Storage.vcxproj index 5ce665a1..02036190 100644 --- a/Microsoft.WindowsAzure.Storage/Microsoft.WindowsAzure.Storage.vcxproj +++ b/Microsoft.WindowsAzure.Storage/Microsoft.WindowsAzure.Storage.vcxproj @@ -97,17 +97,15 @@ $(ProjectDir)$(PlatformToolset)\$(Platform)\$(Configuration)\ $(PlatformToolset)\$(Platform)\$(Configuration)\ - + Use - Level4 - Disabled - WASTORAGE_DLL;WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true - true /we4100 /Zm150 %(AdditionalOptions) /bigobj true includes + true + false Windows @@ -115,68 +113,50 @@ rpcrt4.lib;xmllite.lib;bcrypt.lib;%(AdditionalDependencies) + + + Level4 + Disabled + WASTORAGE_DLL;WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + + + + - Use Level4 Disabled WASTORAGE_DLL;WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - true - true - /we4100 /Zm150 %(AdditionalOptions) /bigobj - true - includes - Windows - true - rpcrt4.lib;xmllite.lib;bcrypt.lib;%(AdditionalDependencies) Level3 - Use MaxSpeed true true WASTORAGE_DLL;WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - true false - true - /we4100 /Zm150 %(AdditionalOptions) /bigobj - true - includes - Windows - true true true - rpcrt4.lib;xmllite.lib;bcrypt.lib;%(AdditionalDependencies) Level3 - Use MaxSpeed true true WASTORAGE_DLL;WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - true false - true - /we4100 /Zm150 %(AdditionalOptions) /bigobj - true - includes - Windows - true true true - rpcrt4.lib;xmllite.lib;bcrypt.lib;%(AdditionalDependencies) @@ -215,6 +195,7 @@ + @@ -269,7 +250,7 @@ - + diff --git a/Microsoft.WindowsAzure.Storage/Microsoft.WindowsAzure.Storage.vcxproj.filters b/Microsoft.WindowsAzure.Storage/Microsoft.WindowsAzure.Storage.vcxproj.filters index bb24bbe8..d1155fc9 100644 --- a/Microsoft.WindowsAzure.Storage/Microsoft.WindowsAzure.Storage.vcxproj.filters +++ b/Microsoft.WindowsAzure.Storage/Microsoft.WindowsAzure.Storage.vcxproj.filters @@ -116,6 +116,9 @@ Source Files + + Source Files + Source Files diff --git a/Microsoft.WindowsAzure.Storage/includes/was/auth.h b/Microsoft.WindowsAzure.Storage/includes/was/auth.h index a41406ae..28ea2726 100644 --- a/Microsoft.WindowsAzure.Storage/includes/was/auth.h +++ b/Microsoft.WindowsAzure.Storage/includes/was/auth.h @@ -44,7 +44,7 @@ namespace azure { namespace storage { namespace protocol { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The request to be authenticated. /// The storage account name. @@ -84,6 +84,11 @@ namespace azure { namespace storage { namespace protocol { /// The header name. void append_header(const utility::string_t& header_name); + /// + /// Appends Content-Length header to the canonicalization string. + /// + void append_content_length_header(); + /// /// Appends the Date header to the canonicalization string if it exists on the request. Optionally appends /// the x_ms_date header to the canonicalization string. @@ -140,7 +145,7 @@ namespace azure { namespace storage { namespace protocol { protected: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The storage account name. explicit canonicalizer(utility::string_t account_name) @@ -167,7 +172,7 @@ namespace azure { namespace storage { namespace protocol { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The storage account name. explicit shared_key_blob_queue_canonicalizer(utility::string_t account_name) @@ -214,7 +219,7 @@ namespace azure { namespace storage { namespace protocol { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The storage account name. explicit shared_key_lite_blob_queue_canonicalizer(utility::string_t account_name) @@ -261,7 +266,7 @@ namespace azure { namespace storage { namespace protocol { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The storage account name. explicit shared_key_table_canonicalizer(utility::string_t account_name) @@ -308,7 +313,7 @@ namespace azure { namespace storage { namespace protocol { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The storage account name. explicit shared_key_lite_table_canonicalizer(utility::string_t account_name) @@ -373,9 +378,9 @@ namespace azure { namespace storage { namespace protocol { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// The to use to sign the request. + /// The to use to sign the request. explicit sas_authentication_handler(storage_credentials credentials) : m_credentials(std::move(credentials)) { @@ -401,10 +406,10 @@ namespace azure { namespace storage { namespace protocol { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The canonicalizer to use to sign the request. - /// The to use to sign the request. + /// The to use to sign the request. shared_key_authentication_handler(std::shared_ptr canonicalizer, storage_credentials credentials) : m_canonicalizer(canonicalizer), m_credentials(std::move(credentials)) { diff --git a/Microsoft.WindowsAzure.Storage/includes/was/blob.h b/Microsoft.WindowsAzure.Storage/includes/was/blob.h index 82816486..c8f829b0 100644 --- a/Microsoft.WindowsAzure.Storage/includes/was/blob.h +++ b/Microsoft.WindowsAzure.Storage/includes/was/blob.h @@ -25,6 +25,7 @@ namespace azure { namespace storage { class cloud_blob; class cloud_block_blob; class cloud_page_blob; + class cloud_append_blob; class cloud_blob_directory; class cloud_blob_container; class cloud_blob_client; @@ -37,6 +38,11 @@ namespace azure { namespace storage { class list_blobs_reader; } + namespace core + { + class cloud_append_blob_ostreambuf; + } + /// /// The type of a blob. /// @@ -56,6 +62,11 @@ namespace azure { namespace storage { /// A block blob. /// block_blob, + + /// + /// An append blob. + /// + append_blob, }; /// @@ -317,19 +328,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. copy_state(copy_state&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. copy_state& operator=(copy_state&& other) { if (this != &other) @@ -368,7 +379,7 @@ namespace azure { namespace storage { /// /// Gets the status of the copy blob operation. /// - /// A enumeration indicating the status of the copy operation. + /// An enumeration indicating the status of the copy operation. copy_status status() const { return m_status; @@ -432,7 +443,7 @@ namespace azure { namespace storage { public: /// - /// Describes the set of operators for comparing the blob’s sequence number with the specified value. + /// Describes the set of operators for comparing the blob's sequence number with the specified value. /// enum class sequence_number_operators { @@ -442,17 +453,17 @@ namespace azure { namespace storage { none, /// - /// If the blob’s sequence number is less than the specified value, the request proceeds. + /// If the blob's sequence number is less than the specified value, the request proceeds. /// le, /// - /// If the blob’s sequence number is less than or equal to the specified value, the request proceeds. + /// If the blob's sequence number is less than or equal to the specified value, the request proceeds. /// lt, /// - /// If the blob’s sequence number is equal to the specified value, the request proceeds. + /// If the blob's sequence number is equal to the specified value, the request proceeds. /// eq, }; @@ -461,7 +472,8 @@ namespace azure { namespace storage { /// Constructs an empty access condition. /// access_condition() - : m_sequence_number(0), m_sequence_number_operator(sequence_number_operators::none) + : m_sequence_number(0), m_sequence_number_operator(sequence_number_operators::none), + m_max_size(-1), m_append_position(-1) { } @@ -470,7 +482,7 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// /// An existing object. access_condition(access_condition&& other) @@ -494,6 +506,8 @@ namespace azure { namespace storage { m_lease_id = std::move(other.m_lease_id); m_sequence_number = std::move(other.m_sequence_number); m_sequence_number_operator = std::move(other.m_sequence_number_operator); + m_max_size = std::move(other.m_max_size); + m_append_position = std::move(other.m_append_position); } return *this; } @@ -508,6 +522,30 @@ namespace azure { namespace storage { return access_condition(); } + /// + /// Generates an access condition such that an operation will be performed only if the resource does not exist on the service. + /// + /// An object that represents the If-Not-Exists condition. + /// Setting this access condition modifies the request to include the HTTP If-None-Match conditional header. + static access_condition generate_if_not_exists_condition() + { + access_condition condition; + condition.set_if_none_match_etag(U("*")); + return condition; + } + + /// + /// Generates an access condition such that an operation will be performed only if the resource exists on the service. + /// + /// An object that represents the If-Exists condition. + /// Setting this access condition modifies the request to include the HTTP If-Match conditional header. + static access_condition generate_if_exists_condition() + { + access_condition condition; + condition.set_if_match_etag(U("*")); + return condition; + } + /// /// Generates an access condition such that an operation will be performed only if the resource's ETag value /// matches the specified ETag value. @@ -615,6 +653,31 @@ namespace azure { namespace storage { return condition; } + /// + /// Generates an access condition such that an operation will be performed only if the size of the blob after + /// committing the block is less than or equal to the specified value. + /// + /// The value specifying the maximum length to restrict the blob to when committing the block. + /// An object that represents the blob-condition-maxsize condition. + static access_condition generate_if_max_size_less_than_or_equal_condition(int64_t max_size) + { + access_condition condition; + condition.set_max_size(max_size); + return condition; + } + + /// + /// Generates an access condition such that an operation will be performed only if the end position of the blob is equal to the specified value. + /// + /// The value to compare to the current end position of the blob. + /// An object that represents the blob-condition-appendpos condition. + static access_condition generate_if_append_position_equal_condition(int64_t append_position) + { + access_condition condition; + condition.set_append_position(append_position); + return condition; + } + /// /// Gets an ETag value that must match the ETag of a resource. /// @@ -746,6 +809,50 @@ namespace azure { namespace storage { return m_sequence_number_operator; } + /// + /// Gets a number that indicates the maximum size in bytes to restrict the blob to when commiting the block. + /// + /// The maximum size in bytes, or -1 if no maximum size value is specified. + /// This condition only applies to append blobs. + int64_t max_size() const + { + return m_max_size; + } + + /// + /// Sets a number that indicates the maximum size in bytes to restrict the blob to when commiting the block. + /// + /// The maximum size in bytes. + /// This condition only applies to append blobs. + void set_max_size(int64_t value) + { + utility::assert_in_bounds(U("value"), value, 1); + m_max_size = value; + } + + /// + /// Gets an append position that the end position of an append blob must be equal to in order + /// for the operation to proceed. + /// + /// An append position number, or -1 if no append position value is specified. + /// This condition only applies to append blobs. + int64_t append_position() const + { + return m_append_position; + } + + /// + /// Sets the append position that the end position of an append blob must be equal to in order + /// for the operation to proceed. + /// + /// An append position. + /// This condition only applies to append blobs. + void set_append_position(int64_t value) + { + utility::assert_in_bounds(U("value"), value, 0); + m_append_position = value; + } + /// /// Gets a lease ID that must match the lease on a resource. /// @@ -785,6 +892,8 @@ namespace azure { namespace storage { utility::string_t m_lease_id; int64_t m_sequence_number; sequence_number_operators m_sequence_number_operator; + int64_t m_max_size; + int64_t m_append_position; }; /// @@ -879,19 +988,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. lease_break_period(lease_break_period&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. lease_break_period& operator=(lease_break_period&& other) { if (this != &other) @@ -903,9 +1012,9 @@ namespace azure { namespace storage { #endif /// - /// Indicates whether the object is valid. + /// Indicates whether the object is valid. /// - /// true if the object is valid; otherwise, false. + /// true if the object is valid; otherwise, false. bool is_valid() const { return m_seconds < std::chrono::seconds::max(); @@ -980,19 +1089,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. lease_time(lease_time&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. lease_time& operator=(lease_time&& other) { if (this != &other) @@ -1036,19 +1145,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. blob_container_permissions(blob_container_permissions&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. blob_container_permissions& operator=(blob_container_permissions&& other) { if (this != &other) @@ -1098,10 +1207,10 @@ namespace azure { namespace storage { { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// cloud_blob_properties() - : m_type(blob_type::unspecified), m_page_blob_sequence_number(0), + : m_type(blob_type::unspecified), m_page_blob_sequence_number(0), m_append_blob_committed_block_count(0), m_lease_state(azure::storage::lease_state::unspecified), m_lease_status(azure::storage::lease_status::unspecified), m_lease_duration(azure::storage::lease_duration::unspecified), m_size(0) { @@ -1112,19 +1221,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. cloud_blob_properties(cloud_blob_properties&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. cloud_blob_properties& operator=(cloud_blob_properties&& other) { if (this != &other) @@ -1143,6 +1252,7 @@ namespace azure { namespace storage { m_lease_state = std::move(other.m_lease_state); m_lease_duration = std::move(other.m_lease_duration); m_page_blob_sequence_number = std::move(other.m_page_blob_sequence_number); + m_append_blob_committed_block_count = std::move(other.m_append_blob_committed_block_count); } return *this; } @@ -1286,7 +1396,7 @@ namespace azure { namespace storage { /// /// Gets the type of the blob. /// - /// A object that indicates the type of the blob. + /// An object that indicates the type of the blob. blob_type type() const { return m_type; @@ -1295,7 +1405,7 @@ namespace azure { namespace storage { /// /// Gets the blob's lease status. /// - /// A object that indicates the blob's lease status. + /// An object that indicates the blob's lease status. azure::storage::lease_status lease_status() const { return m_lease_status; @@ -1304,7 +1414,7 @@ namespace azure { namespace storage { /// /// Gets the blob's lease state. /// - /// A object that indicates the blob's lease state. + /// An object that indicates the blob's lease state. azure::storage::lease_state lease_state() const { return m_lease_state; @@ -1313,7 +1423,7 @@ namespace azure { namespace storage { /// /// Gets the blob's lease duration. /// - /// A object that indicates the blob's lease duration. + /// An object that indicates the blob's lease duration. azure::storage::lease_duration lease_duration() const { return m_lease_duration; @@ -1328,6 +1438,15 @@ namespace azure { namespace storage { return m_page_blob_sequence_number; } + /// + /// If the blob is an append blob, gets the number of committed blocks. + /// + /// The number of committed blocks + int append_blob_committed_block_count() const + { + return m_append_blob_committed_block_count; + } + private: void set_type(blob_type value) @@ -1349,16 +1468,19 @@ namespace azure { namespace storage { azure::storage::lease_state m_lease_state; azure::storage::lease_duration m_lease_duration; int64_t m_page_blob_sequence_number; + int m_append_blob_committed_block_count; void copy_from_root(const cloud_blob_properties& root_blob_properties); void update_etag_and_last_modified(const cloud_blob_properties& parsed_properties); void update_size(const cloud_blob_properties& parsed_properties); void update_page_blob_sequence_number(const cloud_blob_properties& parsed_properties); + void update_append_blob_committed_block_count(const cloud_blob_properties& parsed_properties); void update_all(const cloud_blob_properties& parsed_properties, bool ignore_md5); friend class cloud_blob; friend class cloud_block_blob; friend class cloud_page_blob; + friend class cloud_append_blob; friend class protocol::blob_response_parsers; friend class protocol::list_blobs_reader; }; @@ -1370,7 +1492,7 @@ namespace azure { namespace storage { { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// cloud_blob_shared_access_headers() { @@ -1381,19 +1503,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. cloud_blob_shared_access_headers(cloud_blob_shared_access_headers&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. cloud_blob_shared_access_headers& operator=(cloud_blob_shared_access_headers&& other) { if (this != &other) @@ -1524,7 +1646,8 @@ namespace azure { namespace storage { m_single_blob_upload_threshold(protocol::default_single_blob_upload_threshold), m_stream_read_size(protocol::max_block_size), m_stream_write_size(protocol::max_block_size), - m_parallelism_factor(1) + m_parallelism_factor(1), + m_absorb_conditional_errors_on_retry(false) { } @@ -1533,19 +1656,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. blob_request_options(blob_request_options&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. blob_request_options& operator=(blob_request_options&& other) { if (this != &other) @@ -1558,6 +1681,7 @@ namespace azure { namespace storage { m_single_blob_upload_threshold = std::move(other.m_single_blob_upload_threshold); m_stream_write_size = std::move(other.m_stream_write_size); m_stream_read_size = std::move(other.m_stream_read_size); + m_absorb_conditional_errors_on_retry = std::move(other.m_absorb_conditional_errors_on_retry); } return *this; } @@ -1566,8 +1690,8 @@ namespace azure { namespace storage { /// /// Applies the default set of request options. /// - /// A reference to a set of . - /// The blob type, specified by . + /// A reference to a set of . + /// The blob type, specified by . /// Specifies that an expiry time be applied to the /// request options. This parameter is used internally. void apply_defaults(const blob_request_options& other, blob_type type, bool apply_expiry = true) @@ -1591,6 +1715,7 @@ namespace azure { namespace storage { m_single_blob_upload_threshold.merge(other.m_single_blob_upload_threshold); m_stream_write_size.merge(other.m_stream_write_size); m_stream_read_size.merge(other.m_stream_read_size); + m_absorb_conditional_errors_on_retry.merge(other.m_absorb_conditional_errors_on_retry); } /// @@ -1727,6 +1852,30 @@ namespace azure { namespace storage { m_stream_write_size = value; } + /// + /// Gets the value that indicates whether a conditional failure should be absorbed on a retry attempt + /// for the request. This option is only used by in upload_from methods and + /// . By default, it is set to false. Set this to true only for single writer scenario. + /// Setting this to true in a multi writer scenario could lead to a corrupted blob on the service. + /// + /// true to absorb a conditional failure on a retry attempt for the request; otherwise, false. + bool absorb_conditional_errors_on_retry() const + { + return m_absorb_conditional_errors_on_retry; + } + + /// + /// Sets the value that indicates whether a conditional failure should be absorbed on a retry attempt + /// for the request. This option is only used by in upload_from methods and + /// . By default, it is set to false. Set this to true only for single writer scenario. + /// Setting this to true in a multi writer scenario could lead to a corrupted blob on the service. + /// + /// true to absorb a conditional failure on a retry attempt for the request; otherwise, false. + void set_absorb_conditional_errors_on_retry(bool value) + { + m_absorb_conditional_errors_on_retry = value; + } + private: option_with_default m_use_transactional_md5; @@ -1736,6 +1885,7 @@ namespace azure { namespace storage { option_with_default m_single_blob_upload_threshold; option_with_default m_stream_write_size; option_with_default m_stream_read_size; + option_with_default m_absorb_conditional_errors_on_retry; }; /// @@ -1767,7 +1917,7 @@ namespace azure { namespace storage { }; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The block name. block_list_item(utility::string_t id) @@ -1776,10 +1926,10 @@ namespace azure { namespace storage { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The block name. - /// A value that indicates which block lists to search for the block. + /// An value that indicates which block lists to search for the block. block_list_item(utility::string_t id, block_mode mode) : m_id(std::move(id)), m_size(std::numeric_limits::max()), m_mode(mode) { @@ -1790,19 +1940,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. block_list_item(block_list_item&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. block_list_item& operator=(block_list_item&& other) { if (this != &other) @@ -1836,7 +1986,7 @@ namespace azure { namespace storage { /// /// Gets a value indicating whether the block has been committed. /// - /// A value that indicates whether the block has been committed. + /// An value that indicates whether the block has been committed. block_mode mode() const { return m_mode; @@ -1845,7 +1995,7 @@ namespace azure { namespace storage { private: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The block name. /// The size of the block. @@ -1872,8 +2022,8 @@ namespace azure { namespace storage { /// /// Initializes a new instance of the class. /// - /// The starting offset. - /// The ending offset. + /// The starting offset. + /// The ending offset. page_range(int64_t start_offset, int64_t end_offset) : m_start_offset(start_offset), m_end_offset(end_offset) { @@ -1884,19 +2034,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. page_range(page_range&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. page_range& operator=(page_range&& other) { if (this != &other) @@ -1974,7 +2124,7 @@ namespace azure { namespace storage { /// or the value currently stored for the blob. /// /// The sequence number. - /// A object that represents the action. + /// An object that represents the action. static sequence_number maximum(int64_t value) { return sequence_number(sequence_number_action::maximum, value); @@ -1984,7 +2134,7 @@ namespace azure { namespace storage { /// Constructs a sequence number action to set the sequence number to the value included with the request. /// /// The sequence number. - /// A object that represents the action. + /// An object that represents the action. static sequence_number update(int64_t value) { return sequence_number(sequence_number_action::update, value); @@ -1993,7 +2143,7 @@ namespace azure { namespace storage { /// /// Constructs a sequence number action to increment the value of the sequence number by 1. /// - /// A object that represents the action. + /// An object that represents the action. static sequence_number increment() { return sequence_number(sequence_number_action::increment, -1); @@ -2035,7 +2185,7 @@ namespace azure { namespace storage { { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// cloud_blob_container_properties() : m_lease_status(azure::storage::lease_status::unspecified), m_lease_state(azure::storage::lease_state::unspecified), @@ -2048,19 +2198,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. cloud_blob_container_properties(cloud_blob_container_properties&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. cloud_blob_container_properties& operator=(cloud_blob_container_properties&& other) { if (this != &other) @@ -2096,7 +2246,7 @@ namespace azure { namespace storage { /// /// Gets the container's lease status. /// - /// A object that indicates the container's lease status. + /// An object that indicates the container's lease status. azure::storage::lease_status lease_status() const { return m_lease_status; @@ -2105,7 +2255,7 @@ namespace azure { namespace storage { /// /// Gets the container's lease state. /// - /// A object that indicates the container's lease state. + /// An object that indicates the container's lease state. azure::storage::lease_state lease_state() const { return m_lease_state; @@ -2114,7 +2264,7 @@ namespace azure { namespace storage { /// /// Gets the container's lease duration. /// - /// A object that indicates the container's lease duration. + /// An object that indicates the container's lease duration. azure::storage::lease_duration lease_duration() const { return m_lease_duration; @@ -2153,7 +2303,7 @@ namespace azure { namespace storage { /// Initializes a new instance of the class using the specified Blob service endpoint /// and anonymous credentials. /// - /// A object containing the Blob service endpoint for all locations. + /// An object containing the Blob service endpoint for all locations. explicit cloud_blob_client(storage_uri base_uri) : cloud_client(std::move(base_uri)) { @@ -2164,8 +2314,8 @@ namespace azure { namespace storage { /// Initializes a new instance of the class using the specified Blob service endpoint /// and account credentials. /// - /// A object containing the Blob service endpoint for all locations. - /// The to use. + /// An object containing the Blob service endpoint for all locations. + /// The to use. cloud_blob_client(storage_uri base_uri, storage_credentials credentials) : cloud_client(std::move(base_uri), std::move(credentials)) { @@ -2176,9 +2326,9 @@ namespace azure { namespace storage { /// Initializes a new instance of the class using the specified Blob service endpoint /// and account credentials. /// - /// A object containing the Blob service endpoint for all locations. - /// The to use. - /// The default object to use for all requests made with this client object. + /// An object containing the Blob service endpoint for all locations. + /// The to use. + /// The default object to use for all requests made with this client object. cloud_blob_client(storage_uri base_uri, storage_credentials credentials, blob_request_options default_request_options) : cloud_client(std::move(base_uri), std::move(credentials)), m_default_request_options(std::move(default_request_options)) { @@ -2190,19 +2340,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. cloud_blob_client(cloud_blob_client&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. cloud_blob_client& operator=(cloud_blob_client&& other) { if (this != &other) @@ -2222,41 +2372,41 @@ namespace azure { namespace storage { WASTORAGE_API void set_authentication_scheme(azure::storage::authentication_scheme value) override; /// - /// Returns a that can be used to to lazily enumerate a collection of containers. + /// Returns an that can be used to to lazily enumerate a collection of containers. /// - /// A that can be used to to lazily enumerate a collection of containers. + /// An that can be used to to lazily enumerate a collection of containers. container_result_iterator list_containers() const { return list_containers(utility::string_t(), container_listing_details::none, 0, blob_request_options(), operation_context()); } /// - /// Returns a that can be used to to lazily enumerate a collection of containers. + /// Returns an that can be used to to lazily enumerate a collection of containers. /// /// The container name prefix. - /// A that can be used to to lazily enumerate a collection of containers. + /// An that can be used to to lazily enumerate a collection of containers. container_result_iterator list_containers(const utility::string_t& prefix) const { return list_containers(prefix, container_listing_details::none, 0, blob_request_options(), operation_context()); } /// - /// Returns a that can be used to to lazily enumerate a collection of containers. + /// Returns an that can be used to to lazily enumerate a collection of containers. /// /// The container name prefix. - /// A enumeration describing which items to include in the listing. + /// An enumeration describing which items to include in the listing. /// A non-negative integer value that indicates the maximum number of results to be returned. /// If this value is zero, the maximum possible number of results will be returned. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A that can be used to to lazily enumerate a collection of containers. + /// An that can be used to to lazily enumerate a collection of containers. WASTORAGE_API container_result_iterator list_containers(const utility::string_t& prefix, container_listing_details::values includes, int max_results, const blob_request_options& options, operation_context context) const; /// /// Returns a result segment containing a collection of objects. /// - /// A returned by a previous listing operation. - /// A containing a collection of containers. + /// An returned by a previous listing operation. + /// An containing a collection of containers. container_result_segment list_containers_segmented(const continuation_token& token) const { return list_containers_segmented_async(token).get(); @@ -2266,8 +2416,8 @@ namespace azure { namespace storage { /// Returns a result segment containing a collection of objects. /// /// The container name prefix. - /// A returned by a previous listing operation. - /// A containing a collection of containers. + /// An returned by a previous listing operation. + /// An containing a collection of containers. container_result_segment list_containers_segmented(const utility::string_t& prefix, const continuation_token& token) const { return list_containers_segmented_async(prefix, token).get(); @@ -2277,13 +2427,13 @@ namespace azure { namespace storage { /// Returns a result segment containing a collection of objects. /// /// The container name prefix. - /// A enumeration describing which items to include in the listing. + /// An enumeration describing which items to include in the listing. /// A non-negative integer value that indicates the maximum number of results to be returned /// in the result segment, up to the per-operation limit of 5000. If this value is 0, the maximum possible number of results will be returned, up to 5000. - /// A returned by a previous listing operation. - /// A object that specifies additional options for the request. + /// An returned by a previous listing operation. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A containing a collection of containers. + /// An containing a collection of containers. container_result_segment list_containers_segmented(const utility::string_t& prefix, container_listing_details::values includes, int max_results, const continuation_token& token, const blob_request_options& options, operation_context context) const { return list_containers_segmented_async(prefix, includes, max_results, token, options, context).get(); @@ -2292,8 +2442,8 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to return a result segment containing a collection of objects. /// - /// A returned by a previous listing operation. - /// A object of type that represents the current operation. + /// An returned by a previous listing operation. + /// A object of type that represents the current operation. pplx::task list_containers_segmented_async(const continuation_token& token) const { return list_containers_segmented_async(utility::string_t(), token); @@ -2303,8 +2453,8 @@ namespace azure { namespace storage { /// Intitiates an asynchronous operation to return a result segment containing a collection of objects. /// /// The container name prefix. - /// A returned by a previous listing operation. - /// A object of type that represents the current operation. + /// An returned by a previous listing operation. + /// A object of type that represents the current operation. pplx::task list_containers_segmented_async(const utility::string_t& prefix, const continuation_token& token) const { return list_containers_segmented_async(prefix, container_listing_details::none, 0, token, blob_request_options(), operation_context()); @@ -2314,95 +2464,95 @@ namespace azure { namespace storage { /// Intitiates an asynchronous operation to return a result segment containing a collection of objects. /// /// The container name prefix. - /// A enumeration describing which items to include in the listing. + /// An enumeration describing which items to include in the listing. /// A non-negative integer value that indicates the maximum number of results to be returned /// in the result segment, up to the per-operation limit of 5000. If this value is 0, the maximum possible number of results will be returned, up to 5000. - /// A returned by a previous listing operation. - /// A object that specifies additional options for the request. + /// An returned by a previous listing operation. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. WASTORAGE_API pplx::task list_containers_segmented_async(const utility::string_t& prefix, container_listing_details::values includes, int max_results, const continuation_token& token, const blob_request_options& options, operation_context context) const; /// - /// Returns a that can be used to to lazily enumerate a collection of blob items. + /// Returns an that can be used to to lazily enumerate a collection of blob items. /// /// The blob name prefix. - /// A that can be used to to lazily enumerate a collection of blob items. + /// An that can be used to to lazily enumerate a collection of blob items. list_blob_item_iterator list_blobs(const utility::string_t& prefix) const { return list_blobs(prefix, false, blob_listing_details::none, 0, blob_request_options(), operation_context()); } /// - /// Returns a that can be used to to lazily enumerate a collection of blob items. + /// Returns an that can be used to to lazily enumerate a collection of blob items. /// /// The blob name prefix. /// Indicates whether to list blobs in a flat listing, or whether to list blobs hierarchically, by virtual directory. - /// A enumeration describing which items to include in the listing. + /// An enumeration describing which items to include in the listing. /// A non-negative integer value that indicates the maximum number of results to be returned. /// If this value is zero, the maximum possible number of results will be returned. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A that can be used to to lazily enumerate a collection of blob items. + /// An that can be used to to lazily enumerate a collection of blob items. WASTORAGE_API list_blob_item_iterator list_blobs(const utility::string_t& prefix, bool use_flat_blob_listing, blob_listing_details::values includes, int max_results, const blob_request_options& options, operation_context context) const; /// - /// Returns a containing a collection of blob items in the container. + /// Returns an containing a collection of blob items in the container. /// /// The blob name prefix. - /// A returned by a previous listing operation. - /// A containing a collection of blob items in the container. + /// An returned by a previous listing operation. + /// An containing a collection of blob items in the container. list_blob_item_segment list_blobs_segmented(const utility::string_t& prefix, const continuation_token& token) const { return list_blobs_segmented_async(prefix, token).get(); } /// - /// Returns a containing a collection of blob items in the container. + /// Returns an containing a collection of blob items in the container. /// /// The blob name prefix. /// Indicates whether to list blobs in a flat listing, or whether to list blobs hierarchically, by virtual directory. - /// A enumeration describing which items to include in the listing. + /// An enumeration describing which items to include in the listing. /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the - /// per-operation limit of 5000. If this value is 0, the maximum possible number of results will be returned, up to 5000. - /// A returned by a previous listing operation. - /// A object that specifies additional options for the request. + /// per-operation limit of 5000. If this value is 0, the maximum possible number of results will be returned, up to 5000. + /// An returned by a previous listing operation. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A containing a collection of blob items in the container. + /// An containing a collection of blob items in the container. list_blob_item_segment list_blobs_segmented(const utility::string_t& prefix, bool use_flat_blob_listing, blob_listing_details::values includes, int max_results, const continuation_token& token, const blob_request_options& options, operation_context context) const { return list_blobs_segmented_async(prefix, use_flat_blob_listing, includes, max_results, token, options, context).get(); } /// - /// Intitiates an asynchronous operation to return a containing a collection of blob items in the container. + /// Intitiates an asynchronous operation to return an containing a collection of blob items in the container. /// /// The blob name prefix. - /// A returned by a previous listing operation. - /// A object of type that represents the current operation. + /// An returned by a previous listing operation. + /// A object of type that represents the current operation. pplx::task list_blobs_segmented_async(const utility::string_t& prefix, const continuation_token& token) const { return list_blobs_segmented_async(prefix, false, blob_listing_details::none, 0, token, blob_request_options(), operation_context()); } /// - /// Intitiates an asynchronous operation to return a containing a collection of blob items in the container. + /// Intitiates an asynchronous operation to return an containing a collection of blob items in the container. /// /// The blob name prefix. /// Indicates whether to list blobs in a flat listing, or whether to list blobs hierarchically, by virtual directory. - /// A enumeration describing which items to include in the listing. + /// An enumeration describing which items to include in the listing. /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the - /// per-operation limit of 5000. If this value is 0, the maximum possible number of results will be returned, up to 5000. - /// A returned by a previous listing operation. - /// A object that specifies additional options for the request. + /// per-operation limit of 5000. If this value is 0, the maximum possible number of results will be returned, up to 5000. + /// An returned by a previous listing operation. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. WASTORAGE_API pplx::task list_blobs_segmented_async(const utility::string_t& prefix, bool use_flat_blob_listing, blob_listing_details::values includes, int max_results, const continuation_token& token, const blob_request_options& options, operation_context context) const; /// /// Gets the service properties for the Blob service client. /// - /// The for the Blob service client. + /// The for the Blob service client. service_properties download_service_properties() const { return download_service_properties_async().get(); @@ -2411,9 +2561,9 @@ namespace azure { namespace storage { /// /// Gets the service properties for the Blob service client. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// The for the Blob service client. + /// The for the Blob service client. service_properties download_service_properties(const blob_request_options& options, operation_context context) const { return download_service_properties_async(options, context).get(); @@ -2422,7 +2572,7 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to get the properties of the service. /// - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. pplx::task download_service_properties_async() const { return download_service_properties_async(blob_request_options(), operation_context()); @@ -2431,16 +2581,16 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to get the properties of the service. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. WASTORAGE_API pplx::task download_service_properties_async(const blob_request_options& options, operation_context context) const; /// /// Sets the service properties for the Blob service client. /// - /// The for the Blob service client. - /// A enumeration describing which items to include when setting service properties. + /// The for the Blob service client. + /// An enumeration describing which items to include when setting service properties. void upload_service_properties(const service_properties& properties, const service_properties_includes& includes) const { upload_service_properties_async(properties, includes).wait(); @@ -2449,9 +2599,9 @@ namespace azure { namespace storage { /// /// Sets the service properties for the Blob service client. /// - /// The for the Blob service client. - /// A enumeration describing which items to include when setting service properties. - /// A object that specifies additional options for the request. + /// The for the Blob service client. + /// An enumeration describing which items to include when setting service properties. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void upload_service_properties(const service_properties& properties, const service_properties_includes& includes, const blob_request_options& options, operation_context context) const { @@ -2461,8 +2611,8 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to set the service properties for the Blob service client. /// - /// The for the Blob service client. - /// A enumeration describing which items to include when setting service properties. + /// The for the Blob service client. + /// An enumeration describing which items to include when setting service properties. /// A object that represents the current operation. pplx::task upload_service_properties_async(const service_properties& properties, const service_properties_includes& includes) const { @@ -2472,9 +2622,9 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to set the service properties for the Blob service client. /// - /// The for the Blob service client. - /// A enumeration describing which items to include when setting service properties. - /// A object that specifies additional options for the request. + /// The for the Blob service client. + /// An enumeration describing which items to include when setting service properties. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task upload_service_properties_async(const service_properties& properties, const service_properties_includes& includes, const blob_request_options& options, operation_context context) const; @@ -2482,7 +2632,7 @@ namespace azure { namespace storage { /// /// Gets the service stats for the Blob service client. /// - /// The for the Blob service client. + /// The for the Blob service client. service_stats download_service_stats() const { return download_service_stats_async().get(); @@ -2491,9 +2641,9 @@ namespace azure { namespace storage { /// /// Gets the service stats for the Blob service client. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// The for the Blob service client. + /// The for the Blob service client. service_stats download_service_stats(const blob_request_options& options, operation_context context) const { return download_service_stats_async(options, context).get(); @@ -2502,7 +2652,7 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to get the stats of the service. /// - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. pplx::task download_service_stats_async() const { return download_service_stats_async(blob_request_options(), operation_context()); @@ -2511,28 +2661,28 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to get the stats of the service. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. WASTORAGE_API pplx::task download_service_stats_async(const blob_request_options& options, operation_context context) const; /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// A reference to the root container, of type . + /// A reference to the root container, of type . WASTORAGE_API cloud_blob_container get_root_container_reference() const; /// - /// Returns a reference to a object with the specified name. + /// Returns a reference to an object with the specified name. /// /// The name of the container, or an absolute URI to the container. - /// A reference to a . + /// A reference to an . WASTORAGE_API cloud_blob_container get_container_reference(utility::string_t container_name) const; /// /// Returns the default set of request options. /// - /// A object. + /// An object. const blob_request_options& default_request_options() const { return m_default_request_options; @@ -2589,14 +2739,14 @@ namespace azure { namespace storage { /// /// Initializes a new instance of the class. /// - /// A object containing the absolute URI to the container for all locations. + /// An object containing the absolute URI to the container for all locations. WASTORAGE_API cloud_blob_container(storage_uri uri); /// /// Initializes a new instance of the class. /// - /// A object containing the absolute URI to the container for all locations. - /// The to use. + /// An object containing the absolute URI to the container for all locations. + /// The to use. WASTORAGE_API cloud_blob_container(storage_uri uri, storage_credentials credentials); /// @@ -2620,19 +2770,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. cloud_blob_container(cloud_blob_container&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. cloud_blob_container& operator=(cloud_blob_container&& other) { if (this != &other) @@ -2669,7 +2819,7 @@ namespace azure { namespace storage { /// Gets a reference to a blob in this container. /// /// The name of the blob. - /// A reference to a . + /// A reference to an . WASTORAGE_API cloud_blob get_blob_reference(utility::string_t blob_name) const; /// @@ -2677,14 +2827,14 @@ namespace azure { namespace storage { /// /// The name of the blob. /// The snapshot timestamp, if the blob is a snapshot. - /// A reference to a . + /// A reference to an . WASTORAGE_API cloud_blob get_blob_reference(utility::string_t blob_name, utility::string_t snapshot_time) const; /// /// Gets a reference to a page blob in this container. /// /// The name of the blob. - /// A reference to a . + /// A reference to an . WASTORAGE_API cloud_page_blob get_page_blob_reference(utility::string_t blob_name) const; /// @@ -2692,14 +2842,14 @@ namespace azure { namespace storage { /// /// The name of the blob. /// The snapshot timestamp, if the blob is a snapshot. - /// A reference to a . + /// A reference to an . WASTORAGE_API cloud_page_blob get_page_blob_reference(utility::string_t blob_name, utility::string_t snapshot_time) const; /// /// Gets a reference to a block blob in this container. /// /// The name of the blob. - /// A reference to a . + /// A reference to an . WASTORAGE_API cloud_block_blob get_block_blob_reference(utility::string_t blob_name) const; /// @@ -2707,14 +2857,29 @@ namespace azure { namespace storage { /// /// The name of the blob. /// The snapshot timestamp, if the blob is a snapshot. - /// A reference to a . + /// A reference to an . WASTORAGE_API cloud_block_blob get_block_blob_reference(utility::string_t blob_name, utility::string_t snapshot_time) const; + /// + /// Gets a reference to an append blob in this container. + /// + /// The name of the blob. + /// A reference to a . + WASTORAGE_API cloud_append_blob get_append_blob_reference(utility::string_t blob_name) const; + + /// + /// Gets a reference to an append blob in this container. + /// + /// The name of the blob. + /// The snapshot timestamp, if the blob is a snapshot. + /// A reference to a . + WASTORAGE_API cloud_append_blob get_append_blob_reference(utility::string_t blob_name, utility::string_t snapshot_time) const; + /// /// Gets a reference to a virtual blob directory beneath this container. /// /// The name of the virtual blob directory. - /// A reference to a . + /// A reference to an . WASTORAGE_API cloud_blob_directory get_directory_reference(utility::string_t directory_name) const; /// @@ -2729,7 +2894,7 @@ namespace azure { namespace storage { /// Retrieves the container's attributes. /// /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void download_attributes(const access_condition& condition, const blob_request_options& options, operation_context context) { @@ -2749,7 +2914,7 @@ namespace azure { namespace storage { /// Intitiates an asynchronous operation to retrieve the container's attributes. /// /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task download_attributes_async(const access_condition& condition, const blob_request_options& options, operation_context context); @@ -2766,7 +2931,7 @@ namespace azure { namespace storage { /// Sets the container's user-defined metadata. /// /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void upload_metadata(const access_condition& condition, const blob_request_options& options, operation_context context) { @@ -2786,7 +2951,7 @@ namespace azure { namespace storage { /// Intitiates an asynchronous operation to set the container's user-defined metadata. /// /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task upload_metadata_async(const access_condition& condition, const blob_request_options& options, operation_context context); @@ -2794,7 +2959,7 @@ namespace azure { namespace storage { /// /// Acquires a lease on the container. /// - /// A representing the span of time for which to acquire the lease. + /// An representing the span of time for which to acquire the lease. /// A string representing the proposed lease ID for the new lease. May be an empty string if no lease ID is proposed. /// A string containing the ID of the acquired lease. utility::string_t acquire_lease(const azure::storage::lease_time& duration, const utility::string_t& proposed_lease_id) const @@ -2805,10 +2970,10 @@ namespace azure { namespace storage { /// /// Acquires a lease on the container. /// - /// A representing the span of time for which to acquire the lease. + /// An representing the span of time for which to acquire the lease. /// A string representing the proposed lease ID for the new lease. May be an empty string if no lease ID is proposed. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A string containing the ID of the acquired lease. utility::string_t acquire_lease(const azure::storage::lease_time& duration, const utility::string_t& proposed_lease_id, const access_condition& condition, const blob_request_options& options, operation_context context) const @@ -2819,7 +2984,7 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to acquire a lease on the container. /// - /// A object representing the span of time for which to acquire the lease. + /// An object representing the span of time for which to acquire the lease. /// A string representing the proposed lease ID for the new lease. May be an empty string if no lease ID is proposed.. /// A object of type that represents the current operation. pplx::task acquire_lease_async(const azure::storage::lease_time& duration, const utility::string_t& proposed_lease_id) const @@ -2830,10 +2995,10 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to acquire a lease on the container. /// - /// A representing the span of time for which to acquire the lease. + /// An representing the span of time for which to acquire the lease. /// A string representing the proposed lease ID for the new lease. May be an empty string if no lease ID is proposed. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object of type that represents the current operation. WASTORAGE_API pplx::task acquire_lease_async(const azure::storage::lease_time& duration, const utility::string_t& proposed_lease_id, const access_condition& condition, const blob_request_options& options, operation_context context) const; @@ -2850,7 +3015,7 @@ namespace azure { namespace storage { /// Renews a lease on the container. /// /// An object that represents the access condition for the operation, including a required lease ID. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void renew_lease(const access_condition& condition, const blob_request_options& options, operation_context context) const { @@ -2870,7 +3035,7 @@ namespace azure { namespace storage { /// Intitiates an asynchronous operation to renew a lease on the container. /// /// An object that represents the access condition for the operation, including a required lease ID. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task renew_lease_async(const access_condition& condition, const blob_request_options& options, operation_context context) const; @@ -2890,7 +3055,7 @@ namespace azure { namespace storage { /// /// A string containing the proposed lease ID for the lease. May not be empty. /// An object that represents the access condition for the operation, including a required lease ID. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// The new lease ID. utility::string_t change_lease(const utility::string_t& proposed_lease_id, const access_condition& condition, const blob_request_options& options, operation_context context) const @@ -2913,7 +3078,7 @@ namespace azure { namespace storage { /// /// A string containing the proposed lease ID for the lease. May not be empty. /// An object that represents the access condition for the operation, including a required lease ID. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object of type that represents the current operation. WASTORAGE_API pplx::task change_lease_async(const utility::string_t& proposed_lease_id, const access_condition& condition, const blob_request_options& options, operation_context context) const; @@ -2930,7 +3095,7 @@ namespace azure { namespace storage { /// Releases a lease on the container. /// /// An object that represents the access condition for the operation, including a required lease ID. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void release_lease(const access_condition& condition, const blob_request_options& options, operation_context context) const { @@ -2950,7 +3115,7 @@ namespace azure { namespace storage { /// Intitiates an asynchronous operation to release a lease on the container. /// /// An object that represents the access condition for the operation, including a required lease ID. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task release_lease_async(const access_condition& condition, const blob_request_options& options, operation_context context) const; @@ -2958,7 +3123,7 @@ namespace azure { namespace storage { /// /// Breaks the current lease on the container. /// - /// A representing the amount of time to allow the lease to remain. + /// An representing the amount of time to allow the lease to remain. /// The time until the lease ends, in seconds. std::chrono::seconds break_lease(const azure::storage::lease_break_period& break_period) const { @@ -2968,9 +3133,9 @@ namespace azure { namespace storage { /// /// Breaks the current lease on the container. /// - /// A representing the amount of time to allow the lease to remain. + /// An representing the amount of time to allow the lease to remain. /// An object that represents the access condition for the operation, including a required lease ID. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// The time until the lease ends, in seconds. std::chrono::seconds break_lease(const azure::storage::lease_break_period& break_period, const access_condition& condition, const blob_request_options& options, operation_context context) const @@ -2981,7 +3146,7 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to break the current lease on the container. /// - /// A representing the amount of time to allow the lease to remain. + /// An representing the amount of time to allow the lease to remain. /// A object of type that represents the current operation. pplx::task break_lease_async(const azure::storage::lease_break_period& break_period) const { @@ -2991,9 +3156,9 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to break the current lease on the container. /// - /// A representing the amount of time to allow the lease to remain. + /// An representing the amount of time to allow the lease to remain. /// An object that represents the access condition for the operation, including a required lease ID. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object of type that represents the current operation. WASTORAGE_API pplx::task break_lease_async(const azure::storage::lease_break_period& break_period, const access_condition& condition, const blob_request_options& options, operation_context context) const; @@ -3009,8 +3174,8 @@ namespace azure { namespace storage { /// /// Creates the container and specifies the level of access to the container's data. /// - /// A value that specifies whether data in the container may be accessed publicly and what level of access is to be allowed. - /// A object that specifies additional options for the request. + /// An value that specifies whether data in the container may be accessed publicly and what level of access is to be allowed. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. This object /// is used to track requests to the storage service, and to provide additional runtime information about the operation. void create(blob_container_public_access_type public_access, const blob_request_options& options, operation_context context) @@ -3030,8 +3195,8 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to create the container. /// - /// A value that specifies whether data in the container may be accessed publicly and what level of access is to be allowed. - /// A object that specifies additional options for the request. + /// An value that specifies whether data in the container may be accessed publicly and what level of access is to be allowed. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task create_async(blob_container_public_access_type public_access, const blob_request_options& options, operation_context context); @@ -3048,8 +3213,8 @@ namespace azure { namespace storage { /// /// Creates the container if it does not already exist and specifies the level of public access to the container's data. /// - /// A value that specifies whether data in the container may be accessed publicly and what level of access is to be allowed. - /// A object that specifies additional options for the request. + /// An value that specifies whether data in the container may be accessed publicly and what level of access is to be allowed. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// true if the container did not already exist and was created; otherwise false. bool create_if_not_exists(blob_container_public_access_type public_access, const blob_request_options& options, operation_context context) @@ -3069,8 +3234,8 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to create the container if it does not already exist and specify the level of public access to the container's data. /// - /// A value that specifies whether data in the container may be accessed publicly and what level of access is to be allowed. - /// A object that specifies additional options for the request. + /// An value that specifies whether data in the container may be accessed publicly and what level of access is to be allowed. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task create_if_not_exists_async(blob_container_public_access_type public_access, const blob_request_options& options, operation_context context); @@ -3087,7 +3252,7 @@ namespace azure { namespace storage { /// Deletes the container. /// /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void delete_container(const access_condition& condition, const blob_request_options& options, operation_context context) { @@ -3107,7 +3272,7 @@ namespace azure { namespace storage { /// Intitiates an asynchronous operation to delete the container. /// /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task delete_container_async(const access_condition& condition, const blob_request_options& options, operation_context context); @@ -3125,7 +3290,7 @@ namespace azure { namespace storage { /// Deletes the container if it already exists. /// /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// true if the container did not already exist and was created; otherwise false. bool delete_container_if_exists(const access_condition& condition, const blob_request_options& options, operation_context context) @@ -3147,39 +3312,39 @@ namespace azure { namespace storage { /// Intitiates an asynchronous operation to delete the container if it already exists. /// /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// true if the container did not already exist and was created; otherwise false. /// A object that represents the current operation. WASTORAGE_API pplx::task delete_container_if_exists_async(const access_condition& condition, const blob_request_options& options, operation_context context); /// - /// Returns a that can be used to to lazily enumerate a collection of blob items in the container. + /// Returns an that can be used to to lazily enumerate a collection of blob items in the container. /// - /// A that can be used to to lazily enumerate a collection of blob items in the container. + /// An that can be used to to lazily enumerate a collection of blob items in the container. list_blob_item_iterator list_blobs() const { return list_blobs(utility::string_t(), false, blob_listing_details::none, 0, blob_request_options(), operation_context()); } /// - /// Returns a that can be used to to lazily enumerate a collection of blob items in the the container. + /// Returns an that can be used to to lazily enumerate a collection of blob items in the the container. /// /// The blob name prefix. /// Indicates whether to list blobs in a flat listing, or whether to list blobs hierarchically, by virtual directory. - /// A enumeration describing which items to include in the listing. + /// An enumeration describing which items to include in the listing. /// A non-negative integer value that indicates the maximum number of results to be returned. /// If this value is zero, the maximum possible number of results will be returned. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A that can be used to to lazily enumerate a collection of blob items in the the container. + /// An that can be used to to lazily enumerate a collection of blob items in the the container. WASTORAGE_API list_blob_item_iterator list_blobs(const utility::string_t& prefix, bool use_flat_blob_listing, blob_listing_details::values includes, int max_results, const blob_request_options& options, operation_context context) const; /// /// Returns a result segment containing a collection of blob items in the container. /// /// A continuation token returned by a previous listing operation. - /// A containing blob items, which may implement or . + /// An containing blob items, which may implement or . list_blob_item_segment list_blobs_segmented(const continuation_token& token) const { return list_blobs_segmented_async(token).get(); @@ -3190,7 +3355,7 @@ namespace azure { namespace storage { /// /// The blob name prefix. /// A continuation token returned by a previous listing operation. - /// A result segment containing objects that implement and . + /// A r containing objects that implement and . list_blob_item_segment list_blobs_segmented(const utility::string_t& prefix, const continuation_token& token) const { return list_blobs_segmented_async(prefix, token).get(); @@ -3201,54 +3366,54 @@ namespace azure { namespace storage { /// /// The blob name prefix. /// Indicates whether to list blobs in a flat listing, or whether to list blobs hierarchically, by virtual directory. - /// A enumeration describing which items to include in the listing. + /// An enumeration describing which items to include in the listing. /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the /// per-operation limit of 5000. If this value is 0, the maximum possible number of results will be returned, up to 5000. /// A continuation token returned by a previous listing operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A containing a collection of blob items in the container. + /// An containing a collection of blob items in the container. list_blob_item_segment list_blobs_segmented(const utility::string_t& prefix, bool use_flat_blob_listing, blob_listing_details::values includes, int max_results, const continuation_token& token, const blob_request_options& options, operation_context context) const { return list_blobs_segmented_async(prefix, use_flat_blob_listing, includes, max_results, token, options, context).get(); } /// - /// Intitiates an asynchronous operation to return a containing a collection of blob items + /// Intitiates an asynchronous operation to return an containing a collection of blob items /// in the container. /// /// A continuation token returned by a previous listing operation. - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. pplx::task list_blobs_segmented_async(const continuation_token& token) const { return list_blobs_segmented_async(utility::string_t(), token); } /// - /// Intitiates an asynchronous operation to return a containing a collection of blob items + /// Intitiates an asynchronous operation to return an containing a collection of blob items /// in the container. /// /// The blob name prefix. /// A continuation token returned by a previous listing operation. - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. pplx::task list_blobs_segmented_async(const utility::string_t& prefix, const continuation_token& token) const { return list_blobs_segmented_async(prefix, false, blob_listing_details::none, 0, token, blob_request_options(), operation_context()); } /// - /// Intitiates an asynchronous operation to return a containing a collection of blob items + /// Intitiates an asynchronous operation to return an containing a collection of blob items /// in the container. /// /// The blob name prefix. /// Indicates whether to list blobs in a flat listing, or whether to list blobs hierarchically, by virtual directory. - /// A enumeration describing which items to include in the listing. + /// An enumeration describing which items to include in the listing. /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the /// per-operation limit of 5000. If this value is 0, the maximum possible number of results will be returned, up to 5000. /// A continuation token returned by a previous listing operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. WASTORAGE_API pplx::task list_blobs_segmented_async(const utility::string_t& prefix, bool use_flat_blob_listing, blob_listing_details::values includes, int max_results, const continuation_token& token, const blob_request_options& options, operation_context context) const; /// @@ -3265,7 +3430,7 @@ namespace azure { namespace storage { /// /// The permissions to apply to the container. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void upload_permissions(const blob_container_permissions& permissions, const access_condition& condition, const blob_request_options& options, operation_context context) { @@ -3287,7 +3452,7 @@ namespace azure { namespace storage { /// /// The permissions to apply to the container. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task upload_permissions_async(const blob_container_permissions& permissions, const access_condition& condition, const blob_request_options& options, operation_context context); @@ -3305,7 +3470,7 @@ namespace azure { namespace storage { /// Gets the permissions settings for the container. /// /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// The container's permissions. blob_container_permissions download_permissions(const access_condition& condition, const blob_request_options& options, operation_context context) @@ -3316,7 +3481,7 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to get permissions settings for the container. /// - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. pplx::task download_permissions_async() { return download_permissions_async(access_condition(), blob_request_options(), operation_context()); @@ -3326,9 +3491,9 @@ namespace azure { namespace storage { /// Intitiates an asynchronous operation to get permissions settings for the container. /// /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. WASTORAGE_API pplx::task download_permissions_async(const access_condition& condition, const blob_request_options& options, operation_context context); /// @@ -3343,7 +3508,7 @@ namespace azure { namespace storage { /// /// Checks existence of the container. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// true if the container exists. bool exists(const blob_request_options& options, operation_context context) @@ -3363,7 +3528,7 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to check the existence of the container. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that that represents the current operation. pplx::task exists_async(const blob_request_options& options, operation_context context) @@ -3374,7 +3539,7 @@ namespace azure { namespace storage { /// /// Gets the Blob service client for the container. /// - /// A object that specifies the endpoint for the Blob service. + /// An object that specifies the endpoint for the Blob service. const cloud_blob_client& service_client() const { return m_client; @@ -3392,7 +3557,7 @@ namespace azure { namespace storage { /// /// Gets the container URI for all locations. /// - /// A containing the container URI for all locations. + /// An containing the container URI for all locations. const storage_uri& uri() const { return m_uri; @@ -3401,7 +3566,7 @@ namespace azure { namespace storage { /// /// Gets the container's metadata. /// - /// A object containing the container's metadata. + /// An object containing the container's metadata. cloud_metadata& metadata() { return *m_metadata; @@ -3410,7 +3575,7 @@ namespace azure { namespace storage { /// /// Gets the container's metadata. /// - /// A object containing the container's metadata. + /// An object containing the container's metadata. const cloud_metadata& metadata() const { return *m_metadata; @@ -3426,9 +3591,9 @@ namespace azure { namespace storage { } /// - /// Indicates whether the object is valid. + /// Indicates whether the object is valid. /// - /// true if the object is valid; otherwise, false. + /// true if the object is valid; otherwise, false. bool is_valid() const { return !m_name.empty(); @@ -3465,19 +3630,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. cloud_blob_directory(cloud_blob_directory&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. cloud_blob_directory& operator=(cloud_blob_directory&& other) { if (this != &other) @@ -3494,7 +3659,7 @@ namespace azure { namespace storage { /// Gets a reference to a blob in this virtual directory. /// /// The name of the blob. - /// A reference to a . + /// A reference to an . WASTORAGE_API cloud_blob get_blob_reference(utility::string_t blob_name) const; /// @@ -3502,14 +3667,14 @@ namespace azure { namespace storage { /// /// The name of the blob. /// The snapshot timestamp, if the blob is a snapshot. - /// A reference to a . + /// A reference to an . WASTORAGE_API cloud_blob get_blob_reference(utility::string_t blob_name, utility::string_t snapshot_time) const; /// /// Gets a reference to a page blob in this virtual directory. /// /// The name of the blob. - /// A reference to a . + /// A reference to an . WASTORAGE_API cloud_page_blob get_page_blob_reference(utility::string_t blob_name) const; /// @@ -3517,14 +3682,14 @@ namespace azure { namespace storage { /// /// The name of the blob. /// The snapshot timestamp, if the blob is a snapshot. - /// A reference to a . + /// A reference to an . WASTORAGE_API cloud_page_blob get_page_blob_reference(utility::string_t blob_name, utility::string_t snapshot_time) const; /// /// Gets a reference to a block blob in this virtual directory. /// /// The name of the blob. - /// A reference to a . + /// A reference to an . WASTORAGE_API cloud_block_blob get_block_blob_reference(utility::string_t blob_name) const; /// @@ -3532,14 +3697,29 @@ namespace azure { namespace storage { /// /// The name of the blob. /// The snapshot timestamp, if the blob is a snapshot. - /// A reference to a . + /// A reference to an . WASTORAGE_API cloud_block_blob get_block_blob_reference(utility::string_t blob_name, utility::string_t snapshot_time) const; + /// + /// Gets a reference to an append blob in this virtual directory. + /// + /// The name of the blob. + /// A reference to a . + WASTORAGE_API cloud_append_blob get_append_blob_reference(utility::string_t blob_name) const; + + /// + /// Gets a reference to an append blob in this virtual directory. + /// + /// The name of the blob. + /// The snapshot timestamp, if the blob is a snapshot. + /// A reference to a . + WASTORAGE_API cloud_append_blob get_append_blob_reference(utility::string_t blob_name, utility::string_t snapshot_time) const; + /// /// Returns a virtual subdirectory within this virtual directory. /// /// The name of the virtual subdirectory. - /// A object representing the virtual subdirectory. + /// An object representing the virtual subdirectory. WASTORAGE_API cloud_blob_directory get_subdirectory_reference(utility::string_t name) const; /// @@ -3550,24 +3730,24 @@ namespace azure { namespace storage { WASTORAGE_API cloud_blob_directory get_parent_reference() const; /// - /// Returns a that can be used to to lazily enumerate a collection of blob items in the virtual directory. + /// Returns an that can be used to to lazily enumerate a collection of blob items in the virtual directory. /// - /// A that can be used to to lazily enumerate a collection of blob items in the virtual directory. + /// An that can be used to to lazily enumerate a collection of blob items in the virtual directory. list_blob_item_iterator list_blobs() const { return list_blobs(false, blob_listing_details::none, 0, blob_request_options(), operation_context()); } /// - /// Returns a that can be used to to lazily enumerate a collection of blob items in the the virtual directory. + /// Returns an that can be used to to lazily enumerate a collection of blob items in the the virtual directory. /// /// Indicates whether to list blobs in a flat listing, or whether to list blobs hierarchically, by virtual directory. - /// A enumeration describing which items to include in the listing. + /// An enumeration describing which items to include in the listing. /// A non-negative integer value that indicates the maximum number of results to be returned. /// If this value is zero, the maximum possible number of results will be returned. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A that can be used to to lazily enumerate a collection of blob items in the the virtual directory. + /// An that can be used to to lazily enumerate a collection of blob items in the the virtual directory. WASTORAGE_API list_blob_item_iterator list_blobs(bool use_flat_blob_listing, blob_listing_details::values includes, int max_results, const blob_request_options& options, operation_context context) const; /// @@ -3575,51 +3755,51 @@ namespace azure { namespace storage { /// in the container. /// /// A continuation token returned by a previous listing operation. - /// A containing a collection of blob items in the container. + /// An containing a collection of blob items in the container. list_blob_item_segment list_blobs_segmented(const continuation_token& token) const { return list_blobs_segmented_async(token).get(); } /// - /// Returns a containing a collection of blob items in the container. + /// Returns an containing a collection of blob items in the container. /// /// Indicates whether to list blobs in a flat listing, or whether to list blobs hierarchically, by virtual directory. - /// A enumeration describing which items to include in the listing. + /// An enumeration describing which items to include in the listing. /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the /// per-operation limit of 5000. If this value is 0, the maximum possible number of results will be returned, up to 5000. /// A continuation token returned by a previous listing operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A containing a collection of blob items in the container. + /// An containing a collection of blob items in the container. list_blob_item_segment list_blobs_segmented(bool use_flat_blob_listing, blob_listing_details::values includes, int max_results, const continuation_token& token, const blob_request_options& options, operation_context context) const { return list_blobs_segmented_async(use_flat_blob_listing, includes, max_results, token, options, context).get(); } /// - /// Intitiates an asynchronous operation to return a containing a collection of blob items + /// Intitiates an asynchronous operation to return an containing a collection of blob items /// in the container. /// /// A continuation token returned by a previous listing operation. - /// A object of type that that represents the current operation. + /// A object of type that that represents the current operation. pplx::task list_blobs_segmented_async(const continuation_token& token) const { return list_blobs_segmented_async(false, blob_listing_details::none, 0, token, blob_request_options(), operation_context()); } /// - /// Intitiates an asynchronous operation to return a containing a collection of blob items + /// Intitiates an asynchronous operation to return an containing a collection of blob items /// in the container. /// /// Indicates whether to list blobs in a flat listing, or whether to list blobs hierarchically, by virtual directory. - /// A enumeration describing which items to include in the listing. + /// An enumeration describing which items to include in the listing. /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the /// per-operation limit of 5000. If this value is 0, the maximum possible number of results will be returned, up to 5000. /// A continuation token returned by a previous listing operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. WASTORAGE_API pplx::task list_blobs_segmented_async(bool use_flat_blob_listing, blob_listing_details::values includes, int max_results, const continuation_token& token, const blob_request_options& options, operation_context context) const; /// @@ -3632,7 +3812,7 @@ namespace azure { namespace storage { } /// - /// Gets a object representing the virtual directory's container. + /// Gets an object representing the virtual directory's container. /// /// The virtual directory's container. const cloud_blob_container& container() const @@ -3643,7 +3823,7 @@ namespace azure { namespace storage { /// /// Gets the virtual directory URI for all locations. /// - /// A containing the virtual directory URI for all locations. + /// An containing the virtual directory URI for all locations. const storage_uri& uri() const { return m_uri; @@ -3659,9 +3839,9 @@ namespace azure { namespace storage { } /// - /// Indicates whether the object is valid. + /// Indicates whether the object is valid. /// - /// true if the object is valid; otherwise, false. + /// true if the object is valid; otherwise, false. bool is_valid() const { return !m_name.empty(); @@ -3686,38 +3866,40 @@ namespace azure { namespace storage { }; /// - /// A class for Windows Azure blob types. The and - /// classes derive from the class. + /// A class for Windows Azure blob types. The and + /// classes derive from the class. /// class cloud_blob { public: /// - /// Initializes a new instance of the class using an absolute URI to the blob. + /// Initializes a new instance of the class. /// cloud_blob() + : m_metadata(std::make_shared()), m_properties(std::make_shared()), m_copy_state(std::make_shared()) { + set_type(blob_type::unspecified); } /// /// Initializes a new instance of the class using an absolute URI to the blob. /// - /// A object containing the absolute URI to the blob for all locations. + /// An object containing the absolute URI to the blob for all locations. WASTORAGE_API cloud_blob(storage_uri uri); /// /// Initializes a new instance of the class using an absolute URI to the blob. /// - /// A object containing the absolute URI to the blob for all locations. - /// The to use. + /// An object containing the absolute URI to the blob for all locations. + /// The to use. WASTORAGE_API cloud_blob(storage_uri uri, storage_credentials credentials); /// /// Initializes a new instance of the class using an absolute URI to the blob. /// - /// A object containing the absolute URI to the blob for all locations. + /// An object containing the absolute URI to the blob for all locations. /// The snapshot timestamp, if the blob is a snapshot. - /// The to use. + /// The to use. WASTORAGE_API cloud_blob(storage_uri uri, utility::string_t snapshot_time, storage_credentials credentials); #if defined(_MSC_VER) && _MSC_VER < 1900 @@ -3725,19 +3907,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. cloud_blob(cloud_blob&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. cloud_blob& operator=(cloud_blob&& other) { if (this != &other) @@ -3810,7 +3992,7 @@ namespace azure { namespace storage { /// Opens a stream for reading from the blob. /// /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A stream to be used for reading from the blob. concurrency::streams::istream open_read(const access_condition& condition, const blob_request_options& options, operation_context context) @@ -3831,7 +4013,7 @@ namespace azure { namespace storage { /// Intitiates an asynchronous operation to open a stream for reading from the blob. /// /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object of type that represents the current operation. WASTORAGE_API pplx::task open_read_async(const access_condition& condition, const blob_request_options& options, operation_context context); @@ -3848,7 +4030,7 @@ namespace azure { namespace storage { /// /// Checks existence of the blob. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// true if the blob exists. bool exists(const blob_request_options& options, operation_context context) @@ -3868,7 +4050,7 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to check the existence of the blob. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. pplx::task exists_async(const blob_request_options& options, operation_context context) @@ -3888,7 +4070,7 @@ namespace azure { namespace storage { /// Populates a blob's properties and metadata. /// /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void download_attributes(const access_condition& condition, const blob_request_options& options, operation_context context) { @@ -3908,7 +4090,7 @@ namespace azure { namespace storage { /// Intitiates an asynchronous operation to populate a blob's properties and metadata. /// /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task download_attributes_async(const access_condition& condition, const blob_request_options& options, operation_context context); @@ -3925,7 +4107,7 @@ namespace azure { namespace storage { /// Updates the blob's metadata. /// /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void upload_metadata(const access_condition& condition, const blob_request_options& options, operation_context context) { @@ -3945,7 +4127,7 @@ namespace azure { namespace storage { /// Intitiates an asynchronous operation to update the blob's metadata. /// /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task upload_metadata_async(const access_condition& condition, const blob_request_options& options, operation_context context); @@ -3962,7 +4144,7 @@ namespace azure { namespace storage { /// Updates the blob's properties. /// /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void upload_properties(const access_condition& condition, const blob_request_options& options, operation_context context) { @@ -3982,7 +4164,7 @@ namespace azure { namespace storage { /// Intitiates an asynchronous operation to update the blob's properties. /// /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task upload_properties_async(const access_condition& condition, const blob_request_options& options, operation_context context); @@ -4000,7 +4182,7 @@ namespace azure { namespace storage { /// /// Indicates whether to delete only the blob, to delete the blob and all snapshots, or to delete only snapshots. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void delete_blob(delete_snapshots_option snapshots_option, const access_condition& condition, const blob_request_options& options, operation_context context) { @@ -4021,7 +4203,7 @@ namespace azure { namespace storage { /// /// Indicates whether to delete only the blob, to delete the blob and all snapshots, or to delete only snapshots. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task delete_blob_async(delete_snapshots_option snapshots_option, const access_condition& condition, const blob_request_options& options, operation_context context); @@ -4040,7 +4222,7 @@ namespace azure { namespace storage { /// /// Indicates whether to delete only the blob, to delete the blob and all snapshots, or to delete only snapshots. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// true if the blob did already exist and was deleted; otherwise false. bool delete_blob_if_exists(delete_snapshots_option snapshots_option, const access_condition& condition, const blob_request_options& options, operation_context context) @@ -4062,7 +4244,7 @@ namespace azure { namespace storage { /// /// Indicates whether to delete only the blob, to delete the blob and all snapshots, or to delete only snapshots. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task delete_blob_if_exists_async(delete_snapshots_option snapshots_option, const access_condition& condition, const blob_request_options& options, operation_context context); @@ -4070,7 +4252,7 @@ namespace azure { namespace storage { /// /// Acquires a lease on the blob. /// - /// A representing the span of time for which to acquire the lease. + /// An representing the span of time for which to acquire the lease. /// A string representing the proposed lease ID for the new lease. May be an empty string if no lease ID is proposed. /// A string containing the lease ID. utility::string_t acquire_lease(const azure::storage::lease_time& duration, const utility::string_t& proposed_lease_id) const @@ -4081,10 +4263,10 @@ namespace azure { namespace storage { /// /// Acquires a lease on the blob. /// - /// A representing the span of time for which to acquire the lease. + /// An representing the span of time for which to acquire the lease. /// A string representing the proposed lease ID for the new lease. May be an empty string if no lease ID is proposed. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A string containing the lease ID. utility::string_t acquire_lease(const azure::storage::lease_time& duration, const utility::string_t& proposed_lease_id, const access_condition& condition, const blob_request_options& options, operation_context context) const @@ -4095,7 +4277,7 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to acquire a lease on the blob. /// - /// A representing the span of time for which to acquire the lease. + /// An representing the span of time for which to acquire the lease. /// A string representing the proposed lease ID for the new lease. May be an empty string if no lease ID is proposed. /// A object of type that represents the current operation. pplx::task acquire_lease_async(const azure::storage::lease_time& duration, const utility::string_t& proposed_lease_id) const @@ -4106,10 +4288,10 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to acquire a lease on the blob. /// - /// A representing the span of time for which to acquire the lease. + /// An representing the span of time for which to acquire the lease. /// A string representing the proposed lease ID for the new lease. May be an empty string if no lease ID is proposed. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object of type that represents the current operation. WASTORAGE_API pplx::task acquire_lease_async(const azure::storage::lease_time& duration, const utility::string_t& proposed_lease_id, const access_condition& condition, const blob_request_options& options, operation_context context) const; @@ -4127,7 +4309,7 @@ namespace azure { namespace storage { /// Renews a lease on the blob. /// /// An object that represents the access conditions for the blob, including a required lease ID. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void renew_lease(const access_condition& condition, const blob_request_options& options, operation_context context) const { @@ -4148,7 +4330,7 @@ namespace azure { namespace storage { /// Intitiates an asynchronous operation to renew a lease on the blob. /// /// An object that represents the access conditions for the blob, including a required lease ID. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task renew_lease_async(const access_condition& condition, const blob_request_options& options, operation_context context) const; @@ -4169,7 +4351,7 @@ namespace azure { namespace storage { /// /// A string containing the proposed lease ID for the lease. May not be empty. /// An object that represents the access conditions for the blob, including a required lease ID. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// The new lease ID. utility::string_t change_lease(const utility::string_t& proposed_lease_id, const access_condition& condition, const blob_request_options& options, operation_context context) const @@ -4193,7 +4375,7 @@ namespace azure { namespace storage { /// /// A string containing the proposed lease ID for the lease. May not be empty. /// An object that represents the access conditions for the blob, including a required lease ID. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object of type that represents the current operation. WASTORAGE_API pplx::task change_lease_async(const utility::string_t& proposed_lease_id, const access_condition& condition, const blob_request_options& options, operation_context context) const; @@ -4211,7 +4393,7 @@ namespace azure { namespace storage { /// Releases the lease on the blob. /// /// An object that represents the access conditions for the blob, including a required lease ID. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void release_lease(const access_condition& condition, const blob_request_options& options, operation_context context) const { @@ -4232,7 +4414,7 @@ namespace azure { namespace storage { /// Intitiates an asynchronous operation to release the lease on the blob. /// /// An object that represents the access conditions for the blob, including a required lease ID. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task release_lease_async(const access_condition& condition, const blob_request_options& options, operation_context context) const; @@ -4240,7 +4422,7 @@ namespace azure { namespace storage { /// /// Breaks the current lease on the blob. /// - /// A representing the amount of time to allow the lease to remain. + /// An representing the amount of time to allow the lease to remain. /// The time until the lease ends, in seconds. std::chrono::seconds break_lease(const azure::storage::lease_break_period& break_period) const { @@ -4250,9 +4432,9 @@ namespace azure { namespace storage { /// /// Breaks the current lease on the blob. /// - /// A representing the amount of time to allow the lease to remain. + /// An representing the amount of time to allow the lease to remain. /// An object that represents the access conditions for the blob, including a required lease ID. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// The time until the lease ends, in seconds. std::chrono::seconds break_lease(const azure::storage::lease_break_period& break_period, const access_condition& condition, const blob_request_options& options, operation_context context) const @@ -4263,7 +4445,7 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to break the current lease on the blob. /// - /// A representing the amount of time to allow the lease to remain. + /// An representing the amount of time to allow the lease to remain. /// A object of type that represents the current operation. pplx::task break_lease_async(const azure::storage::lease_break_period& break_period) const { @@ -4273,9 +4455,9 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to break the current lease on the blob. /// - /// A representing the amount of time to allow the lease to remain. + /// An representing the amount of time to allow the lease to remain. /// An object that represents the access conditions for the blob, including a required lease ID. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object of type that represents the current operation. WASTORAGE_API pplx::task break_lease_async(const azure::storage::lease_break_period& break_period, const access_condition& condition, const blob_request_options& options, operation_context context) const; @@ -4294,7 +4476,7 @@ namespace azure { namespace storage { /// /// The target stream. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void download_to_stream(concurrency::streams::ostream target, const access_condition& condition, const blob_request_options& options, operation_context context) { @@ -4316,7 +4498,7 @@ namespace azure { namespace storage { /// /// The target stream. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. pplx::task download_to_stream_async(concurrency::streams::ostream target, const access_condition& condition, const blob_request_options& options, operation_context context) @@ -4342,7 +4524,7 @@ namespace azure { namespace storage { /// The offset at which to begin downloading the blob, in bytes. /// The length of the data to download from the blob, in bytes. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void download_range_to_stream(concurrency::streams::ostream target, utility::size64_t offset, utility::size64_t length, const access_condition& condition, const blob_request_options& options, operation_context context) { @@ -4368,7 +4550,7 @@ namespace azure { namespace storage { /// The offset at which to begin downloading the blob, in bytes. /// The length of the data to download from the blob, in bytes. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task download_range_to_stream_async(concurrency::streams::ostream target, utility::size64_t offset, utility::size64_t length, const access_condition& condition, const blob_request_options& options, operation_context context); @@ -4387,7 +4569,7 @@ namespace azure { namespace storage { /// /// The target file. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void download_to_file(const utility::string_t &path, const access_condition& condition, const blob_request_options& options, operation_context context) { @@ -4409,7 +4591,7 @@ namespace azure { namespace storage { /// /// The target file. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task download_to_file_async(const utility::string_t &path, const access_condition& condition, const blob_request_options& options, operation_context context); @@ -4420,12 +4602,14 @@ namespace azure { namespace storage { /// The URI of a source blob. /// The copy ID associated with the copy operation. /// - /// This method fetches the blob's ETag, last-modified time, and part of the copy state. - /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. + /// This method fetches the blob's ETag, last-modified time, and part of the copy state. + /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. + /// This method is deprecated in favor of start_copy. /// + DEPRECATED("Deprecated this method in favor of start_copy.") utility::string_t start_copy_from_blob(const web::http::uri& source) { - return start_copy_from_blob_async(source).get(); + return start_copy_async(source).get(); } /// @@ -4434,16 +4618,18 @@ namespace azure { namespace storage { /// The URI of a source blob. /// An object that represents the for the source blob. /// An object that represents the for the destination blob. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// The copy ID associated with the copy operation. /// - /// This method fetches the blob's ETag, last-modified time, and part of the copy state. - /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. + /// This method fetches the blob's ETag, last-modified time, and part of the copy state. + /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. + /// This method is deprecated in favor of start_copy. /// + DEPRECATED("Deprecated this method in favor of start_copy.") utility::string_t start_copy_from_blob(const web::http::uri& source, const access_condition& source_condition, const access_condition& destination_condition, const blob_request_options& options, operation_context context) { - return start_copy_from_blob_async(source, source_condition, destination_condition, options, context).get(); + return start_copy_async(source, source_condition, destination_condition, options, context).get(); } /// @@ -4452,12 +4638,14 @@ namespace azure { namespace storage { /// The URI of a source blob. /// The copy ID associated with the copy operation. /// - /// This method fetches the blob's ETag, last-modified time, and part of the copy state. - /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. + /// This method fetches the blob's ETag, last-modified time, and part of the copy state. + /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. + /// This method is deprecated in favor of start_copy. /// + DEPRECATED("Deprecated this method in favor of start_copy.") utility::string_t start_copy_from_blob(const cloud_blob& source) { - return start_copy_from_blob_async(source).get(); + return start_copy_async(source).get(); } /// @@ -4466,16 +4654,18 @@ namespace azure { namespace storage { /// The URI of a source blob. /// An object that represents the for the source blob. /// An object that represents the for the destination blob. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// The copy ID associated with the copy operation. /// - /// This method fetches the blob's ETag, last-modified time, and part of the copy state. - /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. + /// This method fetches the blob's ETag, last-modified time, and part of the copy state. + /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. + /// This method is deprecated in favor of start_copy. /// + DEPRECATED("Deprecated this method in favor of start_copy.") utility::string_t start_copy_from_blob(const cloud_blob& source, const access_condition& source_condition, const access_condition& destination_condition, const blob_request_options& options, operation_context context) { - return start_copy_from_blob_async(source, source_condition, destination_condition, options, context).get(); + return start_copy_async(source, source_condition, destination_condition, options, context).get(); } /// @@ -4484,12 +4674,14 @@ namespace azure { namespace storage { /// The URI of a source blob. /// A object of type that represents the current operation. /// - /// This method fetches the blob's ETag, last-modified time, and part of the copy state. - /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. + /// This method fetches the blob's ETag, last-modified time, and part of the copy state. + /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. + /// This method is deprecated in favor of start_copy. /// + DEPRECATED("Deprecated this method in favor of start_copy_async.") pplx::task start_copy_from_blob_async(const web::http::uri& source) { - return start_copy_from_blob_async(source, access_condition(), access_condition(), blob_request_options(), operation_context()); + return start_copy_async(source, access_condition(), access_condition(), blob_request_options(), operation_context()); } /// @@ -4498,12 +4690,14 @@ namespace azure { namespace storage { /// The URI of a source blob. /// A object of type that represents the current operation. /// - /// This method fetches the blob's ETag, last-modified time, and part of the copy state. - /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. + /// This method fetches the blob's ETag, last-modified time, and part of the copy state. + /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. + /// This method is deprecated in favor of start_copy. /// + DEPRECATED("Deprecated this method in favor of start_copy_async.") pplx::task start_copy_from_blob_async(const cloud_blob& source) { - return start_copy_from_blob_async(source, access_condition(), access_condition(), blob_request_options(), operation_context()); + return start_copy_async(source, access_condition(), access_condition(), blob_request_options(), operation_context()); } /// @@ -4512,13 +4706,15 @@ namespace azure { namespace storage { /// The URI of a source blob. /// An object that represents the for the source blob. /// An object that represents the for the destination blob. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object of type that represents the current operation. /// - /// This method fetches the blob's ETag, last-modified time, and part of the copy state. - /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. + /// This method fetches the blob's ETag, last-modified time, and part of the copy state. + /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. + /// This method is deprecated in favor of start_copy. /// + DEPRECATED("Deprecated this method in favor of start_copy_async.") WASTORAGE_API pplx::task start_copy_from_blob_async(const web::http::uri& source, const access_condition& source_condition, const access_condition& destination_condition, const blob_request_options& options, operation_context context); /// @@ -4527,63 +4723,187 @@ namespace azure { namespace storage { /// The URI of a source blob. /// An object that represents the for the source blob. /// An object that represents the for the destination blob. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object of type that represents the current operation. /// - /// This method fetches the blob's ETag, last-modified time, and part of the copy state. - /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. + /// This method fetches the blob's ETag, last-modified time, and part of the copy state. + /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. + /// This method is deprecated in favor of start_copy. /// + DEPRECATED("Deprecated this method in favor of start_copy_async.") WASTORAGE_API pplx::task start_copy_from_blob_async(const cloud_blob& source, const access_condition& source_condition, const access_condition& destination_condition, const blob_request_options& options, operation_context context); /// - /// Aborts an ongoing blob copy operation. + /// Begins an operation to copy a blob's contents, properties, and metadata to a new blob. /// - /// A string identifying the copy operation. - void abort_copy(const utility::string_t& copy_id) const + /// The URI of a source blob. + /// The copy ID associated with the copy operation. + /// + /// This method fetches the blob's ETag, last-modified time, and part of the copy state. + /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. + /// + utility::string_t start_copy(const web::http::uri& source) { - abort_copy_async(copy_id).wait(); + return start_copy_async(source).get(); } /// - /// Aborts an ongoing blob copy operation. + /// Begins an operation to copy a blob's contents, properties, and metadata to a new blob. /// - /// A string identifying the copy operation. - /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// The URI of a source blob. + /// An object that represents the for the source blob. + /// An object that represents the for the destination blob. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - void abort_copy(const utility::string_t& copy_id, const access_condition& condition, const blob_request_options& options, operation_context context) const + /// The copy ID associated with the copy operation. + /// + /// This method fetches the blob's ETag, last-modified time, and part of the copy state. + /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. + /// + utility::string_t start_copy(const web::http::uri& source, const access_condition& source_condition, const access_condition& destination_condition, const blob_request_options& options, operation_context context) { - abort_copy_async(copy_id, condition, options, context).wait(); + return start_copy_async(source, source_condition, destination_condition, options, context).get(); } /// - /// Intitiates an asynchronous operation to abort an ongoing blob copy operation. + /// Begins an operation to copy a blob's contents, properties, and metadata to a new blob. /// - /// A string identifying the copy operation. - /// A object that represents the current operation. - pplx::task abort_copy_async(const utility::string_t& copy_id) const + /// The URI of a source blob. + /// The copy ID associated with the copy operation. + /// + /// This method fetches the blob's ETag, last-modified time, and part of the copy state. + /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. + /// + utility::string_t start_copy(const cloud_blob& source) { - return abort_copy_async(copy_id, access_condition(), blob_request_options(), operation_context()); + return start_copy_async(source).get(); } /// - /// Intitiates an asynchronous operation to abort an ongoing blob copy operation. + /// Begins an operation to copy a blob's contents, properties, and metadata to a new blob. /// - /// A string identifying the copy operation. - /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// The URI of a source blob. + /// An object that represents the for the source blob. + /// An object that represents the for the destination blob. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A object that represents the current operation. - WASTORAGE_API pplx::task abort_copy_async(const utility::string_t& copy_id, const access_condition& condition, const blob_request_options& options, operation_context context) const; + /// The copy ID associated with the copy operation. + /// + /// This method fetches the blob's ETag, last-modified time, and part of the copy state. + /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. + /// + utility::string_t start_copy(const cloud_blob& source, const access_condition& source_condition, const access_condition& destination_condition, const blob_request_options& options, operation_context context) + { + return start_copy_async(source, source_condition, destination_condition, options, context).get(); + } /// - /// Creates a snapshot of the blob. + /// Intitiates an asynchronous operation to begin to copy a blob's contents, properties, and metadata to a new blob. /// - /// A blob snapshot. - cloud_blob create_snapshot() + /// The URI of a source blob. + /// A object of type that represents the current operation. + /// + /// This method fetches the blob's ETag, last-modified time, and part of the copy state. + /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. + /// + pplx::task start_copy_async(const web::http::uri& source) { - return create_snapshot_async().get(); + return start_copy_async(source, access_condition(), access_condition(), blob_request_options(), operation_context()); + } + + /// + /// Intitiates an asynchronous operation to begin to copy a blob's contents, properties, and metadata to a new blob. + /// + /// The URI of a source blob. + /// A object of type that represents the current operation. + /// + /// This method fetches the blob's ETag, last-modified time, and part of the copy state. + /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. + /// + pplx::task start_copy_async(const cloud_blob& source) + { + return start_copy_async(source, access_condition(), access_condition(), blob_request_options(), operation_context()); + } + + /// + /// Intitiates an asynchronous operation to begin to copy a blob's contents, properties, and metadata to a new blob. + /// + /// The URI of a source blob. + /// An object that represents the for the source blob. + /// An object that represents the for the destination blob. + /// An object that specifies additional options for the request. + /// An object that represents the context for the current operation. + /// A object of type that represents the current operation. + /// + /// This method fetches the blob's ETag, last-modified time, and part of the copy state. + /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. + /// + WASTORAGE_API pplx::task start_copy_async(const web::http::uri& source, const access_condition& source_condition, const access_condition& destination_condition, const blob_request_options& options, operation_context context); + + /// + /// Intitiates an asynchronous operation to begin to copy a blob's contents, properties, and metadata to a new blob. + /// + /// The URI of a source blob. + /// An object that represents the for the source blob. + /// An object that represents the for the destination blob. + /// An object that specifies additional options for the request. + /// An object that represents the context for the current operation. + /// A object of type that represents the current operation. + /// + /// This method fetches the blob's ETag, last-modified time, and part of the copy state. + /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. + /// + WASTORAGE_API pplx::task start_copy_async(const cloud_blob& source, const access_condition& source_condition, const access_condition& destination_condition, const blob_request_options& options, operation_context context); + + /// + /// Aborts an ongoing blob copy operation. + /// + /// A string identifying the copy operation. + void abort_copy(const utility::string_t& copy_id) const + { + abort_copy_async(copy_id).wait(); + } + + /// + /// Aborts an ongoing blob copy operation. + /// + /// A string identifying the copy operation. + /// An object that represents the access condition for the operation. + /// An object that specifies additional options for the request. + /// An object that represents the context for the current operation. + void abort_copy(const utility::string_t& copy_id, const access_condition& condition, const blob_request_options& options, operation_context context) const + { + abort_copy_async(copy_id, condition, options, context).wait(); + } + + /// + /// Intitiates an asynchronous operation to abort an ongoing blob copy operation. + /// + /// A string identifying the copy operation. + /// A object that represents the current operation. + pplx::task abort_copy_async(const utility::string_t& copy_id) const + { + return abort_copy_async(copy_id, access_condition(), blob_request_options(), operation_context()); + } + + /// + /// Intitiates an asynchronous operation to abort an ongoing blob copy operation. + /// + /// A string identifying the copy operation. + /// An object that represents the access condition for the operation. + /// An object that specifies additional options for the request. + /// An object that represents the context for the current operation. + /// A object that represents the current operation. + WASTORAGE_API pplx::task abort_copy_async(const utility::string_t& copy_id, const access_condition& condition, const blob_request_options& options, operation_context context) const; + + /// + /// Creates a snapshot of the blob. + /// + /// A blob snapshot. + cloud_blob create_snapshot() + { + return create_snapshot_async().get(); } /// @@ -4591,7 +4911,7 @@ namespace azure { namespace storage { /// /// A collection of name-value pairs defining the metadata of the snapshot. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A blob snapshot. cloud_blob create_snapshot(cloud_metadata metadata, const access_condition& condition, const blob_request_options& options, operation_context context) @@ -4613,7 +4933,7 @@ namespace azure { namespace storage { /// /// A collection of name-value pairs defining the metadata of the snapshot. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object of type that represents the current operation. WASTORAGE_API pplx::task create_snapshot_async(cloud_metadata metadata, const access_condition& condition, const blob_request_options& options, operation_context context); @@ -4628,7 +4948,7 @@ namespace azure { namespace storage { } /// - /// Gets a object representing the blob's container. + /// Gets an object representing the blob's container. /// /// The blob's container. const cloud_blob_container& container() const @@ -4693,7 +5013,7 @@ namespace azure { namespace storage { /// /// Gets the state of the most recent or pending copy operation. /// - /// A object containing the copy state. + /// An object containing the copy state. const azure::storage::copy_state& copy_state() const { return *m_copy_state; @@ -4702,7 +5022,7 @@ namespace azure { namespace storage { /// /// Gets the blob URI for all locations. /// - /// A containing the blob URI for all locations. + /// An containing the blob URI for all locations. const storage_uri& uri() const { return m_uri; @@ -4727,9 +5047,9 @@ namespace azure { namespace storage { } /// - /// Indicates whether the object is valid. + /// Indicates whether the object is valid. /// - /// true if the object is valid; otherwise, false. + /// true if the object is valid; otherwise, false. bool is_valid() const { return !m_name.empty(); @@ -4790,17 +5110,18 @@ namespace azure { namespace storage { public: /// - /// Initializes a new instance of the class using an absolute URI to the blob. + /// Initializes a new instance of the class. /// cloud_block_blob() : cloud_blob() { + set_type(blob_type::block_blob); } /// /// Initializes a new instance of the class using an absolute URI to the blob. /// - /// A object containing the absolute URI to the blob for all locations. + /// An object containing the absolute URI to the blob for all locations. explicit cloud_block_blob(storage_uri uri) : cloud_blob(std::move(uri)) { @@ -4810,8 +5131,8 @@ namespace azure { namespace storage { /// /// Initializes a new instance of the class using an absolute URI to the blob. /// - /// A object containing the absolute URI to the blob for all locations. - /// The to use. + /// An object containing the absolute URI to the blob for all locations. + /// The to use. cloud_block_blob(storage_uri uri, storage_credentials credentials) : cloud_blob(std::move(uri), std::move(credentials)) { @@ -4821,9 +5142,9 @@ namespace azure { namespace storage { /// /// Initializes a new instance of the class using an absolute URI to the blob. /// - /// A object containing the absolute URI to the blob for all locations. + /// An object containing the absolute URI to the blob for all locations. /// The snapshot timestamp, if the blob is a snapshot. - /// The to use. + /// The to use. cloud_block_blob(storage_uri uri, utility::string_t snapshot_time, storage_credentials credentials) : cloud_blob(std::move(uri), std::move(snapshot_time), std::move(credentials)) { @@ -4845,19 +5166,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. cloud_block_blob(cloud_block_blob&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. cloud_block_blob& operator=(cloud_block_blob&& other) { if (this != &other) @@ -4869,7 +5190,7 @@ namespace azure { namespace storage { #endif /// - /// Opens a stream for writing to the block blob. + /// Opens a stream for writing to the block blob. If the blob already exists on the service, it will be overwritten. /// /// A stream to be used for writing to the blob. concurrency::streams::ostream open_write() @@ -4878,19 +5199,21 @@ namespace azure { namespace storage { } /// - /// Opens a stream for writing to the block blob. + /// Opens a stream for writing to the block blob. If the blob already exists on the service, it will be overwritten. /// /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A stream to be used for writing to the blob. + /// To avoid overwriting and instead throw an error if the blob exists, please pass in an + /// parameter generated using concurrency::streams::ostream open_write(const access_condition& condition, const blob_request_options& options, operation_context context) { return open_write_async(condition, options, context).get(); } /// - /// Intitiates an asynchronous operation to open a stream for writing to the block blob. + /// Intitiates an asynchronous operation to open a stream for writing to the block blob. If the blob already exists on the service, it will be overwritten. /// /// A object of type that represents the current operation. pplx::task open_write_async() @@ -4899,12 +5222,14 @@ namespace azure { namespace storage { } /// - /// Intitiates an asynchronous operation to open a stream for writing to the block blob. + /// Intitiates an asynchronous operation to open a stream for writing to the block blob. If the blob already exists on the service, it will be overwritten. /// /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object of type that represents the current operation. + /// To avoid overwriting and instead throw an error if the blob exists, please pass in an + /// parameter generated using WASTORAGE_API pplx::task open_write_async(const access_condition& condition, const blob_request_options& options, operation_context context); /// @@ -4922,7 +5247,7 @@ namespace azure { namespace storage { /// One of the enumeration values that indicates whether to return /// committed blocks, uncommitted blocks, or both. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// An enumerable collection of objects implementing . std::vector download_block_list(block_listing_filter listing_filter, const access_condition& condition, const blob_request_options& options, operation_context context) const @@ -4934,7 +5259,7 @@ namespace azure { namespace storage { /// Intitiates an asynchronous operation to return an enumerable collection of the blob's blocks, /// using the specified block list filter. /// - /// A object of type , of type , that represents the current operation. + /// A object of type , of type , that represents the current operation. pplx::task> download_block_list_async() const { return download_block_list_async(block_listing_filter::committed, access_condition(), blob_request_options(), operation_context()); @@ -4947,9 +5272,9 @@ namespace azure { namespace storage { /// One of the enumeration values that indicates whether to return /// committed blocks, uncommitted blocks, or both. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A object of type , of type , that represents the current operation. + /// A object of type , of type , that represents the current operation. WASTORAGE_API pplx::task> download_block_list_async(block_listing_filter listing_filter, const access_condition& condition, const blob_request_options& options, operation_context context) const; /// @@ -4965,7 +5290,7 @@ namespace azure { namespace storage { /// Downloads the blob's contents as a string. /// /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// The contents of the blob, as a string. utility::string_t download_text(const access_condition& condition, const blob_request_options& options, operation_context context) @@ -4986,7 +5311,7 @@ namespace azure { namespace storage { /// Intitiates an asynchronous operation to download the blob's contents as a string. /// /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object of type that represents the current operation. WASTORAGE_API pplx::task download_text_async(const access_condition& condition, const blob_request_options& options, operation_context context); @@ -5011,7 +5336,7 @@ namespace azure { namespace storage { /// An optional hash value that will be used to set the Content-MD5 property /// on the blob. May be an empty string. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void upload_block(const utility::string_t& block_id, concurrency::streams::istream block_data, const utility::string_t& content_md5, const access_condition& condition, const blob_request_options& options, operation_context context) const { @@ -5039,7 +5364,7 @@ namespace azure { namespace storage { /// An optional hash value that will be used to set the Content-MD5 property /// on the blob. May be an empty string. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task upload_block_async(const utility::string_t& block_id, concurrency::streams::istream block_data, const utility::string_t& content_md5, const access_condition& condition, const blob_request_options& options, operation_context context) const; @@ -5058,7 +5383,7 @@ namespace azure { namespace storage { /// /// An enumerable collection of block IDs, as Base64-encoded strings. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void upload_block_list(const std::vector& block_list, const access_condition& condition, const blob_request_options& options, operation_context context) { @@ -5080,13 +5405,13 @@ namespace azure { namespace storage { /// /// An enumerable collection of block IDs, as Base64-encoded strings. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task upload_block_list_async(const std::vector& block_list, const access_condition& condition, const blob_request_options& options, operation_context context); /// - /// Uploads a stream to a block blob. + /// Uploads a stream to a block blob. If the blob already exists on the service, it will be overwritten. /// /// The stream providing the blob content. void upload_from_stream(concurrency::streams::istream source) @@ -5095,11 +5420,11 @@ namespace azure { namespace storage { } /// - /// Uploads a stream to a block blob. + /// Uploads a stream to a block blob. If the blob already exists on the service, it will be overwritten. /// /// The stream providing the blob content. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void upload_from_stream(concurrency::streams::istream source, const access_condition& condition, const blob_request_options& options, operation_context context) { @@ -5107,7 +5432,7 @@ namespace azure { namespace storage { } /// - /// Uploads a stream to a block blob. + /// Uploads a stream to a block blob. If the blob already exists on the service, it will be overwritten. /// /// The stream providing the blob content. /// The number of bytes to write from the source stream at its current position. @@ -5117,12 +5442,12 @@ namespace azure { namespace storage { } /// - /// Uploads a stream to a block blob. + /// Uploads a stream to a block blob. If the blob already exists on the service, it will be overwritten. /// /// The stream providing the blob content. /// The number of bytes to write from the source stream at its current position. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void upload_from_stream(concurrency::streams::istream source, utility::size64_t length, const access_condition& condition, const blob_request_options& options, operation_context context) { @@ -5130,7 +5455,7 @@ namespace azure { namespace storage { } /// - /// Intitiates an asynchronous operation to upload a stream to a block blob. + /// Intitiates an asynchronous operation to upload a stream to a block blob. If the blob already exists on the service, it will be overwritten. /// /// The stream providing the blob content. /// A object that represents the current operation. @@ -5140,11 +5465,11 @@ namespace azure { namespace storage { } /// - /// Intitiates an asynchronous operation to upload a stream to a block blob. + /// Intitiates an asynchronous operation to upload a stream to a block blob. If the blob already exists on the service, it will be overwritten. /// /// The stream providing the blob content. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. pplx::task upload_from_stream_async(concurrency::streams::istream source, const access_condition& condition, const blob_request_options& options, operation_context context) @@ -5153,7 +5478,7 @@ namespace azure { namespace storage { } /// - /// Intitiates an asynchronous operation to upload a stream to a block blob. + /// Intitiates an asynchronous operation to upload a stream to a block blob. If the blob already exists on the service, it will be overwritten. /// /// The stream providing the blob content. /// The number of bytes to write from the source stream at its current position. @@ -5164,18 +5489,18 @@ namespace azure { namespace storage { } /// - /// Intitiates an asynchronous operation to upload a stream to a block blob. + /// Intitiates an asynchronous operation to upload a stream to a block blob. If the blob already exists on the service, it will be overwritten. /// /// The stream providing the blob content. /// The number of bytes to write from the source stream at its current position. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task upload_from_stream_async(concurrency::streams::istream source, utility::size64_t length, const access_condition& condition, const blob_request_options& options, operation_context context); /// - /// Uploads a file to a block blob. + /// Uploads a file to a block blob. If the blob already exists on the service, it will be overwritten. /// /// The file providing the blob content. void upload_from_file(const utility::string_t &path) @@ -5184,11 +5509,11 @@ namespace azure { namespace storage { } /// - /// Uploads a file to a block blob. + /// Uploads a file to a block blob. If the blob already exists on the service, it will be overwritten. /// /// The file providing the blob content. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void upload_from_file(const utility::string_t &path, const access_condition& condition, const blob_request_options& options, operation_context context) { @@ -5196,7 +5521,7 @@ namespace azure { namespace storage { } /// - /// Intitiates an asynchronous operation to upload a file to a block blob. + /// Intitiates an asynchronous operation to upload a file to a block blob. If the blob already exists on the service, it will be overwritten. /// /// The file providing the blob content. /// A object that represents the current operation. @@ -5206,17 +5531,17 @@ namespace azure { namespace storage { } /// - /// Intitiates an asynchronous operation to upload a file to a block blob. + /// Intitiates an asynchronous operation to upload a file to a block blob. If the blob already exists on the service, it will be overwritten. /// /// The file providing the blob content. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task upload_from_file_async(const utility::string_t &path, const access_condition& condition, const blob_request_options& options, operation_context context); /// - /// Uploads a string of text to a blob. + /// Uploads a string of text to a blob. If the blob already exists on the service, it will be overwritten. /// /// A string containing the text to upload. void upload_text(const utility::string_t& content) @@ -5225,11 +5550,11 @@ namespace azure { namespace storage { } /// - /// Uploads a string of text to a blob. + /// Uploads a string of text to a blob. If the blob already exists on the service, it will be overwritten. /// /// A string containing the text to upload. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void upload_text(const utility::string_t& content, const access_condition& condition, const blob_request_options& options, operation_context context) { @@ -5237,7 +5562,7 @@ namespace azure { namespace storage { } /// - /// Uploads a string of text to a blob. + /// Uploads a string of text to a blob. If the blob already exists on the service, it will be overwritten. /// /// A string containing the text to upload. /// A object that represents the current operation. @@ -5247,11 +5572,11 @@ namespace azure { namespace storage { } /// - /// Uploads a string of text to a blob. + /// Uploads a string of text to a blob. If the blob already exists on the service, it will be overwritten. /// /// A string containing the text to upload. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task upload_text_async(const utility::string_t& content, const access_condition& condition, const blob_request_options& options, operation_context context); @@ -5263,7 +5588,7 @@ namespace azure { namespace storage { /// /// The name of the blob. /// The snapshot timestamp, if the blob is a snapshot. - /// A object. + /// An object. cloud_block_blob(utility::string_t name, utility::string_t snapshot_time, cloud_blob_container container) : cloud_blob(std::move(name), std::move(snapshot_time), std::move(container)) { @@ -5287,12 +5612,13 @@ namespace azure { namespace storage { cloud_page_blob() : cloud_blob() { + set_type(blob_type::page_blob); } /// /// Initializes a new instance of the class using an absolute URI to the blob. /// - /// A object containing the absolute URI to the blob for all locations. + /// An object containing the absolute URI to the blob for all locations. explicit cloud_page_blob(storage_uri uri) : cloud_blob(std::move(uri)) { @@ -5302,8 +5628,8 @@ namespace azure { namespace storage { /// /// Initializes a new instance of the class using an absolute URI to the blob. /// - /// A object containing the absolute URI to the blob for all locations. - /// The to use. + /// An object containing the absolute URI to the blob for all locations. + /// The to use. cloud_page_blob(storage_uri uri, storage_credentials credentials) : cloud_blob(std::move(uri), std::move(credentials)) { @@ -5313,9 +5639,9 @@ namespace azure { namespace storage { /// /// Initializes a new instance of the class using an absolute URI to the blob. /// - /// A object containing the absolute URI to the blob for all locations. + /// An object containing the absolute URI to the blob for all locations. /// The snapshot timestamp, if the blob is a snapshot. - /// The to use. + /// The to use. cloud_page_blob(storage_uri uri, utility::string_t snapshot_time, storage_credentials credentials) : cloud_blob(std::move(uri), std::move(snapshot_time), std::move(credentials)) { @@ -5337,19 +5663,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. cloud_page_blob(cloud_page_blob&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. cloud_page_blob& operator=(cloud_page_blob&& other) { if (this != &other) @@ -5373,7 +5699,7 @@ namespace azure { namespace storage { /// Opens a stream for writing to an existing page blob. /// /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A stream to be used for writing to the blob. concurrency::streams::ostream open_write(const access_condition& condition, const blob_request_options& options, operation_context context) @@ -5397,7 +5723,7 @@ namespace azure { namespace storage { /// The size of the write operation, in bytes. The size must be a multiple of 512. /// A user-controlled number to track request sequence, whose value must be between 0 and 2^63 - 1. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A stream to be used for writing to the blob. concurrency::streams::ostream open_write(utility::size64_t size, int64_t sequence_number, const access_condition& condition, const blob_request_options& options, operation_context context) @@ -5418,7 +5744,7 @@ namespace azure { namespace storage { /// Intitiates an asynchronous operation to open a stream for writing to an existing page blob. /// /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object of type that represents the current operation. WASTORAGE_API pplx::task open_write_async(const access_condition& condition, const blob_request_options& options, operation_context context); @@ -5439,7 +5765,7 @@ namespace azure { namespace storage { /// The size of the write operation, in bytes. The size must be a multiple of 512. /// A user-controlled number to track request sequence, whose value must be between 0 and 2^63 - 1. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object of type that represents the current operation. WASTORAGE_API pplx::task open_write_async(utility::size64_t size, int64_t sequence_number, const access_condition& condition, const blob_request_options& options, operation_context context); @@ -5460,7 +5786,7 @@ namespace azure { namespace storage { /// The offset at which to begin clearing pages, in bytes. The offset must be a multiple of 512. /// The length of the data range to be cleared, in bytes. The length must be a multiple of 512. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void clear_pages(int64_t start_offset, int64_t length, const access_condition& condition, const blob_request_options& options, operation_context context) { @@ -5484,7 +5810,7 @@ namespace azure { namespace storage { /// The offset at which to begin clearing pages, in bytes. The offset must be a multiple of 512. /// The length of the data range to be cleared, in bytes. The length must be a multiple of 512. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task clear_pages_async(int64_t start_offset, int64_t length, const access_condition& condition, const blob_request_options& options, operation_context context); @@ -5502,7 +5828,7 @@ namespace azure { namespace storage { /// Gets a collection of valid page ranges and their starting and ending bytes. /// /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// An enumerable collection of page ranges. std::vector download_page_ranges(const access_condition& condition, const blob_request_options& options, operation_context context) const @@ -5527,7 +5853,7 @@ namespace azure { namespace storage { /// The starting offset of the data range over which to list page ranges, in bytes. Must be a multiple of 512. /// The length of the data range over which to list page ranges, in bytes. Must be a multiple of 512. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// An enumerable collection of page ranges. std::vector download_page_ranges(utility::size64_t offset, utility::size64_t length, const access_condition& condition, const blob_request_options& options, operation_context context) const @@ -5538,7 +5864,7 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to get a collection of valid page ranges and their starting and ending bytes. /// - /// A object of type , of type , that represents the current operation. + /// A object of type , of type , that represents the current operation. pplx::task> download_page_ranges_async() const { return download_page_ranges_async(access_condition(), blob_request_options(), operation_context()); @@ -5548,9 +5874,9 @@ namespace azure { namespace storage { /// Intitiates an asynchronous operation to get a collection of valid page ranges and their starting and ending bytes. /// /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A object of type , of type , that represents the current operation. + /// A object of type , of type , that represents the current operation. pplx::task> download_page_ranges_async(const access_condition& condition, const blob_request_options& options, operation_context context) const { return download_page_ranges_async(std::numeric_limits::max(), 0, condition, options, context); @@ -5561,7 +5887,7 @@ namespace azure { namespace storage { /// /// The starting offset of the data range over which to list page ranges, in bytes. Must be a multiple of 512. /// The length of the data range over which to list page ranges, in bytes. Must be a multiple of 512. - /// A object of type , of type , that represents the current operation. + /// A object of type , of type , that represents the current operation. pplx::task> download_page_ranges_async(utility::size64_t offset, utility::size64_t length) const { return download_page_ranges_async(offset, length, access_condition(), blob_request_options(), operation_context()); @@ -5573,9 +5899,9 @@ namespace azure { namespace storage { /// The starting offset of the data range over which to list page ranges, in bytes. Must be a multiple of 512. /// The length of the data range over which to list page ranges, in bytes. Must be a multiple of 512. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A object of type , of type , that represents the current operation. + /// A object of type , of type , that represents the current operation. WASTORAGE_API pplx::task> download_page_ranges_async(utility::size64_t offset, utility::size64_t length, const access_condition& condition, const blob_request_options& options, operation_context context) const; /// @@ -5598,7 +5924,7 @@ namespace azure { namespace storage { /// An optional hash value that will be used to set the Content-MD5 property /// on the blob. May be an empty string. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void upload_pages(concurrency::streams::istream page_data, int64_t start_offset, const utility::string_t& content_md5, const access_condition& condition, const blob_request_options& options, operation_context context) { @@ -5608,7 +5934,7 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to write pages to a page blob. /// - /// A stream providing the page data. + /// A stream providing the page data. /// The offset at which to begin writing, in bytes. The offset must be a multiple of 512. /// An optional hash value that will be used to set the Content-MD5 property /// on the blob. May be an empty string. @@ -5621,18 +5947,18 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to write pages to a page blob. /// - /// A stream providing the page data. + /// A stream providing the page data. /// The offset at which to begin writing, in bytes. The offset must be a multiple of 512. /// An optional hash value that will be used to set the Content-MD5 property /// on the blob. May be an empty string. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task upload_pages_async(concurrency::streams::istream source, int64_t start_offset, const utility::string_t& content_md5, const access_condition& condition, const blob_request_options& options, operation_context context); /// - /// Uploads a stream to a page blob. + /// Uploads a stream to a page blob. If the blob already exists on the service, it will be overwritten. /// /// The stream providing the blob content. void upload_from_stream(concurrency::streams::istream source) @@ -5641,12 +5967,12 @@ namespace azure { namespace storage { } /// - /// Uploads a stream to a page blob. + /// Uploads a stream to a page blob. If the blob already exists on the service, it will be overwritten. /// /// The stream providing the blob content. /// A user-controlled number to track request sequence, whose value must be between 0 and 2^63 - 1. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void upload_from_stream(concurrency::streams::istream source, int64_t sequence_number, const access_condition& condition, const blob_request_options& options, operation_context context) { @@ -5654,7 +5980,7 @@ namespace azure { namespace storage { } /// - /// Uploads a stream to a page blob. + /// Uploads a stream to a page blob. If the blob already exists on the service, it will be overwritten. /// /// The stream providing the blob content. /// The number of bytes to write from the source stream at its current position. @@ -5664,13 +5990,13 @@ namespace azure { namespace storage { } /// - /// Uploads a stream to a page blob. + /// Uploads a stream to a page blob. If the blob already exists on the service, it will be overwritten. /// /// The stream providing the blob content. /// The number of bytes to write from the source stream at its current position. /// A user-controlled number to track request sequence, whose value must be between 0 and 2^63 - 1. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void upload_from_stream(concurrency::streams::istream source, utility::size64_t length, int64_t sequence_number, const access_condition& condition, const blob_request_options& options, operation_context context) { @@ -5678,7 +6004,7 @@ namespace azure { namespace storage { } /// - /// Intitiates an asynchronous operation to upload a stream to a page blob. + /// Intitiates an asynchronous operation to upload a stream to a page blob. If the blob already exists on the service, it will be overwritten. /// /// The stream providing the blob content. /// A object that represents the current operation. @@ -5688,12 +6014,12 @@ namespace azure { namespace storage { } /// - /// Intitiates an asynchronous operation to upload a stream to a page blob. + /// Intitiates an asynchronous operation to upload a stream to a page blob. If the blob already exists on the service, it will be overwritten. /// /// The stream providing the blob content. /// A user-controlled number to track request sequence, whose value must be between 0 and 2^63 - 1. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. pplx::task upload_from_stream_async(concurrency::streams::istream source, int64_t sequence_number, const access_condition& condition, const blob_request_options& options, operation_context context) @@ -5702,7 +6028,7 @@ namespace azure { namespace storage { } /// - /// Intitiates an asynchronous operation to upload a stream to a page blob. + /// Intitiates an asynchronous operation to upload a stream to a page blob. If the blob already exists on the service, it will be overwritten. /// /// The stream providing the blob content. /// The number of bytes to write from the source stream at its current position. @@ -5713,19 +6039,19 @@ namespace azure { namespace storage { } /// - /// Intitiates an asynchronous operation to upload a stream to a page blob. + /// Intitiates an asynchronous operation to upload a stream to a page blob. If the blob already exists on the service, it will be overwritten. /// /// The stream providing the blob content. /// The number of bytes to write from the source stream at its current position. /// A user-controlled number to track request sequence, whose value must be between 0 and 2^63 - 1. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task upload_from_stream_async(concurrency::streams::istream source, utility::size64_t length, int64_t sequence_number, const access_condition& condition, const blob_request_options& options, operation_context context); /// - /// Uploads a file to a page blob. + /// Uploads a file to a page blob. If the blob already exists on the service, it will be overwritten. /// /// The file providing the blob content. void upload_from_file(const utility::string_t &path) @@ -5734,12 +6060,12 @@ namespace azure { namespace storage { } /// - /// Uploads a file to a page blob. + /// Uploads a file to a page blob. If the blob already exists on the service, it will be overwritten. /// /// The file providing the blob content. /// A user-controlled number to track request sequence, whose value must be between 0 and 2^63 - 1. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void upload_from_file(const utility::string_t &path, int64_t sequence_number, const access_condition& condition, const blob_request_options& options, operation_context context) { @@ -5747,7 +6073,7 @@ namespace azure { namespace storage { } /// - /// Intitiates an asynchronous operation to upload a file to a page blob. + /// Intitiates an asynchronous operation to upload a file to a page blob. If the blob already exists on the service, it will be overwritten. /// /// The file providing the blob content. /// A object that represents the current operation. @@ -5757,12 +6083,12 @@ namespace azure { namespace storage { } /// - /// Intitiates an asynchronous operation to upload a file to a page blob. + /// Intitiates an asynchronous operation to upload a file to a page blob. If the blob already exists on the service, it will be overwritten. /// /// The file providing the blob content. /// A user-controlled number to track request sequence, whose value must be between 0 and 2^63 - 1. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task upload_from_file_async(const utility::string_t &path, int64_t sequence_number, const access_condition& condition, const blob_request_options& options, operation_context context); @@ -5782,7 +6108,7 @@ namespace azure { namespace storage { /// The maximum size of the page blob, in bytes. /// A user-controlled number to track request sequence, whose value must be between 0 and 2^63 - 1. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void create(utility::size64_t size, int64_t sequence_number, const access_condition& condition, const blob_request_options& options, operation_context context) { @@ -5805,7 +6131,7 @@ namespace azure { namespace storage { /// The maximum size of the page blob, in bytes. /// A user-controlled number to track request sequence, whose value must be between 0 and 2^63 - 1. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task create_async(utility::size64_t size, int64_t sequence_number, const access_condition& condition, const blob_request_options& options, operation_context context); @@ -5824,7 +6150,7 @@ namespace azure { namespace storage { /// /// The size of the page blob, in bytes. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void resize(utility::size64_t size, const access_condition& condition, const blob_request_options& options, operation_context context) { @@ -5846,7 +6172,7 @@ namespace azure { namespace storage { /// /// The size of the page blob, in bytes. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task resize_async(utility::size64_t size, const access_condition& condition, const blob_request_options& options, operation_context context); @@ -5854,7 +6180,7 @@ namespace azure { namespace storage { /// /// Sets the page blob's sequence number. /// - /// A value of type , indicating the operation to perform on the sequence number. + /// A value of type , indicating the operation to perform on the sequence number. void set_sequence_number(const azure::storage::sequence_number& sequence_number) { set_sequence_number_async(sequence_number).wait(); @@ -5863,9 +6189,9 @@ namespace azure { namespace storage { /// /// Sets the page blob's sequence number. /// - /// A value of type , indicating the operation to perform on the sequence number. + /// A value of type , indicating the operation to perform on the sequence number. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void set_sequence_number(const azure::storage::sequence_number& sequence_number, const access_condition& condition, const blob_request_options& options, operation_context context) { @@ -5875,7 +6201,7 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to set the page blob's sequence number. /// - /// A value of type , indicating the operation to perform on the sequence number. + /// A value of type , indicating the operation to perform on the sequence number. /// A object that represents the current operation. pplx::task set_sequence_number_async(const azure::storage::sequence_number& sequence_number) { @@ -5885,9 +6211,9 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to set the page blob's sequence number. /// - /// A value of type , indicating the operation to perform on the sequence number. + /// A value of type , indicating the operation to perform on the sequence number. /// An object that represents the access condition for the operation. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task set_sequence_number_async(const azure::storage::sequence_number& sequence_number, const access_condition& condition, const blob_request_options& options, operation_context context); @@ -5910,6 +6236,724 @@ namespace azure { namespace storage { friend class cloud_blob_directory; }; + /// + /// Represents a Windows Azure append blob. + /// + class cloud_append_blob : public cloud_blob + { + public: + + /// + /// Initializes a new instance of the class. + /// + cloud_append_blob() + : cloud_blob() + { + set_type(blob_type::append_blob); + } + + /// + /// Initializes a new instance of the class using an absolute URI to the blob. + /// + /// A object containing the absolute URI to the blob for all locations. + explicit cloud_append_blob(storage_uri uri) + : cloud_blob(std::move(uri)) + { + set_type(blob_type::append_blob); + } + + /// + /// Initializes a new instance of the class using an absolute URI to the blob. + /// + /// A object containing the absolute URI to the blob for all locations. + /// The to use. + cloud_append_blob(storage_uri uri, storage_credentials credentials) + : cloud_blob(std::move(uri), std::move(credentials)) + { + set_type(blob_type::append_blob); + } + + /// + /// Initializes a new instance of the class using an absolute URI to the blob. + /// + /// A object containing the absolute URI to the blob for all locations. + /// The snapshot timestamp, if the blob is a snapshot. + /// The to use. + cloud_append_blob(storage_uri uri, utility::string_t snapshot_time, storage_credentials credentials) + : cloud_blob(std::move(uri), std::move(snapshot_time), std::move(credentials)) + { + set_type(blob_type::append_blob); + } + + /// + /// Initializes a new instance of the class. + /// + /// Reference to the blob. + cloud_append_blob(const cloud_blob& blob) + : cloud_blob(blob) + { + set_type(blob_type::append_blob); + } + + /// + /// Creates an empty append blob. If the blob already exists, this will replace it. To avoid overwriting and instead throw an error, please pass in an + /// parameter generated using + /// + void create_or_replace() + { + create_or_replace_async().wait(); + } + + /// + /// Creates an empty append blob. If the blob already exists, this will replace it. To avoid overwriting and instead throw an error, please pass in an + /// parameter generated using + /// + /// An object that represents the access condition for the operation. + /// A object that specifies additional options for the request. + /// An object that represents the context for the current operation. + void create_or_replace(const access_condition& condition, const blob_request_options& options, operation_context context) + { + create_or_replace_async(condition, options, context).wait(); + } + + /// + /// Intitiates an asynchronous operation to create an empty append blob. If the blob already exists, this will replace it. To avoid overwriting and instead throw an error, please pass in an + /// parameter generated using + /// + /// A object that represents the current operation. + pplx::task create_or_replace_async() + { + return create_or_replace_async(access_condition(), blob_request_options(), operation_context()); + } + + /// + /// Intitiates an asynchronous operation to create an empty append blob. If the blob already exists, this will replace it. To avoid overwriting and instead throw an error, please pass in an + /// parameter generated using + /// + /// An object that represents the access condition for the operation. + /// A object that specifies additional options for the request. + /// An object that represents the context for the current operation. + /// A object that represents the current operation. + WASTORAGE_API pplx::task create_or_replace_async(const access_condition& condition, const blob_request_options& options, operation_context context); + + /// + /// Commits a new block of data to the end of the blob. + /// + /// A stream that provides the data for the block. + /// An optional hash value that will be used to to ensure transactional integrity + /// for the block. May be an empty string. + /// The offset in bytes at which the block was committed to. + int64_t append_block(concurrency::streams::istream block_data, const utility::string_t& content_md5) const + { + return append_block_async(block_data, content_md5).get(); + } + + /// + /// Commits a new block of data to the end of the blob. + /// + /// A stream that provides the data for the block. + /// An optional hash value that will be used to to ensure transactional integrity + /// for the block. May be an empty string. + /// An object that represents the access condition for the operation. + /// A object that specifies additional options for the request. + /// An object that represents the context for the current operation. + /// The offset in bytes at which the block was committed to. + int64_t append_block(concurrency::streams::istream block_data, const utility::string_t& content_md5, const access_condition& condition, const blob_request_options& options, operation_context context) const + { + return append_block_async(block_data, content_md5, condition, options, context).get(); + } + + /// + /// Intitiates an asynchronous operation to commit a new block of data to the end of the blob. + /// + /// A stream that provides the data for the block. + /// An optional hash value that will be used to to ensure transactional integrity + /// for the block. May be an empty string. + /// A object that represents the current operation. + pplx::task append_block_async(concurrency::streams::istream block_data, const utility::string_t& content_md5) const + { + return append_block_async(block_data, content_md5, access_condition(), blob_request_options(), operation_context()); + } + + /// + /// Intitiates an asynchronous operation to commit a new block of data to the end of the blob. + /// + /// A stream that provides the data for the block. + /// An optional hash value that will be used to to ensure transactional integrity + /// for the block. May be an empty string. + /// An object that represents the access condition for the operation. + /// A object that specifies additional options for the request. + /// An object that represents the context for the current operation. + /// A object that represents the current operation. + WASTORAGE_API pplx::task append_block_async(concurrency::streams::istream block_data, const utility::string_t& content_md5, const access_condition& condition, const blob_request_options& options, operation_context context) const; + + /// + /// Downloads the blob's contents as a string. + /// + /// The contents of the blob, as a string. + utility::string_t download_text() + { + return download_text_async().get(); + } + + /// + /// Downloads the blob's contents as a string. + /// + /// An object that represents the access condition for the operation. + /// A object that specifies additional options for the request. + /// An object that represents the context for the current operation. + /// The contents of the blob, as a string. + utility::string_t download_text(const access_condition& condition, const blob_request_options& options, operation_context context) + { + return download_text_async(condition, options, context).get(); + } + + /// + /// Intitiates an asynchronous operation to download the blob's contents as a string. + /// + /// A object of type that represents the current operation. + pplx::task download_text_async() + { + return download_text_async(access_condition(), blob_request_options(), operation_context()); + } + + /// + /// Intitiates an asynchronous operation to download the blob's contents as a string. + /// + /// An object that represents the access condition for the operation. + /// A object that specifies additional options for the request. + /// An object that represents the context for the current operation. + /// A object of type that represents the current operation. + WASTORAGE_API pplx::task download_text_async(const access_condition& condition, const blob_request_options& options, operation_context context); + + /// + /// Opens a stream for writing to the append blob. + /// + /// Use true to create a new append blob or overwrite an existing one, false to append to an existing blob. + /// A stream to be used for writing to the blob. + concurrency::streams::ostream open_write(bool create_new) + { + return open_write_async(create_new).get(); + } + + /// + /// Opens a stream for writing to the append blob. + /// + /// Use true to create a new append blob or overwrite an existing one, false to append to an existing blob. + /// An object that represents the access condition for the operation. + /// A object that specifies additional options for the request. + /// An object that represents the context for the current operation. + /// A stream to be used for writing to the blob. + concurrency::streams::ostream open_write(bool create_new, const access_condition& condition, const blob_request_options& options, operation_context context) + { + return open_write_async(create_new, condition, options, context).get(); + } + + /// + /// Intitiates an asynchronous operation to open a stream for writing to the append blob. + /// + /// Use true to create a new append blob or overwrite an existing one, false to append to an existing blob. + /// A object of type that represents the current operation. + pplx::task open_write_async(bool create_new) + { + return open_write_async(create_new, access_condition(), blob_request_options(), operation_context()); + } + + /// + /// Intitiates an asynchronous operation to open a stream for writing to the append blob. + /// + /// Use true to create a new append blob or overwrite an existing one, false to append to an existing blob. + /// An object that represents the access condition for the operation. + /// A object that specifies additional options for the request. + /// An object that represents the context for the current operation. + /// A object of type that represents the current operation. + WASTORAGE_API pplx::task open_write_async(bool create_new, const access_condition& condition, const blob_request_options& options, operation_context context); + + /// + /// Uploads a stream to an append blob. If the blob already exists on the service, it will be overwritten. + /// + /// The stream providing the blob content. + /// + /// This API should be used strictly in a single writer scenario because the API internally uses the + /// append-offset conditional header to avoid duplicate blocks. + /// If you want to append data to an already existing blob, please look at append_from_stream method. + /// + void upload_from_stream(concurrency::streams::istream source) + { + upload_from_stream_async(source).wait(); + } + + /// + /// Uploads a stream to an append blob. If the blob already exists on the service, it will be overwritten. + /// + /// The stream providing the blob content. + /// An object that represents the access condition for the operation. + /// A object that specifies additional options for the request. + /// An object that represents the context for the current operation. + /// + /// This API should be used strictly in a single writer scenario because the API internally uses the + /// append-offset conditional header to avoid duplicate blocks. + /// If you are guaranteed to have a single writer scenario, please look at + /// and see if setting this flag to true is acceptable for you. + /// If you want to append data to an already existing blob, please look at append_from_stream method. + /// + void upload_from_stream(concurrency::streams::istream source, const access_condition& condition, const blob_request_options& options, operation_context context) + { + upload_from_stream_async(source, condition, options, context).wait(); + } + + /// + /// Uploads a stream to an append blob. If the blob already exists on the service, it will be overwritten. + /// + /// The stream providing the blob content. + /// The number of bytes to write from the source stream at its current position. + /// + /// This API should be used strictly in a single writer scenario because the API internally uses the + /// append-offset conditional header to avoid duplicate blocks. + /// If you want to append data to an already existing blob, please look at append_from_stream method. + /// + void upload_from_stream(concurrency::streams::istream source, utility::size64_t length) + { + upload_from_stream_async(source, length).wait(); + } + + /// + /// Uploads a stream to an append blob. If the blob already exists on the service, it will be overwritten. + /// + /// The stream providing the blob content. + /// The number of bytes to write from the source stream at its current position. + /// An object that represents the access condition for the operation. + /// A object that specifies additional options for the request. + /// An object that represents the context for the current operation. + /// + /// This API should be used strictly in a single writer scenario because the API internally uses the + /// append-offset conditional header to avoid duplicate blocks. + /// If you are guaranteed to have a single writer scenario, please look at + /// and see if setting this flag to true is acceptable for you. + /// If you want to append data to an already existing blob, please look at append_from_stream method. + /// + void upload_from_stream(concurrency::streams::istream source, utility::size64_t length, const access_condition& condition, const blob_request_options& options, operation_context context) + { + upload_from_stream_async(source, length, condition, options, context).wait(); + } + + /// + /// Intitiates an asynchronous operation to upload a stream to the append blob. If the blob already exists on the service, it will be overwritten. + /// + /// The stream providing the blob content. + /// A object that represents the current operation. + /// + /// This API should be used strictly in a single writer scenario because the API internally uses the + /// append-offset conditional header to avoid duplicate blocks. + /// If you want to append data to an already existing blob, please look at append_from_stream_async method. + /// + pplx::task upload_from_stream_async(concurrency::streams::istream source) + { + return upload_from_stream_async(source, std::numeric_limits::max()); + } + + /// + /// Intitiates an asynchronous operation to upload a stream to the append blob. If the blob already exists on the service, it will be overwritten. + /// + /// The stream providing the blob content. + /// An object that represents the access condition for the operation. + /// A object that specifies additional options for the request. + /// An object that represents the context for the current operation. + /// A object that represents the current operation. + /// + /// This API should be used strictly in a single writer scenario because the API internally uses the + /// append-offset conditional header to avoid duplicate blocks. + /// If you are guaranteed to have a single writer scenario, please look at + /// and see if setting this flag to true is acceptable for you. + /// If you want to append data to an already existing blob, please look at append_from_stream_async method. + /// + pplx::task upload_from_stream_async(concurrency::streams::istream source, const access_condition& condition, const blob_request_options& options, operation_context context) + { + return upload_from_stream_async(source, std::numeric_limits::max(), condition, options, context); + } + + /// + /// Intitiates an asynchronous operation to upload a stream to the append blob. If the blob already exists on the service, it will be overwritten. + /// + /// The stream providing the blob content. + /// The number of bytes to write from the source stream at its current position. + /// A object that represents the current operation. + /// + /// This API should be used strictly in a single writer scenario because the API internally uses the + /// append-offset conditional header to avoid duplicate blocks. + /// If you want to append data to an already existing blob, please look at append_from_stream_async method. + /// + pplx::task upload_from_stream_async(concurrency::streams::istream source, utility::size64_t length) + { + return upload_from_stream_async(source, length, access_condition(), blob_request_options(), operation_context()); + } + + /// + /// Intitiates an asynchronous operation to upload a stream to the append blob. If the blob already exists on the service, it will be overwritten. + /// + /// The stream providing the blob content. + /// The number of bytes to write from the source stream at its current position. + /// An object that represents the access condition for the operation. + /// A object that specifies additional options for the request. + /// An object that represents the context for the current operation. + /// A object that represents the current operation. + /// + /// This API should be used strictly in a single writer scenario because the API internally uses the + /// append-offset conditional header to avoid duplicate blocks. + /// If you are guaranteed to have a single writer scenario, please look at + /// and see if setting this flag to true is acceptable for you. + /// If you want to append data to an already existing blob, please look at append_from_stream_async method. + /// + WASTORAGE_API pplx::task upload_from_stream_async(concurrency::streams::istream source, utility::size64_t length, const access_condition& condition, const blob_request_options& options, operation_context context); + + /// + /// Uploads a file to the append blob. If the blob already exists on the service, it will be overwritten. + /// + /// The file providing the blob content. + /// + /// This API should be used strictly in a single writer scenario because the API internally uses the + /// append-offset conditional header to avoid duplicate blocks. + /// If you want to append data to an already existing blob, please look at append_from_file method. + /// + void upload_from_file(const utility::string_t &path) + { + upload_from_file_async(path).wait(); + } + + /// + /// Uploads a file to the append blob. If the blob already exists on the service, it will be overwritten. + /// + /// The file providing the blob content. + /// An object that represents the access condition for the operation. + /// A object that specifies additional options for the request. + /// An object that represents the context for the current operation. + /// + /// This API should be used strictly in a single writer scenario because the API internally uses the + /// append-offset conditional header to avoid duplicate blocks. + /// If you are guaranteed to have a single writer scenario, please look at + /// and see if setting this flag to true is acceptable for you. + /// If you want to append data to an already existing blob, please look at append_from_file method. + /// + void upload_from_file(const utility::string_t &path, const access_condition& condition, const blob_request_options& options, operation_context context) + { + upload_from_file_async(path, condition, options, context).wait(); + } + + /// + /// Intitiates an asynchronous operation to upload a file to the append blob. If the blob already exists on the service, it will be overwritten. + /// + /// The file providing the blob content. + /// A object that represents the current operation. + /// + /// This API should be used strictly in a single writer scenario because the API internally uses the + /// append-offset conditional header to avoid duplicate blocks. + /// If you want to append data to an already existing blob, please look at append_from_file_async method. + /// + pplx::task upload_from_file_async(const utility::string_t &path) + { + return upload_from_file_async(path, access_condition(), blob_request_options(), operation_context()); + } + + /// + /// Intitiates an asynchronous operation to upload a file to the append blob. If the blob already exists on the service, it will be overwritten. + /// + /// The file providing the blob content. + /// An object that represents the access condition for the operation. + /// A object that specifies additional options for the request. + /// An object that represents the context for the current operation. + /// A object that represents the current operation. + /// + /// This API should be used strictly in a single writer scenario because the API internally uses the + /// append-offset conditional header to avoid duplicate blocks. + /// If you are guaranteed to have a single writer scenario, please look at + /// and see if setting this flag to true is acceptable for you. + /// If you want to append data to an already existing blob, please look at append_from_file_async method. + /// + WASTORAGE_API pplx::task upload_from_file_async(const utility::string_t &path, const access_condition& condition, const blob_request_options& options, operation_context context); + + /// + /// Uploads a string of text to the append blob. If the blob already exists on the service, it will be overwritten. + /// + /// A string containing the text to upload. + /// + /// This API should be used strictly in a single writer scenario because the API internally uses the + /// append-offset conditional header to avoid duplicate blocks. + /// If you want to append data to an already existing blob, please look at append_text method. + /// + void upload_text(const utility::string_t& content) + { + upload_text_async(content).wait(); + } + + /// + /// Uploads a string of text to the append blob. If the blob already exists on the service, it will be overwritten. + /// + /// A string containing the text to upload. + /// An object that represents the access condition for the operation. + /// A object that specifies additional options for the request. + /// An object that represents the context for the current operation. + /// + /// This API should be used strictly in a single writer scenario because the API internally uses the + /// append-offset conditional header to avoid duplicate blocks. + /// If you are guaranteed to have a single writer scenario, please look at + /// and see if setting this flag to true is acceptable for you. + /// If you want to append data to an already existing blob, please look at append_text method. + /// + void upload_text(const utility::string_t& content, const access_condition& condition, const blob_request_options& options, operation_context context) + { + upload_text_async(content, condition, options, context).wait(); + } + + /// + /// Uploads a string of text to the append blob. If the blob already exists on the service, it will be overwritten. + /// + /// A string containing the text to upload. + /// A object that represents the current operation. + /// + /// This API should be used strictly in a single writer scenario because the API internally uses the + /// append-offset conditional header to avoid duplicate blocks. + /// If you want to append data to an already existing blob, please look at append_text_async method. + /// + pplx::task upload_text_async(const utility::string_t& content) + { + return upload_text_async(content, access_condition(), blob_request_options(), operation_context()); + } + + /// + /// Uploads a string of text to the append blob. If the blob already exists on the service, it will be overwritten. + /// + /// A string containing the text to upload. + /// An object that represents the access condition for the operation. + /// A object that specifies additional options for the request. + /// An object that represents the context for the current operation. + /// A object that represents the current operation. + /// + /// This API should be used strictly in a single writer scenario because the API internally uses the + /// append-offset conditional header to avoid duplicate blocks. + /// If you are guaranteed to have a single writer scenario, please look at + /// and see if setting this flag to true is acceptable for you. + /// If you want to append data to an already existing blob, please look at append_text_async method. + /// + WASTORAGE_API pplx::task upload_text_async(const utility::string_t& content, const access_condition& condition, const blob_request_options& options, operation_context context); + + /// + /// Appends a stream to an append blob. This API should be used strictly in a single writer scenario because the API internally uses the + /// append-offset conditional header to avoid duplicate blocks which does not work in a multiple writer scenario. + /// + /// A object providing the blob content. + void append_from_stream(concurrency::streams::istream source) + { + append_from_stream_async(source).wait(); + } + + /// + /// Appends a stream to an append blob. This API should be used strictly in a single writer scenario because the API internally uses the + /// append-offset conditional header to avoid duplicate blocks which does not work in a multiple writer scenario. + /// + /// A object providing the blob content. + /// An object that represents the access condition for the operation. + /// A object that specifies additional options for the request. + /// An object that represents the context for the current operation. + void append_from_stream(concurrency::streams::istream source, const access_condition& condition, const blob_request_options& options, operation_context context) + { + append_from_stream_async(source, condition, options, context).wait(); + } + + /// + /// Appends a stream to an append blob. This API should be used strictly in a single writer scenario because the API internally uses the + /// append-offset conditional header to avoid duplicate blocks which does not work in a multiple writer scenario. + /// + /// A object providing the blob content. + /// The number of bytes to write from the source stream at its current position. + void append_from_stream(concurrency::streams::istream source, utility::size64_t length) + { + append_from_stream_async(source, length).wait(); + } + + /// + /// Appends a stream to an append blob. This API should be used strictly in a single writer scenario because the API internally uses the + /// append-offset conditional header to avoid duplicate blocks which does not work in a multiple writer scenario. + /// + /// A object providing the blob content. + /// The number of bytes to write from the source stream at its current position. + /// An object that represents the access condition for the operation. + /// A object that specifies additional options for the request. + /// An object that represents the context for the current operation. + void append_from_stream(concurrency::streams::istream source, utility::size64_t length, const access_condition& condition, const blob_request_options& options, operation_context context) + { + append_from_stream_async(source, length, condition, options, context).wait(); + } + + /// + /// Initiates an asynchronous operation to append a stream to an append blob. This API should be used strictly in a single writer scenario because the API internally uses the + /// append-offset conditional header to avoid duplicate blocks which does not work in a multiple writer scenario. + /// + /// A object providing the blob content. + /// A object that represents the current operation. + pplx::task append_from_stream_async(concurrency::streams::istream source) + { + return append_from_stream_async(source, std::numeric_limits::max()); + } + + /// + /// Initiates an asynchronous operation to append a stream to an append blob. This API should be used strictly in a single writer scenario because the API internally uses the + /// append-offset conditional header to avoid duplicate blocks which does not work in a multiple writer scenario. + /// + /// A object providing the blob content. + /// An object that represents the access condition for the operation. + /// A object that specifies additional options for the request. + /// An object that represents the context for the current operation. + /// A object that represents the current operation. + pplx::task append_from_stream_async(concurrency::streams::istream source, const access_condition& condition, const blob_request_options& options, operation_context context) + { + return append_from_stream_async(source, std::numeric_limits::max(), condition, options, context); + } + + /// + /// Initiates an asynchronous operation to append a stream to an append blob. This API should be used strictly in a single writer scenario because the API internally uses the + /// append-offset conditional header to avoid duplicate blocks which does not work in a multiple writer scenario. + /// + /// A object providing the blob content. + /// The number of bytes to write from the source stream at its current position. + /// A object that represents the current operation. + pplx::task append_from_stream_async(concurrency::streams::istream source, utility::size64_t length) + { + return append_from_stream_async(source, length, access_condition(), blob_request_options(), operation_context()); + } + + /// + /// Initiates an asynchronous operation to append a stream to an append blob. This API should be used strictly in a single writer scenario because the API internally uses the + /// append-offset conditional header to avoid duplicate blocks which does not work in a multiple writer scenario. + /// + /// A object providing the blob content. + /// The number of bytes to write from the source stream at its current position. + /// An object that represents the access condition for the operation. + /// A object that specifies additional options for the request. + /// An object that represents the context for the current operation. + /// A object that represents the current operation. + WASTORAGE_API pplx::task append_from_stream_async(concurrency::streams::istream source, utility::size64_t length, const access_condition& condition, const blob_request_options& options, operation_context context); + + /// + /// Appends a file to an append blob. This API should be used strictly in a single writer scenario because the API internally uses the + /// append-offset conditional header to avoid duplicate blocks which does not work in a multiple writer scenario. + /// + /// The file providing the blob content. + void append_from_file(const utility::string_t &path) + { + append_from_file_async(path).wait(); + } + + /// + /// Appends a file to an append blob. This API should be used strictly in a single writer scenario because the API internally uses the + /// append-offset conditional header to avoid duplicate blocks which does not work in a multiple writer scenario. + /// + /// The file providing the blob content. + /// An object that represents the access condition for the operation. + /// A object that specifies additional options for the request. + /// An object that represents the context for the current operation. + void append_from_file(const utility::string_t &path, const access_condition& condition, const blob_request_options& options, operation_context context) + { + append_from_file_async(path, condition, options, context).wait(); + } + + /// + /// Initiates an asynchronous operation to append a file to an append blob. This API should be used strictly in a single writer scenario because the API internally uses the + /// append-offset conditional header to avoid duplicate blocks which does not work in a multiple writer scenario. + /// + /// The file providing the blob content. + /// A object that represents the current operation. + pplx::task append_from_file_async(const utility::string_t &path) + { + return append_from_file_async(path, access_condition(), blob_request_options(), operation_context()); + } + + /// + /// Initiates an asynchronous operation to append a file to an append blob. This API should be used strictly in a single writer scenario because the API internally uses the + /// append-offset conditional header to avoid duplicate blocks which does not work in a multiple writer scenario. + /// + /// The file providing the blob content. + /// An object that represents the access condition for the operation. + /// A object that specifies additional options for the request. + /// An object that represents the context for the current operation. + /// A object that represents the current operation. + WASTORAGE_API pplx::task append_from_file_async(const utility::string_t &path, const access_condition& condition, const blob_request_options& options, operation_context context); + + /// + /// Appends a string of text to an append blob. This API should be used strictly in a single writer scenario + /// because the API internally uses the append-offset conditional header to avoid duplicate blocks which does not work in a multiple writer scenario. + /// + /// A string containing the text to append. + void append_text(const utility::string_t& content) + { + append_text_async(content).wait(); + } + + /// + /// Appends a string of text to an append blob. This API should be used strictly in a single writer scenario + /// because the API internally uses the append-offset conditional header to avoid duplicate blocks which does not work in a multiple writer scenario. + /// + /// A string containing the text to append. + /// An object that represents the access condition for the operation. + /// A object that specifies additional options for the request. + /// An object that represents the context for the current operation. + void append_text(const utility::string_t& content, const access_condition& condition, const blob_request_options& options, operation_context context) + { + append_text_async(content, condition, options, context).wait(); + } + + /// + /// Initiates an asynchronous operation to append a string of text to an append blob. This API should be used strictly in a single writer scenario + /// because the API internally uses the append-offset conditional header to avoid duplicate blocks which does not work in a multiple writer scenario. + /// + /// A string containing the text to append. + /// A object that represents the current operation. + pplx::task append_text_async(const utility::string_t& content) + { + return append_text_async(content, access_condition(), blob_request_options(), operation_context()); + } + + /// + /// Initiates an asynchronous operation to append a string of text to an append blob. This API should be used strictly in a single writer scenario + /// because the API internally uses the append-offset conditional header to avoid duplicate blocks which does not work in a multiple writer scenario. + /// + /// A string containing the text to append. + /// An object that represents the access condition for the operation. + /// A object that specifies additional options for the request. + /// An object that represents the context for the current operation. + /// A object that represents the current operation. + WASTORAGE_API pplx::task append_text_async(const utility::string_t& content, const access_condition& condition, const blob_request_options& options, operation_context context); + + private: + + /// + /// Initializes a new instance of the class. + /// + /// The name of the blob. + /// The snapshot timestamp, if the blob is a snapshot. + /// A reference to the parent container. + cloud_append_blob(utility::string_t name, utility::string_t snapshot_time, cloud_blob_container container) + : cloud_blob(std::move(name), std::move(snapshot_time), std::move(container)) + { + set_type(blob_type::append_blob); + } + + /// + /// Uploads a stream to a new or existing append blob. This API should be used strictly in a single writer scenario because the API internally uses the + /// append-offset conditional header to avoid duplicate blocks which does not work in a multiple writer scenario. + /// + /// The stream providing the blob content. + /// The number of bytes to write from the source stream at its current position. + /// true if the append blob is newly created, false otherwise. + /// An object that represents the access condition for the operation. + /// A object that specifies additional options for the request. + /// An object that represents the context for the current operation. + /// A object that represents the current operation. + pplx::task upload_from_stream_internal_async(concurrency::streams::istream source, utility::size64_t length, bool create_new, const access_condition& condition, const blob_request_options& options, operation_context context); + + friend class cloud_blob_container; + friend class cloud_blob_directory; + }; + /// /// Represents an item that may be returned by a blob listing operation. /// @@ -5918,9 +6962,8 @@ namespace azure { namespace storage { public: /// - /// Initializes a new instance of the class that represents a cloud blob. + /// Initializes a new instance of the class that represents a cloud blob. /// - /// A object. /// The name of the blob. /// The snapshot timestamp, if the blob is a snapshot. /// A reference to the parent container. @@ -5934,7 +6977,7 @@ namespace azure { namespace storage { } /// - /// Initializes a new instance of the class that represents a cloud blob directory. + /// Initializes a new instance of the class that represents a cloud blob directory. /// /// Name of the virtual directory. /// The container. @@ -5948,19 +6991,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. list_blob_item(list_blob_item&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. list_blob_item& operator=(list_blob_item&& other) { if (this != &other) @@ -5979,18 +7022,18 @@ namespace azure { namespace storage { #endif /// - /// Gets a value indicating whether this represents a cloud blob or a cloud blob directory. + /// Gets a value indicating whether this represents a cloud blob or a cloud blob directory. /// - /// true if this represents a cloud blob; otherwise, false. + /// true if this represents a cloud blob; otherwise, false. bool is_blob() const { return m_is_blob; } /// - /// Returns the item as a object, if and only if it represents a cloud blob. + /// Returns the item as an object, if and only if it represents a cloud blob. /// - /// A object. + /// An object. cloud_blob as_blob() const { if (!is_blob()) @@ -6002,9 +7045,9 @@ namespace azure { namespace storage { } /// - /// Returns the item as a object, if and only if it represents a cloud blob directory. + /// Returns the item as an object, if and only if it represents a cloud blob directory. /// - /// A object. + /// An object. cloud_blob_directory as_directory() const { if (is_blob()) diff --git a/Microsoft.WindowsAzure.Storage/includes/was/common.h b/Microsoft.WindowsAzure.Storage/includes/was/common.h index d18e6726..e557435d 100644 --- a/Microsoft.WindowsAzure.Storage/includes/was/common.h +++ b/Microsoft.WindowsAzure.Storage/includes/was/common.h @@ -51,7 +51,7 @@ namespace azure { namespace storage { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// continuation_token() : m_target_location(storage_location::unspecified) @@ -59,7 +59,7 @@ namespace azure { namespace storage { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The next_marker. explicit continuation_token(utility::string_t next_marker) @@ -72,19 +72,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. continuation_token(continuation_token&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. continuation_token& operator=(continuation_token&& other) { if (this != &other) @@ -157,14 +157,14 @@ namespace azure { namespace storage { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// result_segment() { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// An enumerable collection of results. /// The continuation token. @@ -178,19 +178,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. result_segment(result_segment&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. result_segment& operator=(result_segment&& other) { if (this != &other) @@ -236,7 +236,7 @@ namespace azure { namespace storage { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// result_iterator() : m_result_generator(nullptr), @@ -248,14 +248,14 @@ namespace azure { namespace storage { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The result segment generator. /// A non-negative integer value that indicates the maximum number of results to be returned /// by the result iterator. If this value is 0, the maximum possible number of results will be returned. /// A non-negative integer value that indicates the maximum number of results to /// be returned in one segment. If this value is 0, the maximum possible number of results returned in a segment will be - // determined by individual service. + /// determined by individual service. result_iterator(std::function(const continuation_token &, size_t)> result_generator, utility::size64_t max_results, size_t max_results_per_segment) : m_result_generator(std::move(result_generator)), m_segment_index(0), @@ -271,19 +271,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// A reference to a set of on which to base the new instance. + /// A reference to a set of on which to base the new instance. result_iterator(result_iterator&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// A reference to a set of to use to set properties. - /// A object with properties set. + /// A reference to a set of to use to set properties. + /// An object with properties set. result_iterator& operator=(result_iterator&& other) { if (this != &other) @@ -416,6 +416,29 @@ namespace azure { namespace storage { size_t m_max_results_per_segment; }; + /// + /// begin method that treats a result iterator as a range. + /// + /// The type of the result. + /// An object that represents a range starting from the specified iterator. + /// An object that represents begin of the range. + template + result_iterator begin(result_iterator range) + { + return std::move(range); + } + + /// + /// end method that treats a result iterator as a range. + /// + /// The type of the result. + /// An object that represents end of the range. + template + result_iterator end(result_iterator) + { + return result_iterator(); + } + /// /// Specifies which items to include when setting service properties. /// @@ -423,7 +446,7 @@ namespace azure { namespace storage { { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// service_properties_includes() : m_logging(false), m_hour_metrics(false), m_minute_metrics(false), m_cors(false) @@ -435,19 +458,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. service_properties_includes(service_properties_includes&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. service_properties_includes& operator=(service_properties_includes&& other) { if (this != &other) @@ -462,9 +485,9 @@ namespace azure { namespace storage { #endif /// - /// Gets a object that includes all available service properties. + /// Gets an object that includes all available service properties. /// - /// A object with all properties set to true. + /// An object with all properties set to true. static service_properties_includes all() { service_properties_includes includes; @@ -570,7 +593,7 @@ namespace azure { namespace storage { public: /// - /// Initializes a new instance of the struct. + /// Initializes a new instance of the struct. /// logging_properties() : m_delete_enabled(false), m_read_enabled(false), m_write_enabled(false), m_retention_enabled(false), m_retention_days(0) @@ -582,19 +605,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. logging_properties(logging_properties&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. logging_properties& operator=(logging_properties&& other) { if (this != &other) @@ -748,19 +771,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. metrics_properties(metrics_properties&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. metrics_properties& operator=(metrics_properties&& other) { if (this != &other) @@ -893,19 +916,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. cors_rule(cors_rule&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. cors_rule& operator=(cors_rule&& other) { if (this != &other) @@ -1056,7 +1079,7 @@ namespace azure { namespace storage { }; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// service_properties() { @@ -1067,19 +1090,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. service_properties(service_properties&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. service_properties& operator=(service_properties&& other) { if (this != &other) @@ -1265,7 +1288,7 @@ namespace azure { namespace storage { public: /// - /// Initializes a new instance of the struct. + /// Initializes a new instance of the struct. /// geo_replication_stats() : m_status(geo_replication_status::unavailable) @@ -1277,19 +1300,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. geo_replication_stats(geo_replication_stats&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. geo_replication_stats& operator=(geo_replication_stats&& other) { if (this != &other) @@ -1347,7 +1370,7 @@ namespace azure { namespace storage { }; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// service_stats() { @@ -1358,19 +1381,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. service_stats(service_stats&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. service_stats& operator=(service_stats&& other) { if (this != &other) @@ -1500,7 +1523,7 @@ namespace azure { namespace storage { /// /// Gets the level at which messages are logged. /// - /// A object indicating the level at which messages are logged. + /// An object indicating the level at which messages are logged. client_log_level log_level() const { return m_log_level; @@ -1509,7 +1532,7 @@ namespace azure { namespace storage { /// /// Sets the level at which messages are logged. /// - /// A object indicating the level at which messages are to be logged. + /// An object indicating the level at which messages are to be logged. void set_log_level(client_log_level log_level) { m_log_level = log_level; @@ -1536,7 +1559,7 @@ namespace azure { namespace storage { /// /// Gets the results of the request. /// - /// An enumerable collection of objects. + /// An enumerable collection of objects. const std::vector& request_results() const { return m_request_results; @@ -1545,7 +1568,7 @@ namespace azure { namespace storage { /// /// Adds a request result to the set of results. /// - /// A object. + /// An object. void add_request_result(request_result result) { pplx::extensibility::scoped_critical_section_t l(m_request_results_lock); @@ -1556,7 +1579,7 @@ namespace azure { namespace storage { /// Gets the function to call when sending a request. /// /// A pointer to a function that takes an object - /// and an object. + /// and an object. std::function sending_request() const { return m_sending_request; @@ -1566,7 +1589,7 @@ namespace azure { namespace storage { /// Sets the function to call when sending a request. /// /// A pointer to a function that takes an object - /// and an object. + /// and an object. void set_sending_request(std::function value) { m_sending_request = value; @@ -1576,7 +1599,7 @@ namespace azure { namespace storage { /// Gets the function to call when receiving a response from a request. /// /// A pointer to a function that takes an object, - /// an object, and an object. + /// an object, and an object. std::function response_received() const { return m_response_received; @@ -1586,7 +1609,7 @@ namespace azure { namespace storage { /// Sets the function to call when receiving a response from a request. /// /// A pointer to a function that takes an object, - /// an object, and an object. + /// an object, and an object. void set_response_received(std::function value) { m_response_received = value; @@ -1596,7 +1619,7 @@ namespace azure { namespace storage { /// /// Gets the logger object on this operation context. /// - /// The object used by this operation context. + /// The object used by this operation context. boost::log::sources::severity_logger& logger() { return m_logger; @@ -1605,7 +1628,7 @@ namespace azure { namespace storage { /// /// Gets the logger object on this operation context. /// - /// The object used by this operation context. + /// The object used by this operation context. const boost::log::sources::severity_logger& logger() const { return m_logger; @@ -1614,7 +1637,7 @@ namespace azure { namespace storage { /// /// Sets the logger object on this operation context. /// - /// The object to use for requests made by this operation context. + /// The object to use for requests made by this operation context. void set_logger(boost::log::sources::severity_logger logger) { m_logger = std::move(logger); @@ -1645,24 +1668,24 @@ namespace azure { namespace storage { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// WASTORAGE_API operation_context(); /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// The operation context. + /// A reference to an object. operation_context(const operation_context& context) : m_impl(context.m_impl) { } /// - /// Returns a reference to an object. + /// Returns a reference to an object. /// - /// A reference to an object. - /// An object. + /// A reference to an object. + /// An object. operation_context& operator=(const operation_context& context) { m_impl = context.m_impl; @@ -1724,30 +1747,30 @@ namespace azure { namespace storage { } /// - /// Gets the default logging level to be used for subsequently created instances of the class. + /// Gets the default logging level to be used for subsequently created instances of the class. /// - /// A value of type that specifies which events are logged by default by instances of the . + /// A value of type that specifies which events are logged by default by instances of the . WASTORAGE_API static client_log_level default_log_level(); /// - /// Sets the default logging level to be used for subsequently created instances of the class. + /// Sets the default logging level to be used for subsequently created instances of the class. /// - /// A value of type that specifies which events are logged by default by instances of the . + /// A value of type that specifies which events are logged by default by instances of the . WASTORAGE_API static void set_default_log_level(client_log_level log_level); /// - /// Gets the logging level to be used for an instance of the class. + /// Gets the logging level to be used for an instance of the class. /// - /// A value of type that specifies which events are logged by the . + /// A value of type that specifies which events are logged by the . client_log_level log_level() const { return m_impl->log_level(); } /// - /// Sets the logging level to be used for an instance of the class. + /// Sets the logging level to be used for an instance of the class. /// - /// A value of type that specifies which events are logged by the . + /// A value of type that specifies which events are logged by the . void set_log_level(client_log_level log_level) { m_impl->set_log_level(log_level); @@ -1756,7 +1779,7 @@ namespace azure { namespace storage { /// /// Gets or sets additional headers on the request, for example, for proxy or logging information. /// - /// A reference containing additional header information. + /// A reference containing additional header information. web::http::http_headers& user_headers() { return m_impl->user_headers(); @@ -1765,7 +1788,7 @@ namespace azure { namespace storage { /// /// Gets or sets additional headers on the request, for example, for proxy or logging information. /// - /// A reference containing additional header information. + /// A reference containing additional header information. const web::http::http_headers& user_headers() const { return m_impl->user_headers(); @@ -1774,7 +1797,7 @@ namespace azure { namespace storage { /// /// Gets the set of request results that the current operation has created. /// - /// A object that contains objects that represent the request results created by the current operation. + /// A object that contains objects that represent the request results created by the current operation. const std::vector& request_results() const { return m_impl->request_results(); @@ -1784,7 +1807,7 @@ namespace azure { namespace storage { /// Sets the function to call when sending a request. /// /// A pointer to a function that takes an object - /// and an object. + /// and an object. void set_sending_request(std::function value) { m_impl->set_sending_request(value); @@ -1794,7 +1817,7 @@ namespace azure { namespace storage { /// Sets the function that is called when a response is received from the server. /// /// A pointer to a function that takes an object, - /// an object, and an object. + /// an object, and an object. void set_response_received(std::function value) { m_impl->set_response_received(value); @@ -1804,7 +1827,7 @@ namespace azure { namespace storage { /// /// Gets the logger object on this operation context. /// - /// The object used by this operation context. + /// The object used by this operation context. boost::log::sources::severity_logger& logger() { return m_impl->logger(); @@ -1813,7 +1836,7 @@ namespace azure { namespace storage { /// /// Gets the logger object on this operation context. /// - /// The object used by this operation context. + /// The object used by this operation context. const boost::log::sources::severity_logger& logger() const { return m_impl->logger(); @@ -1822,7 +1845,7 @@ namespace azure { namespace storage { /// /// Sets the logger object on this operation context. /// - /// The object to use for requests made by this operation context. + /// The object to use for requests made by this operation context. void set_logger(boost::log::sources::severity_logger logger) { m_impl->set_logger(std::move(logger)); @@ -1903,7 +1926,7 @@ namespace azure { namespace storage { /// /// Sets the permissions from the given string. /// - /// The permissions for the shared access policy. + /// The permissions for the shared access policy. void set_permissions_from_string(const utility::string_t& value) { m_permission = 0; @@ -1946,10 +1969,10 @@ namespace azure { namespace storage { /// /// Sets the permissions from the specified permissions. /// - /// The permissions for the shared access policy. - void set_permissions(uint8_t permissions) + /// The permissions for the shared access policy. + void set_permissions(uint8_t value) { - m_permission = permissions; + m_permission = value; } /// @@ -1964,7 +1987,7 @@ namespace azure { namespace storage { /// /// Sets the start time for the shared access policy. /// - /// The start time for the access policy. + /// The start time for the access policy. void set_start(utility::datetime value) { m_start = value; @@ -1982,7 +2005,7 @@ namespace azure { namespace storage { /// /// Sets the expiry time for the shared access policy. /// - /// The expiry time for the shared access policy. + /// The expiry time for the shared access policy. void set_expiry(utility::datetime value) { m_expiry = value; @@ -1998,9 +2021,9 @@ namespace azure { namespace storage { } /// - /// Indicates whether the object is valid. + /// Indicates whether the object is valid. /// - /// true if the object is valid; otherwise, false. + /// true if the object is valid; otherwise, false. bool is_valid() const { return m_expiry.is_initialized() && (m_permission != none); @@ -2009,7 +2032,7 @@ namespace azure { namespace storage { protected: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// shared_access_policy() : m_permission(none) @@ -2017,7 +2040,7 @@ namespace azure { namespace storage { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The expiration date and time for the shared access policy. /// A mask specifying permissions for the shared access policy. @@ -2027,7 +2050,7 @@ namespace azure { namespace storage { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The start date and time for the shared access policy. /// The expiration date and time for the shared access policy. @@ -2074,19 +2097,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. cloud_permissions(cloud_permissions&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. cloud_permissions& operator=(cloud_permissions&& other) { if (this != &other) @@ -2144,19 +2167,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. request_options(request_options&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. request_options& operator=(request_options&& other) { if (this != &other) @@ -2280,14 +2303,14 @@ namespace azure { namespace storage { protected: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// WASTORAGE_API request_options(); /// /// Applies the default set of request options. /// - /// A reference to a set of . + /// A reference to a set of . /// Specifies that an expiry time be applied to the /// request options. This parameter is used internally. void apply_defaults(const request_options& other, bool apply_expiry) diff --git a/Microsoft.WindowsAzure.Storage/includes/was/core.h b/Microsoft.WindowsAzure.Storage/includes/was/core.h index d43eea51..554a2707 100644 --- a/Microsoft.WindowsAzure.Storage/includes/was/core.h +++ b/Microsoft.WindowsAzure.Storage/includes/was/core.h @@ -95,20 +95,20 @@ namespace azure { namespace storage { { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// storage_uri() { } /// - /// Initializes a new instance of the class using the primary endpoint. + /// Initializes a new instance of the class using the primary endpoint. /// /// The endpoint for the primary location. WASTORAGE_API storage_uri(web::http::uri primary_uri); /// - /// Initializes a new instance of the class using the primary endpoint. + /// Initializes a new instance of the class using the primary endpoint. /// /// The endpoint for the primary location. /// The endpoint for the secondary location. @@ -119,19 +119,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. storage_uri(storage_uri&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. storage_uri& operator=(storage_uri&& other) { if (this != &other) @@ -173,7 +173,7 @@ namespace azure { namespace storage { /// /// Gets the endpoint for a specified location. /// - /// A object. + /// An object. /// The location endpoint. const web::http::uri& get_location_uri(storage_location location) { @@ -259,19 +259,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. storage_credentials(storage_credentials&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. storage_credentials& operator=(storage_credentials&& other) { if (this != &other) @@ -372,7 +372,7 @@ namespace azure { namespace storage { { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// option_with_default() : m_has_value(false) @@ -380,7 +380,7 @@ namespace azure { namespace storage { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The default_value. option_with_default(const T& default_value) @@ -393,19 +393,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. option_with_default(option_with_default&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. option_with_default& operator=(option_with_default&& other) { if (this != &other) @@ -421,7 +421,7 @@ namespace azure { namespace storage { /// Returns a reference to a request option set to the specified value. /// /// The option value. - /// A object. + /// An object. option_with_default& operator=(const T& value) { m_value = value; @@ -473,14 +473,14 @@ namespace azure { namespace storage { { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// storage_extended_error() { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The error code. /// The error message. @@ -497,19 +497,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. storage_extended_error(storage_extended_error&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. storage_extended_error& operator=(storage_extended_error&& other) { if (this != &other) @@ -564,7 +564,7 @@ namespace azure { namespace storage { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// request_result() : m_is_response_available(false), @@ -575,7 +575,7 @@ namespace azure { namespace storage { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The start time of the request. /// The target location for the request. @@ -590,7 +590,7 @@ namespace azure { namespace storage { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The start time of the request. /// The target location for the request. @@ -599,7 +599,7 @@ namespace azure { namespace storage { WASTORAGE_API request_result(utility::datetime start_time, storage_location target_location, const web::http::http_response& response, bool parse_body_as_error); /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The start time of the request. /// The target location for the request. @@ -613,19 +613,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. request_result(request_result&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. request_result& operator=(request_result&& other) { if (this != &other) @@ -788,7 +788,7 @@ namespace azure { namespace storage { { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The error message. /// Indicates whether the request is retryable. @@ -798,7 +798,7 @@ namespace azure { namespace storage { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The error message. /// A object containing the inner exception. @@ -809,7 +809,7 @@ namespace azure { namespace storage { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The error message. /// The request result. @@ -820,7 +820,7 @@ namespace azure { namespace storage { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The error message. /// The request result. @@ -850,11 +850,11 @@ namespace azure { namespace storage { } /// - /// Gets the inner exception object that is the cause for the current . + /// Gets the inner exception object that is the cause for the current . /// /// /// A object that points to the inner exception associated with the current - /// . A null exception_ptr is returned if there is no inner exception + /// . A null exception_ptr is returned if there is no inner exception /// object. /// std::exception_ptr inner_exception() const @@ -877,7 +877,7 @@ namespace azure { namespace storage { { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The current retry count. /// The last request result. @@ -893,19 +893,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. retry_context(retry_context&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. retry_context& operator=(retry_context&& other) { if (this != &other) @@ -931,7 +931,7 @@ namespace azure { namespace storage { /// /// Gets the results of the last request. /// - /// A object that represents the results of the last request. + /// An object that represents the results of the last request. const request_result& last_request_result() const { return m_last_request_result; @@ -940,7 +940,7 @@ namespace azure { namespace storage { /// /// Gets the target location for the next retry. /// - /// The for the next retry. + /// The for the next retry. storage_location next_location() const { return m_next_location; @@ -949,7 +949,7 @@ namespace azure { namespace storage { /// /// Gets the location mode for subsequent retries. /// - /// The for subsequent retries. + /// The for subsequent retries. location_mode current_location_mode() const { return m_current_location_mode; @@ -971,7 +971,7 @@ namespace azure { namespace storage { { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// retry_info() : m_should_retry(false), m_target_location(storage_location::unspecified), @@ -980,9 +980,9 @@ namespace azure { namespace storage { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// The object that was passed in to the retry policy. + /// The object that was passed in to the retry policy. explicit retry_info(const retry_context& context) : m_should_retry(true), m_target_location(context.next_location()), m_updated_location_mode(context.current_location_mode()), m_retry_interval(protocol::default_retry_interval) @@ -994,19 +994,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. retry_info(retry_info&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. retry_info& operator=(retry_info&& other) { if (this != &other) @@ -1100,7 +1100,7 @@ namespace azure { namespace storage { { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// basic_retry_policy() { @@ -1118,7 +1118,7 @@ namespace azure { namespace storage { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// retry_policy() : m_policy(nullptr) @@ -1126,7 +1126,7 @@ namespace azure { namespace storage { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The PTR. explicit retry_policy(std::shared_ptr ptr) @@ -1137,9 +1137,9 @@ namespace azure { namespace storage { WASTORAGE_API retry_info evaluate(const retry_context& retry_context, operation_context context) override; /// - /// Indicates whether the object is valid. + /// Indicates whether the object is valid. /// - /// true if the object is valid; otherwise, false. + /// true if the object is valid; otherwise, false. bool is_valid() const { return m_policy != nullptr; @@ -1148,7 +1148,7 @@ namespace azure { namespace storage { /// /// Clones the retry policy. /// - /// A cloned . + /// A cloned . retry_policy clone() const override { if (m_policy != nullptr) diff --git a/Microsoft.WindowsAzure.Storage/includes/was/error_code_strings.h b/Microsoft.WindowsAzure.Storage/includes/was/error_code_strings.h index 91e1b07f..f43103ee 100644 --- a/Microsoft.WindowsAzure.Storage/includes/was/error_code_strings.h +++ b/Microsoft.WindowsAzure.Storage/includes/was/error_code_strings.h @@ -237,6 +237,16 @@ namespace azure { namespace storage { namespace protocol { // This section provides error code strings that are specific to the Blob service. + /// + /// The specified append offset is invalid. + /// + const utility::string_t error_code_invalid_append_condition(U("AppendPositionConditionNotMet")); + + /// + /// The specified maximum blob size is invalid. + /// + const utility::string_t error_invalid_max_blob_size_condition(U("MaxBlobSizeConditionNotMet")); + /// /// The specified block or blob is invalid. /// diff --git a/Microsoft.WindowsAzure.Storage/includes/was/queue.h b/Microsoft.WindowsAzure.Storage/includes/was/queue.h index 58673e6b..b47dbfab 100644 --- a/Microsoft.WindowsAzure.Storage/includes/was/queue.h +++ b/Microsoft.WindowsAzure.Storage/includes/was/queue.h @@ -113,19 +113,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. queue_permissions(queue_permissions&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. queue_permissions& operator=(queue_permissions&& other) { if (this != &other) @@ -145,7 +145,7 @@ namespace azure { namespace storage { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// cloud_queue_message() : m_dequeue_count(0) @@ -153,7 +153,7 @@ namespace azure { namespace storage { } /// - /// Initializes a new instance of the class, with text content. + /// Initializes a new instance of the class, with text content. /// /// The content of the message. explicit cloud_queue_message(utility::string_t content) @@ -162,7 +162,7 @@ namespace azure { namespace storage { } /// - /// Initializes a new instance of the class with the specified raw data. + /// Initializes a new instance of the class with the specified raw data. /// /// The content of the message as raw data. explicit cloud_queue_message(const std::vector& content) @@ -171,7 +171,7 @@ namespace azure { namespace storage { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The unique ID of the message. /// The pop receipt token. @@ -185,19 +185,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. cloud_queue_message(cloud_queue_message&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. cloud_queue_message& operator=(cloud_queue_message&& other) { if (this != &other) @@ -235,7 +235,7 @@ namespace azure { namespace storage { /// /// Sets the content of this message. /// - /// The new message content. + /// The new message content. void set_content(utility::string_t value) { m_content = std::move(value); @@ -244,7 +244,7 @@ namespace azure { namespace storage { /// /// Sets the content of this message. /// - /// The new message content. + /// The new message content. void set_content(const std::vector& value) { m_content = utility::conversions::to_base64(value); @@ -367,19 +367,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. queue_request_options(queue_request_options&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. queue_request_options& operator=(queue_request_options&& other) { if (this != &other) @@ -393,7 +393,7 @@ namespace azure { namespace storage { /// /// Applies the default set of request options. /// - /// A reference to a set of . + /// A reference to a set of . void apply_defaults(const queue_request_options& other) { request_options::apply_defaults(other, true); @@ -421,9 +421,9 @@ namespace azure { namespace storage { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// A object containing the Queue service endpoint for all locations. + /// An object containing the Queue service endpoint for all locations. explicit cloud_queue_client(storage_uri base_uri) : cloud_client(std::move(base_uri)) { @@ -431,10 +431,10 @@ namespace azure { namespace storage { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// A object containing the Queue service endpoint for all locations. - /// The to use. + /// An object containing the Queue service endpoint for all locations. + /// The to use. cloud_queue_client(storage_uri base_uri, azure::storage::storage_credentials credentials) : cloud_client(std::move(base_uri), std::move(credentials)) { @@ -442,12 +442,12 @@ namespace azure { namespace storage { } /// - /// Initializes a new instance of the class using the specified Queue + /// Initializes a new instance of the class using the specified Queue /// service endpoint and account credentials. /// - /// A object containing the Queue service endpoint for all locations. - /// The to use. - /// The default object to use for all requests made with this client object. + /// An object containing the Queue service endpoint for all locations. + /// The to use. + /// The default object to use for all requests made with this client object. cloud_queue_client(storage_uri base_uri, azure::storage::storage_credentials credentials, queue_request_options default_request_options) : cloud_client(std::move(base_uri), std::move(credentials)), m_default_request_options(std::move(default_request_options)) { @@ -459,19 +459,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. cloud_queue_client(cloud_queue_client&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. cloud_queue_client& operator=(cloud_queue_client&& other) { if (this != &other) @@ -484,34 +484,34 @@ namespace azure { namespace storage { #endif /// - /// Returns a that can be used to to lazily enumerate a collection of queues. + /// Returns an that can be used to to lazily enumerate a collection of queues. /// - /// A that can be used to to lazily enumerate a collection of queues. + /// An that can be used to to lazily enumerate a collection of queues. queue_result_iterator list_queues() const { return list_queues(utility::string_t(), false, 0, queue_request_options(), operation_context()); } /// - /// Returns a that can be used to to lazily enumerate a collection of queues that begin with the specified prefix. + /// Returns an that can be used to to lazily enumerate a collection of queues that begin with the specified prefix. /// /// The queue name prefix. - /// A that can be used to to lazily enumerate a collection of queues. + /// An that can be used to to lazily enumerate a collection of queues. queue_result_iterator list_queues(const utility::string_t& prefix) const { return list_queues(prefix, false, 0, queue_request_options(), operation_context()); } /// - /// Returns a that can be used to to lazily enumerate a collection of queues that begin with the specified prefix. + /// Returns an that can be used to to lazily enumerate a collection of queues that begin with the specified prefix. /// /// The queue name prefix. /// A flag that specifies whether to retrieve queue metadata. /// A non-negative integer value that indicates the maximum number of results to be returned. /// If this value is zero, the maximum possible number of results will be returned. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A that can be used to to lazily enumerate a collection of queues. + /// An that can be used to to lazily enumerate a collection of queues. WASTORAGE_API queue_result_iterator list_queues(const utility::string_t& prefix, bool get_metadata, utility::size64_t max_results, const queue_request_options& options, operation_context context) const; /// @@ -543,7 +543,7 @@ namespace azure { namespace storage { /// A flag that specifies whether to retrieve queue metadata. /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the /// per-operation limit of 5000. If this value is 0, the maximum possible number of results will be returned, up to 5000. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A result segment containing a collection of queues. queue_result_segment list_queues_segmented(const utility::string_t& prefix, bool get_metadata, int max_results, const continuation_token& token, const queue_request_options& options, operation_context context) const @@ -555,7 +555,7 @@ namespace azure { namespace storage { /// Intitiates an asynchronous operation to return a result segment containing a collection of queue items. /// /// A continuation token returned by a previous listing operation. - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. pplx::task list_queues_segmented_async(const continuation_token& token) const { return list_queues_segmented_async(utility::string_t(), false, 0, token, queue_request_options(), operation_context()); @@ -566,7 +566,7 @@ namespace azure { namespace storage { /// /// A continuation token returned by a previous listing operation. /// The queue name prefix. - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. pplx::task list_queues_segmented_async(const utility::string_t& prefix, const continuation_token& token) const { return list_queues_segmented_async(prefix, false, 0, token, queue_request_options(), operation_context()); @@ -580,15 +580,15 @@ namespace azure { namespace storage { /// A flag that specifies whether to retrieve queue metadata. /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the /// per-operation limit of 5000. If this value is 0, the maximum possible number of results will be returned, up to 5000. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. WASTORAGE_API pplx::task list_queues_segmented_async(const utility::string_t& prefix, bool get_metadata, int max_results, const continuation_token& token, const queue_request_options& options, operation_context context) const; /// /// Gets the service properties for the Queue service client. /// - /// The for the Queue service client. + /// The for the Queue service client. service_properties download_service_properties() const { return download_service_properties_async().get(); @@ -597,9 +597,9 @@ namespace azure { namespace storage { /// /// Gets the service properties for the Queue service client. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// The for the Queue service client. + /// The for the Queue service client. service_properties download_service_properties(const queue_request_options& options, operation_context context) const { return download_service_properties_async(options, context).get(); @@ -608,7 +608,7 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to get the properties of the service. /// - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. pplx::task download_service_properties_async() const { return download_service_properties_async(queue_request_options(), operation_context()); @@ -617,16 +617,16 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to get the properties of the service. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. WASTORAGE_API pplx::task download_service_properties_async(const queue_request_options& options, operation_context context) const; /// /// Sets the service properties for the Queue service client. /// - /// The for the Queue service client. - /// A enumeration describing which items to include when setting service properties. + /// The for the Queue service client. + /// An enumeration describing which items to include when setting service properties. void upload_service_properties(const service_properties& properties, const service_properties_includes& includes) const { upload_service_properties_async(properties, includes).wait(); @@ -635,9 +635,9 @@ namespace azure { namespace storage { /// /// Sets the service properties for the Queue service client. /// - /// The for the Queue service client. - /// A enumeration describing which items to include when setting service properties. - /// A object that specifies additional options for the request. + /// The for the Queue service client. + /// An enumeration describing which items to include when setting service properties. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void upload_service_properties(const service_properties& properties, const service_properties_includes& includes, const queue_request_options& options, operation_context context) const { @@ -647,8 +647,8 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to set the service properties for the Queue service client. /// - /// The for the Queue service client. - /// A enumeration describing which items to include when setting service properties. + /// The for the Queue service client. + /// An enumeration describing which items to include when setting service properties. /// A object that represents the current operation. pplx::task upload_service_properties_async(const service_properties& properties, const service_properties_includes& includes) const { @@ -658,9 +658,9 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to set the service properties for the Queue service client. /// - /// The for the Queue service client. - /// A enumeration describing which items to include when setting service properties. - /// A object that specifies additional options for the request. + /// The for the Queue service client. + /// An enumeration describing which items to include when setting service properties. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task upload_service_properties_async(const service_properties& properties, const service_properties_includes& includes, const queue_request_options& options, operation_context context) const; @@ -668,7 +668,7 @@ namespace azure { namespace storage { /// /// Gets the service stats for the Queue service client. /// - /// The for the Queue service client. + /// The for the Queue service client. service_stats download_service_stats() const { return download_service_stats_async().get(); @@ -677,9 +677,9 @@ namespace azure { namespace storage { /// /// Gets the service stats for the Queue service client. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// The for the Queue service client. + /// The for the Queue service client. service_stats download_service_stats(const queue_request_options& options, operation_context context) const { return download_service_stats_async(options, context).get(); @@ -688,7 +688,7 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to get the stats of the service. /// - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. pplx::task download_service_stats_async() const { return download_service_stats_async(queue_request_options(), operation_context()); @@ -697,9 +697,9 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to get the stats of the service. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. WASTORAGE_API pplx::task download_service_stats_async(const queue_request_options& options, operation_context context) const; /// @@ -740,7 +740,7 @@ namespace azure { namespace storage { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// cloud_queue() : m_metadata(std::make_shared()), m_approximate_message_count(std::make_shared(-1)) @@ -748,16 +748,16 @@ namespace azure { namespace storage { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// A object containing the absolute URI to the queue for all locations. + /// An object containing the absolute URI to the queue for all locations. WASTORAGE_API cloud_queue(const storage_uri& uri); /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// A object containing the absolute URI to the queue for all locations. - /// The to use. + /// An object containing the absolute URI to the queue for all locations. + /// The to use. WASTORAGE_API cloud_queue(const storage_uri& uri, storage_credentials credentials); #if defined(_MSC_VER) && _MSC_VER < 1900 @@ -765,19 +765,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. cloud_queue(cloud_queue&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. cloud_queue& operator=(cloud_queue&& other) { if (this != &other) @@ -803,7 +803,7 @@ namespace azure { namespace storage { /// /// Creates the queue. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void create(const queue_request_options& options, operation_context context) { @@ -822,7 +822,7 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to create the queue. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task create_async(const queue_request_options& options, operation_context context); @@ -838,7 +838,7 @@ namespace azure { namespace storage { /// /// Creates the queue if it does not already exist. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. bool create_if_not_exists(const queue_request_options & options, operation_context context) { @@ -857,7 +857,7 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to create the queue if it does not already exist. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task create_if_not_exists_async(const queue_request_options& options, operation_context context); @@ -873,7 +873,7 @@ namespace azure { namespace storage { /// /// Deletes the queue. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void delete_queue(const queue_request_options& options, operation_context context) { @@ -892,7 +892,7 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to delete the queue. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task delete_queue_async(const queue_request_options& options, operation_context context); @@ -908,7 +908,7 @@ namespace azure { namespace storage { /// /// Deletes the queue if it exists. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. bool delete_queue_if_exists(const queue_request_options& options, operation_context context) { @@ -927,7 +927,7 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to delete the queue if it exists. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task delete_queue_if_exists_async(const queue_request_options& options, operation_context context); @@ -943,7 +943,7 @@ namespace azure { namespace storage { /// /// Checks for the existence of the queue. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. bool exists(const queue_request_options& options, operation_context context) const { @@ -962,7 +962,7 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to check for the existence of the queue. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task exists_async(const queue_request_options& options, operation_context context) const; @@ -982,7 +982,7 @@ namespace azure { namespace storage { /// The message to add to the queue. /// The maximum time to allow the message to be in the queue. /// The length of time from now during which the message will be invisible. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void add_message(cloud_queue_message& message, std::chrono::seconds time_to_live, std::chrono::seconds initial_visibility_timeout, queue_request_options& options, operation_context context) { @@ -1006,7 +1006,7 @@ namespace azure { namespace storage { /// The message to add to the queue. /// The maximum time to allow the message to be in the queue. /// The length of time from now during which the message will be invisible. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task add_message_async(cloud_queue_message& message, std::chrono::seconds time_to_live, std::chrono::seconds initial_visibility_timeout, queue_request_options& options, operation_context context); @@ -1014,7 +1014,7 @@ namespace azure { namespace storage { /// /// Retrieves a message from the front of the queue /// - /// A object. + /// An object. cloud_queue_message get_message() { return get_message_async().get(); @@ -1024,9 +1024,9 @@ namespace azure { namespace storage { /// Retrieves a message from the front of the queue /// /// The length of time from now during which the message will be invisible. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A object. + /// An object. cloud_queue_message get_message(std::chrono::seconds visibility_timeout, queue_request_options& options, operation_context context) { return get_message_async(visibility_timeout, options, context).get(); @@ -1035,7 +1035,7 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation that retrieves a message from the front of the queue /// - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. pplx::task get_message_async() { queue_request_options options; @@ -1046,16 +1046,16 @@ namespace azure { namespace storage { /// Intitiates an asynchronous operation that retrieves a message from the front of the queue /// /// The length of time from now during which the message will be invisible. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. WASTORAGE_API pplx::task get_message_async(std::chrono::seconds visibility_timeout, queue_request_options& options, operation_context context); /// /// Retrieves the specified number of messages from the front of the queue. /// /// The number of messages to retrieve. - /// An enumerable collection of objects. + /// An enumerable collection of objects. std::vector get_messages(size_t message_count) { return get_messages_async(message_count).get(); @@ -1066,9 +1066,9 @@ namespace azure { namespace storage { /// /// The number of messages to retrieve. /// The length of time from now during which the message will be invisible. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// An enumerable collection of objects. + /// An enumerable collection of objects. std::vector get_messages(size_t message_count, std::chrono::seconds visibility_timeout, queue_request_options& options, operation_context context) { return get_messages_async(message_count, visibility_timeout, options, context).get(); @@ -1078,7 +1078,7 @@ namespace azure { namespace storage { /// Intitiates an asynchronous operation that retrieves the specified number of messages from the front of the queue. /// /// The number of messages to retrieve. - /// A object of type , of type , that represents the current operation. + /// A object of type , of type , that represents the current operation. pplx::task> get_messages_async(size_t message_count) { queue_request_options options; @@ -1090,15 +1090,15 @@ namespace azure { namespace storage { /// /// The number of messages to retrieve. /// The length of time from now during which the message will be invisible. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A object of type , of type , that represents the current operation. + /// A object of type , of type , that represents the current operation. WASTORAGE_API pplx::task> get_messages_async(size_t message_count, std::chrono::seconds visibility_timeout, queue_request_options& options, operation_context context); /// /// Peeks a message from the front of the queue /// - /// A object. + /// An object. cloud_queue_message peek_message() const { return peek_message_async().get(); @@ -1107,9 +1107,9 @@ namespace azure { namespace storage { /// /// Peeks a message from the front of the queue /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A object. + /// An object. cloud_queue_message peek_message(const queue_request_options& options, operation_context context) const { return peek_message_async(options, context).get(); @@ -1118,7 +1118,7 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation that peeks a message from the front of the queue /// - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. pplx::task peek_message_async() const { return peek_message_async(queue_request_options(), operation_context()); @@ -1127,9 +1127,9 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation that peeks a message from the front of the queue /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. WASTORAGE_API pplx::task peek_message_async(const queue_request_options& options, operation_context context) const; /// @@ -1137,7 +1137,7 @@ namespace azure { namespace storage { /// message visibility. /// /// The number of messages to be retrieved. - /// An enumerable collection of objects. + /// An enumerable collection of objects. std::vector peek_messages(size_t message_count) const { return peek_messages_async(message_count).get(); @@ -1148,9 +1148,9 @@ namespace azure { namespace storage { /// message visibility. /// /// The number of messages to be retrieved. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// An enumerable collection of objects. + /// An enumerable collection of objects. std::vector peek_messages(size_t message_count, const queue_request_options& options, operation_context context) const { return peek_messages_async(message_count, options, context).get(); @@ -1161,7 +1161,7 @@ namespace azure { namespace storage { /// message visibility. /// /// The number of messages to be retrieved. - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. pplx::task> peek_messages_async(size_t message_count) const { return peek_messages_async(message_count, queue_request_options(), operation_context()); @@ -1172,9 +1172,9 @@ namespace azure { namespace storage { /// message visibility. /// /// The number of messages to be retrieved. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A object of type , of type , that represents the current operation. + /// A object of type , of type , that represents the current operation. WASTORAGE_API pplx::task> peek_messages_async(size_t message_count, const queue_request_options& options, operation_context context) const; /// @@ -1194,7 +1194,7 @@ namespace azure { namespace storage { /// The message to update. /// The time interval, in seconds, after which the message becomes visible again, unless it has been deleted. /// true to update the content of the message. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void update_message(cloud_queue_message& message, std::chrono::seconds visibility_timeout, bool update_content, queue_request_options& options, operation_context context) { @@ -1220,7 +1220,7 @@ namespace azure { namespace storage { /// The message to update. /// The time interval, in seconds, after which the message becomes visible again, unless it has been deleted. /// true to update the content of the message. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task update_message_async(cloud_queue_message& message, std::chrono::seconds visibility_timeout, bool update_content, queue_request_options& options, operation_context context); @@ -1238,7 +1238,7 @@ namespace azure { namespace storage { /// Deletes the given message from the queue. /// /// The message to delete. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void delete_message(cloud_queue_message& message, queue_request_options& options, operation_context context) { @@ -1260,7 +1260,7 @@ namespace azure { namespace storage { /// Intitiates an asynchronous operation that deletes the given message from the queue. /// /// The message to delete. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task delete_message_async(cloud_queue_message& message, queue_request_options& options, operation_context context); @@ -1276,7 +1276,7 @@ namespace azure { namespace storage { /// /// Deletes all the messages in the queue. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void clear(const queue_request_options& options, operation_context context) { @@ -1295,7 +1295,7 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation that deletes all the messages in the queue. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task clear_async(const queue_request_options& options, operation_context context); @@ -1311,7 +1311,7 @@ namespace azure { namespace storage { /// /// Retrieves the user-defined metadata for the queue. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void download_attributes(const queue_request_options& options, operation_context context) { @@ -1330,7 +1330,7 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation that retrieves the user-defined metadata for the queue. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task download_attributes_async(const queue_request_options& options, operation_context context); @@ -1346,7 +1346,7 @@ namespace azure { namespace storage { /// /// Sets the user-defined metadata for the queue. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void upload_metadata(const queue_request_options& options, operation_context context) { @@ -1365,7 +1365,7 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation that sets the user-defined metadata for the queue. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task upload_metadata_async(const queue_request_options& options, operation_context context); @@ -1381,7 +1381,7 @@ namespace azure { namespace storage { /// /// Retrieves the shared access policies for the queue. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. queue_permissions download_permissions(const queue_request_options& options, operation_context context) const { @@ -1391,7 +1391,7 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation that retrieves the shared access policies for the queue. /// - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. pplx::task download_permissions_async() const { return download_permissions_async(queue_request_options(), operation_context()); @@ -1400,9 +1400,9 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation that retrieves the shared access policies for the queue. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. WASTORAGE_API pplx::task download_permissions_async(const queue_request_options& options, operation_context context) const; /// @@ -1418,7 +1418,7 @@ namespace azure { namespace storage { /// Sets permissions for the queue. /// /// The access control list to associate with this queue - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void upload_permissions(const queue_permissions& permissions, const queue_request_options& options, operation_context context) { @@ -1439,7 +1439,7 @@ namespace azure { namespace storage { /// Intitiates an asynchronous operation that sets permissions for the queue. /// /// The access control list to associate with this queue - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task upload_permissions_async(const queue_permissions& permissions, const queue_request_options& options, operation_context context); @@ -1465,7 +1465,7 @@ namespace azure { namespace storage { /// /// Gets the Queue service client that specifies the endpoint for the queue service. /// - /// The object that specifies the endpoint for the queue service. + /// The object that specifies the endpoint for the queue service. const cloud_queue_client& service_client() const { return m_client; @@ -1483,7 +1483,7 @@ namespace azure { namespace storage { /// /// Gets the queue URI for all locations. /// - /// A containing the queue URI for all locations. + /// An containing the queue URI for all locations. const storage_uri& uri() const { return m_uri; diff --git a/Microsoft.WindowsAzure.Storage/includes/was/retry_policies.h b/Microsoft.WindowsAzure.Storage/includes/was/retry_policies.h index d3fe4434..a7720c37 100644 --- a/Microsoft.WindowsAzure.Storage/includes/was/retry_policies.h +++ b/Microsoft.WindowsAzure.Storage/includes/was/retry_policies.h @@ -35,7 +35,7 @@ namespace azure { namespace storage { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// basic_no_retry_policy() : basic_retry_policy() @@ -47,7 +47,7 @@ namespace azure { namespace storage { /// /// Clones the retry policy. /// - /// A cloned . + /// A cloned . retry_policy clone() const override { return retry_policy(std::make_shared()); @@ -62,7 +62,7 @@ namespace azure { namespace storage { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// no_retry_policy() : retry_policy(std::make_shared()) @@ -82,7 +82,7 @@ namespace azure { namespace storage { protected: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The maximum number of retries to attempt. explicit basic_common_retry_policy(int max_attempts) @@ -114,7 +114,7 @@ namespace azure { namespace storage { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The delta backoff. /// The maximum number of retries to attempt. @@ -128,7 +128,7 @@ namespace azure { namespace storage { /// /// Clones the retry policy. /// - /// A cloned . + /// A cloned . retry_policy clone() const override { return retry_policy(std::make_shared(m_delta_backoff, m_max_attempts)); @@ -147,7 +147,7 @@ namespace azure { namespace storage { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// linear_retry_policy() : retry_policy(std::make_shared(protocol::default_retry_interval, default_attempts)) @@ -155,7 +155,7 @@ namespace azure { namespace storage { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The delta backoff. /// The maximum number of retries to attempt. @@ -173,7 +173,7 @@ namespace azure { namespace storage { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The delta backoff. /// The maximum number of retries to attempt. @@ -188,7 +188,7 @@ namespace azure { namespace storage { /// /// Clones the retry policy. /// - /// A cloned . + /// A cloned . retry_policy clone() const override { return retry_policy(std::make_shared(m_delta_backoff, m_max_attempts)); @@ -209,7 +209,7 @@ namespace azure { namespace storage { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// exponential_retry_policy() : retry_policy(std::make_shared(protocol::default_retry_interval, default_attempts)) @@ -217,7 +217,7 @@ namespace azure { namespace storage { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The delta backoff. /// The maximum number of retries to attempt. diff --git a/Microsoft.WindowsAzure.Storage/includes/was/service_client.h b/Microsoft.WindowsAzure.Storage/includes/was/service_client.h index a52d564a..49659fd2 100644 --- a/Microsoft.WindowsAzure.Storage/includes/was/service_client.h +++ b/Microsoft.WindowsAzure.Storage/includes/was/service_client.h @@ -35,19 +35,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. cloud_client(cloud_client&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. cloud_client& operator=(cloud_client&& other) { if (this != &other) @@ -119,7 +119,7 @@ namespace azure { namespace storage { /// /// Initializes a new instance of the service client class using the specified service endpoint. /// - /// A object containing the service endpoint for all locations. + /// An object containing the service endpoint for all locations. explicit cloud_client(storage_uri base_uri) : m_base_uri(std::move(base_uri)), m_authentication_scheme(azure::storage::authentication_scheme::shared_key) { @@ -128,8 +128,8 @@ namespace azure { namespace storage { /// /// Initializes a new instance of the client class using the specified service endpoint and storage account credentials. /// - /// A object containing the service endpoint for all locations. - /// The to use. + /// An object containing the service endpoint for all locations. + /// The to use. cloud_client(storage_uri base_uri, azure::storage::storage_credentials credentials) : m_base_uri(std::move(base_uri)), m_credentials(std::move(credentials)), m_authentication_scheme(azure::storage::authentication_scheme::shared_key) { diff --git a/Microsoft.WindowsAzure.Storage/includes/was/storage_account.h b/Microsoft.WindowsAzure.Storage/includes/was/storage_account.h index 131b9b12..26f92c59 100644 --- a/Microsoft.WindowsAzure.Storage/includes/was/storage_account.h +++ b/Microsoft.WindowsAzure.Storage/includes/was/storage_account.h @@ -36,7 +36,7 @@ namespace azure { namespace storage { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// cloud_storage_account() : m_initialized(false), m_is_development_storage_account(false), m_default_endpoints(false) @@ -47,7 +47,7 @@ namespace azure { namespace storage { /// Initializes a new instance of the class using the specified /// credentials and service endpoints. /// - /// The to use. + /// The to use. /// The Blob service endpoint. /// The Queue service endpoint. /// The Table service endpoint. @@ -60,7 +60,7 @@ namespace azure { namespace storage { /// Initializes a new instance of the class using the specified /// credentials and the default service endpoints. /// - /// The to use. + /// The to use. /// true to use HTTPS to connect to storage service endpoints; otherwise, false. cloud_storage_account(const storage_credentials& credentials, bool use_https) : m_initialized(true), m_is_development_storage_account(false), m_credentials(credentials), m_default_endpoints(true) @@ -72,7 +72,7 @@ namespace azure { namespace storage { /// Initializes a new instance of the class using the specified /// credentials and the default service endpoints. /// - /// The to use. + /// The to use. /// The DNS endpoint suffix for the storage services, e.g., "core.windows.net". /// true to use HTTPS to connect to storage service endpoints; otherwise, false. cloud_storage_account(const storage_credentials& credentials, const utility::string_t& endpoint_suffix, bool use_https) @@ -86,19 +86,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. cloud_storage_account(cloud_storage_account&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. cloud_storage_account& operator=(cloud_storage_account&& other) { if (this != &other) @@ -118,11 +118,11 @@ namespace azure { namespace storage { #endif /// - /// Parses a connection string and returns a created + /// Parses a connection string and returns an created /// from the connection string. /// /// A valid connection string. - /// A object constructed from the values provided in the connection string. + /// An object constructed from the values provided in the connection string. WASTORAGE_API static cloud_storage_account parse(const utility::string_t& connection_string); /// @@ -178,7 +178,7 @@ namespace azure { namespace storage { WASTORAGE_API utility::string_t to_string(bool export_secrets); /// - /// Gets a object that references the development storage account. + /// Gets an object that references the development storage account. /// /// A reference to the development storage account. WASTORAGE_API static cloud_storage_account development_storage_account(); @@ -186,7 +186,7 @@ namespace azure { namespace storage { /// /// Gets the endpoint for the Blob service for all location. /// - /// A object containing the Blob service endpoint for all locations. + /// An object containing the Blob service endpoint for all locations. const storage_uri& blob_endpoint() const { return m_blob_endpoint; @@ -195,7 +195,7 @@ namespace azure { namespace storage { /// /// Gets the endpoint for the Queue service for all location. /// - /// A object containing the Queue service endpoint for all locations. + /// An object containing the Queue service endpoint for all locations. const storage_uri& queue_endpoint() const { return m_queue_endpoint; @@ -204,7 +204,7 @@ namespace azure { namespace storage { /// /// Gets the endpoint for the Table service for all location. /// - /// A object containing the Table service endpoint for all locations. + /// An object containing the Table service endpoint for all locations. const storage_uri& table_endpoint() const { return m_table_endpoint; diff --git a/Microsoft.WindowsAzure.Storage/includes/was/table.h b/Microsoft.WindowsAzure.Storage/includes/was/table.h index d523ffa9..784c0905 100644 --- a/Microsoft.WindowsAzure.Storage/includes/was/table.h +++ b/Microsoft.WindowsAzure.Storage/includes/was/table.h @@ -78,7 +78,7 @@ namespace azure { namespace storage { }; /// - /// Enumeration containing the types of operations that can be performed by a . + /// Enumeration containing the types of operations that can be performed by an . /// enum class table_operation_type { @@ -227,19 +227,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. table_permissions(table_permissions&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. table_permissions& operator=(table_permissions&& other) { if (this != &other) @@ -271,19 +271,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. table_request_options(table_request_options&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. table_request_options& operator=(table_request_options&& other) { if (this != &other) @@ -298,7 +298,7 @@ namespace azure { namespace storage { /// /// Applies the default set of request options. /// - /// A reference to a set of . + /// A reference to a set of . void apply_defaults(const table_request_options& other) { request_options::apply_defaults(other, true); @@ -307,18 +307,18 @@ namespace azure { namespace storage { } /// - /// Gets the to use for the request. + /// Gets the to use for the request. /// - /// A object. + /// An object. azure::storage::table_payload_format payload_format() const { return m_payload_format; } /// - /// Sets the that will be used for the request. + /// Sets the that will be used for the request. /// - /// The to use. + /// The to use. void set_payload_format(azure::storage::table_payload_format payload_format) { m_payload_format = payload_format; @@ -337,7 +337,7 @@ namespace azure { namespace storage { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// entity_property() : m_property_type(edm_type::string), m_is_null(true) @@ -345,7 +345,7 @@ namespace azure { namespace storage { } /// - /// Initializes a new instance of the class with a byte array value. + /// Initializes a new instance of the class with a byte array value. /// /// A byte array. entity_property(const std::vector& value) @@ -355,7 +355,7 @@ namespace azure { namespace storage { } /// - /// Initializes a new instance of the class with a boolean value. + /// Initializes a new instance of the class with a boolean value. /// /// A boolean value. entity_property(bool value) @@ -365,7 +365,7 @@ namespace azure { namespace storage { } /// - /// Initializes a new instance of the class with a date/time value. + /// Initializes a new instance of the class with a date/time value. /// /// A datetime value. entity_property(utility::datetime value) @@ -375,7 +375,7 @@ namespace azure { namespace storage { } /// - /// Initializes a new instance of the class with a double precision floating-point number value. + /// Initializes a new instance of the class with a double precision floating-point number value. /// /// A double value. entity_property(double value) @@ -385,7 +385,7 @@ namespace azure { namespace storage { } /// - /// Initializes a new instance of the class with a GUID value. + /// Initializes a new instance of the class with a GUID value. /// /// A GUID value. entity_property(const utility::uuid& value) @@ -395,7 +395,7 @@ namespace azure { namespace storage { } /// - /// Initializes a new instance of the class with a 32-bit integer value. + /// Initializes a new instance of the class with a 32-bit integer value. /// /// A 32-bit integer value. entity_property(int32_t value) @@ -405,7 +405,7 @@ namespace azure { namespace storage { } /// - /// Initializes a new instance of the class with a 64-bit integer value. + /// Initializes a new instance of the class with a 64-bit integer value. /// /// A 64-bit integer value. entity_property(int64_t value) @@ -415,7 +415,7 @@ namespace azure { namespace storage { } /// - /// Initializes a new instance of the class with a string value. + /// Initializes a new instance of the class with a string value. /// /// A string value. entity_property(utility::string_t value) @@ -424,7 +424,7 @@ namespace azure { namespace storage { } /// - /// Initializes a new instance of the class with a string value. + /// Initializes a new instance of the class with a string value. /// /// A string value. entity_property(const utility::char_t* value) @@ -438,19 +438,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. entity_property(entity_property&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. entity_property& operator=(entity_property&& other) { if (this != &other) @@ -464,18 +464,18 @@ namespace azure { namespace storage { #endif /// - /// Gets the property type of the object. + /// Gets the property type of the object. /// - /// An object. + /// An object. azure::storage::edm_type property_type() const { return m_property_type; } /// - /// Sets the property type of the object. + /// Sets the property type of the object. /// - /// An object indicating the property type. + /// An object indicating the property type. void set_property_type(azure::storage::edm_type property_type) { m_property_type = property_type; @@ -500,79 +500,79 @@ namespace azure { namespace storage { } /// - /// Gets the byte array value of the object. + /// Gets the byte array value of the object. /// - /// The byte array value of the object. + /// The byte array value of the object. /// /// An exception is thrown if this property is set to a value other than a byte array. /// WASTORAGE_API std::vector binary_value() const; /// - /// Gets the boolean value of the object. + /// Gets the boolean value of the object. /// - /// The boolean value of the object. + /// The boolean value of the object. /// /// An exception is thrown if this property is set to a value other than a boolean value. /// WASTORAGE_API bool boolean_value() const; /// - /// Gets the datetime value of the object. + /// Gets the datetime value of the object. /// - /// The datetime value of the object. + /// The datetime value of the object. /// /// An exception is thrown if this property is set to a value other than a datetime value. /// WASTORAGE_API utility::datetime datetime_value() const; /// - /// Gets the double-precision floating point value of the object. + /// Gets the double-precision floating point value of the object. /// - /// The double-precision floating point value of the object. + /// The double-precision floating point value of the object. /// /// An exception is thrown if this property is set to a value other than a double-precision floating point value. /// WASTORAGE_API double double_value() const; /// - /// Gets the GUID value of the object. + /// Gets the GUID value of the object. /// - /// The GUID value of the object. + /// The GUID value of the object. /// /// An exception is thrown if this property is set to a value other than a GUID value. /// WASTORAGE_API utility::uuid guid_value() const; /// - /// Gets the 32-bit integer value of the object. + /// Gets the 32-bit integer value of the object. /// - /// The 32-bit integer value of the object. + /// The 32-bit integer value of the object. /// /// An exception is thrown if this property is set to a value other than a 32-bit integer value. /// WASTORAGE_API int32_t int32_value() const; /// - /// Gets the 64-bit integer value of the object. + /// Gets the 64-bit integer value of the object. /// - /// The 64-bit integer value of the object. + /// The 64-bit integer value of the object. /// /// An exception is thrown if this property is set to a value other than a 64-bit integer value. /// WASTORAGE_API int64_t int64_value() const; /// - /// Gets the string value of the object. + /// Gets the string value of the object. /// - /// The string value of the object. + /// The string value of the object. /// /// An exception is thrown if this property is set to a value other than a string value. /// WASTORAGE_API utility::string_t string_value() const; /// - /// Sets the byte array value of the object. + /// Sets the byte array value of the object. /// /// The byte array value. void set_value(const std::vector& value) @@ -581,7 +581,7 @@ namespace azure { namespace storage { } /// - /// Sets the boolean value of the object. + /// Sets the boolean value of the object. /// /// The boolean value. void set_value(bool value) @@ -594,7 +594,7 @@ namespace azure { namespace storage { // TODO: Test timezone parsing /// - /// Sets the datetime value of the object. + /// Sets the datetime value of the object. /// /// The datetime value. void set_value(utility::datetime value) @@ -605,7 +605,7 @@ namespace azure { namespace storage { } /// - /// Sets the double-precision floating point value of the object. + /// Sets the double-precision floating point value of the object. /// /// The double-precision floating point value. void set_value(double value) @@ -616,7 +616,7 @@ namespace azure { namespace storage { } /// - /// Sets the GUID value of the object. + /// Sets the GUID value of the object. /// /// The GUID point value. void set_value(const utility::uuid& value) @@ -627,7 +627,7 @@ namespace azure { namespace storage { } /// - /// Sets the 32-bit integer value of the object. + /// Sets the 32-bit integer value of the object. /// /// The 32-bit integer value. void set_value(int32_t value) @@ -638,7 +638,7 @@ namespace azure { namespace storage { } /// - /// Sets the 64-bit integer value of the object. + /// Sets the 64-bit integer value of the object. /// /// The 64-bit integer value. void set_value(int64_t value) @@ -649,7 +649,7 @@ namespace azure { namespace storage { } /// - /// Sets the string value of the object. + /// Sets the string value of the object. /// /// The string value. void set_value(utility::string_t value) @@ -660,7 +660,7 @@ namespace azure { namespace storage { } /// - /// Sets the string value of the object. + /// Sets the string value of the object. /// /// The string value. void set_value(const utility::char_t * value) @@ -671,7 +671,7 @@ namespace azure { namespace storage { } /// - /// Returns the value of the object as a string. + /// Returns the value of the object as a string. /// /// A string containing the property value. const utility::string_t& str() const @@ -728,14 +728,14 @@ namespace azure { namespace storage { typedef std::unordered_map::value_type property_type; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// table_entity() { } /// - /// Initializes a new instance of the class with the specified partition key and row key. + /// Initializes a new instance of the class with the specified partition key and row key. /// /// The partition key value for the entity. /// The row key value for the entity. @@ -745,7 +745,7 @@ namespace azure { namespace storage { } /// - /// Initializes a new instance of the class with the entity's partition key, row key, ETag (if available/required), and properties. + /// Initializes a new instance of the class with the entity's partition key, row key, ETag (if available/required), and properties. /// /// The entity's partition key. /// The entity's row key. @@ -761,19 +761,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. table_entity(table_entity&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. table_entity& operator=(table_entity&& other) { if (this != &other) @@ -907,19 +907,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. table_operation(table_operation&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. table_operation& operator=(table_operation&& other) { if (this != &other) @@ -934,7 +934,7 @@ namespace azure { namespace storage { /// /// Gets the entity being operated upon. /// - /// A object. + /// An object. const table_entity& entity() const { return m_entity; @@ -943,7 +943,7 @@ namespace azure { namespace storage { /// /// Gets the type of operation. /// - /// A object. + /// An object. table_operation_type operation_type() const { return m_operation_type; @@ -953,7 +953,7 @@ namespace azure { namespace storage { /// Creates a new table operation to delete the specified entity. /// /// The entity to be deleted from the table. - /// A object. + /// An object. static const table_operation delete_entity(table_entity entity) { return table_operation(table_operation_type::delete_operation, std::move(entity)); @@ -963,7 +963,7 @@ namespace azure { namespace storage { /// Creates a new table operation to insert the specified entity. /// /// The entity to be inserted into the table. - /// A object. + /// An object. static const table_operation insert_entity(table_entity entity) { return table_operation(table_operation_type::insert_operation, std::move(entity)); @@ -974,7 +974,7 @@ namespace azure { namespace storage { /// if the entity does exist, then the contents of the specified entity are merged with the existing entity. /// /// The entity whose contents are being inserted or merged. - /// A object. + /// An object. static const table_operation insert_or_merge_entity(table_entity entity) { return table_operation(table_operation_type::insert_or_merge_operation, std::move(entity)); @@ -985,7 +985,7 @@ namespace azure { namespace storage { /// if the entity does exist, then its contents are replaced with the specified entity. /// /// The entity whose contents are being inserted or replaced. - /// A object. + /// An object. static const table_operation insert_or_replace_entity(table_entity entity) { return table_operation(table_operation_type::insert_or_replace_operation, std::move(entity)); @@ -995,7 +995,7 @@ namespace azure { namespace storage { /// Creates a new table operation to merge the contents of the specified entity with the existing entity. /// /// The entity whose contents are being merged. - /// A object. + /// An object. static const table_operation merge_entity(table_entity entity) { return table_operation(table_operation_type::merge_operation, std::move(entity)); @@ -1005,7 +1005,7 @@ namespace azure { namespace storage { /// Creates a new table operation to replace the contents of the specified entity. /// /// The entity whose contents are being replaced. - /// A object. + /// An object. static const table_operation replace_entity(table_entity entity) { return table_operation(table_operation_type::replace_operation, std::move(entity)); @@ -1016,7 +1016,7 @@ namespace azure { namespace storage { /// /// The partition key of the entity to be replaced. /// The row key of the entity to be replaced. - /// A object. + /// An object. static const table_operation retrieve_entity(utility::string_t partition_key, utility::string_t row_key) { table_entity entity; @@ -1047,7 +1047,7 @@ namespace azure { namespace storage { typedef std::vector operations_type; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// table_batch_operation() { @@ -1058,19 +1058,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. table_batch_operation(table_batch_operation&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. table_batch_operation& operator=(table_batch_operation&& other) { if (this != &other) @@ -1085,7 +1085,7 @@ namespace azure { namespace storage { /// Creates a new table operation to delete the specified entity. /// /// The entity to be deleted from the table. - /// A object. + /// An object. void delete_entity(table_entity entity) { table_operation operation = table_operation::delete_entity(std::move(entity)); @@ -1096,7 +1096,7 @@ namespace azure { namespace storage { /// Creates a new table operation to insert the specified entity. /// /// The entity to be inserted into the table. - /// A object. + /// An object. void insert_entity(table_entity entity) { table_operation operation = table_operation::insert_entity(std::move(entity)); @@ -1108,7 +1108,7 @@ namespace azure { namespace storage { /// if the entity does exist, then the contents of the specified entity are merged with the existing entity. /// /// The entity whose contents are being inserted or merged. - /// A object. + /// An object. void insert_or_merge_entity(table_entity entity) { table_operation operation = table_operation::insert_or_merge_entity(std::move(entity)); @@ -1120,7 +1120,7 @@ namespace azure { namespace storage { /// if the entity does exist, then its contents are replaced with the specified entity. /// /// The entity whose contents are being inserted or replaced. - /// A object. + /// An object. void insert_or_replace_entity(table_entity entity) { table_operation operation = table_operation::insert_or_replace_entity(std::move(entity)); @@ -1131,7 +1131,7 @@ namespace azure { namespace storage { /// Creates a new table operation to merge the contents of the specified entity with the existing entity. /// /// The entity whose contents are being merged. - /// A object. + /// An object. void merge_entity(table_entity entity) { table_operation operation = table_operation::merge_entity(std::move(entity)); @@ -1142,7 +1142,7 @@ namespace azure { namespace storage { /// Creates a new table operation to replace the contents of the specified entity. /// /// The entity whose contents are being replaced. - /// A object. + /// An object. void replace_entity(table_entity entity) { table_operation operation = table_operation::replace_entity(std::move(entity)); @@ -1154,7 +1154,7 @@ namespace azure { namespace storage { /// /// The partition key of the entity to be replaced. /// The row key of the entity to be replaced. - /// A object. + /// An object. void retrieve_entity(utility::string_t partition_key, utility::string_t row_key) { table_operation operation = table_operation::retrieve_entity(std::move(partition_key), std::move(row_key)); @@ -1162,20 +1162,20 @@ namespace azure { namespace storage { } /// - /// Gets a reference to an object containing an enumerable collection + /// Gets a reference to an object containing an enumerable collection /// of operations comprising a batch operation. /// - /// An object. + /// An object. operations_type& operations() { return m_operations; } /// - /// Gets a reference to an object containing an enumerable collection + /// Gets a reference to an object containing an enumerable collection /// of operations comprising a batch operation. /// - /// An object. + /// An object. const operations_type& operations() const { return m_operations; @@ -1255,7 +1255,7 @@ namespace azure { namespace storage { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// table_query() : m_take_count(-1) @@ -1267,19 +1267,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. table_query(table_query&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. table_query& operator=(table_query&& other) { if (this != &other) @@ -1501,14 +1501,14 @@ namespace azure { namespace storage { /// /// Represents the result of a table operation. /// - /// The class encapsulates the HTTP response and any query - /// results returned for a particular . + /// The class encapsulates the HTTP response and any query + /// results returned for a particular . class table_result { public: /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// table_result() : m_http_status_code(0) @@ -1520,19 +1520,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. table_result(table_result&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. table_result& operator=(table_result&& other) { if (this != &other) @@ -1546,25 +1546,25 @@ namespace azure { namespace storage { #endif /// - /// Gets a object returned as part of a object. + /// Gets an object returned as part of an object. /// - /// A object. + /// An object. const azure::storage::table_entity& entity() const { return m_entity; } /// - /// Sets a object returned as part of a object. + /// Sets an object returned as part of an object. /// - /// A object. + /// An object. void set_entity(azure::storage::table_entity value) { m_entity = std::move(value); } /// - /// Gets the HTTP status code for a object. + /// Gets the HTTP status code for an object. /// /// The HTTP status code. int http_status_code() const @@ -1573,7 +1573,7 @@ namespace azure { namespace storage { } /// - /// Sets the HTTP status code for a object. + /// Sets the HTTP status code for an object. /// /// The HTTP status code. void set_http_status_code(int value) @@ -1582,7 +1582,7 @@ namespace azure { namespace storage { } /// - /// Gets the ETag for a object. + /// Gets the ETag for an object. /// /// The ETag, as a string. const utility::string_t& etag() const @@ -1591,7 +1591,7 @@ namespace azure { namespace storage { } /// - /// Sets the ETag for a object. + /// Sets the ETag for an object. /// /// The ETag, as a string. void set_etag(utility::string_t value) @@ -1636,7 +1636,7 @@ namespace azure { namespace storage { /// Initializes a new instance of the class using the specified Table service endpoint /// and anonymous credentials. /// - /// A object containing the Table service endpoint for all locations. + /// An object containing the Table service endpoint for all locations. explicit cloud_table_client(storage_uri base_uri) : cloud_client(std::move(base_uri)) { @@ -1647,8 +1647,8 @@ namespace azure { namespace storage { /// Initializes a new instance of the class using the specified Table service endpoint /// and account credentials. /// - /// A object containing the Table service endpoint for all locations. - /// The to use. + /// An object containing the Table service endpoint for all locations. + /// The to use. cloud_table_client(storage_uri base_uri, storage_credentials credentials) : cloud_client(std::move(base_uri), std::move(credentials)) { @@ -1659,8 +1659,9 @@ namespace azure { namespace storage { /// Initializes a new instance of the class using the specified Table service endpoint /// and account credentials. /// - /// A object containing the Table service endpoint for all locations. - /// The to use. + /// An object containing the Table service endpoint for all locations. + /// The to use. + /// The default to use. cloud_table_client(storage_uri base_uri, storage_credentials credentials, table_request_options default_request_options) : cloud_client(std::move(base_uri), std::move(credentials)), m_default_request_options(std::move(default_request_options)) { @@ -1672,19 +1673,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. cloud_table_client(cloud_table_client&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. cloud_table_client& operator=(cloud_table_client&& other) { if (this != &other) @@ -1703,107 +1704,107 @@ namespace azure { namespace storage { WASTORAGE_API void set_authentication_scheme(azure::storage::authentication_scheme value) override; /// - /// Returns a that can be used to to lazily enumerate a collection of tables. + /// Returns an that can be used to to lazily enumerate a collection of tables. /// - /// A that can be used to to lazily enumerate a collection of tables. + /// An that can be used to to lazily enumerate a collection of tables. table_result_iterator list_tables() const { return list_tables(utility::string_t(), 0, table_request_options(), operation_context()); } /// - /// Returns a that can be used to to lazily enumerate a collection of tables that begin with the specified prefix. + /// Returns an that can be used to to lazily enumerate a collection of tables that begin with the specified prefix. /// - /// A that can be used to to lazily enumerate a collection of tables. + /// An that can be used to to lazily enumerate a collection of tables. table_result_iterator list_tables(const utility::string_t& prefix) const { return list_tables(prefix, 0, table_request_options(), operation_context()); } /// - /// Returns a that can be used to to lazily enumerate a collection of tables that begin with the specified prefix. + /// Returns an that can be used to to lazily enumerate a collection of tables that begin with the specified prefix. /// /// The table name prefix. /// A non-negative integer value that indicates the maximum number of results to be returned. /// If this value is zero, the maximum possible number of results will be returned. - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A that can be used to to lazily enumerate a collection of tables. + /// An that can be used to to lazily enumerate a collection of tables. WASTORAGE_API table_result_iterator list_tables(const utility::string_t& prefix, utility::size64_t max_results, const table_request_options& options, operation_context context) const; /// - /// Returns a containing an enumerable collection of tables. + /// Returns an containing an enumerable collection of tables. /// - /// A returned by a previous listing operation. - /// A containing an enumerable collection of tables. + /// An returned by a previous listing operation. + /// An containing an enumerable collection of tables. table_result_segment list_tables_segmented(const continuation_token& token) const { return list_tables_segmented_async(utility::string_t(), 0, token, table_request_options(), operation_context()).get(); } /// - /// Returns a containing an enumerable collection of tables that begin with the specified prefix. + /// Returns an containing an enumerable collection of tables that begin with the specified prefix. /// /// The table name prefix. - /// A returned by a previous listing operation. - /// A containing an enumerable collection of tables. + /// An returned by a previous listing operation. + /// An containing an enumerable collection of tables. table_result_segment list_tables_segmented(const utility::string_t& prefix, const continuation_token& token) const { return list_tables_segmented_async(prefix, 0, token, table_request_options(), operation_context()).get(); } /// - /// Returns a containing an enumerable collection of tables that begin with the specified prefix. + /// Returns an containing an enumerable collection of tables that begin with the specified prefix. /// /// The table name prefix. /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the /// per-operation limit of 1000. If this value is zero the maximum possible number of results will be returned, up to 1000. - /// A returned by a previous listing operation. - /// A object that specifies additional options for the request. + /// An returned by a previous listing operation. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A containing an enumerable collection of tables. + /// An containing an enumerable collection of tables. table_result_segment list_tables_segmented(const utility::string_t& prefix, int max_results, const continuation_token& token, const table_request_options& options, operation_context context) const { return list_tables_segmented_async(prefix, max_results, token, options, context).get(); } /// - /// Intitiates an asynchronous operation that returns a containing an enumerable collection of tables. + /// Intitiates an asynchronous operation that returns an containing an enumerable collection of tables. /// - /// A returned by a previous listing operation. - /// A object of type that represents the current operation. + /// An returned by a previous listing operation. + /// A object of type that represents the current operation. pplx::task list_tables_segmented_async(const continuation_token& token) const { return list_tables_segmented_async(utility::string_t(), 0, token, table_request_options(), operation_context()); } /// - /// Intitiates an asynchronous operation that returns a containing an enumerable collection of tables that begin with the specified prefix. + /// Intitiates an asynchronous operation that returns an containing an enumerable collection of tables that begin with the specified prefix. /// /// The table name prefix. - /// A returned by a previous listing operation. - /// A object of type that represents the current operation. + /// An returned by a previous listing operation. + /// A object of type that represents the current operation. pplx::task list_tables_segmented_async(const utility::string_t& prefix, const continuation_token& token) const { return list_tables_segmented_async(prefix, 0, token, table_request_options(), operation_context()); } /// - /// Intitiates an asynchronous operation that returns a containing an enumerable collection of tables that begin with the specified prefix. + /// Intitiates an asynchronous operation that returns an containing an enumerable collection of tables that begin with the specified prefix. /// /// The table name prefix. /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the /// per-operation limit of 1000. If this value is zero the maximum possible number of results will be returned, up to 1000. - /// A returned by a previous listing operation. - /// A object that specifies additional options for the request. + /// An returned by a previous listing operation. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. WASTORAGE_API pplx::task list_tables_segmented_async(const utility::string_t& prefix, int max_results, const continuation_token& token, const table_request_options& options, operation_context context) const; /// /// Gets the service properties for the Table service client. /// - /// The for the Table service client. + /// The for the Table service client. service_properties download_service_properties() const { return download_service_properties_async().get(); @@ -1812,9 +1813,9 @@ namespace azure { namespace storage { /// /// Gets the service properties for the Table service client. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// The for the Table service client. + /// The for the Table service client. service_properties download_service_properties(const table_request_options& options, operation_context context) const { return download_service_properties_async(options, context).get(); @@ -1823,7 +1824,7 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to get the properties of the service. /// - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. pplx::task download_service_properties_async() const { return download_service_properties_async(table_request_options(), operation_context()); @@ -1832,16 +1833,16 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to get the properties of the service. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. WASTORAGE_API pplx::task download_service_properties_async(const table_request_options& options, operation_context context) const; /// /// Sets the service properties for the Table service client. /// - /// The for the Table service client. - /// A enumeration describing which items to include when setting service properties. + /// The for the Table service client. + /// An enumeration describing which items to include when setting service properties. void upload_service_properties(const service_properties& properties, const service_properties_includes& includes) const { upload_service_properties_async(properties, includes).wait(); @@ -1850,9 +1851,9 @@ namespace azure { namespace storage { /// /// Sets the service properties for the Table service client. /// - /// The for the Table service client. - /// A enumeration describing which items to include when setting service properties. - /// A object that specifies additional options for the request. + /// The for the Table service client. + /// An enumeration describing which items to include when setting service properties. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void upload_service_properties(const service_properties& properties, const service_properties_includes& includes, const table_request_options& options, operation_context context) const { @@ -1862,8 +1863,8 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to set the service properties for the Table service client. /// - /// The for the Table service client. - /// A enumeration describing which items to include when setting service properties. + /// The for the Table service client. + /// An enumeration describing which items to include when setting service properties. /// A object that represents the current operation. pplx::task upload_service_properties_async(const service_properties& properties, const service_properties_includes& includes) const { @@ -1873,9 +1874,9 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to set the service properties for the Table service client. /// - /// The for the Table service client. - /// A enumeration describing which items to include when setting service properties. - /// A object that specifies additional options for the request. + /// The for the Table service client. + /// An enumeration describing which items to include when setting service properties. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. WASTORAGE_API pplx::task upload_service_properties_async(const service_properties& properties, const service_properties_includes& includes, const table_request_options& options, operation_context context) const; @@ -1883,7 +1884,7 @@ namespace azure { namespace storage { /// /// Gets the service stats for the Table service client. /// - /// The for the Table service client. + /// The for the Table service client. service_stats download_service_stats() const { return download_service_stats_async().get(); @@ -1892,9 +1893,9 @@ namespace azure { namespace storage { /// /// Gets the service stats for the Table service client. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// The for the Table service client. + /// The for the Table service client. service_stats download_service_stats(const table_request_options& options, operation_context context) const { return download_service_stats_async(options, context).get(); @@ -1903,7 +1904,7 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to get the stats of the service. /// - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. pplx::task download_service_stats_async() const { return download_service_stats_async(table_request_options(), operation_context()); @@ -1912,22 +1913,22 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation to get the stats of the service. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. WASTORAGE_API pplx::task download_service_stats_async(const table_request_options& options, operation_context context) const; /// /// Gets a reference to the specified table. /// /// The name of the table. - /// A reference to a object. + /// A reference to an object. WASTORAGE_API cloud_table get_table_reference(utility::string_t table_name) const; /// /// Returns the default set of request options. /// - /// A object. + /// An object. const table_request_options& default_request_options() const { return m_default_request_options; @@ -1962,14 +1963,14 @@ namespace azure { namespace storage { /// /// Initializes a new instance of the class using an absolute URI to the table. /// - /// A object containing the absolute URI to the table for all locations. + /// An object containing the absolute URI to the table for all locations. WASTORAGE_API cloud_table(const storage_uri& uri); /// /// Initializes a new instance of the class using an absolute URI to the table. /// - /// A object containing the absolute URI to the table for all locations. - /// The to use. + /// An object containing the absolute URI to the table for all locations. + /// The to use. WASTORAGE_API cloud_table(const storage_uri& uri, storage_credentials credentials); #if defined(_MSC_VER) && _MSC_VER < 1900 @@ -1977,19 +1978,19 @@ namespace azure { namespace storage { // have implicitly-declared move constructor and move assignment operator. /// - /// Initializes a new instance of the class based on an existing instance. + /// Initializes a new instance of the class based on an existing instance. /// - /// An existing object. + /// An existing object. cloud_table(cloud_table&& other) { *this = std::move(other); } /// - /// Returns a reference to a object. + /// Returns a reference to an object. /// - /// An existing object to use to set properties. - /// A object with properties set. + /// An existing object to use to set properties. + /// An object with properties set. cloud_table& operator=(cloud_table&& other) { if (this != &other) @@ -2005,8 +2006,8 @@ namespace azure { namespace storage { /// /// Executes an operation on a table. /// - /// A object that represents the operation to perform. - /// A containing the result of the operation. + /// An object that represents the operation to perform. + /// An containing the result of the operation. table_result execute(const table_operation& operation) const { return execute_async(operation, table_request_options(), operation_context()).get(); @@ -2015,10 +2016,10 @@ namespace azure { namespace storage { /// /// Executes an operation on a table. /// - /// A object that represents the operation to perform. - /// A object that specifies additional options for the request. + /// An object that represents the operation to perform. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. This object is used to track requests to the storage service, and to provide additional runtime information about the operation. - /// A containing the result of the operation. + /// An containing the result of the operation. table_result execute(const table_operation& operation, const table_request_options& options, operation_context context) const { return execute_async(operation, options, context).get(); @@ -2027,8 +2028,8 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation that executes an operation on a table. /// - /// A object that represents the operation to perform. - /// A object of type that represents the current operation. + /// An object that represents the operation to perform. + /// A object of type that represents the current operation. pplx::task execute_async(const table_operation& operation) const { return execute_async(operation, table_request_options(), operation_context()); @@ -2037,18 +2038,18 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation that executes an operation on a table. /// - /// A object that represents the operation to perform. - /// A object that specifies additional options for the request. + /// An object that represents the operation to perform. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. This object is used to track requests to the storage service, and to provide additional runtime information about the operation. - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. WASTORAGE_API pplx::task execute_async(const table_operation& operation, const table_request_options& options, operation_context context) const; /// /// Executes a batch operation on a table as an atomic operation. /// - /// A object that represents the operation to perform. - /// An enumerable collection of objects that contains the results, in order, - /// of each operation in the . + /// An object that represents the operation to perform. + /// An enumerable collection of objects that contains the results, in order, + /// of each operation in the . std::vector execute_batch(const table_batch_operation& operation) const { return execute_batch_async(operation, table_request_options(), operation_context()).get(); @@ -2057,11 +2058,11 @@ namespace azure { namespace storage { /// /// Executes a batch operation on a table as an atomic operation. /// - /// A object that represents the operation to perform. - /// A object that specifies additional options for the request. + /// An object that represents the operation to perform. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. This object is used to track requests to the storage service, and to provide additional runtime information about the operation. - /// An enumerable collection of objects that contains the results, in order, - /// of each operation in the . + /// An enumerable collection of objects that contains the results, in order, + /// of each operation in the . std::vector execute_batch(const table_batch_operation& operation, const table_request_options& options, operation_context context) const { return execute_batch_async(operation, options, context).get(); @@ -2070,8 +2071,8 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation that executes a batch operation on a table as an atomic operation. /// - /// A object that represents the operation to perform. - /// A object of type , of type , that represents the current operation. + /// An object that represents the operation to perform. + /// A object of type , of type , that represents the current operation. pplx::task> execute_batch_async(const table_batch_operation& operation) const { return execute_batch_async(operation, table_request_options(), operation_context()); @@ -2080,17 +2081,17 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation that executes a batch operation on a table as an atomic operation. /// - /// A object that represents the operation to perform. - /// A object that specifies additional options for the request. + /// An object that represents the operation to perform. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. This object is used to track requests to the storage service, and to provide additional runtime information about the operation. - /// A object of type , of type , that represents the current operation. + /// A object of type , of type , that represents the current operation. WASTORAGE_API pplx::task> execute_batch_async(const table_batch_operation& operation, const table_request_options& options, operation_context context) const; /// /// Executes a query on a table. /// - /// A object. - /// A that can be used to to lazily enumerate a collection of objects. + /// An object. + /// An that can be used to to lazily enumerate a collection of objects. table_query_iterator execute_query(const table_query& query) const { return execute_query(query, table_request_options(), operation_context()); @@ -2099,55 +2100,55 @@ namespace azure { namespace storage { /// /// Executes a query on a table. /// - /// A object. - /// A object that specifies additional options for the request. + /// An object. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. This object is used to track requests to the storage service, and to provide additional runtime information about the operation. - /// A that can be used to to lazily enumerate a collection of objects. + /// An that can be used to to lazily enumerate a collection of objects. WASTORAGE_API table_query_iterator execute_query(const table_query& query, const table_request_options& options, operation_context context) const; /// - /// Executes a query with the specified to retrieve the next page of results. + /// Executes a query with the specified to retrieve the next page of results. /// - /// A object. - /// A object. - /// A object containing the results of the query. + /// An object. + /// An object. + /// An object containing the results of the query. table_query_segment execute_query_segmented(const table_query& query, const continuation_token& token) const { return execute_query_segmented_async(query, token, table_request_options(), operation_context()).get(); } /// - /// Executes a query with the specified to retrieve the next page of results. + /// Executes a query with the specified to retrieve the next page of results. /// - /// A object. - /// A object. - /// A object that specifies additional options for the request. + /// An object. + /// An object. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. This object is used to track requests to the storage service, and to provide additional runtime information about the operation. - /// A object containing the results of the query. + /// An object containing the results of the query. table_query_segment execute_query_segmented(const table_query& query, const continuation_token& token, const table_request_options& options, operation_context context) const { return execute_query_segmented_async(query, token, options, context).get(); } /// - /// Intitiates an asynchronous operation that executes a query with the specified to retrieve the next page of results. + /// Intitiates an asynchronous operation that executes a query with the specified to retrieve the next page of results. /// - /// A object. - /// A object. - /// A object of type that represents the current operation. + /// An object. + /// An object. + /// A object of type that represents the current operation. pplx::task execute_query_segmented_async(const table_query& query, const continuation_token& token) const { return execute_query_segmented_async(query, token, table_request_options(), operation_context()); } /// - /// Intitiates an asynchronous operation that executes a query with the specified to retrieve the next page of results. + /// Intitiates an asynchronous operation that executes a query with the specified to retrieve the next page of results. /// - /// A object. - /// A object. - /// A object that specifies additional options for the request. + /// An object. + /// An object. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. This object is used to track requests to the storage service, and to provide additional runtime information about the operation. - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. WASTORAGE_API pplx::task execute_query_segmented_async(const table_query& query, const continuation_token& token, const table_request_options& options, operation_context context) const; /// @@ -2161,7 +2162,7 @@ namespace azure { namespace storage { /// /// Creates a table. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. This object is used to track requests to the storage service, and to provide additional runtime information about the operation. void create(const table_request_options& options, operation_context context) { @@ -2180,7 +2181,7 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation that creates a table. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. This object is used to track requests to the storage service, and to provide additional runtime information about the operation. /// A object that represents the current operation. WASTORAGE_API pplx::task create_async(const table_request_options& options, operation_context context); @@ -2197,7 +2198,7 @@ namespace azure { namespace storage { /// /// Creates the table if it does not already exist. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. This object is used to track requests to the storage service, and to provide additional runtime information about the operation. /// true if table was created; otherwise, false. bool create_if_not_exists(const table_request_options& options, operation_context context) @@ -2217,7 +2218,7 @@ namespace azure { namespace storage { /// /// Returns a task to create the table if it does not already exist. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. This object is used to track requests to the storage service, and to provide additional runtime information about the operation. /// A object that represents the current operation. WASTORAGE_API pplx::task create_if_not_exists_async(const table_request_options& options, operation_context context); @@ -2233,7 +2234,7 @@ namespace azure { namespace storage { /// /// Deletes a table. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. This object is used to track requests to the storage service, and to provide additional runtime information about the operation. void delete_table(const table_request_options& options, operation_context context) { @@ -2252,7 +2253,7 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation that deletes a table. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. This object is used to track requests to the storage service, and to provide additional runtime information about the operation. /// A object that represents the current operation. WASTORAGE_API pplx::task delete_table_async(const table_request_options& options, operation_context context); @@ -2269,7 +2270,7 @@ namespace azure { namespace storage { /// /// Deletes the table if it exists. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. This object is used to track requests to the storage service, and to provide additional runtime information about the operation. /// true if the table was deleted; otherwise, false. bool delete_table_if_exists(const table_request_options& options, operation_context context) @@ -2289,7 +2290,7 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation that deletes the table if it exists. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. This object is used to track requests to the storage service, and to provide additional runtime information about the operation. /// A object that represents the current operation. WASTORAGE_API pplx::task delete_table_if_exists_async(const table_request_options& options, operation_context context); @@ -2306,7 +2307,7 @@ namespace azure { namespace storage { /// /// Checks whether the table exists. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. This object is used to track requests to the storage service, and to provide additional runtime information about the operation. /// true if table exists; otherwise, false. bool exists(const table_request_options& options, operation_context context) const @@ -2326,7 +2327,7 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation that checks whether the table exists. /// - /// A object that specifies additional options for the request. + /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. This object is used to track requests to the storage service, and to provide additional runtime information about the operation. /// A object that represents the current operation. WASTORAGE_API pplx::task exists_async(const table_request_options& options, operation_context context) const; @@ -2334,7 +2335,7 @@ namespace azure { namespace storage { /// /// Gets the permissions settings for the table. /// - /// A object. + /// An object. table_permissions download_permissions() const { return download_permissions_async().get(); @@ -2345,7 +2346,7 @@ namespace azure { namespace storage { /// /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A object. + /// An object. table_permissions download_permissions(const table_request_options& options, operation_context context) const { return download_permissions_async(options, context).get(); @@ -2354,7 +2355,7 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation that gets the permissions settings for the table. /// - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. pplx::task download_permissions_async() const { return download_permissions_async(table_request_options(), operation_context()); @@ -2365,13 +2366,13 @@ namespace azure { namespace storage { /// /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. - /// A object of type that represents the current operation. + /// A object of type that represents the current operation. WASTORAGE_API pplx::task download_permissions_async(const table_request_options& options, operation_context context) const; /// /// Sets permissions for the table. /// - /// A object. + /// An object. void upload_permissions(const table_permissions& permissions) { upload_permissions_async(permissions).wait(); @@ -2380,7 +2381,7 @@ namespace azure { namespace storage { /// /// Sets permissions for the table. /// - /// A object. + /// An object. /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. void upload_permissions(const table_permissions& permissions, const table_request_options& options, operation_context context) @@ -2391,7 +2392,7 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation that sets permissions for the table. /// - /// A object. + /// An object. /// A object that represents the current operation. pplx::task upload_permissions_async(const table_permissions& permissions) { @@ -2401,7 +2402,7 @@ namespace azure { namespace storage { /// /// Intitiates an asynchronous operation that sets permissions for the table. /// - /// A object. + /// An object. /// An object that specifies additional options for the request. /// An object that represents the context for the current operation. /// A object that represents the current operation. @@ -2410,7 +2411,7 @@ namespace azure { namespace storage { /// /// Returns a shared access signature for the table. /// - /// The for the shared access signature. + /// The for the shared access signature. /// A string containing a shared access signature. utility::string_t get_shared_access_signature(const table_shared_access_policy& policy) const { @@ -2420,7 +2421,7 @@ namespace azure { namespace storage { /// /// Returns a shared access signature for the table. /// - /// The for the shared access signature. + /// The for the shared access signature. /// A string identifying a table-level access policy. /// A string containing a shared access signature. utility::string_t get_shared_access_signature(const table_shared_access_policy& policy, const utility::string_t& stored_policy_identifier) const @@ -2431,8 +2432,12 @@ namespace azure { namespace storage { /// /// Returns a shared access signature for the table. /// - /// The for the shared access signature. + /// The for the shared access signature. /// A string identifying a table-level access policy. + /// A string specifying the start partition key. + /// A string specifying the start row key. + /// A string specifying the end partition key. + /// A string specifying the end row key. /// A string containing a shared access signature. WASTORAGE_API utility::string_t get_shared_access_signature(const table_shared_access_policy& policy, const utility::string_t& stored_policy_identifier, const utility::string_t& start_partition_key, const utility::string_t& start_row_key, const utility::string_t& end_partition_key, const utility::string_t& end_row_key) const; @@ -2457,7 +2462,7 @@ namespace azure { namespace storage { /// /// Gets the table URI for all locations. /// - /// A object containing the absolute URI to the table for all locations. + /// An object containing the absolute URI to the table for all locations. const storage_uri& uri() const { return m_uri; diff --git a/Microsoft.WindowsAzure.Storage/includes/wascore/basic_types.h b/Microsoft.WindowsAzure.Storage/includes/wascore/basic_types.h index bb761880..282f8f41 100644 --- a/Microsoft.WindowsAzure.Storage/includes/wascore/basic_types.h +++ b/Microsoft.WindowsAzure.Storage/includes/wascore/basic_types.h @@ -30,6 +30,12 @@ #endif #endif +#ifdef WIN32 + #define DEPRECATED(message) __declspec(deprecated(message)) +#else + #define DEPRECATED(message) __attribute__((deprecated(message))) +#endif + #ifdef WIN32 #ifndef WIN32_LEAN_AND_MEAN diff --git a/Microsoft.WindowsAzure.Storage/includes/wascore/blobstreams.h b/Microsoft.WindowsAzure.Storage/includes/wascore/blobstreams.h index 01b9c022..10514222 100644 --- a/Microsoft.WindowsAzure.Storage/includes/wascore/blobstreams.h +++ b/Microsoft.WindowsAzure.Storage/includes/wascore/blobstreams.h @@ -456,4 +456,57 @@ namespace azure { namespace storage { namespace core { } }; + class basic_cloud_append_blob_ostreambuf : public basic_cloud_blob_ostreambuf + { + public: + basic_cloud_append_blob_ostreambuf(std::shared_ptr blob, const access_condition &condition, const blob_request_options& options, operation_context context) + : basic_cloud_blob_ostreambuf(condition, options, context), + m_blob(blob), m_current_blob_offset(condition.append_position() == -1 ? blob->properties().size() : condition.append_position()) + { + m_semaphore = async_semaphore(1); + } + + bool can_seek() const + { + return false; + } + + bool has_size() const + { + return false; + } + + utility::size64_t size() const + { + return (utility::size64_t)0; + } + + pos_type seekpos(pos_type pos, std::ios_base::openmode direction) + { + UNREFERENCED_PARAMETER(pos); + UNREFERENCED_PARAMETER(direction); + return (pos_type)traits::eof(); + } + + protected: + + pplx::task upload_buffer(); + pplx::task commit_blob(); + + private: + + std::shared_ptr m_blob; + int64_t m_current_blob_offset; + }; + + class cloud_append_blob_ostreambuf : public concurrency::streams::streambuf + { + public: + + cloud_append_blob_ostreambuf(std::shared_ptr blob, const access_condition &condition, const blob_request_options& options, operation_context context) + : concurrency::streams::streambuf(std::make_shared(blob, condition, options, context)) + { + } + }; + }}} // namespace azure::storage::core diff --git a/Microsoft.WindowsAzure.Storage/includes/wascore/constants.h b/Microsoft.WindowsAzure.Storage/includes/wascore/constants.h index c5cb8d7f..26b6016d 100644 --- a/Microsoft.WindowsAzure.Storage/includes/wascore/constants.h +++ b/Microsoft.WindowsAzure.Storage/includes/wascore/constants.h @@ -49,6 +49,11 @@ namespace azure { namespace storage { namespace protocol { const std::chrono::seconds minimum_fixed_lease_duration(15); const std::chrono::seconds maximum_fixed_lease_duration(60); + // service names + const utility::string_t service_blob(U("blob")); + const utility::string_t service_table(U("table")); + const utility::string_t service_queue(U("queue")); + // uri query parameters const utility::string_t uri_query_timeout(U("timeout")); const utility::string_t uri_query_resource_type(U("restype")); @@ -112,6 +117,7 @@ namespace azure { namespace storage { namespace protocol { const utility::string_t component_block_list(U("blocklist")); const utility::string_t component_page_list(U("pagelist")); const utility::string_t component_page(U("page")); + const utility::string_t component_append_block(U("appendblock")); const utility::string_t component_copy(U("copy")); const utility::string_t component_acl(U("acl")); @@ -140,6 +146,10 @@ namespace azure { namespace storage { namespace protocol { const utility::string_t ms_header_blob_content_type(U("x-ms-blob-content-type")); const utility::string_t ms_header_blob_sequence_number(U("x-ms-blob-sequence-number")); const utility::string_t ms_header_sequence_number_action(U("x-ms-sequence-number-action")); + const utility::string_t ms_header_blob_condition_maxsize(U("x-ms-blob-condition-maxsize")); + const utility::string_t ms_header_blob_condition_appendpos(U("x-ms-blob-condition-appendpos")); + const utility::string_t ms_header_blob_append_offset(U("x-ms-blob-append-offset")); + const utility::string_t ms_header_blob_committed_block_count(U("x-ms-blob-committed-block-count")); const utility::string_t ms_header_copy_id(U("x-ms-copy-id")); const utility::string_t ms_header_copy_completion_time(U("x-ms-copy-completion-time")); const utility::string_t ms_header_copy_action(U("x-ms-copy-action")); @@ -178,7 +188,7 @@ namespace azure { namespace storage { namespace protocol { const utility::string_t ms_header_time_next_visible(U("x-ms-time-next-visible")); // header values - const utility::string_t header_value_storage_version(U("2014-02-14")); + const utility::string_t header_value_storage_version(U("2015-02-21")); const utility::string_t header_value_true(U("true")); const utility::string_t header_value_false(U("false")); const utility::string_t header_value_locked(U("locked")); @@ -205,6 +215,7 @@ namespace azure { namespace storage { namespace protocol { const utility::string_t header_value_page_write_clear(U("Clear")); const utility::string_t header_value_blob_type_block(U("BlockBlob")); const utility::string_t header_value_blob_type_page(U("PageBlob")); + const utility::string_t header_value_blob_type_append(U("AppendBlob")); const utility::string_t header_value_snapshots_include(U("include")); const utility::string_t header_value_snapshots_only(U("only")); const utility::string_t header_value_sequence_max(U("max")); @@ -308,9 +319,9 @@ namespace azure { namespace storage { namespace protocol { // user agent #if defined(WIN32) - const utility::string_t header_value_user_agent(U("Azure-Storage/1.0.0 (Native; Windows)")); + const utility::string_t header_value_user_agent(U("Azure-Storage/2.0.0 (Native; Windows)")); #else - const utility::string_t header_value_user_agent(U("Azure-Storage/1.0.0 (Native)")); + const utility::string_t header_value_user_agent(U("Azure-Storage/2.0.0 (Native)")); #endif }}} // namespace azure::storage::protocol diff --git a/Microsoft.WindowsAzure.Storage/includes/wascore/executor.h b/Microsoft.WindowsAzure.Storage/includes/wascore/executor.h index da87714c..3e495929 100644 --- a/Microsoft.WindowsAzure.Storage/includes/wascore/executor.h +++ b/Microsoft.WindowsAzure.Storage/includes/wascore/executor.h @@ -149,15 +149,11 @@ namespace azure { namespace storage { namespace core { primary_or_secondary, }; - template - class executor; - - template - class storage_command + class storage_command_base { public: - explicit storage_command(const storage_uri& request_uri) + explicit storage_command_base(const storage_uri& request_uri) : m_request_uri(request_uri), m_location_mode(command_location_mode::primary_only) { } @@ -202,16 +198,6 @@ namespace azure { namespace storage { namespace core { m_recover_request = value; } - void set_preprocess_response(std::function value) - { - m_preprocess_response = value; - } - - void set_postprocess_response(std::function(const web::http::http_response &, const request_result&, const ostream_descriptor&, operation_context)> value) - { - m_postprocess_response = value; - } - void set_location_mode(command_location_mode value, storage_location lock_location = storage_location::unspecified) { switch (lock_location) @@ -242,34 +228,130 @@ namespace azure { namespace storage { namespace core { private: + virtual void preprocess_response(const web::http::http_response&, const request_result&, operation_context) = 0; + virtual pplx::task postprocess_response(const web::http::http_response&, const request_result&, const ostream_descriptor&, operation_context) = 0; + storage_uri m_request_uri; istream_descriptor m_request_body; concurrency::streams::ostream m_destination_stream; bool m_calculate_response_body_md5; command_location_mode m_location_mode; - std::function m_build_request; + std::function m_build_request; std::function m_sign_request; std::function m_recover_request; + + friend class executor_impl; + }; + + template + class storage_command : public storage_command_base + { + public: + + explicit storage_command(const storage_uri& request_uri) + : storage_command_base(request_uri) + { + } + + void set_preprocess_response(std::function value) + { + m_preprocess_response = value; + } + + void set_postprocess_response(std::function(const web::http::http_response&, const request_result&, const ostream_descriptor&, operation_context)> value) + { + m_postprocess_response = value; + } + + T&& result() + { + return std::move(m_result); + } + + private: + + virtual void preprocess_response(const web::http::http_response& response, const request_result& result, operation_context context) + { + if (m_preprocess_response != nullptr) + { + m_result = m_preprocess_response(response, result, context); + } + } + + virtual pplx::task postprocess_response(const web::http::http_response& response, const request_result& result, const ostream_descriptor& descriptor, operation_context context) + { + if (m_postprocess_response != nullptr) + { + return m_postprocess_response(response, result, descriptor, context).then([this](pplx::task task) + { + m_result = task.get(); + }); + } + + return pplx::task_from_result(); + } + std::function m_preprocess_response; std::function (const web::http::http_response&, const request_result&, const ostream_descriptor&, operation_context)> m_postprocess_response; + T m_result; + }; + + template<> + class storage_command : public storage_command_base + { + public: + + explicit storage_command(const storage_uri& request_uri) + : storage_command_base(request_uri) + { + } + + void set_preprocess_response(std::function value) + { + m_preprocess_response = value; + } + + void set_postprocess_response(std::function(const web::http::http_response&, const request_result&, const ostream_descriptor&, operation_context)> value) + { + m_postprocess_response = value; + } + + private: + virtual void preprocess_response(const web::http::http_response& response, const request_result& result, operation_context context) + { + if (m_preprocess_response != nullptr) + { + m_preprocess_response(response, result, context); + } + } + + virtual pplx::task postprocess_response(const web::http::http_response& response, const request_result& result, const ostream_descriptor& descriptor, operation_context context) + { + if (m_postprocess_response != nullptr) + { + return m_postprocess_response(response, result, descriptor, context); + } - friend class executor; + return pplx::task_from_result(); + } + + std::function m_preprocess_response; + std::function(const web::http::http_response&, const request_result&, const ostream_descriptor&, operation_context)> m_postprocess_response; }; - template - class executor + class executor_impl { public: - executor(std::shared_ptr> command, const request_options& options, operation_context context) + executor_impl(std::shared_ptr command, const request_options& options, operation_context context) : m_command(command), m_request_options(options), m_context(context), m_is_hashing_started(false), m_total_downloaded(0), m_retry_count(0), m_current_location(get_first_location(options.location_mode())), m_current_location_mode(options.location_mode()), m_retry_policy(options.retry_policy().clone()) { } - static pplx::task execute_async(std::shared_ptr> command, const request_options& options, operation_context context) + static pplx::task execute_async(std::shared_ptr command, const request_options& options, operation_context context) { if (!context.start_time().is_initialized()) { @@ -279,7 +361,7 @@ namespace azure { namespace storage { namespace core { // TODO: Use "it" variable name for iterators in for loops // TODO: Reduce usage of auto variable types - auto instance = std::make_shared>(command, options, context); + auto instance = std::make_shared(command, options, context); return pplx::details::do_while([instance]() -> pplx::task { // 0. Begin request @@ -388,7 +470,7 @@ namespace azure { namespace storage { namespace core { // This is when the status code will be checked and m_preprocess_response // will throw a storage_exception if it is not expected. instance->m_request_result = request_result(instance->m_start_time, instance->m_current_location, response, false); - instance->m_result = instance->m_command->m_preprocess_response(response, instance->m_request_result, instance->m_context); + instance->m_command->preprocess_response(response, instance->m_request_result, instance->m_context); if (logger::instance().should_log(instance->m_context, client_log_level::log_level_informational)) { @@ -451,48 +533,36 @@ namespace azure { namespace storage { namespace core { } } - // If the command asked for post-processing, it is now time to call m_postprocess_response - if (instance->m_command->m_postprocess_response) - { - if (logger::instance().should_log(instance->m_context, client_log_level::log_level_informational)) - { - logger::instance().log(instance->m_context, client_log_level::log_level_informational, U("Processing response body")); - } + // It is now time to call m_postprocess_response + // Finish the MD5 hash if MD5 was being calculated + instance->m_hash_provider.close(); + instance->m_is_hashing_started = false; - // Finish the MD5 hash if MD5 was being calculated - instance->m_hash_provider.close(); - instance->m_is_hashing_started = false; + ostream_descriptor descriptor; + if (instance->m_response_streambuf) + { + utility::size64_t total_downloaded = instance->m_total_downloaded + instance->m_response_streambuf.total_written(); + descriptor = ostream_descriptor(total_downloaded, instance->m_hash_provider.hash()); + } - ostream_descriptor descriptor; - if (instance->m_response_streambuf) + return instance->m_command->postprocess_response(response, instance->m_request_result, descriptor, instance->m_context).then([instance](pplx::task result_task) + { + try { - utility::size64_t total_downloaded = instance->m_total_downloaded + instance->m_response_streambuf.total_written(); - descriptor = ostream_descriptor(total_downloaded, instance->m_hash_provider.hash()); + result_task.get(); } - - return instance->m_command->m_postprocess_response(response, instance->m_request_result, descriptor, instance->m_context).then([instance](pplx::task result_task) + catch (const storage_exception& e) { - try + if (e.result().is_response_available()) { - instance->m_result = result_task.get(); + instance->m_request_result.set_http_status_code(e.result().http_status_code()); + instance->m_request_result.set_extended_error(e.result().extended_error()); } - catch (const storage_exception& e) - { - if (e.result().is_response_available()) - { - instance->m_request_result.set_http_status_code(e.result().http_status_code()); - instance->m_request_result.set_extended_error(e.result().extended_error()); - } - throw; - } + throw; + } - }); - } - else - { - return pplx::task_from_result(); - } + }); }).then([instance](pplx::task final_task) -> pplx::task { bool retryable_exception = true; @@ -582,7 +652,7 @@ namespace azure { namespace storage { namespace core { // Returning false here will cause do_while to exit. return pplx::task_from_result(false); }); - }).then([instance](pplx::task loop_task) -> T + }).then([instance](pplx::task loop_task) { instance->m_context.set_end_time(utility::datetime::utc_now()); loop_task.wait(); @@ -591,8 +661,6 @@ namespace azure { namespace storage { namespace core { { logger::instance().log(instance->m_context, client_log_level::log_level_informational, U("Operation completed successfully")); } - - return instance->m_result; }); } @@ -683,7 +751,7 @@ namespace azure { namespace storage { namespace core { { throw storage_exception(protocol::error_primary_only_command, false); } - + if (logger::instance().should_log(m_context, client_log_level::log_level_verbose)) { logger::instance().log(m_context, client_log_level::log_level_verbose, protocol::error_primary_only_command); @@ -721,7 +789,7 @@ namespace azure { namespace storage { namespace core { headers.add(name, value); } - + static std::exception_ptr capture_inner_exception(const std::exception& exception) { if (nullptr == dynamic_cast(&exception)) @@ -733,7 +801,7 @@ namespace azure { namespace storage { namespace core { return nullptr; } - std::shared_ptr> m_command; + std::shared_ptr m_command; request_options m_request_options; operation_context m_context; utility::datetime m_start_time; @@ -748,39 +816,18 @@ namespace azure { namespace storage { namespace core { int m_retry_count; storage_location m_current_location; location_mode m_current_location_mode; - T m_result; }; - typedef char void_command_type; - const void_command_type VOID_COMMAND_RESULT = 0; - - template<> - class storage_command : public storage_command + template + class executor { public: - - explicit storage_command(const storage_uri& request_uri) - : storage_command(request_uri) - { - } - - void set_preprocess_response(std::function value) - { - storage_command::set_preprocess_response([value] (const web::http::http_response& response, const request_result& result, operation_context context) -> void_command_type - { - value(response, result, context); - return VOID_COMMAND_RESULT; - }); - } - - void set_postprocess_response(std::function (const web::http::http_response &, const request_result&, const ostream_descriptor&, operation_context)> value) + static pplx::task execute_async(std::shared_ptr> command, const request_options& options, operation_context context) { - storage_command::set_postprocess_response([value] (const web::http::http_response& response, const request_result& result, const ostream_descriptor& descriptor, operation_context context) -> pplx::task + return executor_impl::execute_async(command, options, context).then([command](pplx::task task) -> T { - return value(response, result, descriptor, context).then([] () -> void_command_type - { - return VOID_COMMAND_RESULT; - }); + task.get(); + return command->result(); }); } }; @@ -791,7 +838,7 @@ namespace azure { namespace storage { namespace core { public: static pplx::task execute_async(std::shared_ptr> command, const request_options& options, operation_context context) { - return executor::execute_async(command, options, context).then([] (void_command_type) {}); + return executor_impl::execute_async(command, options, context); } }; diff --git a/Microsoft.WindowsAzure.Storage/includes/wascore/protocol.h b/Microsoft.WindowsAzure.Storage/includes/wascore/protocol.h index 6a59bc22..41c66f48 100644 --- a/Microsoft.WindowsAzure.Storage/includes/wascore/protocol.h +++ b/Microsoft.WindowsAzure.Storage/includes/wascore/protocol.h @@ -51,8 +51,10 @@ namespace azure { namespace storage { namespace protocol { web::http::http_request get_block_list(block_listing_filter listing_filter, const utility::string_t& snapshot_time, const access_condition& condition, web::http::uri_builder uri_builder, const std::chrono::seconds& timeout, operation_context context); web::http::http_request get_page_ranges(utility::size64_t offset, utility::size64_t length, const utility::string_t& snapshot_time, const access_condition& condition, web::http::uri_builder uri_builder, const std::chrono::seconds& timeout, operation_context context); web::http::http_request put_page(page_range range, page_write write, const utility::string_t& content_md5, const access_condition& condition, web::http::uri_builder uri_builder, const std::chrono::seconds& timeout, operation_context context); + web::http::http_request append_block(const utility::string_t& content_md5, const access_condition& condition, web::http::uri_builder uri_builder, const std::chrono::seconds& timeout, operation_context context); web::http::http_request put_block_blob(const cloud_blob_properties& properties, const cloud_metadata& metadata, const access_condition& condition, web::http::uri_builder uri_builder, const std::chrono::seconds& timeout, operation_context context); web::http::http_request put_page_blob(utility::size64_t size, int64_t sequence_number, const cloud_blob_properties& properties, const cloud_metadata& metadata, const access_condition& condition, web::http::uri_builder uri_builder, const std::chrono::seconds& timeout, operation_context context); + web::http::http_request put_append_blob(const cloud_blob_properties& properties, const cloud_metadata& metadata, const access_condition& condition, web::http::uri_builder uri_builder, const std::chrono::seconds& timeout, operation_context context); web::http::http_request get_blob(utility::size64_t offset, utility::size64_t length, bool get_range_content_md5, const utility::string_t& snapshot_time, const access_condition& condition, web::http::uri_builder uri_builder, const std::chrono::seconds& timeout, operation_context context); web::http::http_request get_blob_properties(const utility::string_t& snapshot_time, const access_condition& condition, web::http::uri_builder uri_builder, const std::chrono::seconds& timeout, operation_context context); web::http::http_request set_blob_properties(const cloud_blob_properties& properties, const cloud_metadata& metadata, const access_condition& condition, web::http::uri_builder uri_builder, const std::chrono::seconds& timeout, operation_context context); @@ -67,6 +69,7 @@ namespace azure { namespace storage { namespace protocol { void add_sequence_number_condition(web::http::http_request& request, const access_condition& condition); void add_access_condition(web::http::http_request& request, const access_condition& condition); void add_source_access_condition(web::http::http_request& request, const access_condition& condition); + void add_append_condition(web::http::http_request& request, const access_condition& condition); // Table request factory methods diff --git a/Microsoft.WindowsAzure.Storage/includes/wascore/resources.h b/Microsoft.WindowsAzure.Storage/includes/wascore/resources.h index d5a0b980..1a4a76e0 100644 --- a/Microsoft.WindowsAzure.Storage/includes/wascore/resources.h +++ b/Microsoft.WindowsAzure.Storage/includes/wascore/resources.h @@ -41,7 +41,7 @@ namespace azure { namespace storage { namespace protocol { const std::string error_uri_missing_location("The Uri for the target storage location is not specified. Please consider changing the request's location mode."); const std::string error_primary_only_command("This operation can only be executed against the primary storage location."); const std::string error_secondary_only_command("This operation can only be executed against the secondary storage location."); - const std::string error_md5_not_possible("MD5 is not supported for an existing page blobs."); + const std::string error_md5_not_possible("MD5 cannot be calculated for an existing page blob or append blob because it would require reading the existing data. Please disable store_blob_content_md5."); const std::string error_missing_params_for_sas("Missing mandatory parameters for valid Shared Access Signature."); const std::string error_md5_options_mismatch("When uploading a blob in a single request, store_blob_content_md5 must be set to true if use_transactional_md5 is true, because the MD5 calculated for the transaction will be stored in the blob."); const std::string error_storage_uri_empty("Primary or secondary location URI must be supplied."); @@ -83,4 +83,7 @@ namespace azure { namespace storage { namespace protocol { const std::string error_hash_on_closed_streambuf("Hash is calculated when the streambuf is closed."); const std::string error_invalid_settings_form("Settings must be of the form \"name=value\"."); + const std::string error_precondition_failure_ignored("Pre-condition failure on a retry is being ignored since the request should have succeeded in the first attempt."); + const std::string error_invalid_block_size("Append block data should not exceed the maximum blob size condition value."); + }}} // namespace azure::storage::protocol diff --git a/Microsoft.WindowsAzure.Storage/samples/BlobsGettingStarted/Application.cpp b/Microsoft.WindowsAzure.Storage/samples/BlobsGettingStarted/Application.cpp index 2bcb8d2f..ba3bbf5a 100644 --- a/Microsoft.WindowsAzure.Storage/samples/BlobsGettingStarted/Application.cpp +++ b/Microsoft.WindowsAzure.Storage/samples/BlobsGettingStarted/Application.cpp @@ -96,7 +96,27 @@ namespace azure { namespace storage { namespace samples { // Delete the blobs blob1.delete_blob(); blob2.delete_blob(); - blob3.delete_blob(); + blob3.delete_blob(); + + // Create an append blob + azure::storage::cloud_append_blob append_blob = container.get_append_blob_reference(U("my-append-1")); + append_blob.properties().set_content_type(U("text/plain; charset=utf-8")); + append_blob.create(); + + // Append two blocks + concurrency::streams::istream append_input_stream1 = concurrency::streams::bytestream::open_istream(utility::conversions::to_utf8string(U("some text."))); + concurrency::streams::istream append_input_stream2 = concurrency::streams::bytestream::open_istream(utility::conversions::to_utf8string(U("more text."))); + append_blob.append_block(append_input_stream1, utility::string_t()); + append_blob.append_block(append_input_stream2, utility::string_t()); + append_input_stream1.close().wait(); + append_input_stream2.close().wait(); + + // Download append blob as text + utility::string_t append_text = append_blob.download_text(); + ucout << U("Append Text: ") << append_text << std::endl; + + // Delete the blob + append_blob.delete_blob(); // Delete the blob container // Return value is true if the container did exist and was successfully deleted. diff --git a/Microsoft.WindowsAzure.Storage/src/CMakeLists.txt b/Microsoft.WindowsAzure.Storage/src/CMakeLists.txt index 1043f86d..3aa6dc5c 100644 --- a/Microsoft.WindowsAzure.Storage/src/CMakeLists.txt +++ b/Microsoft.WindowsAzure.Storage/src/CMakeLists.txt @@ -40,6 +40,7 @@ if(UNIX) cloud_blob_istreambuf.cpp cloud_blob_client.cpp cloud_blob.cpp + cloud_append_blob.cpp blob_response_parsers.cpp blob_request_factory.cpp basic_types.cpp diff --git a/Microsoft.WindowsAzure.Storage/src/authentication.cpp b/Microsoft.WindowsAzure.Storage/src/authentication.cpp index 7fdc81d7..69db4e30 100644 --- a/Microsoft.WindowsAzure.Storage/src/authentication.cpp +++ b/Microsoft.WindowsAzure.Storage/src/authentication.cpp @@ -105,6 +105,17 @@ namespace azure { namespace storage { namespace protocol { append(value); } + void canonicalizer_helper::append_content_length_header() + { + utility::string_t value; + m_request.headers().match(web::http::header_names::content_length, value); + if (value == U("0")) + { + value.clear(); + } + append(value); + } + void canonicalizer_helper::append_date_header(bool allow_x_ms_date) { utility::string_t value; @@ -148,7 +159,7 @@ namespace azure { namespace storage { namespace protocol { helper.append(request.method()); helper.append_header(web::http::header_names::content_encoding); helper.append_header(web::http::header_names::content_language); - helper.append_header(web::http::header_names::content_length); + helper.append_content_length_header(); helper.append_header(web::http::header_names::content_md5); helper.append_header(web::http::header_names::content_type); helper.append_date_header(false); diff --git a/Microsoft.WindowsAzure.Storage/src/blob_request_factory.cpp b/Microsoft.WindowsAzure.Storage/src/blob_request_factory.cpp index 3c4fa576..c8eeb97f 100644 --- a/Microsoft.WindowsAzure.Storage/src/blob_request_factory.cpp +++ b/Microsoft.WindowsAzure.Storage/src/blob_request_factory.cpp @@ -329,6 +329,16 @@ namespace azure { namespace storage { namespace protocol { return request; } + web::http::http_request append_block(const utility::string_t& content_md5, const access_condition& condition, web::http::uri_builder uri_builder, const std::chrono::seconds& timeout, operation_context context) + { + uri_builder.append_query(core::make_query_parameter(uri_query_component, component_append_block, /* do_encoding */ false)); + web::http::http_request request(base_request(web::http::methods::PUT, uri_builder, timeout, context)); + request.headers().add(web::http::header_names::content_md5, content_md5); + add_append_condition(request, condition); + add_access_condition(request, condition); + return request; + } + web::http::http_request put_block_blob(const cloud_blob_properties& properties, const cloud_metadata& metadata, const access_condition& condition, web::http::uri_builder uri_builder, const std::chrono::seconds& timeout, operation_context context) { web::http::http_request request(base_request(web::http::methods::PUT, uri_builder, timeout, context)); @@ -352,6 +362,16 @@ namespace azure { namespace storage { namespace protocol { return request; } + web::http::http_request put_append_blob(const cloud_blob_properties& properties, const cloud_metadata& metadata, const access_condition& condition, web::http::uri_builder uri_builder, const std::chrono::seconds& timeout, operation_context context) + { + web::http::http_request request(base_request(web::http::methods::PUT, uri_builder, timeout, context)); + request.headers().add(ms_header_blob_type, header_value_blob_type_append); + add_properties(request, properties); + add_metadata(request, metadata); + add_access_condition(request, condition); + return request; + } + web::http::http_request get_blob(utility::size64_t offset, utility::size64_t length, bool get_range_content_md5, const utility::string_t& snapshot_time, const access_condition& condition, web::http::uri_builder uri_builder, const std::chrono::seconds& timeout, operation_context context) { add_snapshot_time(uri_builder, snapshot_time); @@ -548,4 +568,17 @@ namespace azure { namespace storage { namespace protocol { } } + void add_append_condition(web::http::http_request& request, const access_condition& condition) + { + if (condition.max_size() != -1) + { + request.headers().add(ms_header_blob_condition_maxsize, condition.max_size()); + } + + if (condition.append_position() != -1) + { + request.headers().add(ms_header_blob_condition_appendpos, condition.append_position()); + } + } + }}} // namespace azure::storage::protocol diff --git a/Microsoft.WindowsAzure.Storage/src/blob_response_parsers.cpp b/Microsoft.WindowsAzure.Storage/src/blob_response_parsers.cpp index c9363c93..f11f2b9e 100644 --- a/Microsoft.WindowsAzure.Storage/src/blob_response_parsers.cpp +++ b/Microsoft.WindowsAzure.Storage/src/blob_response_parsers.cpp @@ -58,6 +58,10 @@ namespace azure { namespace storage { namespace protocol { { return blob_type::page_blob; } + else if (value == header_value_blob_type_append) + { + return blob_type::append_blob; + } else { return blob_type::unspecified; @@ -97,6 +101,7 @@ namespace azure { namespace storage { namespace protocol { auto& headers = response.headers(); properties.m_page_blob_sequence_number = utility::conversions::scan_string(get_header_value(headers, ms_header_blob_sequence_number)); + properties.m_append_blob_committed_block_count = utility::conversions::scan_string(get_header_value(headers, ms_header_blob_committed_block_count)); properties.m_cache_control = get_header_value(headers, web::http::header_names::cache_control); properties.m_content_disposition = get_header_value(headers, header_content_disposition); properties.m_content_encoding = get_header_value(headers, web::http::header_names::content_encoding); diff --git a/Microsoft.WindowsAzure.Storage/src/cloud_append_blob.cpp b/Microsoft.WindowsAzure.Storage/src/cloud_append_blob.cpp new file mode 100644 index 00000000..c48320a7 --- /dev/null +++ b/Microsoft.WindowsAzure.Storage/src/cloud_append_blob.cpp @@ -0,0 +1,218 @@ +// ----------------------------------------------------------------------------------------- +// +// Copyright 2013 Microsoft Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ----------------------------------------------------------------------------------------- + +#include "stdafx.h" +#include "wascore/protocol.h" +#include "wascore/protocol_xml.h" +#include "wascore/blobstreams.h" + +namespace azure { namespace storage { + + pplx::task cloud_append_blob::create_or_replace_async(const access_condition& condition, const blob_request_options& options, operation_context context) + { + assert_no_snapshot(); + blob_request_options modified_options(options); + modified_options.apply_defaults(service_client().default_request_options(), type()); + + auto properties = m_properties; + + auto command = std::make_shared>(uri()); + command->set_build_request(std::bind(protocol::put_append_blob, *properties, metadata(), condition, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + command->set_authentication_handler(service_client().authentication_handler()); + command->set_preprocess_response([properties](const web::http::http_response& response, const request_result& result, operation_context context) + { + protocol::preprocess_response_void(response, result, context); + properties->update_etag_and_last_modified(protocol::blob_response_parsers::parse_blob_properties(response)); + properties->m_size = 0; + }); + return core::executor::execute_async(command, modified_options, context); + } + + pplx::task cloud_append_blob::append_block_async(concurrency::streams::istream block_data, const utility::string_t& content_md5, const access_condition& condition, const blob_request_options& options, operation_context context) const + { + assert_no_snapshot(); + blob_request_options modified_options(options); + modified_options.apply_defaults(service_client().default_request_options(), type()); + + auto properties = m_properties; + bool needs_md5 = content_md5.empty() && modified_options.use_transactional_md5(); + + auto command = std::make_shared>(uri()); + command->set_authentication_handler(service_client().authentication_handler()); + command->set_preprocess_response([properties](const web::http::http_response& response, const request_result& result, operation_context context)->int64_t + { + protocol::preprocess_response_void(response, result, context); + + auto parsed_properties = protocol::blob_response_parsers::parse_blob_properties(response); + properties->update_etag_and_last_modified(parsed_properties); + properties->update_append_blob_committed_block_count(parsed_properties); + return utility::conversions::scan_string(protocol::get_header_value(response.headers(), protocol::ms_header_blob_append_offset)); + }); + return core::istream_descriptor::create(block_data, needs_md5).then([command, context, content_md5, modified_options, condition] (core::istream_descriptor request_body) -> pplx::task + { + const utility::string_t& md5 = content_md5.empty() ? request_body.content_md5() : content_md5; + command->set_build_request(std::bind(protocol::append_block, md5, condition, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + command->set_request_body(request_body); + return core::executor::execute_async(command, modified_options, context); + }); + } + + pplx::task cloud_append_blob::download_text_async(const access_condition& condition, const blob_request_options& options, operation_context context) + { + auto properties = m_properties; + + concurrency::streams::container_buffer> buffer; + return download_to_stream_async(buffer.create_ostream(), condition, options, context).then([buffer, properties] () mutable -> utility::string_t + { + if (properties->content_type() != protocol::header_value_content_type_utf8) + { + throw std::logic_error(protocol::error_unsupported_text_blob); + } + + std::string utf8_body(reinterpret_cast(buffer.collection().data()), static_cast(buffer.size())); + return utility::conversions::to_string_t(utf8_body); + }); + } + + pplx::task cloud_append_blob::open_write_async(bool create_new, const access_condition& condition, const blob_request_options& options, operation_context context) + { + assert_no_snapshot(); + blob_request_options modified_options(options); + modified_options.apply_defaults(service_client().default_request_options(), type(), false); + + pplx::task create_task; + if (create_new) + { + create_task = create_or_replace_async(condition, modified_options, context); + } + else + { + if (modified_options.store_blob_content_md5()) + { + throw std::logic_error(protocol::error_md5_not_possible); + } + + create_task = download_attributes_async(condition, modified_options, context); + } + + auto instance = std::make_shared(*this); + return create_task.then([instance, condition, modified_options, context]() + { + auto modified_condition = access_condition::generate_lease_condition(condition.lease_id()); + if (condition.max_size() != -1) + { + modified_condition.set_max_size(condition.max_size()); + } + + if (condition.append_position() != -1) + { + modified_condition.set_append_position(condition.append_position()); + } + + return core::cloud_append_blob_ostreambuf(instance, modified_condition, modified_options, context).create_ostream(); + }); + } + + pplx::task cloud_append_blob::upload_from_stream_async(concurrency::streams::istream source, utility::size64_t length, const access_condition& condition, const blob_request_options& options, operation_context context) + { + return upload_from_stream_internal_async(source, length, true, condition, options, context); + } + + pplx::task cloud_append_blob::upload_from_stream_internal_async(concurrency::streams::istream source, utility::size64_t length, bool create_new, const access_condition& condition, const blob_request_options& options, operation_context context) + { + assert_no_snapshot(); + blob_request_options modified_options(options); + modified_options.apply_defaults(service_client().default_request_options(), type()); + + // This will be std::numeric_limits::max() if the stream is not seekable. + utility::size64_t remaining_stream_length = core::get_remaining_stream_length(source); + + // Before this line, 'length = max' means "no length was given by the user." After this line, 'length = max' means "no length was given, and the stream is not seekable." + if (length == std::numeric_limits::max()) + { + length = remaining_stream_length; + } + + // If the stream is seekable, check for the case where the stream is too short. + // If the stream is not seekable, this will be caught later, when we run out of bytes in the stream when uploading. + if (source.can_seek() && (length > remaining_stream_length)) + { + throw std::invalid_argument(protocol::error_stream_short); + } + + return open_write_async(create_new, condition, modified_options, context).then([source, length](concurrency::streams::ostream blob_stream) -> pplx::task + { + return core::stream_copy_async(source, blob_stream, length).then([blob_stream](utility::size64_t) -> pplx::task + { + return blob_stream.close(); + }); + }); + } + + pplx::task cloud_append_blob::upload_from_file_async(const utility::string_t &path, const access_condition& condition, const blob_request_options& options, operation_context context) + { + auto instance = std::make_shared(*this); + return concurrency::streams::file_stream::open_istream(path).then([instance, condition, options, context](concurrency::streams::istream stream) -> pplx::task + { + return instance->upload_from_stream_async(stream, condition, options, context).then([stream](pplx::task upload_task) -> pplx::task + { + return stream.close().then([upload_task]() + { + upload_task.wait(); + }); + }); + }); + } + + pplx::task cloud_append_blob::upload_text_async(const utility::string_t& content, const access_condition& condition, const blob_request_options& options, operation_context context) + { + auto utf8_body = utility::conversions::to_utf8string(content); + auto length = utf8_body.size(); + auto stream = concurrency::streams::bytestream::open_istream(std::move(utf8_body)); + m_properties->set_content_type(protocol::header_value_content_type_utf8); + return upload_from_stream_async(stream, length, condition, options, context); + } + + pplx::task cloud_append_blob::append_from_stream_async(concurrency::streams::istream source, utility::size64_t length, const access_condition& condition, const blob_request_options& options, operation_context context) + { + return upload_from_stream_internal_async(source, length, false, condition, options, context); + } + + pplx::task cloud_append_blob::append_from_file_async(const utility::string_t &path, const access_condition& condition, const blob_request_options& options, operation_context context) + { + auto instance = std::make_shared(*this); + return concurrency::streams::file_stream::open_istream(path).then([instance, condition, options, context](concurrency::streams::istream stream) -> pplx::task + { + return instance->append_from_stream_async(stream, condition, options, context).then([stream](pplx::task upload_task) -> pplx::task + { + return stream.close().then([upload_task]() + { + upload_task.wait(); + }); + }); + }); + } + + pplx::task cloud_append_blob::append_text_async(const utility::string_t& content, const access_condition& condition, const blob_request_options& options, operation_context context) + { + auto utf8_body = utility::conversions::to_utf8string(content); + auto length = utf8_body.size(); + auto stream = concurrency::streams::bytestream::open_istream(std::move(utf8_body)); + m_properties->set_content_type(protocol::header_value_content_type_utf8); + return append_from_stream_async(stream, length, condition, options, context); + } +}} // namespace azure::storage diff --git a/Microsoft.WindowsAzure.Storage/src/cloud_blob.cpp b/Microsoft.WindowsAzure.Storage/src/cloud_blob.cpp index 6a827203..06a48039 100644 --- a/Microsoft.WindowsAzure.Storage/src/cloud_blob.cpp +++ b/Microsoft.WindowsAzure.Storage/src/cloud_blob.cpp @@ -111,8 +111,9 @@ namespace azure { namespace storage { throw std::logic_error(protocol::error_sas_missing_credentials); } + // since 2015-02-21, canonicalized resource is changed from "/account/container/name" to "/blob/account/container/name" utility::ostringstream_t resource_str; - resource_str << U('/') << service_client().credentials().account_name() << U('/') << container().name() << U('/') << name(); + resource_str << U('/') << protocol::service_blob << U('/') << service_client().credentials().account_name() << U('/') << container().name() << U('/') << name(); return protocol::get_blob_sas_token(stored_policy_identifier, policy, headers, U("b"), resource_str.str(), service_client().credentials()); } @@ -530,11 +531,11 @@ namespace azure { namespace storage { auto instance = std::make_shared(*this); return concurrency::streams::file_stream::open_ostream(path).then([instance, condition, options, context] (concurrency::streams::ostream stream) -> pplx::task { - return instance->download_to_stream_async(stream, condition, options, context).then([stream] (pplx::task download_task) -> pplx::task + return instance->download_to_stream_async(stream, condition, options, context).then([stream] (pplx::task upload_task) -> pplx::task { - return stream.close().then([download_task] () + return stream.close().then([upload_task]() { - download_task.wait(); + upload_task.wait(); }); }); }); @@ -569,7 +570,7 @@ namespace azure { namespace storage { return core::executor::execute_async(command, modified_options, context); } - pplx::task cloud_blob::start_copy_from_blob_async(const web::http::uri& source, const access_condition& source_condition, const access_condition& destination_condition, const blob_request_options& options, operation_context context) + pplx::task cloud_blob::start_copy_async(const web::http::uri& source, const access_condition& source_condition, const access_condition& destination_condition, const blob_request_options& options, operation_context context) { assert_no_snapshot(); blob_request_options modified_options(options); @@ -592,12 +593,12 @@ namespace azure { namespace storage { return core::executor::execute_async(command, modified_options, context); } - pplx::task cloud_blob::start_copy_from_blob_async(const cloud_blob& source, const access_condition& source_condition, const access_condition& destination_condition, const blob_request_options& options, operation_context context) + pplx::task cloud_blob::start_copy_async(const cloud_blob& source, const access_condition& source_condition, const access_condition& destination_condition, const blob_request_options& options, operation_context context) { web::http::uri raw_source_uri = source.snapshot_qualified_uri().primary_uri(); web::http::uri source_uri = service_client().credentials().transform_uri(raw_source_uri); - return start_copy_from_blob_async(source_uri, source_condition, destination_condition, options, context); + return start_copy_async(source_uri, source_condition, destination_condition, options, context); } pplx::task cloud_blob::abort_copy_async(const utility::string_t& copy_id, const access_condition& condition, const blob_request_options& options, operation_context context) const diff --git a/Microsoft.WindowsAzure.Storage/src/cloud_blob_container.cpp b/Microsoft.WindowsAzure.Storage/src/cloud_blob_container.cpp index 78184063..32224d96 100644 --- a/Microsoft.WindowsAzure.Storage/src/cloud_blob_container.cpp +++ b/Microsoft.WindowsAzure.Storage/src/cloud_blob_container.cpp @@ -69,9 +69,11 @@ namespace azure { namespace storage { throw std::logic_error(protocol::error_sas_missing_credentials); } + // since 2015-02-21, canonicalized resource is changed from "/account/name" to "/blob/account/name" utility::ostringstream_t resource_str; - resource_str << U('/') << service_client().credentials().account_name() << U('/') << name(); + resource_str << U('/') << protocol::service_blob << U('/') << service_client().credentials().account_name() << U('/') << name(); + // Future resource type changes from "c" => "container" return protocol::get_blob_sas_token(stored_policy_identifier, policy, cloud_blob_shared_access_headers(), U("c"), resource_str.str(), service_client().credentials()); } @@ -105,6 +107,16 @@ namespace azure { namespace storage { return cloud_block_blob(std::move(blob_name), std::move(snapshot_time), *this); } + cloud_append_blob cloud_blob_container::get_append_blob_reference(utility::string_t blob_name) const + { + return get_append_blob_reference(std::move(blob_name), utility::string_t()); + } + + cloud_append_blob cloud_blob_container::get_append_blob_reference(utility::string_t blob_name, utility::string_t snapshot_time) const + { + return cloud_append_blob(std::move(blob_name), std::move(snapshot_time), *this); + } + cloud_blob_directory cloud_blob_container::get_directory_reference(utility::string_t directory_name) const { return cloud_blob_directory(std::move(directory_name), *this); diff --git a/Microsoft.WindowsAzure.Storage/src/cloud_blob_directory.cpp b/Microsoft.WindowsAzure.Storage/src/cloud_blob_directory.cpp index d9861331..8127ca91 100644 --- a/Microsoft.WindowsAzure.Storage/src/cloud_blob_directory.cpp +++ b/Microsoft.WindowsAzure.Storage/src/cloud_blob_directory.cpp @@ -64,6 +64,16 @@ namespace azure { namespace storage { return cloud_block_blob(m_name + blob_name, std::move(snapshot_time), m_container); } + cloud_append_blob cloud_blob_directory::get_append_blob_reference(utility::string_t blob_name) const + { + return get_block_blob_reference(std::move(blob_name), utility::string_t()); + } + + cloud_append_blob cloud_blob_directory::get_append_blob_reference(utility::string_t blob_name, utility::string_t snapshot_time) const + { + return cloud_append_blob(m_name + blob_name, std::move(snapshot_time), m_container); + } + cloud_blob_directory cloud_blob_directory::get_subdirectory_reference(utility::string_t name) const { return cloud_blob_directory(m_name + name, m_container); diff --git a/Microsoft.WindowsAzure.Storage/src/cloud_blob_ostreambuf.cpp b/Microsoft.WindowsAzure.Storage/src/cloud_blob_ostreambuf.cpp index af764672..eba97051 100644 --- a/Microsoft.WindowsAzure.Storage/src/cloud_blob_ostreambuf.cpp +++ b/Microsoft.WindowsAzure.Storage/src/cloud_blob_ostreambuf.cpp @@ -16,7 +16,9 @@ // ----------------------------------------------------------------------------------------- #include "stdafx.h" +#include "was/error_code_strings.h" #include "wascore/blobstreams.h" +#include "wascore/logging.h" #include "wascore/resources.h" namespace azure { namespace storage { namespace core { @@ -260,4 +262,93 @@ namespace azure { namespace storage { namespace core { } } + pplx::task basic_cloud_append_blob_ostreambuf::upload_buffer() + { + auto buffer = prepare_buffer(); + if (buffer->is_empty()) + { + return pplx::task_from_result(); + } + + auto offset = m_current_blob_offset; + m_current_blob_offset += buffer->size(); + + if (m_condition.max_size() != -1 && m_current_blob_offset > m_condition.max_size()) + { + m_currentException = std::make_exception_ptr(std::invalid_argument(protocol::error_invalid_block_size)); + return pplx::task_from_result(); + } + + auto this_pointer = std::dynamic_pointer_cast(shared_from_this()); + return m_semaphore.lock_async().then([this_pointer, buffer, offset]() + { + if (this_pointer->m_currentException == nullptr) + { + try + { + this_pointer->m_condition.set_append_position(offset); + auto previous_results_count = this_pointer->m_context.request_results().size(); + this_pointer->m_blob->append_block_async(buffer->stream(), buffer->content_md5(), this_pointer->m_condition, this_pointer->m_options, this_pointer->m_context).then([this_pointer, previous_results_count](pplx::task upload_task) + { + std::lock_guard guard(this_pointer->m_semaphore, std::adopt_lock); + try + { + upload_task.wait(); + } + catch (const azure::storage::storage_exception& ex) + { + if (this_pointer->m_options.absorb_conditional_errors_on_retry() + && ex.result().http_status_code() == web::http::status_codes::PreconditionFailed + && (ex.result().extended_error().code() == protocol::error_code_invalid_append_condition || ex.result().extended_error().code() == protocol::error_invalid_max_blob_size_condition) + && this_pointer->m_context.request_results().size() - previous_results_count > 1) + { + // Pre-condition failure on a retry should be ignored in a single writer scenario since the request + // succeeded in the first attempt. + if (logger::instance().should_log(this_pointer->m_context, client_log_level::log_level_warning)) + { + logger::instance().log(this_pointer->m_context, client_log_level::log_level_warning, protocol::error_precondition_failure_ignored); + } + } + else + { + this_pointer->m_currentException = std::current_exception(); + } + } + catch (const std::exception&) + { + this_pointer->m_currentException = std::current_exception(); + } + }); + } + catch (...) + { + this_pointer->m_semaphore.unlock(); + } + } + else + { + this_pointer->m_semaphore.unlock(); + } + }); + } + + pplx::task basic_cloud_append_blob_ostreambuf::commit_blob() + { + if (m_blob_hash_provider.is_enabled()) + { + auto this_pointer = std::dynamic_pointer_cast(shared_from_this()); + return _sync().then([this_pointer](bool) -> pplx::task + { + this_pointer->m_blob->properties().set_content_md5(this_pointer->m_blob_hash_provider.hash()); + return this_pointer->m_blob->upload_properties_async(this_pointer->m_condition, this_pointer->m_options, this_pointer->m_context); + }); + } + else + { + return _sync().then([](bool) + { + }); + } + } + }}} // namespace azure::storage::core diff --git a/Microsoft.WindowsAzure.Storage/src/cloud_blob_shared.cpp b/Microsoft.WindowsAzure.Storage/src/cloud_blob_shared.cpp index 8cb948cf..7cd89a3d 100644 --- a/Microsoft.WindowsAzure.Storage/src/cloud_blob_shared.cpp +++ b/Microsoft.WindowsAzure.Storage/src/cloud_blob_shared.cpp @@ -59,6 +59,11 @@ namespace azure { namespace storage { m_page_blob_sequence_number = parsed_properties.page_blob_sequence_number(); } + void cloud_blob_properties::update_append_blob_committed_block_count(const cloud_blob_properties& parsed_properties) + { + m_append_blob_committed_block_count = parsed_properties.append_blob_committed_block_count(); + } + void cloud_blob_properties::update_all(const cloud_blob_properties& parsed_properties, bool ignore_md5) { if ((type() != blob_type::unspecified) && (type() != parsed_properties.type())) diff --git a/Microsoft.WindowsAzure.Storage/src/cloud_block_blob.cpp b/Microsoft.WindowsAzure.Storage/src/cloud_block_blob.cpp index eb2e1448..765eb778 100644 --- a/Microsoft.WindowsAzure.Storage/src/cloud_block_blob.cpp +++ b/Microsoft.WindowsAzure.Storage/src/cloud_block_blob.cpp @@ -205,7 +205,7 @@ namespace azure { namespace storage { { return instance->upload_from_stream_async(stream, condition, options, context).then([stream] (pplx::task upload_task) -> pplx::task { - return stream.close().then([upload_task] () + return stream.close().then([upload_task]() { upload_task.wait(); }); diff --git a/Microsoft.WindowsAzure.Storage/src/cloud_page_blob.cpp b/Microsoft.WindowsAzure.Storage/src/cloud_page_blob.cpp index fa52ad7e..05e1afbc 100644 --- a/Microsoft.WindowsAzure.Storage/src/cloud_page_blob.cpp +++ b/Microsoft.WindowsAzure.Storage/src/cloud_page_blob.cpp @@ -139,7 +139,7 @@ namespace azure { namespace storage { { return instance->upload_from_stream_async(stream, sequence_number, condition, options, context).then([stream](pplx::task upload_task) -> pplx::task { - return stream.close().then([upload_task] () + return stream.close().then([upload_task]() { upload_task.wait(); }); diff --git a/Microsoft.WindowsAzure.Storage/src/cloud_queue.cpp b/Microsoft.WindowsAzure.Storage/src/cloud_queue.cpp index d7602536..5f4e9b48 100644 --- a/Microsoft.WindowsAzure.Storage/src/cloud_queue.cpp +++ b/Microsoft.WindowsAzure.Storage/src/cloud_queue.cpp @@ -395,8 +395,9 @@ namespace azure { namespace storage { throw std::logic_error(protocol::error_sas_missing_credentials); } + // since 2015-02-21, canonicalized resource is changed from "/account/name" to "/queue/account/name" utility::ostringstream_t resource_str; - resource_str << U('/') << service_client().credentials().account_name() << U('/') << name(); + resource_str << U('/') << protocol::service_queue << U('/') << service_client().credentials().account_name() << U('/') << name(); return protocol::get_queue_sas_token(stored_policy_identifier, policy, resource_str.str(), service_client().credentials()); } diff --git a/Microsoft.WindowsAzure.Storage/src/cloud_table.cpp b/Microsoft.WindowsAzure.Storage/src/cloud_table.cpp index ce578fae..d740c5a5 100644 --- a/Microsoft.WindowsAzure.Storage/src/cloud_table.cpp +++ b/Microsoft.WindowsAzure.Storage/src/cloud_table.cpp @@ -108,7 +108,7 @@ namespace azure { namespace storage { bool allow_not_found = operation.operation_type() == table_operation_type::retrieve_operation; std::shared_ptr> command = std::make_shared>(uri); - command->set_build_request(std::bind(protocol::execute_operation, operation, options.payload_format(), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + command->set_build_request(std::bind(protocol::execute_operation, operation, modified_options.payload_format(), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); command->set_authentication_handler(service_client().authentication_handler()); command->set_location_mode(operation.operation_type() == azure::storage::table_operation_type::retrieve_operation ? core::command_location_mode::primary_or_secondary : core::command_location_mode::primary_only); command->set_preprocess_response([allow_not_found] (const web::http::http_response& response, const request_result& result, operation_context context) -> table_result @@ -229,7 +229,7 @@ namespace azure { namespace storage { storage_uri uri = protocol::generate_table_uri(service_client(), *this, query, token); std::shared_ptr> command = std::make_shared>(uri); - command->set_build_request(std::bind(protocol::execute_query, options.payload_format(), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + command->set_build_request(std::bind(protocol::execute_query, modified_options.payload_format(), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); command->set_authentication_handler(service_client().authentication_handler()); command->set_location_mode(core::command_location_mode::primary_or_secondary, token.target_location()); command->set_preprocess_response(std::bind(protocol::preprocess_response, table_query_segment(), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); @@ -257,8 +257,9 @@ namespace azure { namespace storage { utility::string_t table_name = name(); std::transform(table_name.begin(), table_name.end(), table_name.begin(), core::utility_char_tolower); + // since 2015-02-21, canonicalized resource is changed from "/account/name" to "/table/account/name" utility::ostringstream_t resource_str; - resource_str << U('/') << service_client().credentials().account_name() << U('/') << table_name; + resource_str << U('/') << protocol::service_table << U('/') << service_client().credentials().account_name() << U('/') << table_name; return protocol::get_table_sas_token(stored_policy_identifier, policy, name(), start_partition_key, start_row_key, end_partition_key, end_row_key, resource_str.str(), service_client().credentials()); } diff --git a/Microsoft.WindowsAzure.Storage/src/cloud_table_client.cpp b/Microsoft.WindowsAzure.Storage/src/cloud_table_client.cpp index baf58a75..915f2807 100644 --- a/Microsoft.WindowsAzure.Storage/src/cloud_table_client.cpp +++ b/Microsoft.WindowsAzure.Storage/src/cloud_table_client.cpp @@ -64,7 +64,7 @@ namespace azure { namespace storage { } auto instance = std::make_shared(*this); - return table.execute_query_segmented_async(query, token, options, context).then([instance] (table_query_segment query_segment) -> table_result_segment + return table.execute_query_segmented_async(query, token, modified_options, context).then([instance] (table_query_segment query_segment) -> table_result_segment { std::vector query_results = query_segment.results(); @@ -102,8 +102,7 @@ namespace azure { namespace storage { pplx::task cloud_table_client::download_service_stats_async(const table_request_options& options, operation_context context) const { - table_request_options modified_options(options); - modified_options.apply_defaults(default_request_options()); + table_request_options modified_options = get_modified_options(options); return download_service_stats_base_async(modified_options, context); } diff --git a/Microsoft.WindowsAzure.Storage/src/navigation.cpp b/Microsoft.WindowsAzure.Storage/src/navigation.cpp index 969af67c..bab0c941 100644 --- a/Microsoft.WindowsAzure.Storage/src/navigation.cpp +++ b/Microsoft.WindowsAzure.Storage/src/navigation.cpp @@ -169,13 +169,11 @@ namespace azure { namespace storage { namespace core { storage_credentials parsed_credentials = protocol::parse_query(uri, require_signed_resource); if (parsed_credentials.is_sas()) { - if (credentials.is_shared_key() || (credentials.is_sas() && credentials.sas_token() != parsed_credentials.sas_token())) + if (credentials.is_shared_key() || credentials.is_sas()) { throw std::invalid_argument(protocol::error_multiple_credentials); } - // TODO: Consider if it is OK here to override explicitly given anonymous credentials with the parsed SAS credentials (the .Net Library does not) - // Overwrite the given credentials with the SAS credentials read from the URI credentials = parsed_credentials; } diff --git a/Microsoft.WindowsAzure.Storage/src/shared_access_signature.cpp b/Microsoft.WindowsAzure.Storage/src/shared_access_signature.cpp index 8ba5bdc6..4e82dfbd 100644 --- a/Microsoft.WindowsAzure.Storage/src/shared_access_signature.cpp +++ b/Microsoft.WindowsAzure.Storage/src/shared_access_signature.cpp @@ -21,6 +21,7 @@ #include "was/blob.h" #include "was/queue.h" #include "was/table.h" +#include "wascore/logging.h" #include "wascore/util.h" #include "wascore/resources.h" @@ -41,6 +42,17 @@ namespace azure { namespace storage { namespace protocol { return value.is_initialized() ? core::truncate_fractional_seconds(value).to_string(utility::datetime::ISO_8601) : utility::string_t(); } + void log_sas_string_to_sign(const utility::string_t& string_to_sign) + { + operation_context context; + if (core::logger::instance().should_log(context, client_log_level::log_level_verbose)) + { + utility::string_t with_dots(string_to_sign); + std::replace(with_dots.begin(), with_dots.end(), U('\n'), U('.')); + core::logger::instance().log(context, client_log_level::log_level_verbose, U("StringToSign: ") + with_dots); + } + } + web::http::uri_builder get_sas_token_builder(const utility::string_t& identifier, const shared_access_policy& policy, const utility::string_t& signature) { web::http::uri_builder builder; @@ -71,56 +83,49 @@ namespace azure { namespace storage { namespace protocol { storage_credentials parse_query(const web::http::uri& uri, bool require_signed_resource) { - // Order of the strings in the sas_parameters vector is per MSDN's - // definition of Shared Access Signatures. - const utility::string_t sas_parameters[] = { - protocol::uri_query_sas_version, - protocol::uri_query_sas_resource, - protocol::uri_query_sas_table_name, - protocol::uri_query_sas_start, - protocol::uri_query_sas_expiry, - protocol::uri_query_sas_permissions, - protocol::uri_query_sas_start_partition_key, - protocol::uri_query_sas_start_row_key, - protocol::uri_query_sas_end_partition_key, - protocol::uri_query_sas_end_row_key, - protocol::uri_query_sas_identifier, - protocol::uri_query_sas_cache_control, - protocol::uri_query_sas_content_disposition, - protocol::uri_query_sas_content_encoding, - protocol::uri_query_sas_content_language, - protocol::uri_query_sas_content_type, - protocol::uri_query_sas_signature, - }; - - const int sas_parameters_size = (int) (sizeof(sas_parameters) / sizeof(sas_parameters[0])); - + bool sas_parameter_found = false; auto splitted_query = web::http::uri::split_query(uri.query()); - - bool params_found = false; - web::http::uri_builder builder; - for (int i = 0; i < sas_parameters_size; ++i) + std::vector remove_list; + for (auto iter = splitted_query.cbegin(); iter != splitted_query.cend(); ++iter) { - auto param = splitted_query.find(sas_parameters[i]); - if (param != splitted_query.end()) + utility::string_t query_key = iter->first; + std::transform(query_key.begin(), query_key.end(), query_key.begin(), core::utility_char_tolower); + + if (query_key == protocol::uri_query_sas_signature) + { + sas_parameter_found = true; + } + else if (query_key == protocol::uri_query_resource_type || + query_key == protocol::uri_query_component || + query_key == protocol::uri_query_snapshot || + query_key == protocol::uri_query_sas_api_version) { - params_found = true; - add_query_if_not_empty(builder, param->first, param->second, /* do_encoding */ false); + remove_list.push_back(iter->first); } } - if (!params_found) + if (!sas_parameter_found) { return storage_credentials(); } - auto signature = splitted_query.find(protocol::uri_query_sas_signature); + for (auto remove_param : remove_list) + { + splitted_query.erase(remove_param); + } + auto signed_resource = splitted_query.find(protocol::uri_query_sas_resource); - if ((signature == splitted_query.end()) || (require_signed_resource && (signed_resource == splitted_query.end()))) + if (require_signed_resource && signed_resource == splitted_query.end()) { throw std::invalid_argument(protocol::error_missing_params_for_sas); } + web::http::uri_builder builder; + for (auto iter = splitted_query.cbegin(); iter != splitted_query.cend(); ++iter) + { + add_query_if_not_empty(builder, iter->first, iter->second, /* do_encoding */ false); + } + return storage_credentials(builder.query()); } @@ -130,6 +135,22 @@ namespace azure { namespace storage { namespace protocol { utility::string_t get_blob_sas_string_to_sign(const utility::string_t& identifier, const shared_access_policy& policy, const cloud_blob_shared_access_headers& headers, const utility::string_t& resource, const storage_credentials& credentials) { + //// StringToSign = signedpermissions + "\n" + + //// signedstart + "\n" + + //// signedexpiry + "\n" + + //// canonicalizedresource + "\n" + + //// signedidentifier + "\n" + + //// signedversion + "\n" + + //// cachecontrol + "\n" + + //// contentdisposition + "\n" + + //// contentencoding + "\n" + + //// contentlanguage + "\n" + + //// contenttype + //// + //// HMAC-SHA256(UTF8.Encode(StringToSign)) + //// + //// Note that the final five headers are invalid for the 2012-02-12 version. + utility::ostringstream_t str; get_sas_string_to_sign(str, identifier, policy, resource); str << U('\n') << headers.cache_control(); @@ -138,7 +159,10 @@ namespace azure { namespace storage { namespace protocol { str << U('\n') << headers.content_language(); str << U('\n') << headers.content_type(); - return calculate_hmac_sha256_hash(str.str(), credentials); + auto string_to_sign = str.str(); + log_sas_string_to_sign(string_to_sign); + + return calculate_hmac_sha256_hash(string_to_sign, credentials); } utility::string_t get_blob_sas_token(const utility::string_t& identifier, const shared_access_policy& policy, const cloud_blob_shared_access_headers& headers, const utility::string_t& resource_type, const utility::string_t& resource, const storage_credentials& credentials) @@ -162,10 +186,22 @@ namespace azure { namespace storage { namespace protocol { utility::string_t get_queue_sas_string_to_sign(const utility::string_t& identifier, const shared_access_policy& policy, const utility::string_t& resource, const storage_credentials& credentials) { + //// StringToSign = signedpermissions + "\n" + + //// signedstart + "\n" + + //// signedexpiry + "\n" + + //// canonicalizedresource + "\n" + + //// signedidentifier + "\n" + + //// signedversion + //// + //// HMAC-SHA256(UTF8.Encode(StringToSign)) + utility::ostringstream_t str; get_sas_string_to_sign(str, identifier, policy, resource); - return calculate_hmac_sha256_hash(str.str(), credentials); + auto string_to_sign = str.str(); + log_sas_string_to_sign(string_to_sign); + + return calculate_hmac_sha256_hash(string_to_sign, credentials); } utility::string_t get_queue_sas_token(const utility::string_t& identifier, const shared_access_policy& policy, const utility::string_t& resource, const storage_credentials& credentials) @@ -182,15 +218,30 @@ namespace azure { namespace storage { namespace protocol { utility::string_t get_table_sas_string_to_sign(const utility::string_t& identifier, const shared_access_policy& policy, const utility::string_t& start_partition_key, const utility::string_t& start_row_key, const utility::string_t& end_partition_key, const utility::string_t& end_row_key, const utility::string_t& resource, const storage_credentials& credentials) { + //// StringToSign = signedpermissions + "\n" + + //// signedstart + "\n" + + //// signedexpiry + "\n" + + //// canonicalizedresource + "\n" + + //// signedidentifier + "\n" + + //// signedversion + "\n" + + //// startpk + "\n" + + //// startrk + "\n" + + //// endpk + "\n" + + //// endrk + //// + //// HMAC-SHA256(UTF8.Encode(StringToSign)) + utility::ostringstream_t str; get_sas_string_to_sign(str, identifier, policy, resource); - str << U('\n') << start_partition_key; str << U('\n') << start_row_key; str << U('\n') << end_partition_key; str << U('\n') << end_row_key; - return calculate_hmac_sha256_hash(str.str(), credentials); + auto string_to_sign = str.str(); + log_sas_string_to_sign(string_to_sign); + + return calculate_hmac_sha256_hash(string_to_sign, credentials); } utility::string_t get_table_sas_token(const utility::string_t& identifier, const shared_access_policy& policy, const utility::string_t& table_name, const utility::string_t& start_partition_key, const utility::string_t& start_row_key, const utility::string_t& end_partition_key, const utility::string_t& end_row_key, const utility::string_t& resource, const storage_credentials& credentials) diff --git a/Microsoft.WindowsAzure.Storage/tests/CMakeLists.txt b/Microsoft.WindowsAzure.Storage/tests/CMakeLists.txt index 6959ea9f..9f4c4d3a 100644 --- a/Microsoft.WindowsAzure.Storage/tests/CMakeLists.txt +++ b/Microsoft.WindowsAzure.Storage/tests/CMakeLists.txt @@ -6,6 +6,7 @@ if(UNIX) blob_lease_test.cpp blob_streams_test.cpp blob_test_base.cpp + cloud_append_blob_test.cpp cloud_blob_client_test.cpp cloud_blob_container_test.cpp cloud_blob_directory_test.cpp diff --git a/Microsoft.WindowsAzure.Storage/tests/Microsoft.WindowsAzure.Storage.UnitTests.v120.vcxproj b/Microsoft.WindowsAzure.Storage/tests/Microsoft.WindowsAzure.Storage.UnitTests.v120.vcxproj index 7a81fbfd..7257c70e 100644 --- a/Microsoft.WindowsAzure.Storage/tests/Microsoft.WindowsAzure.Storage.UnitTests.v120.vcxproj +++ b/Microsoft.WindowsAzure.Storage/tests/Microsoft.WindowsAzure.Storage.UnitTests.v120.vcxproj @@ -104,6 +104,7 @@ + diff --git a/Microsoft.WindowsAzure.Storage/tests/Microsoft.WindowsAzure.Storage.UnitTests.v120.vcxproj.filters b/Microsoft.WindowsAzure.Storage/tests/Microsoft.WindowsAzure.Storage.UnitTests.v120.vcxproj.filters index 10bfe94e..a88d05dd 100644 --- a/Microsoft.WindowsAzure.Storage/tests/Microsoft.WindowsAzure.Storage.UnitTests.v120.vcxproj.filters +++ b/Microsoft.WindowsAzure.Storage/tests/Microsoft.WindowsAzure.Storage.UnitTests.v120.vcxproj.filters @@ -104,6 +104,9 @@ Source Files + + Source Files + Source Files diff --git a/Microsoft.WindowsAzure.Storage/tests/Microsoft.WindowsAzure.Storage.UnitTests.vcxproj b/Microsoft.WindowsAzure.Storage/tests/Microsoft.WindowsAzure.Storage.UnitTests.vcxproj index dc271611..a07cc723 100644 --- a/Microsoft.WindowsAzure.Storage/tests/Microsoft.WindowsAzure.Storage.UnitTests.vcxproj +++ b/Microsoft.WindowsAzure.Storage/tests/Microsoft.WindowsAzure.Storage.UnitTests.vcxproj @@ -104,6 +104,7 @@ + diff --git a/Microsoft.WindowsAzure.Storage/tests/Microsoft.WindowsAzure.Storage.UnitTests.vcxproj.filters b/Microsoft.WindowsAzure.Storage/tests/Microsoft.WindowsAzure.Storage.UnitTests.vcxproj.filters index 2cd8367f..51568a30 100644 --- a/Microsoft.WindowsAzure.Storage/tests/Microsoft.WindowsAzure.Storage.UnitTests.vcxproj.filters +++ b/Microsoft.WindowsAzure.Storage/tests/Microsoft.WindowsAzure.Storage.UnitTests.vcxproj.filters @@ -104,6 +104,9 @@ Source Files + + Source Files + Source Files diff --git a/Microsoft.WindowsAzure.Storage/tests/blob_streams_test.cpp b/Microsoft.WindowsAzure.Storage/tests/blob_streams_test.cpp index 6a95c8c4..00699ea3 100644 --- a/Microsoft.WindowsAzure.Storage/tests/blob_streams_test.cpp +++ b/Microsoft.WindowsAzure.Storage/tests/blob_streams_test.cpp @@ -193,7 +193,7 @@ SUITE(Blob) auto stream = m_blob.open_read(azure::storage::access_condition(), options, m_context); stream.read_to_end(output_buffer).wait(); - stream.close(); + stream.close().wait(); CHECK_EQUAL(buffer.size(), output_buffer.collection().size()); CHECK_ARRAY_EQUAL(buffer, output_buffer.collection(), (int)output_buffer.collection().size()); @@ -212,13 +212,13 @@ SUITE(Blob) auto stream = m_blob.open_read(azure::storage::access_condition(), options, m_context); m_blob.upload_metadata(azure::storage::access_condition(), options, m_context); CHECK_THROW(stream.read().wait(), azure::storage::storage_exception); - stream.close(); + stream.close().wait(); auto condition = azure::storage::access_condition::generate_if_match_condition(U("*")); stream = m_blob.open_read(condition, options, m_context); m_blob.upload_metadata(azure::storage::access_condition(), options, m_context); CHECK_THROW(stream.read().wait(), azure::storage::storage_exception); - stream.close(); + stream.close().wait(); } TEST_FIXTURE(block_blob_test_base, blob_read_stream_seek) diff --git a/Microsoft.WindowsAzure.Storage/tests/blob_test_base.h b/Microsoft.WindowsAzure.Storage/tests/blob_test_base.h index 9edbcd0d..714f4659 100644 --- a/Microsoft.WindowsAzure.Storage/tests/blob_test_base.h +++ b/Microsoft.WindowsAzure.Storage/tests/blob_test_base.h @@ -228,3 +228,21 @@ class page_blob_test_base : public blob_test_base azure::storage::cloud_page_blob m_blob; }; + +class append_blob_test_base : public blob_test_base +{ +public: + + append_blob_test_base() + { + m_blob = m_container.get_append_blob_reference(U("appendblob")); + } + + ~append_blob_test_base() + { + } + +protected: + + azure::storage::cloud_append_blob m_blob; +}; diff --git a/Microsoft.WindowsAzure.Storage/tests/cloud_append_blob_test.cpp b/Microsoft.WindowsAzure.Storage/tests/cloud_append_blob_test.cpp new file mode 100644 index 00000000..907ab1d7 --- /dev/null +++ b/Microsoft.WindowsAzure.Storage/tests/cloud_append_blob_test.cpp @@ -0,0 +1,496 @@ +// ----------------------------------------------------------------------------------------- +// +// Copyright 2013 Microsoft Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ----------------------------------------------------------------------------------------- + +#include "stdafx.h" +#include "blob_test_base.h" +#include "check_macros.h" + +#include "cpprest/producerconsumerstream.h" +#include "wascore/constants.h" + +#pragma region Fixture + +#pragma endregion + +SUITE(Blob) +{ + TEST_FIXTURE(append_blob_test_base, append_block) + { + const size_t buffer_size = 16 * 1024; + std::vector buffer; + buffer.resize(buffer_size); + azure::storage::blob_request_options options; + + utility::string_t md5_header; + m_context.set_sending_request([&md5_header](web::http::http_request& request, azure::storage::operation_context) + { + if (!request.headers().match(web::http::header_names::content_md5, md5_header)) + { + md5_header.clear(); + } + }); + + m_blob.create_or_replace(azure::storage::access_condition(), options, m_context); + + options.set_use_transactional_md5(false); + for (uint16_t i = 0; i < 3; ++i) + { + fill_buffer_and_get_md5(buffer); + auto stream = concurrency::streams::bytestream::open_istream(buffer); + int64_t offset = m_blob.append_block(stream, utility::string_t(), azure::storage::access_condition(), options, m_context); + CHECK_UTF8_EQUAL(utility::string_t(), md5_header); + CHECK_EQUAL(i * buffer_size, offset); + CHECK_EQUAL(i + 1, m_blob.properties().append_blob_committed_block_count()); + } + + options.set_use_transactional_md5(false); + for (uint16_t i = 3; i < 6; ++i) + { + auto md5 = fill_buffer_and_get_md5(buffer); + auto stream = concurrency::streams::bytestream::open_istream(buffer); + int64_t offset = m_blob.append_block(stream, md5, azure::storage::access_condition(), options, m_context); + CHECK_UTF8_EQUAL(md5, md5_header); + CHECK_EQUAL(i * buffer_size, offset); + CHECK_EQUAL(i + 1, m_blob.properties().append_blob_committed_block_count()); + } + + options.set_use_transactional_md5(true); + for (uint16_t i = 6; i < 9; ++i) + { + auto md5 = fill_buffer_and_get_md5(buffer); + auto stream = concurrency::streams::bytestream::open_istream(buffer); + int64_t offset = m_blob.append_block(stream, utility::string_t(), azure::storage::access_condition(), options, m_context); + CHECK_UTF8_EQUAL(md5, md5_header); + CHECK_EQUAL(i * buffer_size, offset); + CHECK_EQUAL(i + 1, m_blob.properties().append_blob_committed_block_count()); + } + + // block stream with length = 0 + options.set_use_transactional_md5(true); + fill_buffer_and_get_md5(buffer); + auto stream1 = concurrency::streams::bytestream::open_istream(buffer); + stream1.seek(buffer.size()); + CHECK_THROW(m_blob.append_block(stream1, utility::string_t(), azure::storage::access_condition(), options, m_context), azure::storage::storage_exception); + + options.set_use_transactional_md5(true); + fill_buffer_and_get_md5(buffer); + auto stream = concurrency::streams::bytestream::open_istream(buffer); + CHECK_THROW(m_blob.append_block(stream, dummy_md5, azure::storage::access_condition(), options, m_context), azure::storage::storage_exception); + CHECK_UTF8_EQUAL(dummy_md5, md5_header); + + m_context.set_sending_request(std::function()); + } + + TEST_FIXTURE(append_blob_test_base, append_block_size) + { + const size_t buffer_size = 8 * 1024 * 1024; + std::vector buffer; + buffer.reserve(buffer_size); + + azure::storage::blob_request_options options; + m_blob.create_or_replace(azure::storage::access_condition(), options, m_context); + + size_t sizes[] = { 1, 2, 1023, 1024, 4 * 1024, 1024 * 1024, azure::storage::protocol::max_block_size - 1, azure::storage::protocol::max_block_size }; + size_t invalid_sizes[] = { azure::storage::protocol::max_block_size + 1, 6 * 1024 * 1024, 8 * 1024 * 1024 }; + int64_t bytes_appended = 0; + + options.set_use_transactional_md5(true); + for (size_t size : sizes) + { + buffer.resize(size); + auto md5 = fill_buffer_and_get_md5(buffer, 0, size); + auto stream = concurrency::streams::bytestream::open_istream(buffer); + int64_t offset = m_blob.append_block(stream, md5, azure::storage::access_condition(), options, m_context); + CHECK_EQUAL(bytes_appended, offset); + + bytes_appended += size; + } + + options.set_use_transactional_md5(false); + for (size_t size : invalid_sizes) + { + buffer.resize(size); + fill_buffer_and_get_md5(buffer, 0, size); + auto stream = concurrency::streams::bytestream::open_istream(buffer); + CHECK_THROW(m_blob.append_block(stream, utility::string_t(), azure::storage::access_condition(), options, m_context), azure::storage::storage_exception); + } + } + + TEST_FIXTURE(append_blob_test_base, append_block_max_size_condition) + { + const size_t buffer_size = 64 * 1024; + std::vector buffer; + buffer.resize(buffer_size); + fill_buffer_and_get_md5(buffer); + + azure::storage::blob_request_options options; + options.set_use_transactional_md5(false); + + int64_t max_sizes1[] = {1, 1024, buffer_size - 1}; + for (int64_t max_size : max_sizes1) + { + m_blob.create_or_replace(azure::storage::access_condition(), options, m_context); + + auto stream = concurrency::streams::bytestream::open_istream(buffer); + CHECK_THROW(m_blob.append_block(stream, utility::string_t(), azure::storage::access_condition::generate_if_max_size_less_than_or_equal_condition(max_size), options, m_context), azure::storage::storage_exception); + m_blob.delete_blob(); + } + + int64_t max_sizes2[] = { buffer_size, 2 * buffer_size, std::numeric_limits::max() }; + for (int64_t max_size : max_sizes2) + { + m_blob.create_or_replace(azure::storage::access_condition(), options, m_context); + + auto stream = concurrency::streams::bytestream::open_istream(buffer); + int64_t offset = m_blob.append_block(stream, utility::string_t(), azure::storage::access_condition::generate_if_max_size_less_than_or_equal_condition(max_size), options, m_context); + CHECK_EQUAL(0, offset); + m_blob.delete_blob(); + } + + int64_t blob_size = 0; + int block_count = 0; + m_blob.create_or_replace(azure::storage::access_condition(), options, m_context); + + for (uint16_t i = 0; i < 3; ++i) + { + fill_buffer_and_get_md5(buffer); + auto stream = concurrency::streams::bytestream::open_istream(buffer); + int64_t offset = m_blob.append_block(stream, utility::string_t(), azure::storage::access_condition(), options, m_context); + block_count++; + CHECK_EQUAL(blob_size, offset); + CHECK_EQUAL(block_count, m_blob.properties().append_blob_committed_block_count()); + blob_size += buffer.size(); + } + + int64_t max_sizes3[] = { 3 * buffer_size - 1, 3 * buffer_size, 3 * buffer_size + 1, 4 * buffer_size - 1 }; + for (int64_t max_size : max_sizes3) + { + auto stream = concurrency::streams::bytestream::open_istream(buffer); + CHECK_THROW(m_blob.append_block(stream, utility::string_t(), azure::storage::access_condition::generate_if_max_size_less_than_or_equal_condition(max_size), options, m_context), azure::storage::storage_exception); + } + + int64_t max_sizes4[] = { 4 * buffer_size, std::numeric_limits::max() }; + for (int64_t max_size : max_sizes4) + { + auto stream = concurrency::streams::bytestream::open_istream(buffer); + int64_t offset = m_blob.append_block(stream, utility::string_t(), azure::storage::access_condition::generate_if_max_size_less_than_or_equal_condition(max_size), options, m_context); + block_count++; + CHECK_EQUAL(blob_size, offset); + CHECK_EQUAL(block_count, m_blob.properties().append_blob_committed_block_count()); + blob_size += buffer.size(); + } + + m_blob.delete_blob(); + } + + TEST_FIXTURE(append_blob_test_base, append_block_append_position_condition) + { + const size_t buffer_size = 64 * 1024; + std::vector buffer; + buffer.resize(buffer_size); + + azure::storage::blob_request_options options; + options.set_use_transactional_md5(true); + + m_blob.create_or_replace(azure::storage::access_condition(), options, m_context); + + int64_t invalid_appendpos[] = { 1, 2, buffer_size, buffer_size + 1, std::numeric_limits::max() }; + for (int64_t appendpos : invalid_appendpos) + { + auto md5 = fill_buffer_and_get_md5(buffer); + auto stream = concurrency::streams::bytestream::open_istream(buffer); + CHECK_THROW(m_blob.append_block(stream, md5, azure::storage::access_condition::generate_if_append_position_equal_condition(appendpos), options, m_context), azure::storage::storage_exception); + } + + for (int16_t i = 0; i < 3; i++) + { + auto md5 = fill_buffer_and_get_md5(buffer); + auto stream = concurrency::streams::bytestream::open_istream(buffer); + int64_t offset = m_blob.append_block(stream, md5, azure::storage::access_condition::generate_if_append_position_equal_condition(i * buffer_size), options, m_context); + CHECK_EQUAL(offset, i * buffer_size); + CHECK_EQUAL(i + 1, m_blob.properties().append_blob_committed_block_count()); + } + + int64_t invalid_appendpos2[] = { buffer_size * 3 - 1, buffer_size * 3 + 1}; + for (int64_t appendpos : invalid_appendpos2) + { + auto md5 = fill_buffer_and_get_md5(buffer); + auto stream = concurrency::streams::bytestream::open_istream(buffer); + CHECK_THROW(m_blob.append_block(stream, md5, azure::storage::access_condition::generate_if_append_position_equal_condition(appendpos), options, m_context), azure::storage::storage_exception); + } + + auto md5 = fill_buffer_and_get_md5(buffer); + auto stream = concurrency::streams::bytestream::open_istream(buffer); + CHECK_EQUAL(3 * buffer_size, m_blob.append_block(stream, md5, azure::storage::access_condition::generate_if_append_position_equal_condition(3 * buffer_size), options, m_context)); + CHECK_EQUAL(4, m_blob.properties().append_blob_committed_block_count()); + + m_blob.delete_blob(); + } + + TEST_FIXTURE(append_blob_test_base, append_blob_upload) + { + const size_t buffer_size = 6 * 1024 * 1024; + azure::storage::blob_request_options options; + options.set_use_transactional_md5(true); + + const size_t buffer_offsets[2] = { 0, 1024 }; + for (auto buffer_offset : buffer_offsets) + { + upload_and_download(m_blob, buffer_size, buffer_offset, 0, true, options, 3, false); + m_blob.delete_blob(); + m_blob.properties().set_content_md5(utility::string_t()); + } + } + + TEST_FIXTURE(append_blob_test_base, append_blob_upload_with_nonseekable) + { + const size_t buffer_size = 6 * 1024 * 1024; + azure::storage::blob_request_options options; + options.set_use_transactional_md5(true); + + const size_t buffer_offsets[2] = { 0, 1024 }; + for (auto buffer_offset : buffer_offsets) + { + upload_and_download(m_blob, buffer_size, buffer_offset, 0, false, options, 3, false); + m_blob.delete_blob(); + m_blob.properties().set_content_md5(utility::string_t()); + } + } + + TEST_FIXTURE(append_blob_test_base, append_blob_append) + { + const size_t file_buffer_size = 24 * 1024 * 1024 + 6; + std::vector file_buffer; + file_buffer.resize(file_buffer_size); + + azure::storage::blob_request_options options; + options.set_use_transactional_md5(false); + + utility::string_t md5_header; + m_context.set_sending_request([&md5_header](web::http::http_request& request, azure::storage::operation_context) + { + if (!request.headers().match(web::http::header_names::content_md5, md5_header)) + { + md5_header.clear(); + } + }); + + m_blob.create_or_replace(azure::storage::access_condition(), options, m_context); + + int block_count = 0; + + // append stream (4M, 4M) + const size_t buffer_offsets1[2] = { 0, 4 * 1024 * 1024}; + for (uint16_t i = 0; i < 2; ++i) + { + std::vector buffer; + buffer.resize(4 * 1024 * 1024); + fill_buffer_and_get_md5(buffer); + std::copy(buffer.begin(), buffer.end(), file_buffer.begin() + buffer_offsets1[i]); + + auto stream = concurrency::streams::bytestream::open_istream(buffer); + azure::storage::access_condition condition = azure::storage::access_condition::generate_if_append_position_equal_condition(buffer_offsets1[i]); + m_blob.append_from_stream(stream, condition, options, m_context); + CHECK_UTF8_EQUAL(utility::string_t(), md5_header); + + block_count++; + CHECK_EQUAL(block_count, m_blob.properties().append_blob_committed_block_count()); + } + + // append stream with length (2M, 2M, 2M) + const size_t buffer_offsets2[3] = { 8 * 1024 * 1024, 10 * 1024 * 1024, 12 * 1024 * 1024 }; + for (uint16_t i = 0; i < 3; ++i) + { + std::vector buffer; + buffer.resize(4 * 1024 * 1024); + fill_buffer_and_get_md5(buffer); + std::copy(buffer.begin(), buffer.begin() + 2 * 1024 * 1024, file_buffer.begin() + buffer_offsets2[i]); + + auto stream = concurrency::streams::bytestream::open_istream(buffer); + m_blob.append_from_stream(stream, 2 * 1024 * 1024, azure::storage::access_condition(), options, m_context); + CHECK_UTF8_EQUAL(utility::string_t(), md5_header); + + block_count++; + CHECK_EQUAL(block_count, m_blob.properties().append_blob_committed_block_count()); + } + + // append file (5M, 5M) + const size_t buffer_offsets3[2] = { 14 * 1024 * 1024, 19 * 1024 * 1024 }; + for (uint16_t i = 0; i < 2; ++i) + { + std::vector buffer; + buffer.resize(5 * 1024 * 1024); + fill_buffer_and_get_md5(buffer); + std::copy(buffer.begin(), buffer.end(), file_buffer.begin() + buffer_offsets3[i]); + + // create a temporary test file + utility::string_t tmp_file_path = get_random_container_name(8); + auto stream = concurrency::streams::file_stream::open_ostream(tmp_file_path).get(); + stream.streambuf().putn(buffer.data(), buffer.size()).wait(); + stream.close().wait(); + + // append from file + m_blob.append_from_file(tmp_file_path, azure::storage::access_condition(), options, m_context); + + // remote the temporary test file + std::remove(utility::conversions::to_utf8string(tmp_file_path).c_str()); + + block_count += 2; + CHECK_EQUAL(block_count, m_blob.properties().append_blob_committed_block_count()); + } + + // append text (1, 5) + const size_t buffer_offsets4[2] = { 24 * 1024 * 1024, 24 * 1024 * 1024 + 1}; + { + utility::string_t text1 = U("1"); + std::string text1_copy = utility::conversions::to_utf8string(text1); + std::copy(text1_copy.begin(), text1_copy.end(), file_buffer.begin() + buffer_offsets4[0]); + m_blob.append_text(text1); + block_count++; + CHECK_EQUAL(block_count, m_blob.properties().append_blob_committed_block_count()); + + utility::string_t text2 = U("test2"); + std::string text2_copy = utility::conversions::to_utf8string(text2); + std::copy(text2_copy.begin(), text2_copy.end(), file_buffer.begin() + buffer_offsets4[1]); + m_blob.append_text(text2); + block_count++; + CHECK_EQUAL(block_count, m_blob.properties().append_blob_committed_block_count()); + } + + // download the blob + concurrency::streams::container_buffer> downloaded_blob; + m_blob.download_to_stream(downloaded_blob.create_ostream(), azure::storage::access_condition(), options, m_context); + + CHECK_ARRAY_EQUAL(file_buffer, downloaded_blob.collection(), (int)file_buffer.size()); + + m_blob.delete_blob(); + + m_context.set_sending_request(std::function()); + } + + TEST_FIXTURE(append_blob_test_base, append_blob_constructor) + { + m_blob.create_or_replace(azure::storage::access_condition(), azure::storage::blob_request_options(), m_context); + CHECK(!m_blob.properties().etag().empty()); + + azure::storage::cloud_append_blob blob1(m_blob.uri()); + CHECK_UTF8_EQUAL(m_blob.name(), blob1.name()); + CHECK_UTF8_EQUAL(m_blob.uri().primary_uri().to_string(), blob1.uri().primary_uri().to_string()); + CHECK_UTF8_EQUAL(m_blob.uri().secondary_uri().to_string(), blob1.uri().secondary_uri().to_string()); + CHECK(blob1.properties().etag().empty()); + + azure::storage::cloud_blob blob2(m_blob); + CHECK_UTF8_EQUAL(m_blob.name(), blob2.name()); + CHECK_UTF8_EQUAL(m_blob.uri().primary_uri().to_string(), blob2.uri().primary_uri().to_string()); + CHECK_UTF8_EQUAL(m_blob.uri().secondary_uri().to_string(), blob2.uri().secondary_uri().to_string()); + CHECK_UTF8_EQUAL(m_blob.properties().etag(), blob2.properties().etag()); + + azure::storage::cloud_append_blob blob3(blob2); + CHECK_UTF8_EQUAL(m_blob.name(), blob3.name()); + CHECK_UTF8_EQUAL(m_blob.uri().primary_uri().to_string(), blob3.uri().primary_uri().to_string()); + CHECK_UTF8_EQUAL(m_blob.uri().secondary_uri().to_string(), blob3.uri().secondary_uri().to_string()); + CHECK_UTF8_EQUAL(m_blob.properties().etag(), blob2.properties().etag()); + } + + TEST_FIXTURE(append_blob_test_base, append_blob_create) + { + auto same_blob = m_container.get_append_blob_reference(m_blob.name()); + CHECK(!same_blob.exists(azure::storage::blob_request_options(), m_context)); + CHECK_EQUAL(0U, same_blob.properties().size()); + CHECK(same_blob.properties().etag().empty()); + + m_blob.create_or_replace(azure::storage::access_condition(), azure::storage::blob_request_options(), m_context); + CHECK_EQUAL(0U, m_blob.properties().size()); + CHECK(!m_blob.properties().etag().empty()); + CHECK(same_blob.exists(azure::storage::blob_request_options(), m_context)); + CHECK_EQUAL(0U, same_blob.properties().size()); + CHECK(!same_blob.properties().etag().empty()); + + m_blob.delete_blob(azure::storage::delete_snapshots_option::none, azure::storage::access_condition(), azure::storage::blob_request_options(), m_context); + CHECK(!m_blob.exists(azure::storage::blob_request_options(), m_context)); + CHECK(!same_blob.exists(azure::storage::blob_request_options(), m_context)); + CHECK(!m_blob.properties().etag().empty()); + + m_blob.create_or_replace(azure::storage::access_condition(), azure::storage::blob_request_options(), m_context); + CHECK_EQUAL(0U, m_blob.properties().size()); + CHECK(!m_blob.properties().etag().empty()); + CHECK(same_blob.exists(azure::storage::blob_request_options(), m_context)); + CHECK_EQUAL(0U, same_blob.properties().size()); + CHECK(!same_blob.properties().etag().empty()); + } + + TEST_FIXTURE(append_blob_test_base, append_blob_create_with_metadata) + { + m_blob.metadata()[U("key1")] = U("value1"); + m_blob.metadata()[U("key2")] = U("value2"); + m_blob.create_or_replace(azure::storage::access_condition(), azure::storage::blob_request_options(), m_context); + + auto same_blob = m_container.get_append_blob_reference(m_blob.name()); + CHECK(same_blob.metadata().empty()); + same_blob.download_attributes(azure::storage::access_condition(), azure::storage::blob_request_options(), m_context); + CHECK_EQUAL(2U, same_blob.metadata().size()); + CHECK_UTF8_EQUAL(U("value1"), same_blob.metadata()[U("key1")]); + CHECK_UTF8_EQUAL(U("value2"), same_blob.metadata()[U("key2")]); + } + + TEST_FIXTURE(append_blob_test_base, append_blob_snapshot_metadata) + { + m_blob.metadata()[U("key1")] = U("value1"); + m_blob.metadata()[U("key2")] = U("value2"); + m_blob.create_or_replace(azure::storage::access_condition(), azure::storage::blob_request_options(), m_context); + + auto snapshot1 = m_blob.create_snapshot(azure::storage::cloud_metadata(), azure::storage::access_condition(), azure::storage::blob_request_options(), m_context); + CHECK_EQUAL(2U, snapshot1.metadata().size()); + CHECK_UTF8_EQUAL(U("value1"), snapshot1.metadata()[U("key1")]); + CHECK_UTF8_EQUAL(U("value2"), snapshot1.metadata()[U("key2")]); + + azure::storage::cloud_append_blob snapshot1_clone(snapshot1.uri(), snapshot1.snapshot_time(), snapshot1.service_client().credentials()); + CHECK(snapshot1_clone.metadata().empty()); + snapshot1_clone.download_attributes(azure::storage::access_condition(), azure::storage::blob_request_options(), m_context); + CHECK_EQUAL(2U, snapshot1_clone.metadata().size()); + CHECK_UTF8_EQUAL(U("value1"), snapshot1_clone.metadata()[U("key1")]); + CHECK_UTF8_EQUAL(U("value2"), snapshot1_clone.metadata()[U("key2")]); + + azure::storage::cloud_metadata snapshot_metadata; + snapshot_metadata[U("key3")] = U("value1"); + snapshot_metadata[U("key4")] = U("value2"); + auto snapshot2 = m_blob.create_snapshot(snapshot_metadata, azure::storage::access_condition(), azure::storage::blob_request_options(), m_context); + CHECK_EQUAL(2U, snapshot1.metadata().size()); + CHECK_UTF8_EQUAL(U("value1"), snapshot2.metadata()[U("key3")]); + CHECK_UTF8_EQUAL(U("value2"), snapshot2.metadata()[U("key4")]); + + azure::storage::cloud_append_blob snapshot2_clone(snapshot2.uri(), snapshot2.snapshot_time(), snapshot2.service_client().credentials()); + CHECK(snapshot2_clone.metadata().empty()); + snapshot2_clone.download_attributes(azure::storage::access_condition(), azure::storage::blob_request_options(), m_context); + CHECK_EQUAL(2U, snapshot2_clone.metadata().size()); + CHECK_UTF8_EQUAL(U("value1"), snapshot2_clone.metadata()[U("key3")]); + CHECK_UTF8_EQUAL(U("value2"), snapshot2_clone.metadata()[U("key4")]); + } + + TEST_FIXTURE(append_blob_test_base, append_blob_upload_max_size_condition) + { + const size_t buffer_size = 1024 * 1024; + + std::vector buffer; + buffer.resize(buffer_size); + fill_buffer_and_get_md5(buffer); + concurrency::streams::istream stream = concurrency::streams::bytestream::open_istream(buffer); + + auto condition = azure::storage::access_condition::generate_if_max_size_less_than_or_equal_condition(512); + CHECK_THROW(m_blob.upload_from_stream(stream, condition, azure::storage::blob_request_options(), m_context), std::invalid_argument); + } +} diff --git a/Microsoft.WindowsAzure.Storage/tests/cloud_blob_client_test.cpp b/Microsoft.WindowsAzure.Storage/tests/cloud_blob_client_test.cpp index 0d1ce0f9..9d87e259 100644 --- a/Microsoft.WindowsAzure.Storage/tests/cloud_blob_client_test.cpp +++ b/Microsoft.WindowsAzure.Storage/tests/cloud_blob_client_test.cpp @@ -105,10 +105,9 @@ void blob_service_test_base_with_objects_to_delete::check_blob_list(const std::v std::vector blob_service_test_base::list_all_containers(const utility::string_t& prefix, azure::storage::container_listing_details::values includes, int max_results, const azure::storage::blob_request_options& options) { std::vector results; - azure::storage::container_result_iterator end_of_result; - for (azure::storage::container_result_iterator iter = m_client.list_containers(prefix, includes, max_results, options, m_context); iter != end_of_result; ++iter) + for (auto&& item : m_client.list_containers(prefix, includes, max_results, options, m_context)) { - results.push_back(*iter); + results.push_back(item); } return results; @@ -117,28 +116,13 @@ std::vector blob_service_test_base::list_a std::vector blob_service_test_base::list_all_blobs_from_client(const utility::string_t& prefix, azure::storage::blob_listing_details::values includes, int max_results, const azure::storage::blob_request_options& options) { std::vector blobs; - azure::storage::continuation_token token; - - do + for (auto&& item : m_client.list_blobs(prefix, true, includes, max_results, options, m_context)) { - auto results = m_client.list_blobs_segmented(prefix, true, includes, max_results, token, options, m_context); - - if (max_results > 0) + if (item.is_blob()) { - CHECK(results.results().size() <= static_cast(max_results)); + blobs.push_back(std::move(item.as_blob())); } - - blobs.reserve(results.results().size()); - for (auto& item : results.results()) - { - if (item.is_blob()) - { - blobs.push_back(std::move(item.as_blob())); - } - } - - token = results.continuation_token(); - } while (!token.empty()); + } return blobs; } diff --git a/Microsoft.WindowsAzure.Storage/tests/cloud_blob_container_test.cpp b/Microsoft.WindowsAzure.Storage/tests/cloud_blob_container_test.cpp index 6180b945..9e5c16f3 100644 --- a/Microsoft.WindowsAzure.Storage/tests/cloud_blob_container_test.cpp +++ b/Microsoft.WindowsAzure.Storage/tests/cloud_blob_container_test.cpp @@ -83,6 +83,10 @@ SUITE(Blob) CHECK_UTF8_EQUAL(m_container.uri().primary_uri().to_string(), page_blob.container().uri().primary_uri().to_string()); CHECK_UTF8_EQUAL(m_container.uri().secondary_uri().to_string(), page_blob.container().uri().secondary_uri().to_string()); + auto append_blob = m_container.get_append_blob_reference(U("blob3")); + CHECK_UTF8_EQUAL(m_container.uri().primary_uri().to_string(), append_blob.container().uri().primary_uri().to_string()); + CHECK_UTF8_EQUAL(m_container.uri().secondary_uri().to_string(), append_blob.container().uri().secondary_uri().to_string()); + auto directory = m_container.get_directory_reference(U("dir")); CHECK_UTF8_EQUAL(m_container.uri().primary_uri().to_string(), directory.container().uri().primary_uri().to_string()); CHECK_UTF8_EQUAL(m_container.uri().secondary_uri().to_string(), directory.container().uri().secondary_uri().to_string()); @@ -202,6 +206,22 @@ SUITE(Blob) blobs[blob.name()] = blob; } + for (int i = 0; i < 3; i++) + { + auto index = utility::conversions::print_string(i); + auto blob = m_container.get_append_blob_reference(U("appendblob") + index); + blob.metadata()[U("index")] = index; + + blob.create_or_replace(azure::storage::access_condition(), azure::storage::blob_request_options(), m_context); + + std::vector buffer; + buffer.resize((i + 1) * 8 * 1024); + fill_buffer_and_get_md5(buffer); + auto stream = concurrency::streams::container_stream>::open_istream(buffer); + blob.append_block(stream, utility::string_t(), azure::storage::access_condition(), azure::storage::blob_request_options(), m_context); + blobs[blob.name()] = blob; + } + auto listing1 = list_all_blobs(utility::string_t(), azure::storage::blob_listing_details::all, 0, azure::storage::blob_request_options()); for (auto iter = listing1.begin(); iter != listing1.end(); ++iter) { @@ -225,6 +245,10 @@ SUITE(Blob) CHECK_EQUAL(index * 512, iter->properties().size()); break; + case azure::storage::blob_type::append_blob: + CHECK_EQUAL((index + 1) * 8 * 1024, iter->properties().size()); + break; + default: CHECK(false); break; diff --git a/Microsoft.WindowsAzure.Storage/tests/cloud_blob_directory_test.cpp b/Microsoft.WindowsAzure.Storage/tests/cloud_blob_directory_test.cpp index cc5a637f..a4155298 100644 --- a/Microsoft.WindowsAzure.Storage/tests/cloud_blob_directory_test.cpp +++ b/Microsoft.WindowsAzure.Storage/tests/cloud_blob_directory_test.cpp @@ -60,11 +60,16 @@ void create_blob_tree(const azure::storage::cloud_blob_container& container, con azure::storage::cloud_page_blob page_blob(blob); page_blob.create(0, 0, azure::storage::access_condition(), azure::storage::blob_request_options(), context); } - else + else if (iter->type() == azure::storage::blob_type::block_blob) { azure::storage::cloud_block_blob block_blob(blob); block_blob.upload_block_list(std::vector(), azure::storage::access_condition(), azure::storage::blob_request_options(), context); } + else if (iter->type() == azure::storage::blob_type::append_blob) + { + azure::storage::cloud_append_blob append_blob(blob); + append_blob.create_or_replace(azure::storage::access_condition(), azure::storage::blob_request_options(), context); + } } } @@ -163,6 +168,10 @@ void check_parents(const azure::storage::cloud_blob_container& container, const CHECK(azure::storage::blob_type::page_blob == page_blob.type()); CHECK_UTF8_EQUAL(U("dir1") + delimiter + U("dir2") + delimiter + U("dir3") + delimiter + U("page_blob"), page_blob.name()); + auto append_blob = dir3.get_append_blob_reference(U("append_blob")); + CHECK(azure::storage::blob_type::append_blob == append_blob.type()); + CHECK_UTF8_EQUAL(U("dir1") + delimiter + U("dir2") + delimiter + U("dir3") + delimiter + U("append_blob"), append_blob.name()); + auto blob_parent = blob.get_parent_reference(); CHECK_UTF8_EQUAL(dir3.prefix(), blob_parent.prefix()); @@ -221,6 +230,8 @@ SUITE(Blob) blobs.push_back(container.get_block_blob_reference(U("block_blobs") + delimiter + U("blob5"))); blobs.push_back(container.get_page_blob_reference(U("page_blobs") + delimiter + U("dir1") + delimiter + U("dir2") + delimiter + U("blob6"))); blobs.push_back(container.get_page_blob_reference(U("page_blobs") + delimiter + U("blob7"))); + blobs.push_back(container.get_append_blob_reference(U("append_blobs") + delimiter + U("dir1") + delimiter + U("dir3") + delimiter + U("blob8"))); + blobs.push_back(container.get_append_blob_reference(U("append_blobs") + delimiter + U("blob9"))); create_blob_tree(container, blobs, delimiter, m_context); diff --git a/Microsoft.WindowsAzure.Storage/tests/cloud_blob_test.cpp b/Microsoft.WindowsAzure.Storage/tests/cloud_blob_test.cpp index e1b22d80..809aac47 100644 --- a/Microsoft.WindowsAzure.Storage/tests/cloud_blob_test.cpp +++ b/Microsoft.WindowsAzure.Storage/tests/cloud_blob_test.cpp @@ -50,7 +50,8 @@ azure::storage::operation_context blob_test_base::upload_and_download(azure::sto std::vector buffer; buffer.resize(buffer_size); - auto md5 = fill_buffer_and_get_md5(buffer, buffer_offset, blob_size == 0 ? buffer_size - buffer_offset : blob_size); + size_t target_blob_size = blob_size == 0 ? buffer_size - buffer_offset : blob_size; + auto md5 = fill_buffer_and_get_md5(buffer, buffer_offset, target_blob_size); concurrency::streams::istream stream; if (use_seekable_stream) @@ -90,6 +91,18 @@ azure::storage::operation_context blob_test_base::upload_and_download(azure::sto page_blob.upload_from_stream(stream, blob_size, 0, azure::storage::access_condition(), options, context); } } + else if (blob.type() == azure::storage::blob_type::append_blob) + { + azure::storage::cloud_append_blob append_blob(blob); + if (blob_size == 0) + { + append_blob.upload_from_stream(stream, azure::storage::access_condition(), options, context); + } + else + { + append_blob.upload_from_stream(stream, blob_size, azure::storage::access_condition(), options, context); + } + } CHECK_UTF8_EQUAL(expect_md5_header ? md5 : utility::string_t(), md5_header); CHECK_EQUAL(expected_request_count, context.request_results().size()); @@ -99,7 +112,7 @@ azure::storage::operation_context blob_test_base::upload_and_download(azure::sto concurrency::streams::container_buffer> output_buffer; blob.download_to_stream(output_buffer.create_ostream(), azure::storage::access_condition(), download_options, context); - CHECK_ARRAY_EQUAL(buffer.data() + buffer_offset, output_buffer.collection().data(),(int) (blob_size == 0 ? (buffer_size - buffer_offset) : blob_size)); + CHECK_ARRAY_EQUAL(buffer.data() + buffer_offset, output_buffer.collection().data(),(int) target_blob_size); context.set_sending_request(std::function()); return context; @@ -526,7 +539,7 @@ SUITE(Blob) CHECK_UTF8_EQUAL(U("1"), azure::storage::cloud_block_blob(snapshot1).download_text(azure::storage::access_condition(), azure::storage::blob_request_options(), m_context)); auto snapshot1_copy = m_container.get_block_blob_reference(m_blob.name() + U("copy")); - snapshot1_copy.start_copy_from_blob(defiddler(snapshot1.snapshot_qualified_uri().primary_uri()), azure::storage::access_condition(), azure::storage::access_condition(), azure::storage::blob_request_options(), m_context); + snapshot1_copy.start_copy(defiddler(snapshot1.snapshot_qualified_uri().primary_uri()), azure::storage::access_condition(), azure::storage::access_condition(), azure::storage::blob_request_options(), m_context); CHECK(wait_for_copy(snapshot1_copy)); CHECK_UTF8_EQUAL(U("1"), snapshot1_copy.download_text(azure::storage::access_condition(), azure::storage::blob_request_options(), m_context)); @@ -572,18 +585,18 @@ SUITE(Blob) blob.upload_text(U("1"), azure::storage::access_condition(), azure::storage::blob_request_options(), m_context); auto copy = m_container.get_block_blob_reference(U("copy")); - CHECK_THROW(copy.start_copy_from_blob(defiddler(blob.uri().primary_uri()), azure::storage::access_condition::generate_if_match_condition(U("\"0xFFFFFFFFFFFFFFF\"")), azure::storage::access_condition(), azure::storage::blob_request_options(), m_context), azure::storage::storage_exception); + CHECK_THROW(copy.start_copy(defiddler(blob.uri().primary_uri()), azure::storage::access_condition::generate_if_match_condition(U("\"0xFFFFFFFFFFFFFFF\"")), azure::storage::access_condition(), azure::storage::blob_request_options(), m_context), azure::storage::storage_exception); CHECK_EQUAL(web::http::status_codes::PreconditionFailed, m_context.request_results().back().http_status_code()); - auto copy_id = copy.start_copy_from_blob(defiddler(blob.uri().primary_uri()), azure::storage::access_condition::generate_if_match_condition(blob.properties().etag()), azure::storage::access_condition(), azure::storage::blob_request_options(), m_context); + auto copy_id = copy.start_copy(defiddler(blob.uri().primary_uri()), azure::storage::access_condition::generate_if_match_condition(blob.properties().etag()), azure::storage::access_condition(), azure::storage::blob_request_options(), m_context); CHECK(wait_for_copy(copy)); CHECK_THROW(copy.abort_copy(copy_id, azure::storage::access_condition(), azure::storage::blob_request_options(), m_context), azure::storage::storage_exception); CHECK_EQUAL(web::http::status_codes::Conflict, m_context.request_results().back().http_status_code()); - CHECK_THROW(copy.start_copy_from_blob(defiddler(blob.uri().primary_uri()), azure::storage::access_condition::generate_if_match_condition(blob.properties().etag()), azure::storage::access_condition::generate_if_match_condition(U("\"0xFFFFFFFFFFFFFFF\"")), azure::storage::blob_request_options(), m_context), azure::storage::storage_exception); + CHECK_THROW(copy.start_copy(defiddler(blob.uri().primary_uri()), azure::storage::access_condition::generate_if_match_condition(blob.properties().etag()), azure::storage::access_condition::generate_if_match_condition(U("\"0xFFFFFFFFFFFFFFF\"")), azure::storage::blob_request_options(), m_context), azure::storage::storage_exception); CHECK_EQUAL(web::http::status_codes::PreconditionFailed, m_context.request_results().back().http_status_code()); auto copy2 = m_container.get_block_blob_reference(U("copy2")); - copy2.start_copy_from_blob(blob, azure::storage::access_condition::generate_if_match_condition(blob.properties().etag()), azure::storage::access_condition(), azure::storage::blob_request_options(), m_context); + copy2.start_copy(blob, azure::storage::access_condition::generate_if_match_condition(blob.properties().etag()), azure::storage::access_condition(), azure::storage::blob_request_options(), m_context); CHECK(wait_for_copy(copy2)); - CHECK_THROW(copy2.start_copy_from_blob(blob, azure::storage::access_condition::generate_if_match_condition(blob.properties().etag()), azure::storage::access_condition::generate_if_match_condition(U("\"0xFFFFFFFFFFFFFFF\"")), azure::storage::blob_request_options(), m_context), azure::storage::storage_exception); + CHECK_THROW(copy2.start_copy(blob, azure::storage::access_condition::generate_if_match_condition(blob.properties().etag()), azure::storage::access_condition::generate_if_match_condition(U("\"0xFFFFFFFFFFFFFFF\"")), azure::storage::blob_request_options(), m_context), azure::storage::storage_exception); } } diff --git a/Microsoft.WindowsAzure.Storage/tests/cloud_queue_client_test.cpp b/Microsoft.WindowsAzure.Storage/tests/cloud_queue_client_test.cpp index 4e0b7413..a171f8bd 100644 --- a/Microsoft.WindowsAzure.Storage/tests/cloud_queue_client_test.cpp +++ b/Microsoft.WindowsAzure.Storage/tests/cloud_queue_client_test.cpp @@ -26,10 +26,9 @@ std::vector < azure::storage::cloud_queue> list_all_queues( const azure::storage::queue_request_options& options, azure::storage::operation_context context) { std::vector results; - azure::storage::queue_result_iterator end_of_result; - for (azure::storage::queue_result_iterator iter = queue_client.list_queues(prefix, get_metadata, 0, options, context); iter != end_of_result; ++iter) + for (auto&& item : queue_client.list_queues(prefix, get_metadata, 0, options, context)) { - results.push_back(*iter); + results.push_back(item); } return results; diff --git a/Microsoft.WindowsAzure.Storage/tests/cloud_queue_test.cpp b/Microsoft.WindowsAzure.Storage/tests/cloud_queue_test.cpp index 26b875a8..a766d8b5 100644 --- a/Microsoft.WindowsAzure.Storage/tests/cloud_queue_test.cpp +++ b/Microsoft.WindowsAzure.Storage/tests/cloud_queue_test.cpp @@ -51,7 +51,7 @@ SUITE(Queue) CHECK(queue1.uri().secondary_uri() == uri.secondary_uri()); CHECK_EQUAL(-1, queue1.approximate_message_count()); - utility::string_t sas_token(U("sv=2012-02-12&st=2013-05-14T17%3A23%3A15Z&se=2013-05-14T18%3A23%3A15Z&sp=raup&sig=mysignature")); + utility::string_t sas_token(U("se=2013-05-14T18%3A23%3A15Z&sig=mysignature&sp=raup&st=2013-05-14T17%3A23%3A15Z&sv=2012-02-12")); azure::storage::storage_uri sas_uri(web::http::uri(U("https://myaccount.queue.core.windows.net/myqueue?sp=raup&sv=2012-02-12&se=2013-05-14T18%3A23%3A15Z&st=2013-05-14T17%3A23%3A15Z&sig=mysignature")), web::http::uri(U("https://myaccount-secondary.queue.core.windows.net/myqueue?sp=raup&sv=2012-02-12&se=2013-05-14T18%3A23%3A15Z&st=2013-05-14T17%3A23%3A15Z&sig=mysignature"))); @@ -91,16 +91,7 @@ SUITE(Queue) azure::storage::storage_uri sas_uri(web::http::uri(U("https://myaccount.queue.core.windows.net/myqueue?sp=raup&sv=2012-02-12&se=2013-05-14T18%3A23%3A15Z&st=2013-05-14T17%3A23%3A15Z&sig=mysignature")), web::http::uri(U("https://myaccount-secondary.queue.core.windows.net/myqueue?sp=raup&sv=2012-02-12&se=2013-05-14T18%3A23%3A15Z&st=2013-05-14T17%3A23%3A15Z&sig=mysignature"))); azure::storage::storage_credentials sas_credentials(sas_token); - azure::storage::cloud_queue queue2(sas_uri, sas_credentials); - - CHECK(queue2.service_client().base_uri().primary_uri() == expected_primary_uri); - CHECK(queue2.service_client().base_uri().secondary_uri() == expected_secondary_uri); - CHECK(queue2.service_client().credentials().is_sas()); - CHECK(queue2.service_client().credentials().sas_token() == sas_token); - CHECK(queue2.name().compare(U("myqueue")) == 0); - CHECK(queue2.uri().primary_uri() == uri.primary_uri()); - CHECK(queue2.uri().secondary_uri() == uri.secondary_uri()); - CHECK_EQUAL(-1, queue2.approximate_message_count()); + CHECK_THROW(azure::storage::cloud_queue(sas_uri, sas_credentials), std::invalid_argument); azure::storage::storage_credentials invalid_sas_credentials(invalid_sas_token); diff --git a/Microsoft.WindowsAzure.Storage/tests/cloud_table_client_test.cpp b/Microsoft.WindowsAzure.Storage/tests/cloud_table_client_test.cpp index 0dff6791..98ac9661 100644 --- a/Microsoft.WindowsAzure.Storage/tests/cloud_table_client_test.cpp +++ b/Microsoft.WindowsAzure.Storage/tests/cloud_table_client_test.cpp @@ -26,10 +26,9 @@ std::vector list_all_tables( azure::storage::operation_context context) { std::vector results; - azure::storage::table_result_iterator end_of_result; - for (azure::storage::table_result_iterator iter = table_client.list_tables(prefix, 0, options, context); iter != end_of_result; ++iter) + for (auto&& item : table_client.list_tables(prefix, 0, options, context)) { - results.push_back(*iter); + results.push_back(item); } return results; diff --git a/Microsoft.WindowsAzure.Storage/tests/cloud_table_test.cpp b/Microsoft.WindowsAzure.Storage/tests/cloud_table_test.cpp index 0abd0095..c65c5d13 100644 --- a/Microsoft.WindowsAzure.Storage/tests/cloud_table_test.cpp +++ b/Microsoft.WindowsAzure.Storage/tests/cloud_table_test.cpp @@ -68,7 +68,7 @@ SUITE(Table) CHECK(table1.uri().primary_uri() == uri.primary_uri()); CHECK(table1.uri().secondary_uri() == uri.secondary_uri()); - utility::string_t sas_token(U("sv=2012-02-12&tn=people&st=2013-05-15T16%3A20%3A36Z&se=2013-05-15T17%3A20%3A36Z&sp=raud&sig=mysignature")); + utility::string_t sas_token(U("se=2013-05-15T17%3A20%3A36Z&sig=mysignature&sp=raud&st=2013-05-15T16%3A20%3A36Z&sv=2012-02-12&tn=people")); azure::storage::storage_uri sas_uri(web::http::uri(U("https://myaccount.table.core.windows.net/mytable?tn=people&sp=raud&sv=2012-02-12&se=2013-05-15T17%3A20%3A36Z&st=2013-05-15T16%3A20%3A36Z&sig=mysignature")), web::http::uri(U("https://myaccount-secondary.table.core.windows.net/mytable?tn=people&sp=raud&sv=2012-02-12&se=2013-05-15T17%3A20%3A36Z&st=2013-05-15T16%3A20%3A36Z&sig=mysignature"))); @@ -106,15 +106,7 @@ SUITE(Table) azure::storage::storage_uri sas_uri(web::http::uri(U("https://myaccount.table.core.windows.net/mytable?tn=people&sp=raud&sv=2012-02-12&se=2013-05-15T17%3A20%3A36Z&st=2013-05-15T16%3A20%3A36Z&sig=mysignature")), web::http::uri(U("https://myaccount-secondary.table.core.windows.net/mytable?tn=people&sp=raud&sv=2012-02-12&se=2013-05-15T17%3A20%3A36Z&st=2013-05-15T16%3A20%3A36Z&sig=mysignature"))); azure::storage::storage_credentials sas_credentials(sas_token); - azure::storage::cloud_table table2(sas_uri, sas_credentials); - - CHECK(table2.service_client().base_uri().primary_uri() == expected_primary_uri); - CHECK(table2.service_client().base_uri().secondary_uri() == expected_secondary_uri); - CHECK(table2.service_client().credentials().is_sas()); - CHECK(table2.service_client().credentials().sas_token() == sas_token); - CHECK(table2.name().compare(U("mytable")) == 0); - CHECK(table2.uri().primary_uri() == uri.primary_uri()); - CHECK(table2.uri().secondary_uri() == uri.secondary_uri()); + CHECK_THROW(azure::storage::cloud_table(sas_uri, sas_credentials), std::invalid_argument); azure::storage::storage_credentials invalid_sas_credentials(invalid_sas_token); diff --git a/Microsoft.WindowsAzure.Storage/tests/executor_test.cpp b/Microsoft.WindowsAzure.Storage/tests/executor_test.cpp index e74643e5..ff7137b0 100644 --- a/Microsoft.WindowsAzure.Storage/tests/executor_test.cpp +++ b/Microsoft.WindowsAzure.Storage/tests/executor_test.cpp @@ -141,7 +141,7 @@ SUITE(Core) CHECK_THROW(azure::storage::storage_uri(U("http://www.microsoft.com/test1?parameter=value1"), U("http://127.0.0.1:10000/account/test1?parameter=value2")), std::invalid_argument); } - TEST(storage_exception) + TEST_FIXTURE(test_base, storage_exception) { azure::storage::cloud_blob blob(azure::storage::storage_uri(U("http://www.nonexistenthost.com/test1"))); diff --git a/Microsoft.WindowsAzure.Storage/tests/result_iterator_test.cpp b/Microsoft.WindowsAzure.Storage/tests/result_iterator_test.cpp index 360c13fe..5ae749df 100644 --- a/Microsoft.WindowsAzure.Storage/tests/result_iterator_test.cpp +++ b/Microsoft.WindowsAzure.Storage/tests/result_iterator_test.cpp @@ -43,7 +43,12 @@ class test_result_provider return azure::storage::result_segment(); } - if (maximum_results == 0 || maximum_results > m_max_results_per_segment) + if (m_max_results_per_segment != 0) + { + CHECK(maximum_results <= m_max_results_per_segment); + } + + if (maximum_results == 0) { // each segment return up to "m_max_results_per_segment" results maximum_results = m_max_results_per_segment; @@ -94,15 +99,12 @@ result_generator_type get_result_generator(test_result_provider& result_provider void result_iterator_check_result_number(result_generator_type generator, size_t max_results, size_t max_results_per_segment, size_t num_of_results) { - azure::storage::result_iterator end_of_results; azure::storage::result_iterator iter(generator, max_results, max_results_per_segment); int count = 0; - while (iter != end_of_results) + for (auto& item : iter) { count++; - CHECK(*iter == count); - - iter++; + CHECK(item == count); } CHECK_EQUAL(num_of_results, (size_t)count); diff --git a/Microsoft.WindowsAzure.Storage/version.rc b/Microsoft.WindowsAzure.Storage/version.rc index 899276b8..24aaf6e3 100644 Binary files a/Microsoft.WindowsAzure.Storage/version.rc and b/Microsoft.WindowsAzure.Storage/version.rc differ diff --git a/README.md b/README.md index 559a4478..f8bbc630 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,6 @@ The Azure Storage Client Library for C++ allows you to build applications agains - Insert/Peek Queue Messages - Advanced Queue Operations -Please check details on [API reference documents](http://azure.github.io/azure-storage-cpp). - # Getting started For the best development experience, we recommend that developers use the official Microsoft NuGet packages for libraries. NuGet packages are regularly updated with new functionality and hotfixes. diff --git a/build.proj b/build.proj index 394d8179..a9aa2952 100644 --- a/build.proj +++ b/build.proj @@ -1,35 +1,49 @@ + DefaultTargets="Clean;BuildAll"> - - + + Configuration=Debug;Platform=Win32 + + + Configuration=Release;Platform=Win32 + + + Configuration=Debug;Platform=x64 + + + Configuration=Release;Platform=x64 + + + Configuration=Debug;Platform=Win32 + + + Configuration=Release;Platform=Win32 + + + Configuration=Debug;Platform=x64 + + + Configuration=Release;Platform=x64 + - + - - - + + + + + @@ -38,7 +52,7 @@ @@ -47,7 +61,7 @@ @@ -56,7 +70,7 @@ @@ -65,7 +79,7 @@ diff --git a/tools/copy_Signed.bat b/tools/copy_Signed.bat new file mode 100644 index 00000000..88c7684f --- /dev/null +++ b/tools/copy_Signed.bat @@ -0,0 +1,27 @@ +@echo off + +pushd %~dp0 + +if NOT EXIST %1\Signed echo %1\Signed not exists && goto copyfailed + +echo Copying signed DLLs and the pdbs to the final drop location... +copy /y %1\Signed\v110_Win32_Debug_wastorage.dll ..\Microsoft.WindowsAzure.Storage\v110\Win32\Debug\wastorage.dll +copy /y %1\Signed\v110_x64_Debug_wastorage.dll ..\Microsoft.WindowsAzure.Storage\v110\x64\Debug\wastorage.dll +copy /y %1\Signed\v110_Win32_Release_wastorage.dll ..\Microsoft.WindowsAzure.Storage\v110\Win32\Release\wastorage.dll +copy /y %1\Signed\v110_x64_Release_wastorage.dll ..\Microsoft.WindowsAzure.Storage\v110\x64\Release\wastorage.dll +copy /y %1\Signed\v120_Win32_Debug_wastorage.dll ..\Microsoft.WindowsAzure.Storage\v120\Win32\Debug\wastorage.dll +copy /y %1\Signed\v120_x64_Debug_wastorage.dll ..\Microsoft.WindowsAzure.Storage\v120\x64\Debug\wastorage.dll +copy /y %1\Signed\v120_Win32_Release_wastorage.dll ..\Microsoft.WindowsAzure.Storage\v120\Win32\Release\wastorage.dll +copy /y %1\Signed\v120_x64_Release_wastorage.dll ..\Microsoft.WindowsAzure.Storage\v120\x64\Release\wastorage.dll +if %ERRORLEVEL% neq 0 goto copyfailed +echo OK + +popd +exit /b 0 + +:copyfailed + +echo FAILED. Unable to copy DLLs + +popd +exit /b -1 \ No newline at end of file diff --git a/tools/copy_ToSign.bat b/tools/copy_ToSign.bat new file mode 100644 index 00000000..ee639515 --- /dev/null +++ b/tools/copy_ToSign.bat @@ -0,0 +1,30 @@ +@echo off + +pushd %~dp0 + +echo Clean up the existing ToSign folder +if EXIST %1\ToSign rmdir /s /q %1\ToSign +mkdir %1\ToSign +if %ERRORLEVEL% neq 0 goto copyfailed +echo OK + +echo Copying DLLs to signing source directory +copy /y ..\Microsoft.WindowsAzure.Storage\v110\Win32\Debug\wastorage.dll %1\ToSign\v110_Win32_Debug_wastorage.dll +copy /y ..\Microsoft.WindowsAzure.Storage\v110\x64\Debug\wastorage.dll %1\ToSign\v110_x64_Debug_wastorage.dll +copy /y ..\Microsoft.WindowsAzure.Storage\v110\Win32\Release\wastorage.dll %1\ToSign\v110_Win32_Release_wastorage.dll +copy /y ..\Microsoft.WindowsAzure.Storage\v110\x64\Release\wastorage.dll %1\ToSign\v110_x64_Release_wastorage.dll +copy /y ..\Microsoft.WindowsAzure.Storage\v120\Win32\Debug\wastorage.dll %1\ToSign\v120_Win32_Debug_wastorage.dll +copy /y ..\Microsoft.WindowsAzure.Storage\v120\x64\Debug\wastorage.dll %1\ToSign\v120_x64_Debug_wastorage.dll +copy /y ..\Microsoft.WindowsAzure.Storage\v120\Win32\Release\wastorage.dll %1\ToSign\v120_Win32_Release_wastorage.dll +copy /y ..\Microsoft.WindowsAzure.Storage\v120\x64\Release\wastorage.dll %1\ToSign\v120_x64_Release_wastorage.dll +if %ERRORLEVEL% neq 0 goto copyfailed +echo OK + +popd +exit /b 0 + +:copyfailed + +echo FAILED. Unable to copy DLLs +popd +exit /b -1 \ No newline at end of file