azure-core
Loading...
Searching...
No Matches
body_stream.hpp
Go to the documentation of this file.
1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
9#pragma once
10
12
13#if defined(AZ_PLATFORM_POSIX)
14#include <unistd.h>
15#endif
16
18
19#include <algorithm>
20#include <cstdint>
21#include <cstdio>
22#include <cstring>
23#include <functional>
24#include <memory>
25#include <vector>
26
27namespace Azure { namespace Core { namespace IO {
28
32 class BodyStream {
33 private:
45 virtual size_t OnRead(uint8_t* buffer, size_t count, Azure::Core::Context const& context) = 0;
46
47 public:
52 virtual ~BodyStream() = default;
53
58 virtual int64_t Length() const = 0;
59
64 virtual void Rewind()
65 {
67 false,
68 "The specified BodyStream doesn't support Rewind which is required to guarantee fault "
69 "tolerance when retrying any operation. Consider creating a MemoryBodyStream or "
70 "FileBodyStream, which are rewindable.");
71 }
72
83 size_t Read(
84 uint8_t* buffer,
85 size_t count,
87 {
88 AZURE_ASSERT(buffer || count == 0);
89
90 context.ThrowIfCancelled();
91 return OnRead(buffer, count, context);
92 }
93
105 uint8_t* buffer,
106 size_t count,
107 Azure::Core::Context const& context = Azure::Core::Context());
108
117 std::vector<uint8_t> ReadToEnd(Azure::Core::Context const& context = Azure::Core::Context());
118 };
119
123 class MemoryBodyStream final : public BodyStream {
124 private:
125 const uint8_t* m_data;
126 size_t m_length;
127 size_t m_offset = 0;
128
129 size_t OnRead(uint8_t* buffer, size_t count, Azure::Core::Context const& context) override;
130
131 public:
132 // Forbid constructor for rval so we don't end up storing dangling ptr
133 MemoryBodyStream(std::vector<uint8_t> const&&) = delete;
134
140 MemoryBodyStream(std::vector<uint8_t> const& buffer)
141 : MemoryBodyStream(buffer.data(), buffer.size())
142 {
143 }
144
152 explicit MemoryBodyStream(const uint8_t* data, size_t length) : m_data(data), m_length(length)
153 {
154 AZURE_ASSERT(data || length == 0);
155 }
156
157 int64_t Length() const override { return this->m_length; }
158
160 void Rewind() override { m_offset = 0; }
161 };
162
163 namespace _internal {
168 class RandomAccessFileBodyStream final : public BodyStream {
169 private:
170 // immutable
171#if defined(AZ_PLATFORM_POSIX)
172 int m_fileDescriptor;
173#elif defined(AZ_PLATFORM_WINDOWS)
174 void* m_filehandle;
175#endif
176 int64_t m_baseOffset;
177 int64_t m_length;
178 // mutable
179 int64_t m_offset;
180
181 size_t OnRead(uint8_t* buffer, size_t count, Azure::Core::Context const& context) override;
182
183 public:
184#if defined(AZ_PLATFORM_POSIX)
199 RandomAccessFileBodyStream(int fileDescriptor, int64_t offset, int64_t length)
200 : m_fileDescriptor(fileDescriptor), m_baseOffset(offset), m_length(length), m_offset(0)
201 {
202 AZURE_ASSERT(fileDescriptor >= 0 && offset >= 0 && length >= 0);
203 }
204
205 RandomAccessFileBodyStream() : m_fileDescriptor(0), m_baseOffset(0), m_length(0), m_offset(0)
206 {
207 }
208
209#elif defined(AZ_PLATFORM_WINDOWS)
224 RandomAccessFileBodyStream(void* fileHandle, int64_t offset, int64_t length)
225 : m_filehandle(fileHandle), m_baseOffset(offset), m_length(length), m_offset(0)
226 {
227 AZURE_ASSERT(fileHandle && offset >= 0 && length >= 0);
228 }
229
230 RandomAccessFileBodyStream()
231 : m_filehandle(nullptr), m_baseOffset(0), m_length(0), m_offset(0)
232 {
233 }
234#endif
235
236 // Rewind seeks back to 0
237 void Rewind() override { this->m_offset = 0; }
238
239 int64_t Length() const override { return this->m_length; }
240 };
241
242 } // namespace _internal
243
248 class FileBodyStream final : public BodyStream {
249 private:
250 // immutable
251#if defined(AZ_PLATFORM_WINDOWS)
252 void* m_filehandle;
253#elif defined(AZ_PLATFORM_POSIX)
254 int m_fileDescriptor;
255#endif
256 // mutable
257 std::unique_ptr<_internal::RandomAccessFileBodyStream> m_randomAccessFileBodyStream;
258
259 size_t OnRead(uint8_t* buffer, size_t count, Azure::Core::Context const& context) override;
260
261 public:
273 FileBodyStream(const std::string& filename);
274
279 ~FileBodyStream() override;
280
282 void Rewind() override;
283
284 int64_t Length() const override;
285 };
286
292 private:
293 BodyStream* m_bodyStream;
294 int64_t m_bytesTransferred;
295 std::function<void(int64_t bytesTransferred)> m_callback;
296
297 private:
298 size_t OnRead(uint8_t* buffer, size_t count, Azure::Core::Context const& context) override;
299
300 public:
312 BodyStream& bodyStream,
313 std::function<void(int64_t bytesTransferred)> callback);
314
316 void Rewind() override;
317
318 int64_t Length() const override;
319 };
320}}} // namespace Azure::Core::IO
#define AZURE_ASSERT(exp)
Azure specific assert macro.
Definition azure_assert.hpp:51
#define AZURE_ASSERT_MSG(exp, msg)
Azure specific assert macro with message.
Definition azure_assert.hpp:53
A context is a node within a unidirectional tree that represents deadlines and key/value pairs.
Definition context.hpp:72
void ThrowIfCancelled() const
Throws if the context is cancelled.
Definition context.hpp:364
Used to read data to/from a service.
Definition body_stream.hpp:32
virtual int64_t Length() const =0
Get the length of the data.
virtual void Rewind()
Resets the stream back to the beginning (for retries).
Definition body_stream.hpp:64
virtual ~BodyStream()=default
Destructs BodyStream.
std::vector< uint8_t > ReadToEnd(Azure::Core::Context const &context=Azure::Core::Context())
Read Azure::Core::IO::BodyStream until the stream is read to end, allocating memory for the entirety ...
size_t Read(uint8_t *buffer, size_t count, Azure::Core::Context const &context=Azure::Core::Context())
Read portion of data into a buffer.
Definition body_stream.hpp:83
size_t ReadToCount(uint8_t *buffer, size_t count, Azure::Core::Context const &context=Azure::Core::Context())
Read Azure::Core::IO::BodyStream into a buffer until the buffer is filled, or until the stream is rea...
A concrete implementation of Azure::Core::IO::BodyStream used for reading data from a file.
Definition body_stream.hpp:248
int64_t Length() const override
Get the length of the data.
FileBodyStream(const std::string &filename)
Constructs FileBodyStream from a file name.
~FileBodyStream() override
Closes the file and cleans up any resources.
void Rewind() override
Rewind seeks the current stream to the start of the file.
Azure::Core::IO::BodyStream providing data from an initialized memory buffer.
Definition body_stream.hpp:123
MemoryBodyStream(std::vector< uint8_t > const &buffer)
Construct using vector of bytes.
Definition body_stream.hpp:140
MemoryBodyStream(const uint8_t *data, size_t length)
Construct using buffer pointer and its size.
Definition body_stream.hpp:152
void Rewind() override
Rewind seeks the current stream to the start of the buffer.
Definition body_stream.hpp:160
int64_t Length() const override
Get the length of the data.
Definition body_stream.hpp:157
A concrete implementation of Azure::Core::IO::BodyStream that wraps another stream and reports progre...
Definition body_stream.hpp:291
ProgressBodyStream(BodyStream &bodyStream, std::function< void(int64_t bytesTransferred)> callback)
Constructs ProgressBodyStream from a BodyStream.
int64_t Length() const override
Get the length of the data.
void Rewind() override
Rewind seeks the current stream to the beginning.
Context for canceling long running operations.
Compute the hash value for the input binary data, using SHA256, SHA384 and SHA512.
Definition azure_assert.hpp:57
Platform-specific macros.