Home | History | Annotate | Download | only in message
      1 // Copyright 2012 Google Inc. All Rights Reserved.
      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 //     http://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 #include "polo/pairing/message/configurationmessage.h"
     16 
     17 #include <algorithm>
     18 #include <sstream>
     19 #include <string>
     20 
     21 namespace polo {
     22 namespace pairing {
     23 namespace message {
     24 
     25 ConfigurationMessage::ConfigurationMessage(
     26     const encoding::EncodingOption& encoding,
     27     message::OptionsMessage::ProtocolRole client_role)
     28     : PoloMessage(PoloMessage::kConfiguration),
     29       encoding_(encoding),
     30       client_role_(client_role) {
     31 }
     32 
     33 const encoding::EncodingOption& ConfigurationMessage::encoding() const {
     34   return encoding_;
     35 }
     36 
     37 OptionsMessage::ProtocolRole ConfigurationMessage::client_role() const {
     38   return client_role_;
     39 }
     40 
     41 std::string ConfigurationMessage::ToString() const {
     42   std::ostringstream ss;
     43   ss << "[ConfigurationMessage encoding=" << encoding_.ToString()
     44       << ", client_role=" << client_role_ << "]";
     45   return ss.str();
     46 }
     47 
     48 ConfigurationMessage* ConfigurationMessage::GetBestConfiguration(
     49     const OptionsMessage &local_options,
     50     const OptionsMessage &peer_options) {
     51   // Compute the intersection of the available encodings. The sets use the
     52   // 'less' comparator so they are ordered using EncodingOption's less-than
     53   // operator.
     54   encoding::EncodingOption::EncodingSet common_outputs;
     55   std::insert_iterator<encoding::EncodingOption::EncodingSet> outputs_inserter(
     56       common_outputs,
     57       common_outputs.begin());
     58   set_intersection(local_options.output_encodings().begin(),
     59                    local_options.output_encodings().end(),
     60                    peer_options.output_encodings().begin(),
     61                    peer_options.output_encodings().end(),
     62                    outputs_inserter,
     63                    encoding::EncodingOption::EncodingOptionComparator());
     64 
     65   encoding::EncodingOption::EncodingSet common_inputs;
     66   std::insert_iterator<encoding::EncodingOption::EncodingSet> inputs_inserter(
     67       common_inputs,
     68       common_inputs.begin());
     69   set_intersection(local_options.input_encodings().begin(),
     70                    local_options.input_encodings().end(),
     71                    peer_options.input_encodings().begin(),
     72                    peer_options.input_encodings().end(),
     73                    inputs_inserter,
     74                    encoding::EncodingOption::EncodingOptionComparator());
     75 
     76   if (common_outputs.size() == 0 || common_inputs.size() == 0) {
     77     return NULL;
     78   }
     79 
     80   const encoding::EncodingOption* best_input = NULL;
     81   const encoding::EncodingOption* best_output = NULL;
     82 
     83   // Use the last option as the best encoding since that one will be the most
     84   // complex based on the sorting order.
     85   if (common_outputs.size() > 0) {
     86     best_output = &*(--common_outputs.end());
     87   }
     88 
     89   if (common_inputs.size() > 0) {
     90     best_input = &*(--common_inputs.end());
     91   }
     92 
     93   if (local_options.protocol_role_preference()
     94       == OptionsMessage::kDisplayDevice) {
     95     if (best_input) {
     96       return new ConfigurationMessage(*best_input,
     97                                       OptionsMessage::kDisplayDevice);
     98     } else {
     99       return new ConfigurationMessage(*best_output,
    100                                       OptionsMessage::kInputDevice);
    101     }
    102   } else {
    103     if (best_output) {
    104       return new ConfigurationMessage(*best_output,
    105                                       OptionsMessage::kInputDevice);
    106     } else {
    107       return new ConfigurationMessage(*best_input,
    108                                       OptionsMessage::kDisplayDevice);
    109     }
    110   }
    111 }
    112 
    113 }  // namespace message
    114 }  // namespace pairing
    115 }  // namespace polo
    116