\brief Splits a GCS path to a bucket and an object. For example, "gs://bucket-name/path/to/file.txt" gets split into "bucket-name" and "path/to/file.txt". If fname only contains the bucket and empty_object_ok = true, the returned object is empty.
| 156 | /// If fname only contains the bucket and empty_object_ok = true, the returned |
| 157 | /// object is empty. |
| 158 | Status ParseGcsPath(StringPiece fname, bool empty_object_ok, string* bucket, |
| 159 | string* object) { |
| 160 | StringPiece scheme, bucketp, objectp; |
| 161 | io::ParseURI(fname, &scheme, &bucketp, &objectp); |
| 162 | if (scheme != "gs") { |
| 163 | return errors::InvalidArgument("GCS path doesn't start with 'gs://': ", |
| 164 | fname); |
| 165 | } |
| 166 | *bucket = string(bucketp); |
| 167 | if (bucket->empty() || *bucket == ".") { |
| 168 | return errors::InvalidArgument("GCS path doesn't contain a bucket name: ", |
| 169 | fname); |
| 170 | } |
| 171 | absl::ConsumePrefix(&objectp, "/"); |
| 172 | *object = string(objectp); |
| 173 | if (!empty_object_ok && object->empty()) { |
| 174 | return errors::InvalidArgument("GCS path doesn't contain an object name: ", |
| 175 | fname); |
| 176 | } |
| 177 | return Status::OK(); |
| 178 | } |
| 179 | |
| 180 | /// Appends a trailing slash if the name doesn't already have one. |
| 181 | string MaybeAppendSlash(const string& name) { |
no test coverage detected