| // Copyright 2026 Google LLC |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // https://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // |
| |
| #include "formats/registry.h" |
| |
| #include <memory> |
| #include <utility> |
| |
| #include "absl/status/status.h" |
| #include "absl/status/statusor.h" |
| #include "absl/strings/str_cat.h" |
| #include "absl/strings/string_view.h" |
| #include "formats/format.h" |
| #include "riegeli/bytes/reader.h" |
| |
| namespace credentio { |
| |
| void FormatRegistry::Register(std::unique_ptr<Format> format) { |
| for (const auto& media_type : format->mime_types()) { |
| format_for_type_[media_type].push_back(format.get()); |
| } |
| formats_.push_back(std::move(format)); |
| } |
| |
| absl::StatusOr<const Format*> FormatRegistry::GetFormat( |
| absl::string_view media_type) const { |
| auto it = format_for_type_.find(media_type); |
| if (it == format_for_type_.end()) { |
| return absl::UnimplementedError( |
| absl::StrCat("Unsupported media type: ", media_type)); |
| } |
| if (it->second.empty()) { |
| return absl::UnimplementedError( |
| absl::StrCat("Unsupported media type: ", media_type)); |
| } |
| if (it->second.size() == 1) { |
| return it->second[0]; |
| } |
| return absl::UnimplementedError( |
| absl::StrCat("Multiple formats support media type: ", media_type)); |
| } |
| |
| absl::StatusOr<const Format*> FormatRegistry::GetFormat( |
| riegeli::Reader& asset) const { |
| for (const std::unique_ptr<Format>& format : formats_) { |
| absl::StatusOr<bool> is_supported = format->assessor()->IsSupported(asset); |
| if (is_supported.ok() && *is_supported) { |
| // Asset is supported by this format. |
| return format.get(); |
| } |
| // Errors are treated as unsupported by the format. |
| } |
| return absl::UnimplementedError("No applicable Format found"); |
| } |
| |
| absl::StatusOr<const Format*> FormatRegistry::GetFormat( |
| absl::string_view media_type, riegeli::Reader& asset) const { |
| auto it = format_for_type_.find(media_type); |
| if (it == format_for_type_.end()) { |
| return absl::UnimplementedError( |
| absl::StrCat("Unsupported media type: ", media_type)); |
| } |
| if (it->second.empty()) { |
| return absl::UnimplementedError( |
| absl::StrCat("Unsupported media type: ", media_type)); |
| } |
| if (it->second.size() == 1) { |
| return it->second[0]; |
| } |
| for (const Format* format : it->second) { |
| absl::StatusOr<bool> is_supported = format->assessor()->IsSupported(asset); |
| if (is_supported.ok() && *is_supported) { |
| // Asset is supported by this format. |
| return format; |
| } |
| // Errors are treated as unsupported by the format. |
| } |
| return absl::UnimplementedError("No applicable Format found"); |
| } |
| |
| } // namespace credentio |