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