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
104 size_t ReadToCount(
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() : m_filehandle(NULL), m_baseOffset(0), m_length(0), m_offset(0)
231 {
232 }
233#endif
234
235 // Rewind seeks back to 0
236 void Rewind() override { this->m_offset = 0; }
237
238 int64_t Length() const override { return this->m_length; }
239 };
240
241 } // namespace _internal
242
247 class FileBodyStream final : public BodyStream {
248 private:
249 // immutable
250#if defined(AZ_PLATFORM_WINDOWS)
251 void* m_filehandle;
252#elif defined(AZ_PLATFORM_POSIX)
253 int m_fileDescriptor;
254#endif
255 // mutable
256 std::unique_ptr<_internal::RandomAccessFileBodyStream> m_randomAccessFileBodyStream;
257
258 size_t OnRead(uint8_t* buffer, size_t count, Azure::Core::Context const& context) override;
259
260 public:
272 FileBodyStream(const std::string& filename);
273
279
281 void Rewind() override;
282
283 int64_t Length() const override;
284 };
285
291 private:
292 BodyStream* m_bodyStream;
293 int64_t m_bytesTransferred;
294 std::function<void(int64_t bytesTransferred)> m_callback;
295
296 private:
297 size_t OnRead(uint8_t* buffer, size_t count, Azure::Core::Context const& context) override;
298
299 public:
311 BodyStream& bodyStream,
312 std::function<void(int64_t bytesTransferred)> callback);
313
315 void Rewind() override;
316
317 int64_t Length() const override;
318 };
319}}} // 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 ...
Definition body_stream.cpp:63
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...
Definition body_stream.cpp:45
A concrete implementation of Azure::Core::IO::BodyStream used for reading data from a file.
Definition body_stream.hpp:247
int64_t Length() const override
Get the length of the data.
Definition body_stream.cpp:194
void Rewind() override
Rewind seeks the current stream to the start of the file.
Definition body_stream.cpp:192
~FileBodyStream()
Closes the file and cleans up any resources.
Definition body_stream.cpp:170
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:290
int64_t Length() const override
Get the length of the data.
Definition body_stream.cpp:222
void Rewind() override
Rewind seeks the current stream to the beginning.
Definition body_stream.cpp:203
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.