| // Copyright 2019 The Fuchsia Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "src/modular/bin/sessionmgr/annotations.h" | |
| namespace modular::annotations { | |
| using Annotation = fuchsia::modular::Annotation; | |
| std::vector<Annotation> Merge(std::vector<Annotation> a, std::vector<Annotation> b) { | |
| std::vector<Annotation> result; | |
| std::map<std::string, Annotation> b_by_key; | |
| std::transform(std::make_move_iterator(b.begin()), std::make_move_iterator(b.end()), | |
| std::inserter(b_by_key, b_by_key.end()), [](Annotation&& annotation) { | |
| return std::make_pair(annotation.key, std::move(annotation)); | |
| }); | |
| for (auto it = std::make_move_iterator(a.begin()); it != std::make_move_iterator(a.end()); ++it) { | |
| // Omit annotations in `a` that have `null` values. | |
| if (!it->value) { | |
| continue; | |
| } | |
| // If `b` contains an annotation with the same key, use its value, unless it's null, | |
| // in which case it's omitted. | |
| if (b_by_key.count(it->key)) { | |
| if (b_by_key[it->key].value) { | |
| result.push_back(std::move(b_by_key.at(it->key))); | |
| } | |
| continue; | |
| } | |
| result.push_back(std::move(*it)); | |
| } | |
| for (auto it = std::make_move_iterator(b_by_key.begin()); | |
| it != std::make_move_iterator(b_by_key.end()); ++it) { | |
| // Omit annotations in `b` that have `null` values. | |
| // We have already omitted the ones from `a` that have the same key. | |
| if (!it->second.value) { | |
| continue; | |
| } | |
| result.push_back(std::move(it->second)); | |
| } | |
| return result; | |
| } | |
| std::string ToInspect(const fuchsia::modular::AnnotationValue& value) { | |
| std::string text; | |
| switch (value.Which()) { | |
| case fuchsia::modular::AnnotationValue::Tag::kText: | |
| text = value.text(); | |
| break; | |
| case fuchsia::modular::AnnotationValue::Tag::kBytes: | |
| text = "bytes"; | |
| break; | |
| case fuchsia::modular::AnnotationValue::Tag::kBuffer: | |
| text = "buffer"; | |
| break; | |
| case fuchsia::modular::AnnotationValue::Tag::kUnknown: | |
| text = "unknown"; | |
| break; | |
| case fuchsia::modular::AnnotationValue::Tag::Invalid: | |
| text = "invalid"; | |
| break; | |
| } | |
| return text; | |
| } | |
| fuchsia::session::Annotation ToSessionAnnotation(const fuchsia::modular::Annotation& annotation) { | |
| std::unique_ptr<fuchsia::session::Value> value; | |
| if (annotation.value->is_buffer()) { | |
| fuchsia::mem::Buffer buffer; | |
| annotation.value->buffer().Clone(&buffer); | |
| value = std::make_unique<fuchsia::session::Value>( | |
| fuchsia::session::Value::WithBuffer(std::move(buffer))); | |
| } else { | |
| value = std::make_unique<fuchsia::session::Value>( | |
| fuchsia::session::Value::WithText(std::string{annotation.value->text()})); | |
| } | |
| return fuchsia::session::Annotation{.key = std::string{annotation.key}, | |
| .value = std::move(value)}; | |
| } | |
| fuchsia::session::Annotations ToSessionAnnotations( | |
| const std::vector<fuchsia::modular::Annotation>& annotations) { | |
| std::vector<fuchsia::session::Annotation> custom_annotations; | |
| custom_annotations.reserve(annotations.size()); | |
| for (const fuchsia::modular::Annotation& annotation : annotations) { | |
| custom_annotations.push_back(modular::annotations::ToSessionAnnotation(annotation)); | |
| } | |
| fuchsia::session::Annotations session_annotations; | |
| session_annotations.set_custom_annotations(std::move(custom_annotations)); | |
| return session_annotations; | |
| } | |
| } // namespace modular::annotations | |
| namespace session::annotations { | |
| fuchsia::modular::Annotation ToModularAnnotation(const fuchsia::session::Annotation& annotation) { | |
| std::unique_ptr<fuchsia::modular::AnnotationValue> value; | |
| if (annotation.value->is_buffer()) { | |
| fuchsia::mem::Buffer buffer; | |
| annotation.value->buffer().Clone(&buffer); | |
| value = std::make_unique<fuchsia::modular::AnnotationValue>( | |
| fuchsia::modular::AnnotationValue::WithBuffer(std::move(buffer))); | |
| } else { | |
| value = std::make_unique<fuchsia::modular::AnnotationValue>( | |
| fuchsia::modular::AnnotationValue::WithText(std::string{annotation.value->text()})); | |
| } | |
| return fuchsia::modular::Annotation{.key = annotation.key, .value = std::move(value)}; | |
| } | |
| std::vector<fuchsia::modular::Annotation> ToModularAnnotations( | |
| const fuchsia::session::Annotations& annotations) { | |
| if (!annotations.has_custom_annotations()) { | |
| return {}; | |
| } | |
| std::vector<fuchsia::modular::Annotation> modular_annotations; | |
| for (const auto& annotation : annotations.custom_annotations()) { | |
| modular_annotations.push_back(ToModularAnnotation(annotation)); | |
| } | |
| return modular_annotations; | |
| } | |
| } // namespace session::annotations |