// Copyright 2012 Google Inc. All Rights Reserved.
//
// 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
//
// http://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 "polo/pairing/message/configurationmessage.h"
#include <algorithm>
#include <sstream>
#include <string>
namespace polo {
namespace pairing {
namespace message {
ConfigurationMessage::ConfigurationMessage(
const encoding::EncodingOption& encoding,
message::OptionsMessage::ProtocolRole client_role)
: PoloMessage(PoloMessage::kConfiguration),
encoding_(encoding),
client_role_(client_role) {
}
const encoding::EncodingOption& ConfigurationMessage::encoding() const {
return encoding_;
}
OptionsMessage::ProtocolRole ConfigurationMessage::client_role() const {
return client_role_;
}
std::string ConfigurationMessage::ToString() const {
std::ostringstream ss;
ss << "[ConfigurationMessage encoding=" << encoding_.ToString()
<< ", client_role=" << client_role_ << "]";
return ss.str();
}
ConfigurationMessage* ConfigurationMessage::GetBestConfiguration(
const OptionsMessage &local_options,
const OptionsMessage &peer_options) {
// Compute the intersection of the available encodings. The sets use the
// 'less' comparator so they are ordered using EncodingOption's less-than
// operator.
encoding::EncodingOption::EncodingSet common_outputs;
std::insert_iterator<encoding::EncodingOption::EncodingSet> outputs_inserter(
common_outputs,
common_outputs.begin());
set_intersection(local_options.output_encodings().begin(),
local_options.output_encodings().end(),
peer_options.output_encodings().begin(),
peer_options.output_encodings().end(),
outputs_inserter,
encoding::EncodingOption::EncodingOptionComparator());
encoding::EncodingOption::EncodingSet common_inputs;
std::insert_iterator<encoding::EncodingOption::EncodingSet> inputs_inserter(
common_inputs,
common_inputs.begin());
set_intersection(local_options.input_encodings().begin(),
local_options.input_encodings().end(),
peer_options.input_encodings().begin(),
peer_options.input_encodings().end(),
inputs_inserter,
encoding::EncodingOption::EncodingOptionComparator());
if (common_outputs.size() == 0 || common_inputs.size() == 0) {
return NULL;
}
const encoding::EncodingOption* best_input = NULL;
const encoding::EncodingOption* best_output = NULL;
// Use the last option as the best encoding since that one will be the most
// complex based on the sorting order.
if (common_outputs.size() > 0) {
best_output = &*(--common_outputs.end());
}
if (common_inputs.size() > 0) {
best_input = &*(--common_inputs.end());
}
if (local_options.protocol_role_preference()
== OptionsMessage::kDisplayDevice) {
if (best_input) {
return new ConfigurationMessage(*best_input,
OptionsMessage::kDisplayDevice);
} else {
return new ConfigurationMessage(*best_output,
OptionsMessage::kInputDevice);
}
} else {
if (best_output) {
return new ConfigurationMessage(*best_output,
OptionsMessage::kInputDevice);
} else {
return new ConfigurationMessage(*best_input,
OptionsMessage::kDisplayDevice);
}
}
}
} // namespace message
} // namespace pairing
} // namespace polo