Google Cloud Storage C++ Client  1.40.2
A C++ Client Library for Google Cloud Storage
object_read_stream.h
Go to the documentation of this file.
1 // Copyright 2021 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_STORAGE_OBJECT_READ_STREAM_H
16 #define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_STORAGE_OBJECT_READ_STREAM_H
17 
18 #include "google/cloud/storage/internal/object_read_streambuf.h"
19 #include "google/cloud/storage/version.h"
20 #include <istream>
21 #include <map>
22 #include <memory>
23 #include <string>
24 
25 namespace google {
26 namespace cloud {
27 namespace storage {
29 
30 /// Represents the headers returned in a streaming upload or download operation.
31 using HeadersMap = std::multimap<std::string, std::string>;
32 
33 /**
34  * Defines a `std::basic_istream<char>` to read from a GCS Object.
35  */
36 class ObjectReadStream : public std::basic_istream<char> {
37  public:
38  /**
39  * Creates a stream not associated with any buffer.
40  *
41  * Attempts to use this stream will result in failures.
42  */
44 
45  /**
46  * Creates a stream associated with the given `streambuf`.
47  */
48  explicit ObjectReadStream(std::unique_ptr<internal::ObjectReadStreambuf> buf)
49  : std::basic_istream<char>(nullptr), buf_(std::move(buf)) {
50  // Initialize the basic_ios<> class
51  init(buf_.get());
52  }
53 
55 
57  ObjectReadStream tmp(std::move(rhs));
58  swap(tmp);
59  return *this;
60  }
61 
62  void swap(ObjectReadStream& rhs) {
63  std::basic_istream<char>::swap(rhs);
64  std::swap(buf_, rhs.buf_);
65  rhs.set_rdbuf(rhs.buf_.get());
66  set_rdbuf(buf_.get());
67  }
68 
71 
72  /// Closes the stream (if necessary).
73  ~ObjectReadStream() override;
74 
75  bool IsOpen() const { return static_cast<bool>(buf_) && buf_->IsOpen(); }
76 
77  /**
78  * Terminate the download, possibly before completing it.
79  */
80  void Close();
81 
82  /**
83  * Report any download errors.
84  *
85  * Note that errors may go undetected until the download completes.
86  */
87  Status const& status() const& { return buf_->status(); }
88 
89  /**
90  * The received CRC32C checksum and the MD5 hash values as reported by GCS.
91  *
92  * When the download is finalized (via `Close()` or the end of file) the GCS
93  * server reports the CRC32C checksum and, except for composite objects, the
94  * MD5 hash of the data. This class compares the locally computed and received
95  * hashes so applications can detect data download errors.
96  *
97  * The values are reported as comma separated `tag=value` pairs, e.g.
98  * `crc32c=AAAAAA==,md5=1B2M2Y8AsgTpgAmY7PhCfg==`. The format of this string
99  * is subject to change without notice, they are provided for informational
100  * purposes only.
101  *
102  * @see https://cloud.google.com/storage/docs/hashes-etags for more
103  * information on checksums and hashes in GCS.
104  */
105  std::string const& received_hash() const { return buf_->received_hash(); }
106 
107  /**
108  * The locally computed checksum and hashes, as a string.
109  *
110  * This object computes the CRC32C checksum and MD5 hash of the downloaded
111  * data. Note that there are several cases where these values may be empty or
112  * irrelevant, for example:
113  * - When reading only a portion of a blob the hash of that portion is
114  * irrelevant, note that GCS only reports the hashes for the full blob.
115  * - The application may disable the CRC32C and/or the MD5 hash computation.
116  *
117  * The string has the same format as the value returned by `received_hash()`.
118  * Note that the format of this string is also subject to change without
119  * notice.
120  *
121  * @see https://cloud.google.com/storage/docs/hashes-etags for more
122  * information on checksums and hashes in GCS.
123  */
124  std::string const& computed_hash() const { return buf_->computed_hash(); }
125 
126  /**
127  * The headers (if any) returned by the service. For debugging only.
128  *
129  * @warning The contents of these headers may change without notice. Unless
130  * documented in the API, headers may be removed or added by the service.
131  * Also note that the client library uses both the XML and JSON API,
132  * choosing between them based on the feature set (some functionality is
133  * only available through the JSON API), and performance. Consequently,
134  * the headers may be different on requests using different features.
135  * Likewise, the headers may change from one version of the library to the
136  * next, as we find more (or different) opportunities for optimization.
137  */
138  HeadersMap const& headers() const { return buf_->headers(); }
139 
140  //@{
141  /**
142  * @name Object metadata information.
143  *
144  * When downloading an object a limited amount of information about the
145  * object's metadata is returned as part of the download. Some of this
146  * information is important for applications performing multiple downloads
147  * (maybe of different ranges) of the same object. Such applications may
148  * want to use the generation number to guarantee all the downloads are
149  * actually referencing the same object. One could do this by first querying
150  * the metadata before the first download, but this is less efficient as it
151  * requires one additional server round trip.
152  *
153  * Note that all these attributes are `absl::optional<>`, as the attributes
154  * may not be known (or exist) if there is an error during the download. If
155  * the attribute is needed for the application's correctness the application
156  * should fetch the object metadata when the attribute is not available.
157  */
158  /// The object's generation at the time of the download, if known.
159  absl::optional<std::int64_t> const& generation() const {
160  return buf_->generation();
161  }
162 
163  /// The object's metageneration at the time of the download, if known.
164  absl::optional<std::int64_t> const& metageneration() const {
165  return buf_->metageneration();
166  }
167 
168  /// The object's storage class at the time of the download, if known.
169  absl::optional<std::string> const& storage_class() const {
170  return buf_->storage_class();
171  }
172 
173  /**
174  * The object's size at the time of the download, if known.
175  *
176  * If you are using [object transcoding] this represents the stored size of
177  * the object, the number of downloaded bytes (after decompression) may be
178  * larger.
179  *
180  * [object transcoding]: https://cloud.google.com/storage/docs/transcoding
181  */
182  absl::optional<std::uint64_t> const& size() const { return buf_->size(); }
183  //@}
184 
185  private:
186  std::unique_ptr<internal::ObjectReadStreambuf> buf_;
187 };
188 
190 } // namespace storage
191 } // namespace cloud
192 } // namespace google
193 
194 #endif // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_STORAGE_OBJECT_READ_STREAM_H