<commit_before>#pragma once

#include "routing/road_graph.hpp"
#include "routing/routing_settings.hpp"
#include "routing/segment.hpp"
#include "routing/turns.hpp"

#include "traffic/speed_groups.hpp"

#include "indexer/feature_altitude.hpp"

#include "geometry/polyline2d.hpp"

#include "base/followed_polyline.hpp"

#include "std/vector.hpp"
#include "std/set.hpp"
#include "std/string.hpp"

#include <limits>
#include <string>
#include <utility>
#include <vector>

namespace location
{
  class GpsInfo;
  class RouteMatchingInfo;
}

namespace routing
{
using SubrouteUid = uint64_t;
SubrouteUid constexpr kInvalidSubrouteId = std::numeric_limits<uint64_t>::max();

/// \brief The route is composed of one or several subroutes. Every subroute is composed of segments.
/// For every Segment is kept some attributes in the structure SegmentInfo.
class RouteSegment final
{
public:
  RouteSegment(Segment const & segment, turns::TurnItem const & turn, Junction const & junction,
               std::string const & street, double distFromBeginningMeters, double distFromBeginningMerc,
               double timeFromBeginningS, traffic::SpeedGroup traffic)
    : m_segment(segment)
    , m_turn(turn)
    , m_junction(junction)
    , m_street(street)
    , m_distFromBeginningMeters(distFromBeginningMeters)
    , m_distFromBeginningMerc(distFromBeginningMerc)
    , m_timeFromBeginningS(timeFromBeginningS)
    , m_traffic(traffic)
  {
  }

  Segment const & GetSegment() const { return m_segment; }
  turns::TurnItem const & GetTurn() const { return m_turn; }
  Junction const & GetJunction() const { return m_junction; }
  std::string const & GetStreet() const { return m_street; }
  double GetDistFromBeginningMeters() const { return m_distFromBeginningMeters; }
  double GetDistFromBeginningMerc() const { return m_distFromBeginningMerc; }
  double GetTimeFromBeginningS() const { return m_timeFromBeginningS; }
  traffic::SpeedGroup GetTraffic() const { return m_traffic; }

private:
  Segment m_segment;
  /// Turn (maneuver) information for the turn next to the |m_segment| if any.
  /// If not |m_turn::m_turn| is equal to TurnDirection::NoTurn.
  turns::TurnItem m_turn;
  Junction m_junction; ///< The front junction of segment.
  /// Street name of |m_segment| if any. Otherwise |m_street| is empty.
  std::string m_street;
  /// Distance from the route beginning to the farthest end of |m_segment| in meters.
  double m_distFromBeginningMeters = 0.0;
  /// Distance from the route beginning to the farthest end of |m_segment| in mercator.
  double m_distFromBeginningMerc = 0.0;
  /// ETA from the route beginning in seconds to reach the farthest from the route beginning end of |m_segment|.
  double m_timeFromBeginningS = 0.0;
  traffic::SpeedGroup m_traffic = traffic::SpeedGroup::Unknown;
};

class Route
{
public:
  using TTurns = vector<turns::TurnItem>;
  using TTimeItem = pair<uint32_t, double>;
  using TTimes = vector<TTimeItem>;
  using TStreetItem = pair<uint32_t, string>;
  using TStreets = vector<TStreetItem>;

  class SubrouteAttrs final
  {
  public:
    SubrouteAttrs() = default;
    SubrouteAttrs(Junction const & start, Junction const & finish)
      : m_start(start), m_finish(finish)
    {
    }

    Junction const & GetStart() const { return m_start; }
    Junction const & GetFinish() const { return m_finish; }

  private:
    Junction m_start;
    Junction m_finish;
  };

  /// \brief For every subroute some attributes are kept the following stucture.
  struct SubrouteSettings final
  {
    SubrouteSettings(RoutingSettings const & routingSettings, string const & router, SubrouteUid id)
      : m_routingSettings(routingSettings), m_router(router), m_id(id)
    {
    }

    RoutingSettings const m_routingSettings;
    string const m_router;
    /// Some subsystems (for example drape) which is used Route class need to have an id of any subroute.
    /// This subsystems may set the id and then use it. The id is kept in |m_id|.
    SubrouteUid const m_id = kInvalidSubrouteId;
  };

  explicit Route(string const & router)
    : m_router(router), m_routingSettings(GetCarRoutingSettings()) {}

  template <class TIter>
  Route(string const & router, TIter beg, TIter end)
    : m_router(router), m_routingSettings(GetCarRoutingSettings()), m_poly(beg, end)
  {
    Update();
  }

  Route(string const & router, vector<m2::PointD> const & points, string const & name = string());

  void Swap(Route & rhs);

  template <class TIter> void SetGeometry(TIter beg, TIter end)
  {
    if (beg == end)
      FollowedPolyline().Swap(m_poly);
    else
      FollowedPolyline(beg, end).Swap(m_poly);
    Update();
  }

  inline void SetTurnInstructions(TTurns && v) { m_turns = move(v); }
  inline void SetSectionTimes(TTimes && v) { m_times = move(v); }
  inline void SetStreetNames(TStreets && v) { m_streets = move(v); }
  inline void SetAltitudes(feature::TAltitudes && v) { m_altitudes = move(v); }
  inline void SetTraffic(vector<traffic::SpeedGroup> && v) { m_traffic = move(v); }

  template <class SI>
  void SetRouteSegments(SI && v) { m_routeSegments = std::forward<SI>(v); }

  uint32_t GetTotalTimeSec() const;
  uint32_t GetCurrentTimeToEndSec() const;

  FollowedPolyline const & GetFollowedPolyline() const { return m_poly; }

  string const & GetRouterId() const { return m_router; }
  m2::PolylineD const & GetPoly() const { return m_poly.GetPolyline(); }
  TTurns const & GetTurns() const { return m_turns; }
  feature::TAltitudes const & GetAltitudes() const { return m_altitudes; }
  vector<traffic::SpeedGroup> const & GetTraffic() const { return m_traffic; }
  vector<double> const & GetSegDistanceMeters() const { return m_poly.GetSegDistanceM(); }
  bool IsValid() const { return (m_poly.GetPolyline().GetSize() > 1); }

  double GetTotalDistanceMeters() const;
  double GetCurrentDistanceFromBeginMeters() const;
  double GetCurrentDistanceToEndMeters() const;
  double GetMercatorDistanceFromBegin() const;

  /// \brief GetCurrentTurn returns information about the nearest turn.
  /// \param distanceToTurnMeters is a distance from current position to the nearest turn.
  /// \param turn is information about the nearest turn.
  bool GetCurrentTurn(double & distanceToTurnMeters, turns::TurnItem & turn) const;

  /// \brief Returns a name of a street where the user rides at this moment.
  void GetCurrentStreetName(string &) const;

  /// \brief Returns a name of a street next to idx point of the path. Function avoids short unnamed links.
  void GetStreetNameAfterIdx(uint32_t idx, string &) const;

  /// @return true if GetNextTurn() returns a valid result in parameters, false otherwise.
  /// \param distanceToTurnMeters is a distance from current position to the second turn.
  /// \param turn is information about the second turn.
  /// @return true if its parameters are filled with correct result.
  /// \note All parameters are filled while a GetNextTurn function call.
  bool GetNextTurn(double & distanceToTurnMeters, turns::TurnItem & turn) const;
  /// \brief Extract information about zero, one or two nearest turns depending on current position.
  /// @return true if its parameter is filled with correct result. (At least with one element.)
  bool GetNextTurns(vector<turns::TurnItemDist> & turns) const;

  void GetCurrentDirectionPoint(m2::PointD & pt) const;

  /// @return true  If position was updated successfully (projection within gps error radius).
  bool MoveIterator(location::GpsInfo const & info) const;

  void MatchLocationToRoute(location::GpsInfo & location, location::RouteMatchingInfo & routeMatchingInfo) const;

  bool IsCurrentOnEnd() const;

  /// Add country name if we have no country filename to make route
  void AddAbsentCountry(string const & name);

  /// Get absent file list of a routing files for shortest path finding
  set<string> const & GetAbsentCountries() const { return m_absentCountries; }

  inline void SetRoutingSettings(RoutingSettings const & routingSettings)
  {
    m_routingSettings = routingSettings;
    Update();
  }

  // Subroute interface.
  /// \returns Number of subroutes.
  /// \note Intermediate points separate a route into several subroutes.
  size_t GetSubrouteCount() const;

  /// \brief Fills |info| with full subroute information.
  /// \param segmentIdx zero base number of subroute. |segmentIdx| should be less than GetSubrouteCount();
  /// \note |info| is a segment oriented route. Size of |info| is equal to number of points in |m_poly| - 1.
  /// Class Route is a point oriented route. While this conversion some attributes of zero point will be lost.
  /// It happens with zero turn for example.
  /// \note It's a fake implementation for single subroute which is equal to route without any
  /// intermediate points.
  /// Note. SegmentInfo::m_segment is filled with default Segment instance.
  /// Note. SegmentInfo::m_streetName is filled with an empty string.
  void GetSubrouteInfo(size_t segmentIdx, std::vector<RouteSegment> & segments) const;

  void GetSubrouteAttrs(size_t segmentIdx, SubrouteAttrs & info) const;

  /// \returns Subroute settings by |segmentIdx|.
  // @TODO(bykoianko) This method should return SubrouteSettings by reference. Now it returns by value
  // because of fake implementation.
  SubrouteSettings const GetSubrouteSettings(size_t segmentIdx) const;

  /// \brief Sets subroute unique id (|subrouteUid|) by |segmentIdx|.
  /// \note |subrouteUid| is a permanent id of a subroute. This id can be used to address to a subroute
  /// after the route is removed.
  void SetSubrouteUid(size_t segmentIdx, SubrouteUid subrouteUid);

private:
  friend string DebugPrint(Route const & r);

  /// Call this fucnction when geometry have changed.
  void Update();
  double GetPolySegAngle(size_t ind) const;
  TTurns::const_iterator GetCurrentTurn() const;
  TStreets::const_iterator GetCurrentStreetNameIterAfter(FollowedPolyline::Iter iter) const;

  Junction GetJunction(size_t pointIdx) const;

  string m_router;
  RoutingSettings m_routingSettings;
  string m_name;

  FollowedPolyline m_poly;
  FollowedPolyline m_simplifiedPoly;

  set<string> m_absentCountries;

  TTurns m_turns;
  TTimes m_times;
  TStreets m_streets;
  feature::TAltitudes m_altitudes;
  vector<traffic::SpeedGroup> m_traffic;

  std::vector<RouteSegment> m_routeSegments;

  mutable double m_currentTime;

  // Subroute
  SubrouteUid m_subrouteUid = kInvalidSubrouteId;
};
} // namespace routing
<commit_msg>Review fixes.<commit_after>#pragma once

#include "routing/road_graph.hpp"
#include "routing/routing_settings.hpp"
#include "routing/segment.hpp"
#include "routing/turns.hpp"

#include "traffic/speed_groups.hpp"

#include "indexer/feature_altitude.hpp"

#include "geometry/polyline2d.hpp"

#include "base/followed_polyline.hpp"

#include "std/vector.hpp"
#include "std/set.hpp"
#include "std/string.hpp"

#include <limits>
#include <string>
#include <utility>
#include <vector>

namespace location
{
  class GpsInfo;
  class RouteMatchingInfo;
}

namespace routing
{
using SubrouteUid = uint64_t;
SubrouteUid constexpr kInvalidSubrouteId = std::numeric_limits<uint64_t>::max();

/// \brief The route is composed of one or several subroutes. Every subroute is composed of segments.
/// For every Segment is kept some attributes in the structure SegmentInfo.
class RouteSegment final
{
public:
  RouteSegment(Segment const & segment, turns::TurnItem const & turn, Junction const & junction,
               std::string const & street, double distFromBeginningMeters, double distFromBeginningMerc,
               double timeFromBeginningS, traffic::SpeedGroup traffic)
    : m_segment(segment)
    , m_turn(turn)
    , m_junction(junction)
    , m_street(street)
    , m_distFromBeginningMeters(distFromBeginningMeters)
    , m_distFromBeginningMerc(distFromBeginningMerc)
    , m_timeFromBeginningS(timeFromBeginningS)
    , m_traffic(traffic)
  {
  }

  Segment const & GetSegment() const { return m_segment; }
  turns::TurnItem const & GetTurn() const { return m_turn; }
  Junction const & GetJunction() const { return m_junction; }
  std::string const & GetStreet() const { return m_street; }
  double GetDistFromBeginningMeters() const { return m_distFromBeginningMeters; }
  double GetDistFromBeginningMerc() const { return m_distFromBeginningMerc; }
  double GetTimeFromBeginningS() const { return m_timeFromBeginningS; }
  traffic::SpeedGroup GetTraffic() const { return m_traffic; }

private:
  Segment m_segment;
  /// Turn (maneuver) information for the turn next to the |m_segment| if any.
  /// If not |m_turn::m_turn| is equal to TurnDirection::NoTurn.
  turns::TurnItem m_turn;
  /// The furthest point of the segment from the beginning of the route along the route.
  Junction m_junction;
  /// Street name of |m_segment| if any. Otherwise |m_street| is empty.
  std::string m_street;
  /// Distance from the route beginning to the farthest end of |m_segment| in meters.
  double m_distFromBeginningMeters = 0.0;
  /// Distance from the route beginning to the farthest end of |m_segment| in mercator.
  double m_distFromBeginningMerc = 0.0;
  /// ETA from the route beginning in seconds to reach the farthest from the route beginning end of |m_segment|.
  double m_timeFromBeginningS = 0.0;
  traffic::SpeedGroup m_traffic = traffic::SpeedGroup::Unknown;
};

class Route
{
public:
  using TTurns = vector<turns::TurnItem>;
  using TTimeItem = pair<uint32_t, double>;
  using TTimes = vector<TTimeItem>;
  using TStreetItem = pair<uint32_t, string>;
  using TStreets = vector<TStreetItem>;

  class SubrouteAttrs final
  {
  public:
    SubrouteAttrs() = default;
    SubrouteAttrs(Junction const & start, Junction const & finish)
      : m_start(start), m_finish(finish)
    {
    }

    Junction const & GetStart() const { return m_start; }
    Junction const & GetFinish() const { return m_finish; }

  private:
    Junction m_start;
    Junction m_finish;
  };

  /// \brief For every subroute some attributes are kept the following stucture.
  struct SubrouteSettings final
  {
    SubrouteSettings(RoutingSettings const & routingSettings, string const & router, SubrouteUid id)
      : m_routingSettings(routingSettings), m_router(router), m_id(id)
    {
    }

    RoutingSettings const m_routingSettings;
    string const m_router;
    /// Some subsystems (for example drape) which is used Route class need to have an id of any subroute.
    /// This subsystems may set the id and then use it. The id is kept in |m_id|.
    SubrouteUid const m_id = kInvalidSubrouteId;
  };

  explicit Route(string const & router)
    : m_router(router), m_routingSettings(GetCarRoutingSettings()) {}

  template <class TIter>
  Route(string const & router, TIter beg, TIter end)
    : m_router(router), m_routingSettings(GetCarRoutingSettings()), m_poly(beg, end)
  {
    Update();
  }

  Route(string const & router, vector<m2::PointD> const & points, string const & name = string());

  void Swap(Route & rhs);

  template <class TIter> void SetGeometry(TIter beg, TIter end)
  {
    if (beg == end)
      FollowedPolyline().Swap(m_poly);
    else
      FollowedPolyline(beg, end).Swap(m_poly);
    Update();
  }

  inline void SetTurnInstructions(TTurns && v) { m_turns = move(v); }
  inline void SetSectionTimes(TTimes && v) { m_times = move(v); }
  inline void SetStreetNames(TStreets && v) { m_streets = move(v); }
  inline void SetAltitudes(feature::TAltitudes && v) { m_altitudes = move(v); }
  inline void SetTraffic(vector<traffic::SpeedGroup> && v) { m_traffic = move(v); }

  template <class SI>
  void SetRouteSegments(SI && v) { m_routeSegments = std::forward<SI>(v); }

  uint32_t GetTotalTimeSec() const;
  uint32_t GetCurrentTimeToEndSec() const;

  FollowedPolyline const & GetFollowedPolyline() const { return m_poly; }

  string const & GetRouterId() const { return m_router; }
  m2::PolylineD const & GetPoly() const { return m_poly.GetPolyline(); }
  TTurns const & GetTurns() const { return m_turns; }
  feature::TAltitudes const & GetAltitudes() const { return m_altitudes; }
  vector<traffic::SpeedGroup> const & GetTraffic() const { return m_traffic; }
  vector<double> const & GetSegDistanceMeters() const { return m_poly.GetSegDistanceM(); }
  bool IsValid() const { return (m_poly.GetPolyline().GetSize() > 1); }

  double GetTotalDistanceMeters() const;
  double GetCurrentDistanceFromBeginMeters() const;
  double GetCurrentDistanceToEndMeters() const;
  double GetMercatorDistanceFromBegin() const;

  /// \brief GetCurrentTurn returns information about the nearest turn.
  /// \param distanceToTurnMeters is a distance from current position to the nearest turn.
  /// \param turn is information about the nearest turn.
  bool GetCurrentTurn(double & distanceToTurnMeters, turns::TurnItem & turn) const;

  /// \brief Returns a name of a street where the user rides at this moment.
  void GetCurrentStreetName(string &) const;

  /// \brief Returns a name of a street next to idx point of the path. Function avoids short unnamed links.
  void GetStreetNameAfterIdx(uint32_t idx, string &) const;

  /// @return true if GetNextTurn() returns a valid result in parameters, false otherwise.
  /// \param distanceToTurnMeters is a distance from current position to the second turn.
  /// \param turn is information about the second turn.
  /// @return true if its parameters are filled with correct result.
  /// \note All parameters are filled while a GetNextTurn function call.
  bool GetNextTurn(double & distanceToTurnMeters, turns::TurnItem & turn) const;
  /// \brief Extract information about zero, one or two nearest turns depending on current position.
  /// @return true if its parameter is filled with correct result. (At least with one element.)
  bool GetNextTurns(vector<turns::TurnItemDist> & turns) const;

  void GetCurrentDirectionPoint(m2::PointD & pt) const;

  /// @return true  If position was updated successfully (projection within gps error radius).
  bool MoveIterator(location::GpsInfo const & info) const;

  void MatchLocationToRoute(location::GpsInfo & location, location::RouteMatchingInfo & routeMatchingInfo) const;

  bool IsCurrentOnEnd() const;

  /// Add country name if we have no country filename to make route
  void AddAbsentCountry(string const & name);

  /// Get absent file list of a routing files for shortest path finding
  set<string> const & GetAbsentCountries() const { return m_absentCountries; }

  inline void SetRoutingSettings(RoutingSettings const & routingSettings)
  {
    m_routingSettings = routingSettings;
    Update();
  }

  // Subroute interface.
  /// \returns Number of subroutes.
  /// \note Intermediate points separate a route into several subroutes.
  size_t GetSubrouteCount() const;

  /// \brief Fills |info| with full subroute information.
  /// \param segmentIdx zero base number of subroute. |segmentIdx| should be less than GetSubrouteCount();
  /// \note |info| is a segment oriented route. Size of |info| is equal to number of points in |m_poly| - 1.
  /// Class Route is a point oriented route. While this conversion some attributes of zero point will be lost.
  /// It happens with zero turn for example.
  /// \note It's a fake implementation for single subroute which is equal to route without any
  /// intermediate points.
  /// Note. SegmentInfo::m_segment is filled with default Segment instance.
  /// Note. SegmentInfo::m_streetName is filled with an empty string.
  void GetSubrouteInfo(size_t segmentIdx, std::vector<RouteSegment> & segments) const;

  void GetSubrouteAttrs(size_t segmentIdx, SubrouteAttrs & info) const;

  /// \returns Subroute settings by |segmentIdx|.
  // @TODO(bykoianko) This method should return SubrouteSettings by reference. Now it returns by value
  // because of fake implementation.
  SubrouteSettings const GetSubrouteSettings(size_t segmentIdx) const;

  /// \brief Sets subroute unique id (|subrouteUid|) by |segmentIdx|.
  /// \note |subrouteUid| is a permanent id of a subroute. This id can be used to address to a subroute
  /// after the route is removed.
  void SetSubrouteUid(size_t segmentIdx, SubrouteUid subrouteUid);

private:
  friend string DebugPrint(Route const & r);

  /// Call this fucnction when geometry have changed.
  void Update();
  double GetPolySegAngle(size_t ind) const;
  TTurns::const_iterator GetCurrentTurn() const;
  TStreets::const_iterator GetCurrentStreetNameIterAfter(FollowedPolyline::Iter iter) const;

  Junction GetJunction(size_t pointIdx) const;

  string m_router;
  RoutingSettings m_routingSettings;
  string m_name;

  FollowedPolyline m_poly;
  FollowedPolyline m_simplifiedPoly;

  set<string> m_absentCountries;

  TTurns m_turns;
  TTimes m_times;
  TStreets m_streets;
  feature::TAltitudes m_altitudes;
  vector<traffic::SpeedGroup> m_traffic;

  std::vector<RouteSegment> m_routeSegments;

  mutable double m_currentTime;

  // Subroute
  SubrouteUid m_subrouteUid = kInvalidSubrouteId;
};
} // namespace routing
<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright 2018 The Apollo Authors. 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 "modules/canbus/vehicle/lexus/lexus_vehicle_factory.h"

#include "modules/canbus/vehicle/lexus/lexus_controller.h"
#include "modules/canbus/vehicle/lexus/lexus_message_manager.h"
#include "modules/common/log.h"
#include "modules/common/util/util.h"

namespace apollo {
namespace canbus {

std::unique_ptr<VehicleController>
LexusVehicleFactory::CreateVehicleController() {
  return std::unique_ptr<VehicleController>(new lexus::LexusController());
}

std::unique_ptr<MessageManager<::apollo::canbus::ChassisDetail>>
LexusVehicleFactory::CreateMessageManager() {
  return std::unique_ptr<MessageManager<::apollo::canbus::ChassisDetail>>(
      new lexus::LexusMessageManager());
}

}  // namespace canbus
}  // namespace apollo
<commit_msg>Canbus : fix log<commit_after>/******************************************************************************
 * Copyright 2018 The Apollo Authors. 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 "modules/canbus/vehicle/lexus/lexus_vehicle_factory.h"

#include "cybertron/common/log.h"
#include "modules/canbus/vehicle/lexus/lexus_controller.h"
#include "modules/canbus/vehicle/lexus/lexus_message_manager.h"
#include "modules/common/util/util.h"

namespace apollo {
namespace canbus {

std::unique_ptr<VehicleController>
LexusVehicleFactory::CreateVehicleController() {
  return std::unique_ptr<VehicleController>(new lexus::LexusController());
}

std::unique_ptr<MessageManager<::apollo::canbus::ChassisDetail>>
LexusVehicleFactory::CreateMessageManager() {
  return std::unique_ptr<MessageManager<::apollo::canbus::ChassisDetail>>(
      new lexus::LexusMessageManager());
}

}  // namespace canbus
}  // namespace apollo
<|endoftext|>


<commit_before>#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <assert.h>

#include <algorithm>
#include <vector>
#include <sstream>
#include <unordered_map>
#include <iostream>
#include <string>

#define PORT    3490
#define MAXMSG  512

using namespace std;

typedef struct {
  unsigned int id;
  unsigned long long hash;
  string name;
  string ip;
  unsigned short port;
} ClientDevice;

unsigned int get_client_id(const char *buffer, unordered_map<unsigned long long, unsigned int> &client_hash_to_id)
{
  unsigned long long hash;
  sscanf(buffer, "%*s (%llx) connected", &hash);
  auto find_it = client_hash_to_id.find(hash);
  if (find_it == end(client_hash_to_id))
    {
      auto client_id = client_hash_to_id.size();
      client_hash_to_id[hash] = client_id;
      return client_id;
    }
  else
    {
       return find_it->second;
    }
}

int make_socket (uint16_t port)
{
  int sock;
  struct sockaddr_in name;

  /* Create the socket. */
  sock = socket (PF_INET, SOCK_STREAM, 0);
  if (sock < 0)
    {
      perror ("socket");
      exit (EXIT_FAILURE);
    }

  // Reuse socket if it is in a time-out state (prevents bind: Address already in use error)
  int optval = 1;
  setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));

  /* Give the socket a name. */
  name.sin_family = AF_INET;
  name.sin_port = htons (port);
  name.sin_addr.s_addr = htonl (INADDR_ANY);
  if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0)
    {
      perror ("bind");
      exit (EXIT_FAILURE);
    }

  return sock;
}

#define BUF_SIZE 10

int reply_to_client (int filedes, unsigned int client_id)
{
  char buf[BUF_SIZE];
  snprintf(buf, BUF_SIZE, "%u", client_id);
  string confirm_msg = "Client #" + string(buf) + " confirmed\n";
  int msg_size = confirm_msg.length() + 1;
  int nbytes = write(filedes, confirm_msg.c_str(), msg_size);
  fprintf (stderr, "Server sent message: %swith nybtes successful: %d\n", confirm_msg.c_str(), nbytes);
  return nbytes >= 0;
}

int read_from_client (int filedes, const struct sockaddr_in clientname, unordered_map<unsigned long long, unsigned int> &client_hash_to_id, vector<ClientDevice> &client_devices)
{
  char buffer[MAXMSG];
  int nbytes;

  nbytes = read (filedes, buffer, MAXMSG);
  if (nbytes < 0)
    {
      /* Read error. */
      perror ("read");
      exit (EXIT_FAILURE);
    }
  else if (nbytes == 0)
    /* End-of-file. */
    return -1;
  else
    {
      /* Data read. */
      buffer[nbytes] = '\0';
      fprintf (stderr, "Server: got message: '%s'\n", buffer);
      unsigned int client_id = get_client_id(buffer, client_hash_to_id);
      if (client_id >= client_devices.size())
        {
          assert(client_id == client_devices.size());
          string client_name;
          stringstream ss;
          ss.str(string(buffer));
          ss >> client_name;
          unsigned long long client_hash;
          sscanf(buffer, "%*s (%llx) connected", &client_hash);
          ClientDevice client_device = {client_id, client_hash, client_name, string(inet_ntoa(clientname.sin_addr)), ntohs(clientname.sin_port)};
          client_devices.push_back(client_device);
          fprintf(stderr, "Created Client Device %u %llx %s %s %hu\n", client_device.id, client_device.hash, client_device.name.c_str(), client_device.ip.c_str(), client_device.port);
        }
      return reply_to_client(filedes, client_id);
    }
}

int main (void)
{
  int sock;
  fd_set active_fd_set, read_fd_set;
  int i;
  struct sockaddr_in clientname;
  socklen_t size;

  // Keeping track of clients
  unordered_map<unsigned long long, unsigned int> client_hash_to_id;
  vector<ClientDevice> client_devices;
  unordered_map<int, struct sockaddr_in> fd_to_sockaddr;

  /* Create the socket and set it up to accept connections. */
  sock = make_socket (PORT);

  if (listen (sock, 1) < 0)
    {
      perror ("listen");
      exit (EXIT_FAILURE);
    }

  /* Initialize the set of active sockets. */
  FD_ZERO (&active_fd_set);
  FD_SET (sock, &active_fd_set);

  cerr << "Server Ready\n";

  while (1)
    {
      /* Block until input arrives on one or more active sockets. */
      read_fd_set = active_fd_set;
      if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0)
        {
          perror ("select");
          exit (EXIT_FAILURE);
        }

      /* Service all the sockets with input pending. */
      for (i = 0; i < FD_SETSIZE; ++i)
        if (FD_ISSET (i, &read_fd_set))
          {
            if (i == sock)
              {
                /* Connection request on original socket. */
                int new_fd;
                size = sizeof (clientname);
                new_fd = accept (sock,
                              (struct sockaddr *) &clientname,
                              &size);
                if (new_fd < 0)
                  {
                    perror ("accept");
                    exit (EXIT_FAILURE);
                  }
                fprintf (stderr,
                         "Server: connect from host %s, port %hu, fd %d.\n",
                         inet_ntoa (clientname.sin_addr),
                         ntohs (clientname.sin_port),
                         new_fd);
                fd_to_sockaddr[new_fd] = clientname;
                FD_SET (new_fd, &active_fd_set);
              }
            else
              {
                /* Data arriving on an already-connected socket. */
                if (read_from_client (i, fd_to_sockaddr.at(i), client_hash_to_id, client_devices) < 0)
                  {
                    close (i);
                    FD_CLR (i, &active_fd_set);
                  }
              }
          }
    }
}
<commit_msg>Use stringstream instead of snprintf.<commit_after>#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <assert.h>

#include <algorithm>
#include <vector>
#include <sstream>
#include <unordered_map>
#include <iostream>
#include <cstdio>
#include <string>

#define PORT    3490
#define MAXMSG  512

using namespace std;

typedef struct {
  unsigned int id;
  unsigned long long hash;
  string name;
  string ip;
  unsigned short port;
} ClientDevice;

unsigned int get_client_id(const char *buffer, unordered_map<unsigned long long, unsigned int> &client_hash_to_id)
{
  unsigned long long hash;
  sscanf(buffer, "%*s (%llx) connected", &hash);
  auto find_it = client_hash_to_id.find(hash);
  if (find_it == end(client_hash_to_id))
    {
      auto client_id = client_hash_to_id.size();
      client_hash_to_id[hash] = client_id;
      return client_id;
    }
  else
    {
       return find_it->second;
    }
}

int make_socket (uint16_t port)
{
  int sock;
  struct sockaddr_in name;

  /* Create the socket. */
  sock = socket (PF_INET, SOCK_STREAM, 0);
  if (sock < 0)
    {
      perror ("socket");
      exit (EXIT_FAILURE);
    }

  // Reuse socket if it is in a time-out state (prevents bind: Address already in use error)
  int optval = 1;
  setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));

  /* Give the socket a name. */
  name.sin_family = AF_INET;
  name.sin_port = htons (port);
  name.sin_addr.s_addr = htonl (INADDR_ANY);
  if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0)
    {
      perror ("bind");
      exit (EXIT_FAILURE);
    }

  return sock;
}

#define BUF_SIZE 10

int reply_to_client (int filedes, unsigned int client_id)
{
  stringstream ss;
  ss << "Client #" << client_id << " confirmed\n";
  string confirm_msg = ss.str();
  int msg_size = confirm_msg.length() + 1;
  int nbytes = write(filedes, confirm_msg.c_str(), msg_size);
  fprintf (stderr, "Server sent message: %swith nybtes successful: %d\n", confirm_msg.c_str(), nbytes);
  return nbytes >= 0;
}

int read_from_client (int filedes, const struct sockaddr_in clientname, unordered_map<unsigned long long, unsigned int> &client_hash_to_id, vector<ClientDevice> &client_devices)
{
  char buffer[MAXMSG];
  int nbytes;

  nbytes = read (filedes, buffer, MAXMSG);
  if (nbytes < 0)
    {
      /* Read error. */
      perror ("read");
      exit (EXIT_FAILURE);
    }
  else if (nbytes == 0)
    /* End-of-file. */
    return -1;
  else
    {
      /* Data read. */
      buffer[nbytes] = '\0';
      fprintf (stderr, "Server: got message: '%s'\n", buffer);
      unsigned int client_id = get_client_id(buffer, client_hash_to_id);
      if (client_id >= client_devices.size())
        {
          assert(client_id == client_devices.size());
          string client_name;
          stringstream ss;
          ss.str(string(buffer));
          ss >> client_name;
          unsigned long long client_hash;
          sscanf(buffer, "%*s (%llx) connected", &client_hash);
          ClientDevice client_device = {client_id, client_hash, client_name, string(inet_ntoa(clientname.sin_addr)), ntohs(clientname.sin_port)};
          client_devices.push_back(client_device);
          fprintf(stderr, "Created Client Device %u %llx %s %s %hu\n", client_device.id, client_device.hash, client_device.name.c_str(), client_device.ip.c_str(), client_device.port);
        }
      return reply_to_client(filedes, client_id);
    }
}

int main (void)
{
  int sock;
  fd_set active_fd_set, read_fd_set;
  int i;
  struct sockaddr_in clientname;
  socklen_t size;

  // Keeping track of clients
  unordered_map<unsigned long long, unsigned int> client_hash_to_id;
  vector<ClientDevice> client_devices;
  unordered_map<int, struct sockaddr_in> fd_to_sockaddr;

  /* Create the socket and set it up to accept connections. */
  sock = make_socket (PORT);

  if (listen (sock, 1) < 0)
    {
      perror ("listen");
      exit (EXIT_FAILURE);
    }

  /* Initialize the set of active sockets. */
  FD_ZERO (&active_fd_set);
  FD_SET (sock, &active_fd_set);

  cerr << "Server Ready\n";

  while (1)
    {
      /* Block until input arrives on one or more active sockets. */
      read_fd_set = active_fd_set;
      if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0)
        {
          perror ("select");
          exit (EXIT_FAILURE);
        }

      /* Service all the sockets with input pending. */
      for (i = 0; i < FD_SETSIZE; ++i)
        if (FD_ISSET (i, &read_fd_set))
          {
            if (i == sock)
              {
                /* Connection request on original socket. */
                int new_fd;
                size = sizeof (clientname);
                new_fd = accept (sock,
                              (struct sockaddr *) &clientname,
                              &size);
                if (new_fd < 0)
                  {
                    perror ("accept");
                    exit (EXIT_FAILURE);
                  }
                fprintf (stderr,
                         "Server: connect from host %s, port %hu, fd %d.\n",
                         inet_ntoa (clientname.sin_addr),
                         ntohs (clientname.sin_port),
                         new_fd);
                fd_to_sockaddr[new_fd] = clientname;
                FD_SET (new_fd, &active_fd_set);
              }
            else
              {
                /* Data arriving on an already-connected socket. */
                if (read_from_client (i, fd_to_sockaddr.at(i), client_hash_to_id, client_devices) < 0)
                  {
                    close (i);
                    FD_CLR (i, &active_fd_set);
                  }
              }
          }
    }
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <stdlib.h>
#include <unordered_map>
#define min(x,y) x < y ? x : y

using namespace std;

typedef unsigned long long ullong;

//method used to compute all bit masks that are to be used in computation.
//Returns a single array that contains all M sets that will need to be processed in
//optimal threshold computation. Sets are sorted ascendingly by the number of missmatch.
//Each element (bit) missing from the set is a missmatch.
ullong* computeBitmaskArray(int* binomCoefCount, int k, int s) {

    ullong* result = NULL;

    ullong resultMask = (1LL << s) - 1;

    int total = 0;
    for(int i = 0; i < k; i++) {
        total += binomCoefCount[i];
    }

    result = (ullong*) malloc(sizeof(ullong) * total);

    ullong bot32Mask = (1LL << 32) - 1;

    //in this loop we compute all masks. First we compute all sets
    //that have 0 missmatch, then 1 missmatch... and so on, up to k
    int c = 0;
    for(int i = 0; i < k; i++) {

        ullong current = (1LL << i) - 1;
        //current = current | (current - 1);

        for(int j = 0; j < binomCoefCount[i]; j++) {
            //we shift the result by one because sets contain elements [1,s-1], therefore
            //we need to shift resut by one to the left in order to have 0-th element not set.
            result[c++] = ((~current) << 1) & resultMask;
            ullong tmp = current | (current - 1);
            int shift = 0;
            uint input = (uint) current;
            if ((bot32Mask & current) == 0) {
                input = (uint) (current >> 32);
                shift = 32;
            }
            shift += __builtin_ctz(input) + 1;

            current = (tmp + 1) | (((~tmp & -~tmp) - 1)) >> shift;
        }

    }

    return result;
}

//method used to calculate all (s-1) choose k values needed for the
//computation.
int* calculateBinomCoef(int k, int s) {

    int* result = (int*) malloc(sizeof(int) * k);

    result[0] = 1;
    result[1] = s-1;

    int top = s-1;
    int bottom = 1;

    for(int i = 2; i < k; i++) {
        top *= s - i;
        bottom *= i;
        result[i] = top / bottom;
    }

    return result;
}

//method used to allocate 2D arrays for data storage.
//total memory usage is O(f(m,k)) as defined in the paper.
int** mallocIntArrays(int* rowSize, int k){

    int** result = (int**) malloc(sizeof(int*) * k);

    for(int i = 0; i < k; i++) {
        result[i] = (int*) malloc(sizeof(int) * rowSize[i]);
    }

    return result;
}

//free...
void freeIntArrays(int**data, int k) {
    for(int i = 0; i < k; i++) {
        free(data[i]);
    }
}

//fill all elements of 2D array with given value
//@param data 2D array to fill
void fill(int** data, int* rowSize, int k, int value) {
    for(int i = 0; i < k; i++) {
        for(int j = 0; j < rowSize[i]; j++) {
            data[i][j] = value;
        }
    }
}

void printArray(int* data, int size) {
    for(int i = 0; i < size; i++) {
        printf("%d, ", data[i]);
    }
    printf("size: %d\n", size);
}

void print2D(int** data, int* rowSize, int k) {
    for(int i = 0; i < k; i++) {
        printArray(data[i], rowSize[i]);
    }
}

int findThreshold(int* shape, int size, int m, int k) {

    if (m > 64 || size > m || k > size) {
        fprintf(stderr,"Invalid input arguments. shape size: %d, m: %d, k: %d\n", size, m, k);
        exit(-1);
    }

    //to include k
    k++;

    int maxInt = 2147483647;

    //mask used check whether some other set M is a subset of shape.
    ullong shape_mask = 0;

    int min = shape[0];
    int max = 0;

    for(int i = 0; i < size; i++) {
        shape_mask |= (1LL << shape[i]);
        if (shape[i] > max) {
            max = shape[i];
        } else {
            if(shape[i] < min) {
                min = shape[i];
            }
        }
    }

    int span = max - min + 1;

    ullong lastElemMask = 1LL << (span - 1);

    int* binCoef = calculateBinomCoef(k, span);

    int binCoefPrefSum[k];

    binCoefPrefSum[0] = binCoef[0];

    for(int i = 1; i < k; i++) {
        binCoefPrefSum[i] = binCoef[i] + binCoefPrefSum[i-1];
    }

    int arraySize = binCoefPrefSum[k-1];

    ullong* bitMaskArray = computeBitmaskArray(binCoef, k, span);

    unordered_map<ullong, int> maskToIndex;

    for(int i = 0; i < arraySize; i++) {
        maskToIndex[bitMaskArray[i]] = i;
    }

    int **currentResult, **nextResult;
    currentResult = mallocIntArrays(binCoefPrefSum, k);
    nextResult = mallocIntArrays(binCoefPrefSum, k);

    fill(currentResult, binCoefPrefSum, k, 0);

    ullong lastElemMaskNot = ~lastElemMask;

    for(int i = span; i <= m; i++) {

        //here we go through all values j and M to compute next iteration
        for(int j = 0; j < k; j++) {
            //end is the index of last set that has at most j missmatches (all the sets that have at most j bits set to zero)
            int end = binCoefPrefSum[j];

            for(int l = 0; l < end; l++) {
                ullong mask = bitMaskArray[l];
                int targetJ = j;
                if ((mask & lastElemMask) == 0) {
                    targetJ--;
                }
                if(targetJ == -1) {
                    //TODO can be removed this will never happen
                    continue;
                }
                //mask in bottom line in paper recurrence
                ullong targetMask = (mask & lastElemMaskNot) << 1;
                //mask in top line in paper recurrence
                ullong targetMask2 = targetMask | 2LL;
                int maskInd = maskToIndex[targetMask];
                int maskInd2 = maskToIndex[targetMask2];

                int hit = ((shape_mask & (mask | 1LL)) != 0 && (mask | 1LL) >= shape_mask) ? 1 : 0;

                int nextVal = maxInt;

                //if target mask has more then targetJ missmatches it is invalid
                if(targetMask != 0 && maskInd < binCoefPrefSum[targetJ]){
                    nextVal = currentResult[targetJ][maskInd];
                }

                if(targetMask2 != 0 && maskInd2 < binCoefPrefSum[targetJ]) {
                    int val = currentResult[targetJ][maskInd2];
                    if(val < nextVal)
                        nextVal = val;
                }

                if(nextVal != maxInt){
                    //printf("update with hit %d\n", hit);
                    nextResult[j][l] = nextVal + hit;
                } else {
                    //TODO just for debugging. This case should never be triggered
                    printf("ERROR\n");
                    exit(-1);
                }
            }

        }

        int** tmp = currentResult;
        currentResult = nextResult;
        nextResult = tmp;
    }

    int result = currentResult[k-1][0];

    for(int i = 1; i < arraySize; i++) {
        if(currentResult[k-1][i] < result) {
            result = currentResult[k-1][i];
        }
    }

    freeIntArrays(currentResult, k);
    freeIntArrays(nextResult, k);
    free(bitMaskArray);
    free(binCoef);

    return result;
}

int main() {

    // int shape[12] = {0,2,4,8,14,16,18,22,28,30,32,36};
    //
    // printf("result: %d\n", findThreshold(shape, 12, 50, 5));

    int shape[3] = {0,1,2};

    printf("result: %d\n", findThreshold(shape, 3, 8, 1));

    return 0;
}
<commit_msg>edge case fixed<commit_after>#include <stdio.h>
#include <stdlib.h>
#include <unordered_map>
#define min(x,y) x < y ? x : y

using namespace std;

typedef unsigned long long ullong;

//method used to compute all bit masks that are to be used in computation.
//Returns a single array that contains all M sets that will need to be processed in
//optimal threshold computation. Sets are sorted ascendingly by the number of missmatch.
//Each element (bit) missing from the set is a missmatch.
ullong* computeBitmaskArray(int* binomCoefCount, int k, int s) {

    ullong* result = NULL;

    ullong resultMask = (1LL << s) - 1;

    int total = 0;
    for(int i = 0; i < k; i++) {
        total += binomCoefCount[i];
    }

    result = (ullong*) malloc(sizeof(ullong) * total);

    ullong bot32Mask = (1LL << 32) - 1;

    //in this loop we compute all masks. First we compute all sets
    //that have 0 missmatch, then 1 missmatch... and so on, up to k
    int c = 0;
    for(int i = 0; i < k; i++) {

        ullong current = (1LL << i) - 1;
        //current = current | (current - 1);

        for(int j = 0; j < binomCoefCount[i]; j++) {
            //we shift the result by one because sets contain elements [1,s-1], therefore
            //we need to shift resut by one to the left in order to have 0-th element not set.
            result[c++] = ((~current) << 1) & resultMask;
            ullong tmp = current | (current - 1);
            int shift = 0;
            uint input = (uint) current;
            if ((bot32Mask & current) == 0) {
                input = (uint) (current >> 32);
                shift = 32;
            }
            shift += __builtin_ctz(input) + 1;

            current = (tmp + 1) | (((~tmp & -~tmp) - 1)) >> shift;
        }

    }

    return result;
}

//method used to calculate all (s-1) choose k values needed for the
//computation.
int* calculateBinomCoef(int k, int s) {

    int* result = (int*) malloc(sizeof(int) * k);

    result[0] = 1;
    result[1] = s-1;

    int top = s-1;
    int bottom = 1;

    for(int i = 2; i < k; i++) {
        top *= s - i;
        bottom *= i;
        result[i] = top / bottom;
    }

    return result;
}

//method used to allocate 2D arrays for data storage.
//total memory usage is O(f(m,k)) as defined in the paper.
int** mallocIntArrays(int* rowSize, int k){

    int** result = (int**) malloc(sizeof(int*) * k);

    for(int i = 0; i < k; i++) {
        result[i] = (int*) malloc(sizeof(int) * rowSize[i]);
    }

    return result;
}

//free...
void freeIntArrays(int**data, int k) {
    for(int i = 0; i < k; i++) {
        free(data[i]);
    }
}

//fill all elements of 2D array with given value
//@param data 2D array to fill
void fill(int** data, int* rowSize, int k, int value) {
    for(int i = 0; i < k; i++) {
        for(int j = 0; j < rowSize[i]; j++) {
            data[i][j] = value;
        }
    }
}

void printArray(int* data, int size) {
    for(int i = 0; i < size; i++) {
        printf("%d, ", data[i]);
    }
    printf("size: %d\n", size);
}

void print2D(int** data, int* rowSize, int k) {
    for(int i = 0; i < k; i++) {
        printArray(data[i], rowSize[i]);
    }
}

int findThreshold(int* shape, int size, int m, int k) {

    if (m > 64 || size > m || k > size) {
        fprintf(stderr,"Invalid input arguments. shape size: %d, m: %d, k: %d\n", size, m, k);
        exit(-1);
    }

    //to include k
    k++;

    int maxInt = 2147483647;

    //mask used check whether some other set M is a subset of shape.
    ullong shape_mask = 0;

    int min = shape[0];
    int max = 0;

    for(int i = 0; i < size; i++) {
        shape_mask |= (1LL << shape[i]);
        if (shape[i] > max) {
            max = shape[i];
        } else {
            if(shape[i] < min) {
                min = shape[i];
            }
        }
    }

    int span = max - min + 1;

    ullong lastElemMask = 1LL << (span - 1);

    int* binCoef = calculateBinomCoef(k, span);

    int binCoefPrefSum[k];

    binCoefPrefSum[0] = binCoef[0];

    for(int i = 1; i < k; i++) {
        binCoefPrefSum[i] = binCoef[i] + binCoefPrefSum[i-1];
    }

    int arraySize = binCoefPrefSum[k-1];

    ullong* bitMaskArray = computeBitmaskArray(binCoef, k, span);

    unordered_map<ullong, int> maskToIndex;

    for(int i = 0; i < arraySize; i++) {
        maskToIndex[bitMaskArray[i]] = i;
    }

    int **currentResult, **nextResult;
    currentResult = mallocIntArrays(binCoefPrefSum, k);
    nextResult = mallocIntArrays(binCoefPrefSum, k);

    fill(currentResult, binCoefPrefSum, k, 0);

    ullong lastElemMaskNot = ~lastElemMask;

    for(int i = span; i <= m; i++) {

        //here we go through all values j and M to compute next iteration
        for(int j = 0; j < k; j++) {
            //end is the index of last set that has at most j missmatches (all the sets that have at most j bits set to zero)
            int end = binCoefPrefSum[j];

            for(int l = 0; l < end; l++) {
                ullong mask = bitMaskArray[l];
                int targetJ = j;
                if ((mask & lastElemMask) == 0) {
                    targetJ--;
                }
                if(targetJ == -1) {
                    //TODO can be removed this will never happen
                    continue;
                }
                //mask in bottom line in paper recurrence
                ullong targetMask = (mask & lastElemMaskNot) << 1;
                //mask in top line in paper recurrence
                ullong targetMask2 = targetMask | 2LL;

                int maskInd = -1, maskInd2 = -1;

                auto it = maskToIndex.find(targetMask);

                if(it != maskToIndex.end()) {
                    maskInd = it->second;
                }

                auto it2 = maskToIndex.find(targetMask2);

                if(it2 != maskToIndex.end()) {
                    maskInd2 = it2->second;
                }

                int hit = ((shape_mask & (mask | 1LL)) != 0 && (mask | 1LL) >= shape_mask) ? 1 : 0;

                int nextVal = maxInt;

                //if target mask has more then targetJ missmatches it is invalid
                if(maskInd != -1 && maskInd < binCoefPrefSum[targetJ]){
                    nextVal = currentResult[targetJ][maskInd];
                }

                if(maskInd2 != -1 && maskInd2 < binCoefPrefSum[targetJ]) {
                    int val = currentResult[targetJ][maskInd2];
                    if(val < nextVal)
                        nextVal = val;
                }

                if(nextVal != maxInt){
                    //printf("update with hit %d\n", hit);
                    nextResult[j][l] = nextVal + hit;
                } else {
                    //TODO just for debugging. This case should never be triggered
                    printf("ERROR\n");
                    exit(-1);
                }
            }

        }

        int** tmp = currentResult;
        currentResult = nextResult;
        nextResult = tmp;
    }

    int result = currentResult[k-1][0];

    for(int i = 1; i < arraySize; i++) {
        if(currentResult[k-1][i] < result) {
            result = currentResult[k-1][i];
        }
    }

    freeIntArrays(currentResult, k);
    freeIntArrays(nextResult, k);
    free(bitMaskArray);
    free(binCoef);

    return result;
}

int main() {

    // int shape[12] = {0,2,4,8,14,16,18,22,28,30,32,36};
    //
    // printf("result: %d\n", findThreshold(shape, 12, 50, 5));

    int shape[3] = {0,1,2};

    printf("result: %d\n", findThreshold(shape, 3, 8, 1));

    return 0;
}
<|endoftext|>


<commit_before>/*
 * George 'papanikge' Papanikolaou
 * CEID Advance Algorithm Design Course 2014
 * Benchmarking of Shortest Augmenting Path MF Algorithm with Boost & LEDA
 */

#include <iostream>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <utility>
#include <LEDA/graph/graph.h>
#include <LEDA/graph/graph_gen.h>
#include <LEDA/graph/max_flow.h>
#include <LEDA/system/timer.h>
#include "boost-types.h"

#define KNRM  "\x1B[0m"
#define KRED  "\x1B[31m"
#define KGRN  "\x1B[32m"
#define KYEL  "\x1B[33m"

/* Global self-explanatory debug variable */
static bool debug = false;

/* Prototypes */
std::pair<leda::node, leda::node> generate_hard_graph(leda::graph& G, unsigned int how_many, leda::edge_array<int>& capacities);
void generate_random_capacities(const leda::graph& G, leda::edge_array<int>& capacities);
void delete_direct_vertices(leda::graph& G, const leda::node source, const leda::node target);
std::pair<BoostVertex, BoostVertex> leda2boost(const leda::graph& LG, BoostGraph& BG, const leda::edge_array<int>& capacities, leda::node s, leda::node t);
long edmonds_karp_flow(BoostGraph& BG, const BoostVertex& source, const BoostVertex& target);

/*
 * Runs benchmarks for a given graph with the given source and target of course.
 * Is responsible for converting the graph to BGL.
 * We are printing directly to cerr in this function to avoid flush() pollution.
 */
static void benchmark(leda::graph& G, leda::edge_array<int>& capacities, leda::node s, leda::node t)
{
    float T;
    long leda_flow, my_flow;
    BoostGraph BG;
    leda::edge_array<int> flow(G);
    std::pair <BoostVertex, BoostVertex> Bst;

    /* Initial obligations */
    std::cerr << "  Preparing graphs... ";
    delete_direct_vertices(G, s, t);
    Bst = leda2boost(G, BG, capacities, s, t);
    std::cerr << "Done." << std::endl;

    /* LEDA's internal implementation */
    T = leda::used_time();
    leda_flow = leda::MAX_FLOW(G, s, t, capacities, flow);
    std::cerr << "\tLEDA's Calculation time: " << leda::used_time(T);
    if (debug) {
        if (CHECK_MAX_FLOW(G, s, t, capacities, flow))
            std::cerr << KGRN << "... [Correct]" << KNRM << std::endl;
        else
            std::cerr << KRED << "... [Wrong]" << KNRM << std::endl;
    } else {
        std::cerr << std::endl;
    }

    /* My implementation */
    T = leda::used_time();
    my_flow = edmonds_karp_flow(BG, Bst.first, Bst.second);
    std::cerr << "\tCustom SAP Algorithm implementation time: " << leda::used_time(T) << std::endl;

    /* Testing & final errands */
    if (debug) {
        if (my_flow == leda_flow)
            std::cerr << KGRN << "\t[Return values match!]" << KNRM << std::endl;
        else
            std::cerr << KRED << "\t[Return values do NOT match!]" << KNRM << std::endl;
    }
    return;
}

/*
 * Finds source and target randomly and calls benchmark()
 */
static void find_nodes_and_benchmark(leda::graph& G, leda::edge_array<int>& capacities)
{
    leda::node s, t;

    /* Pick random source/sink nodes. */
    s = G.choose_node();
    do {
        t = G.choose_node();
    } while (s == t);

    return benchmark(G, capacities, s, t);
}

int main(int argc, char **argv)
{
    int i, n, m;
    leda::graph G;
    leda::edge_array<int> capacities;
    std::pair<leda::node, leda::node> p;
    unsigned int N[] = { 8000, 15000, 30000 };

    std::cout << "\n-=-=-=-=- Shortest Augmenting Path MF Algorithm Benchmarking -=-=-=-=-\n";
    if (argc == 5 && !strcmp(argv[1], "-n") && !strcmp(argv[3], "-m")) {
        /* Custom nodes and edges from the command line */
        n = atoi(argv[2]);
        m = atoi(argv[4]);
        debug = true;
        leda::random_simple_loopfree_graph(G, n, m);
        generate_random_capacities(G, capacities);

        /* Safety check */
        if (G.is_undirected())
            std::cerr << "BUG! Graph is undirected!" << std::endl;

        find_nodes_and_benchmark(G, capacities);
    } else {
        /* Default values in the nodes */
        std::cout << "Give -n <number of nodes> -m <number of edges> if you want a custom amount.\n";
        std::cout << "Moving on with the default values...\n\n";

        std::cout << KYEL << ">>> Random graphs..." << KNRM << std::endl;
        for (i = 0; i < 3; i++) {
            std::cout << "Generating random graph with " << N[i] << " nodes... ";
            std::cout.flush();
            leda::random_simple_loopfree_graph(G, N[i], N[i]*2);
            generate_random_capacities(G, capacities);
            std::cout << "Done." << std::endl;

            find_nodes_and_benchmark(G, capacities);

            /* cleaning up for the next iteration */
            G.clear();
        }
        N[0] = 200;
        N[1] = 400;
        N[2] = 600;
        std::cout << KYEL << ">>> Hard graphs..." << KNRM << std::endl;
        for (i = 0; i < 3; i++) {
            std::cout << "Generating graph with " << N[i] << " nodes... ";
            std::cout.flush();
            p = generate_hard_graph(G, N[i], capacities);
            std::cout << "Done." << std::endl;

            benchmark(G, capacities, p.first, p.second);

            /* cleaning up for the next iteration */
            G.clear();
        }
    }
    return 0;
}
<commit_msg>update default hard nodes amount<commit_after>/*
 * George 'papanikge' Papanikolaou
 * CEID Advance Algorithm Design Course 2014
 * Benchmarking of Shortest Augmenting Path MF Algorithm with Boost & LEDA
 */

#include <iostream>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <utility>
#include <LEDA/graph/graph.h>
#include <LEDA/graph/graph_gen.h>
#include <LEDA/graph/max_flow.h>
#include <LEDA/system/timer.h>
#include "boost-types.h"

#define KNRM  "\x1B[0m"
#define KRED  "\x1B[31m"
#define KGRN  "\x1B[32m"
#define KYEL  "\x1B[33m"

/* Global self-explanatory debug variable */
static bool debug = false;

/* Prototypes */
std::pair<leda::node, leda::node> generate_hard_graph(leda::graph& G, unsigned int how_many, leda::edge_array<int>& capacities);
void generate_random_capacities(const leda::graph& G, leda::edge_array<int>& capacities);
void delete_direct_vertices(leda::graph& G, const leda::node source, const leda::node target);
std::pair<BoostVertex, BoostVertex> leda2boost(const leda::graph& LG, BoostGraph& BG, const leda::edge_array<int>& capacities, leda::node s, leda::node t);
long edmonds_karp_flow(BoostGraph& BG, const BoostVertex& source, const BoostVertex& target);

/*
 * Runs benchmarks for a given graph with the given source and target of course.
 * Is responsible for converting the graph to BGL.
 * We are printing directly to cerr in this function to avoid flush() pollution.
 */
static void benchmark(leda::graph& G, leda::edge_array<int>& capacities, leda::node s, leda::node t)
{
    float T;
    long leda_flow, my_flow;
    BoostGraph BG;
    leda::edge_array<int> flow(G);
    std::pair <BoostVertex, BoostVertex> Bst;

    /* Initial obligations */
    std::cerr << "  Preparing graphs... ";
    delete_direct_vertices(G, s, t);
    Bst = leda2boost(G, BG, capacities, s, t);
    std::cerr << "Done." << std::endl;

    /* LEDA's internal implementation */
    T = leda::used_time();
    leda_flow = leda::MAX_FLOW(G, s, t, capacities, flow);
    std::cerr << "\tLEDA's Calculation time: " << leda::used_time(T);
    if (debug) {
        if (CHECK_MAX_FLOW(G, s, t, capacities, flow))
            std::cerr << KGRN << "... [Correct]" << KNRM << std::endl;
        else
            std::cerr << KRED << "... [Wrong]" << KNRM << std::endl;
    } else {
        std::cerr << std::endl;
    }

    /* My implementation */
    T = leda::used_time();
    my_flow = edmonds_karp_flow(BG, Bst.first, Bst.second);
    std::cerr << "\tCustom SAP Algorithm implementation time: " << leda::used_time(T) << std::endl;

    /* Testing & final errands */
    if (debug) {
        if (my_flow == leda_flow)
            std::cerr << KGRN << "\t[Return values match!]" << KNRM << std::endl;
        else
            std::cerr << KRED << "\t[Return values do NOT match!]" << KNRM << std::endl;
    }
    return;
}

/*
 * Finds source and target randomly and calls benchmark()
 */
static void find_nodes_and_benchmark(leda::graph& G, leda::edge_array<int>& capacities)
{
    leda::node s, t;

    /* Pick random source/sink nodes. */
    s = G.choose_node();
    do {
        t = G.choose_node();
    } while (s == t);

    return benchmark(G, capacities, s, t);
}

int main(int argc, char **argv)
{
    int i, n, m;
    leda::graph G;
    leda::edge_array<int> capacities;
    std::pair<leda::node, leda::node> p;
    unsigned int N[] = { 8000, 15000, 30000 };

    std::cout << "\n-=-=-=-=- Shortest Augmenting Path MF Algorithm Benchmarking -=-=-=-=-\n";
    if (argc == 5 && !strcmp(argv[1], "-n") && !strcmp(argv[3], "-m")) {
        /* Custom nodes and edges from the command line */
        n = atoi(argv[2]);
        m = atoi(argv[4]);
        debug = true;
        leda::random_simple_loopfree_graph(G, n, m);
        generate_random_capacities(G, capacities);

        /* Safety check */
        if (G.is_undirected())
            std::cerr << "BUG! Graph is undirected!" << std::endl;

        find_nodes_and_benchmark(G, capacities);
    } else {
        /* Default values in the nodes */
        std::cout << "Give -n <number of nodes> -m <number of edges> if you want a custom amount.\n";
        std::cout << "Moving on with the default values...\n\n";

        std::cout << KYEL << ">>> Random graphs..." << KNRM << std::endl;
        for (i = 0; i < 3; i++) {
            std::cout << "Generating random graph with " << N[i] << " nodes... ";
            std::cout.flush();
            leda::random_simple_loopfree_graph(G, N[i], N[i]*2);
            generate_random_capacities(G, capacities);
            std::cout << "Done." << std::endl;

            find_nodes_and_benchmark(G, capacities);

            /* cleaning up for the next iteration */
            G.clear();
        }
        N[0] = 100;
        N[1] = 150;
        N[2] = 200;
        std::cout << KYEL << ">>> Hard graphs..." << KNRM << std::endl;
        for (i = 0; i < 3; i++) {
            std::cout << "Generating graph with " << N[i] << " nodes... ";
            std::cout.flush();
            p = generate_hard_graph(G, N[i], capacities);
            std::cout << "Done." << std::endl;

            benchmark(G, capacities, p.first, p.second);

            /* cleaning up for the next iteration */
            G.clear();
        }
    }
    return 0;
}
<|endoftext|>


<commit_before>//===--------------------- catch_const_pointer_nullptr.cpp ----------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include <cassert>

#if __has_feature(cxx_nullptr)

struct A {};

void test1()
{
    try
    {
        throw nullptr;
        assert(false);
    }
    catch (A*)
    {
    }
    catch (const A*)
    {
        assert(false);
    }
}

void test2()
{
    try
    {
        throw nullptr;
        assert(false);
    }
    catch (const A*)
    {
    }
    catch (A*)
    {
        assert(false);
    }
}

void test3()
{
    try
    {
        throw nullptr;
        assert(false);
    }
    catch (const A const*)
    {
    }
    catch (A*)
    {
        assert(false);
    }
}

void test4()
{
    try
    {
        throw nullptr;
        assert(false);
    }
    catch (A*)
    {
    }
    catch (const A const*)
    {
        assert(false);
    }
}

void test5()
{
    try
    {
        throw nullptr;
        assert(false);
    }
    catch (A const*)
    {
    }
    catch (A*)
    {
        assert(false);
    }
}

void test6()
{
    try
    {
        throw nullptr;
        assert(false);
    }
    catch (A*)
    {
    }
    catch (A const*)
    {
        assert(false);
    }
}

#else

void test1() {}
void test2() {}
void test3() {}
void test4() {}
void test5() {}
void test6() {}

#endif

int main()
{
    test1();
    test2();
    test3();
    test4();
    test5();
    test6();
}
<commit_msg>Fixed a couple of test errors; changed 'const A const *' to 'const A* const'. Thanks to Nico for the catch<commit_after>//===--------------------- catch_const_pointer_nullptr.cpp ----------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include <cassert>

#if __has_feature(cxx_nullptr)

struct A {};

void test1()
{
    try
    {
        throw nullptr;
        assert(false);
    }
    catch (A*)
    {
    }
    catch (const A*)
    {
        assert(false);
    }
}

void test2()
{
    try
    {
        throw nullptr;
        assert(false);
    }
    catch (const A*)
    {
    }
    catch (A*)
    {
        assert(false);
    }
}

void test3()
{
    try
    {
        throw nullptr;
        assert(false);
    }
    catch (const A* const)
    {
    }
    catch (A*)
    {
        assert(false);
    }
}

void test4()
{
    try
    {
        throw nullptr;
        assert(false);
    }
    catch (A*)
    {
    }
    catch (const A* const)
    {
        assert(false);
    }
}

void test5()
{
    try
    {
        throw nullptr;
        assert(false);
    }
    catch (A const*)
    {
    }
    catch (A*)
    {
        assert(false);
    }
}

void test6()
{
    try
    {
        throw nullptr;
        assert(false);
    }
    catch (A*)
    {
    }
    catch (A const*)
    {
        assert(false);
    }
}

#else

void test1() {}
void test2() {}
void test3() {}
void test4() {}
void test5() {}
void test6() {}

#endif

int main()
{
    test1();
    test2();
    test3();
    test4();
    test5();
    test6();
}
<|endoftext|>


<commit_before>/*
    This file is part of Kontact.
    Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include <qlabel.h>
#include <qlayout.h>

#include <kdialog.h>
#include <kglobal.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kparts/part.h>
#include <kstandarddirs.h>
#include <kurllabel.h>
#include <qtooltip.h>
#include <libkcal/event.h>
#include <libkcal/resourcecalendar.h>
#include <libkcal/resourcelocal.h>
#include <libkdepim/kpimprefs.h>

#include "korganizeriface_stub.h"

#include "core.h"
#include "plugin.h"
#include "korganizerplugin.h"

#include "korganizer/stdcalendar.h"

#include "summarywidget.h"

SummaryWidget::SummaryWidget( KOrganizerPlugin *plugin, QWidget *parent,
                              const char *name )
  : Kontact::Summary( parent, name ), mPlugin( plugin ), mCalendar( 0 )
{
  QVBoxLayout *mainLayout = new QVBoxLayout( this, 3, 3 );

  QPixmap icon = KGlobal::iconLoader()->loadIcon( "kontact_date",
                   KIcon::Desktop, KIcon::SizeMedium );
  QWidget *header = createHeader( this, icon, i18n( "Appointments" ) );
  mainLayout->addWidget( header );

  mLayout = new QGridLayout( mainLayout, 7, 5, 3 );
  mLayout->setRowStretch( 6, 1 );

  mCalendar = KOrg::StdCalendar::self();
  mCalendar->load();

  connect( mCalendar, SIGNAL( calendarChanged() ), SLOT( updateView() ) );
  connect( mPlugin->core(), SIGNAL( dayChanged( const QDate& ) ),
           SLOT( updateView() ) );

  updateView();
}

SummaryWidget::~SummaryWidget()
{
}

void SummaryWidget::updateView()
{
  mLabels.setAutoDelete( true );
  mLabels.clear();
  mLabels.setAutoDelete( false );

  KIconLoader loader( "korganizer" );

  KConfig config( "kcmkorgsummaryrc" );

  config.setGroup( "Calendar" );
  int days = config.readNumEntry( "DaysToShow", 1 );

  QLabel *label = 0;
  int counter = 0;
  QPixmap pm = loader.loadIcon( "appointment", KIcon::Small );

  QDate dt;
  for ( dt=QDate::currentDate();
        dt<=QDate::currentDate().addDays( days - 1 );
        dt=dt.addDays(1) ) {
    KCal::Event::List events = mCalendar->events( dt,
                                                  KCal::EventSortStartDate,
                                                  KCal::SortDirectionAscending );
    KCal::Event *ev;
    KCal::Event::List::ConstIterator it;
    for ( it=events.begin(); it!=events.end(); ++it ) {
      ev = *it;

      // Count number of days remaining in multiday event
      int span=1; int dayof=1;
      if ( ev->isMultiDay() ) {
        QDate d = ev->dtStart().date();
        if ( d < QDate::currentDate() ) {
          d = QDate::currentDate();
        }
        while ( d < ev->dtEnd().date() ) {
          if ( d < dt ) {
            dayof++;
          }
          span++;
          d=d.addDays( 1 );
        }
      }

      // If this date is part of a floating, multiday event, then we
      // only make a print for the first day of the event.
      if ( ev->isMultiDay() && ev->doesFloat() && dayof != 1 )break;

      // Fill Appointment Pixmap Field
      label = new QLabel( this );
      label->setPixmap( pm );
      label->setMaximumWidth( label->minimumSizeHint().width() );
      label->setAlignment( AlignVCenter );
      mLayout->addWidget( label, counter, 0 );
      mLabels.append( label );

      // Fill Event Date Field
      bool makeBold = false;
      QString datestr;

      // Modify event date for printing
      QDate sD = QDate::QDate( dt.year(), dt.month(), dt.day() );
      if ( ( sD.month() == QDate::currentDate().month() ) &&
           ( sD.day()   == QDate::currentDate().day() ) ) {
        datestr = i18n( "Today" );
        makeBold = true;
      } else if ( ( sD.month() == QDate::currentDate().addDays( 1 ).month() ) &&
                  ( sD.day()   == QDate::currentDate().addDays( 1 ).day() ) ) {
        datestr = i18n( "Tomorrow" );
      } else {
        datestr = KGlobal::locale()->formatDate( sD );
      }

      // Print the date span for multiday, floating events, for the
      // first day of the event only.
      if ( ev->isMultiDay() && ev->doesFloat() && dayof == 1 && span > 1 ) {
        QString endstr = KGlobal::locale()->formatDate( sD.addDays( span-1 ) );
        datestr += " -\n " + endstr;
      }

      label = new QLabel( datestr, this );
      label->setAlignment( AlignLeft | AlignVCenter );
      if ( makeBold ) {
        QFont font = label->font();
        font.setBold( true );
        label->setFont( font );
      }
      mLayout->addWidget( label, counter, 1 );
      mLabels.append( label );

      // Fill Event Summary Field
      QString newtext = ev->summary();
      if ( ev->isMultiDay() &&  !ev->doesFloat() ) {
        newtext.append( QString(" (%1/%2)").arg( dayof ).arg( span ) );
      }

      KURLLabel *urlLabel = new KURLLabel( ev->uid(), newtext, this );
      urlLabel->installEventFilter( this );
      urlLabel->setAlignment( urlLabel->alignment() | Qt::WordBreak );
      mLayout->addWidget( urlLabel, counter, 2 );
      mLabels.append( urlLabel );

      if ( !ev->description().isEmpty() ) {
        QToolTip::add( urlLabel, ev->description() );
      }

      // Fill Event Time Range Field (only for non-floating Events)
      if ( !ev->doesFloat() ) {
        QTime sST = ev->dtStart().time();
        QTime sET = ev->dtEnd().time();
        if ( ev->isMultiDay() ) {
          if ( ev->dtStart().date() < dt ) {
            sST = QTime::QTime( 0, 0 );
          }
          if ( ev->dtEnd().date() > dt ) {
            sET = QTime::QTime( 23, 59 );
          }
        }
        datestr = i18n( "Time from - to", "%1 - %2" )
                  .arg( KGlobal::locale()->formatTime( sST ) )
                  .arg( KGlobal::locale()->formatTime( sET ) );
        label = new QLabel( datestr, this );
        label->setAlignment( AlignLeft | AlignVCenter );
        mLayout->addWidget( label, counter, 3 );
        mLabels.append( label );
      }

      connect( urlLabel, SIGNAL( leftClickedURL( const QString& ) ),
               this, SLOT( selectEvent( const QString& ) ) );

      counter++;
    }
  }

  if ( !counter ) {
    QLabel *noEvents = new QLabel(
      i18n( "No appointments pending within the next day",
            "No appointments pending within the next %n days",
            days ), this, "nothing to see" );
    noEvents->setAlignment( AlignHCenter | AlignVCenter );
    mLayout->addWidget( noEvents, 0, 2 );
    mLabels.append( noEvents );
  }

  for ( label = mLabels.first(); label; label = mLabels.next() )
    label->show();
}

void SummaryWidget::selectEvent( const QString &uid )
{
  mPlugin->core()->selectPlugin( "kontact_korganizerplugin" ); //ensure loaded
  KOrganizerIface_stub iface( "korganizer", "KOrganizerIface" );
  iface.editIncidence( uid );
}

bool SummaryWidget::eventFilter( QObject *obj, QEvent* e )
{
  if ( obj->inherits( "KURLLabel" ) ) {
    KURLLabel* label = static_cast<KURLLabel*>( obj );
    if ( e->type() == QEvent::Enter )
      emit message( i18n( "Edit Appointment: \"%1\"" ).arg( label->text() ) );
    if ( e->type() == QEvent::Leave )
      emit message( QString::null );
  }

  return Kontact::Summary::eventFilter( obj, e );
}

QStringList SummaryWidget::configModules() const
{
  return QStringList( "kcmkorgsummary.desktop" );
}

#include "summarywidget.moc"
<commit_msg>Fix sorting in the appointments summary. This bug was already fixed in trunk, but I forgot to backport. KDE 3.5.2 will have the fix.<commit_after>/*
    This file is part of Kontact.
    Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include <qlabel.h>
#include <qlayout.h>

#include <kdialog.h>
#include <kglobal.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kparts/part.h>
#include <kstandarddirs.h>
#include <kurllabel.h>
#include <qtooltip.h>
#include <libkcal/event.h>
#include <libkcal/resourcecalendar.h>
#include <libkcal/resourcelocal.h>
#include <libkdepim/kpimprefs.h>

#include "korganizeriface_stub.h"

#include "core.h"
#include "plugin.h"
#include "korganizerplugin.h"

#include "korganizer/stdcalendar.h"

#include "summarywidget.h"

SummaryWidget::SummaryWidget( KOrganizerPlugin *plugin, QWidget *parent,
                              const char *name )
  : Kontact::Summary( parent, name ), mPlugin( plugin ), mCalendar( 0 )
{
  QVBoxLayout *mainLayout = new QVBoxLayout( this, 3, 3 );

  QPixmap icon = KGlobal::iconLoader()->loadIcon( "kontact_date",
                   KIcon::Desktop, KIcon::SizeMedium );
  QWidget *header = createHeader( this, icon, i18n( "Appointments" ) );
  mainLayout->addWidget( header );

  mLayout = new QGridLayout( mainLayout, 7, 5, 3 );
  mLayout->setRowStretch( 6, 1 );

  mCalendar = KOrg::StdCalendar::self();
  mCalendar->load();

  connect( mCalendar, SIGNAL( calendarChanged() ), SLOT( updateView() ) );
  connect( mPlugin->core(), SIGNAL( dayChanged( const QDate& ) ),
           SLOT( updateView() ) );

  updateView();
}

SummaryWidget::~SummaryWidget()
{
}

void SummaryWidget::updateView()
{
  mLabels.setAutoDelete( true );
  mLabels.clear();
  mLabels.setAutoDelete( false );

  KIconLoader loader( "korganizer" );

  KConfig config( "kcmkorgsummaryrc" );

  config.setGroup( "Calendar" );
  int days = config.readNumEntry( "DaysToShow", 1 );

  QLabel *label = 0;
  int counter = 0;
  QPixmap pm = loader.loadIcon( "appointment", KIcon::Small );

  QDate dt;
  for ( dt=QDate::currentDate();
        dt<=QDate::currentDate().addDays( days - 1 );
        dt=dt.addDays(1) ) {
    KCal::Event::List events = mCalendar->events( dt );

    // sort the events for this date by summary
    events = KCal::Calendar::sortEvents( &events,
                                         KCal::EventSortSummary,
                                         KCal::SortDirectionAscending );
    // sort the events for this date by start date
    events = KCal::Calendar::sortEvents( &events,
                                         KCal::EventSortStartDate,
                                         KCal::SortDirectionAscending );

    KCal::Event *ev;
    KCal::Event::List::ConstIterator it;
    for ( it=events.begin(); it!=events.end(); ++it ) {
      ev = *it;

      // Count number of days remaining in multiday event
      int span=1; int dayof=1;
      if ( ev->isMultiDay() ) {
        QDate d = ev->dtStart().date();
        if ( d < QDate::currentDate() ) {
          d = QDate::currentDate();
        }
        while ( d < ev->dtEnd().date() ) {
          if ( d < dt ) {
            dayof++;
          }
          span++;
          d=d.addDays( 1 );
        }
      }

      // If this date is part of a floating, multiday event, then we
      // only make a print for the first day of the event.
      if ( ev->isMultiDay() && ev->doesFloat() && dayof != 1 )break;

      // Fill Appointment Pixmap Field
      label = new QLabel( this );
      label->setPixmap( pm );
      label->setMaximumWidth( label->minimumSizeHint().width() );
      label->setAlignment( AlignVCenter );
      mLayout->addWidget( label, counter, 0 );
      mLabels.append( label );

      // Fill Event Date Field
      bool makeBold = false;
      QString datestr;

      // Modify event date for printing
      QDate sD = QDate::QDate( dt.year(), dt.month(), dt.day() );
      if ( ( sD.month() == QDate::currentDate().month() ) &&
           ( sD.day()   == QDate::currentDate().day() ) ) {
        datestr = i18n( "Today" );
        makeBold = true;
      } else if ( ( sD.month() == QDate::currentDate().addDays( 1 ).month() ) &&
                  ( sD.day()   == QDate::currentDate().addDays( 1 ).day() ) ) {
        datestr = i18n( "Tomorrow" );
      } else {
        datestr = KGlobal::locale()->formatDate( sD );
      }

      // Print the date span for multiday, floating events, for the
      // first day of the event only.
      if ( ev->isMultiDay() && ev->doesFloat() && dayof == 1 && span > 1 ) {
        QString endstr = KGlobal::locale()->formatDate( sD.addDays( span-1 ) );
        datestr += " -\n " + endstr;
      }

      label = new QLabel( datestr, this );
      label->setAlignment( AlignLeft | AlignVCenter );
      if ( makeBold ) {
        QFont font = label->font();
        font.setBold( true );
        label->setFont( font );
      }
      mLayout->addWidget( label, counter, 1 );
      mLabels.append( label );

      // Fill Event Summary Field
      QString newtext = ev->summary();
      if ( ev->isMultiDay() &&  !ev->doesFloat() ) {
        newtext.append( QString(" (%1/%2)").arg( dayof ).arg( span ) );
      }

      KURLLabel *urlLabel = new KURLLabel( ev->uid(), newtext, this );
      urlLabel->installEventFilter( this );
      urlLabel->setAlignment( urlLabel->alignment() | Qt::WordBreak );
      mLayout->addWidget( urlLabel, counter, 2 );
      mLabels.append( urlLabel );

      if ( !ev->description().isEmpty() ) {
        QToolTip::add( urlLabel, ev->description() );
      }

      // Fill Event Time Range Field (only for non-floating Events)
      if ( !ev->doesFloat() ) {
        QTime sST = ev->dtStart().time();
        QTime sET = ev->dtEnd().time();
        if ( ev->isMultiDay() ) {
          if ( ev->dtStart().date() < dt ) {
            sST = QTime::QTime( 0, 0 );
          }
          if ( ev->dtEnd().date() > dt ) {
            sET = QTime::QTime( 23, 59 );
          }
        }
        datestr = i18n( "Time from - to", "%1 - %2" )
                  .arg( KGlobal::locale()->formatTime( sST ) )
                  .arg( KGlobal::locale()->formatTime( sET ) );
        label = new QLabel( datestr, this );
        label->setAlignment( AlignLeft | AlignVCenter );
        mLayout->addWidget( label, counter, 3 );
        mLabels.append( label );
      }

      connect( urlLabel, SIGNAL( leftClickedURL( const QString& ) ),
               this, SLOT( selectEvent( const QString& ) ) );

      counter++;
    }
  }

  if ( !counter ) {
    QLabel *noEvents = new QLabel(
      i18n( "No appointments pending within the next day",
            "No appointments pending within the next %n days",
            days ), this, "nothing to see" );
    noEvents->setAlignment( AlignHCenter | AlignVCenter );
    mLayout->addWidget( noEvents, 0, 2 );
    mLabels.append( noEvents );
  }

  for ( label = mLabels.first(); label; label = mLabels.next() )
    label->show();
}

void SummaryWidget::selectEvent( const QString &uid )
{
  mPlugin->core()->selectPlugin( "kontact_korganizerplugin" ); //ensure loaded
  KOrganizerIface_stub iface( "korganizer", "KOrganizerIface" );
  iface.editIncidence( uid );
}

bool SummaryWidget::eventFilter( QObject *obj, QEvent* e )
{
  if ( obj->inherits( "KURLLabel" ) ) {
    KURLLabel* label = static_cast<KURLLabel*>( obj );
    if ( e->type() == QEvent::Enter )
      emit message( i18n( "Edit Appointment: \"%1\"" ).arg( label->text() ) );
    if ( e->type() == QEvent::Leave )
      emit message( QString::null );
  }

  return Kontact::Summary::eventFilter( obj, e );
}

QStringList SummaryWidget::configModules() const
{
  return QStringList( "kcmkorgsummary.desktop" );
}

#include "summarywidget.moc"
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium 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 "chrome/browser/printing/print_preview_tab_controller.h"

#include "chrome/browser/browser_process.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_navigator.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/common/url_constants.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/common/notification_details.h"
#include "content/common/notification_source.h"

namespace printing {

PrintPreviewTabController::PrintPreviewTabController()
    : waiting_for_new_preview_page_(false) {
}

PrintPreviewTabController::~PrintPreviewTabController() {}

// static
PrintPreviewTabController* PrintPreviewTabController::GetInstance() {
  if (!g_browser_process)
    return NULL;
  return g_browser_process->print_preview_tab_controller();
}

TabContents* PrintPreviewTabController::GetOrCreatePreviewTab(
    TabContents* initiator_tab, int browser_window_id ) {
  DCHECK(initiator_tab);

  // Get the print preview tab for |initiator_tab|.
  TabContents* preview_tab = GetPrintPreviewForTab(initiator_tab);
  if (preview_tab) {
    // Show current preview tab.
    preview_tab->Activate();
    return preview_tab;
  }
  return CreatePrintPreviewTab(initiator_tab, browser_window_id);
}

TabContents* PrintPreviewTabController::GetPrintPreviewForTab(
    TabContents* tab) const {
  PrintPreviewTabMap::const_iterator it = preview_tab_map_.find(tab);
  if (it != preview_tab_map_.end())
    return tab;

  for (it = preview_tab_map_.begin(); it != preview_tab_map_.end(); ++it) {
    // If |tab| is an initiator tab.
    if (tab == it->second) {
      // Return the associated preview tab.
      return it->first;
    }
  }
  return NULL;
}

void PrintPreviewTabController::Observe(NotificationType type,
                                        const NotificationSource& source,
                                        const NotificationDetails& details) {
  TabContents* initiator_tab = NULL;
  TabContents* preview_tab = NULL;
  TabContents* source_tab = NULL;
  NavigationController::LoadCommittedDetails* detail_info = NULL;

  switch (type.value) {
    case NotificationType::TAB_CONTENTS_DESTROYED: {
      source_tab = Source<TabContents>(source).ptr();
      break;
    }
    case NotificationType::NAV_ENTRY_COMMITTED: {
      NavigationController* controller =
          Source<NavigationController>(source).ptr();
      source_tab = controller->tab_contents();
      detail_info =
          Details<NavigationController::LoadCommittedDetails>(details).ptr();
      break;
    }
    default: {
      NOTREACHED();
      return;
    }
  }

  DCHECK(source_tab);
  preview_tab = GetPrintPreviewForTab(source_tab);

  // |source_tab| is preview tab.
  if (preview_tab == source_tab)
    initiator_tab = GetInitiatorTab(source_tab);
  else
    initiator_tab = source_tab;

  if (detail_info) {
    PageTransition::Type transition_type =
        detail_info->entry->transition_type();
    NavigationType::Type nav_type = detail_info->type;

    // Don't update/erase the map entry if the page has not changed.
    if (transition_type == PageTransition::RELOAD ||
        nav_type == NavigationType::SAME_PAGE) {
      return;
    }

    // New |preview_tab| is created. Don't update/erase map entry.
    if (waiting_for_new_preview_page_ &&
        transition_type == PageTransition::LINK &&
        nav_type == NavigationType::NEW_PAGE &&
        source_tab == preview_tab) {
      waiting_for_new_preview_page_ = false;
      return;
    }

    // User navigated to a preview tab using forward/back button.
    if (IsPrintPreviewTab(source_tab) &&
        transition_type == PageTransition::FORWARD_BACK &&
        nav_type == NavigationType::EXISTING_PAGE) {
      return;
    }
  }

  // If |source_tab| is |initiator_tab|, update the map entry.
  if (source_tab == initiator_tab) {
    preview_tab_map_[preview_tab] = NULL;
  }

  // If |source_tab| is |preview_tab|, erase the map entry.
  if (source_tab == preview_tab) {
    preview_tab_map_.erase(preview_tab);
    RemoveObservers(preview_tab);
  }

  if (initiator_tab)
    RemoveObservers(initiator_tab);
}

// static
bool PrintPreviewTabController::IsPrintPreviewTab(TabContents* tab) {
  const GURL& url = tab->GetURL();
  return (url.SchemeIs(chrome::kChromeUIScheme) &&
          url.host() == chrome::kChromeUIPrintHost);
}

TabContents* PrintPreviewTabController::GetInitiatorTab(
    TabContents* preview_tab) {
  PrintPreviewTabMap::iterator it = preview_tab_map_.find(preview_tab);
  if (it != preview_tab_map_.end())
    return preview_tab_map_[preview_tab];
  return NULL;
}

TabContents* PrintPreviewTabController::CreatePrintPreviewTab(
    TabContents* initiator_tab, int browser_window_id) {
  Browser* current_browser = BrowserList::FindBrowserWithID(browser_window_id);
  // Add a new tab next to initiator tab.
  browser::NavigateParams params(current_browser,
                                 GURL(chrome::kChromeUIPrintURL),
                                 PageTransition::LINK);
  params.disposition = NEW_FOREGROUND_TAB;
  params.tabstrip_index = current_browser->tabstrip_model()->
      GetWrapperIndex(initiator_tab) + 1;
  browser::Navigate(&params);
  TabContentsWrapper* preview_tab = params.target_contents;
  preview_tab->tab_contents()->Activate();

  // Add an entry to the map.
  preview_tab_map_[preview_tab->tab_contents()] = initiator_tab;
  waiting_for_new_preview_page_ = true;

  AddObservers(initiator_tab);
  AddObservers(preview_tab->tab_contents());

  return preview_tab->tab_contents();
}

void PrintPreviewTabController::AddObservers(TabContents* tab) {
  registrar_.Add(this, NotificationType::TAB_CONTENTS_DESTROYED,
                 Source<TabContents>(tab));
  registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED,
                 Source<NavigationController>(&tab->controller()));
}

void PrintPreviewTabController::RemoveObservers(TabContents* tab) {
  registrar_.Remove(this, NotificationType::TAB_CONTENTS_DESTROYED,
                    Source<TabContents>(tab));
  registrar_.Remove(this, NotificationType::NAV_ENTRY_COMMITTED,
                    Source<NavigationController>(&tab->controller()));
}

}  // namespace printing
<commit_msg>Print Preview: Cleanup PrintPreviewTabController::Observe.<commit_after>// Copyright (c) 2011 The Chromium 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 "chrome/browser/printing/print_preview_tab_controller.h"

#include "chrome/browser/browser_process.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_navigator.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/common/url_constants.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/common/notification_details.h"
#include "content/common/notification_source.h"

namespace printing {

PrintPreviewTabController::PrintPreviewTabController()
    : waiting_for_new_preview_page_(false) {
}

PrintPreviewTabController::~PrintPreviewTabController() {}

// static
PrintPreviewTabController* PrintPreviewTabController::GetInstance() {
  if (!g_browser_process)
    return NULL;
  return g_browser_process->print_preview_tab_controller();
}

TabContents* PrintPreviewTabController::GetOrCreatePreviewTab(
    TabContents* initiator_tab, int browser_window_id ) {
  DCHECK(initiator_tab);

  // Get the print preview tab for |initiator_tab|.
  TabContents* preview_tab = GetPrintPreviewForTab(initiator_tab);
  if (preview_tab) {
    // Show current preview tab.
    preview_tab->Activate();
    return preview_tab;
  }
  return CreatePrintPreviewTab(initiator_tab, browser_window_id);
}

TabContents* PrintPreviewTabController::GetPrintPreviewForTab(
    TabContents* tab) const {
  PrintPreviewTabMap::const_iterator it = preview_tab_map_.find(tab);
  if (it != preview_tab_map_.end())
    return tab;

  for (it = preview_tab_map_.begin(); it != preview_tab_map_.end(); ++it) {
    // If |tab| is an initiator tab.
    if (tab == it->second) {
      // Return the associated preview tab.
      return it->first;
    }
  }
  return NULL;
}

void PrintPreviewTabController::Observe(NotificationType type,
                                        const NotificationSource& source,
                                        const NotificationDetails& details) {
  TabContents* source_tab = NULL;
  NavigationController::LoadCommittedDetails* detail_info = NULL;

  switch (type.value) {
    case NotificationType::TAB_CONTENTS_DESTROYED: {
      source_tab = Source<TabContents>(source).ptr();
      break;
    }
    case NotificationType::NAV_ENTRY_COMMITTED: {
      NavigationController* controller =
          Source<NavigationController>(source).ptr();
      source_tab = controller->tab_contents();
      detail_info =
          Details<NavigationController::LoadCommittedDetails>(details).ptr();
      break;
    }
    default: {
      NOTREACHED();
      break;
    }
  }

  DCHECK(source_tab);

  TabContents* preview_tab = GetPrintPreviewForTab(source_tab);
  bool source_tab_is_preview_tab = (source_tab == preview_tab);

  if (detail_info) {
    PageTransition::Type transition_type =
        detail_info->entry->transition_type();
    NavigationType::Type nav_type = detail_info->type;

    // Don't update/erase the map entry if the page has not changed.
    if (transition_type == PageTransition::RELOAD ||
        nav_type == NavigationType::SAME_PAGE) {
      return;
    }

    // New |preview_tab| is created. Don't update/erase map entry.
    if (waiting_for_new_preview_page_ &&
        transition_type == PageTransition::LINK &&
        nav_type == NavigationType::NEW_PAGE &&
        source_tab_is_preview_tab) {
      waiting_for_new_preview_page_ = false;
      return;
    }

    // User navigated to a preview tab using forward/back button.
    if (source_tab_is_preview_tab &&
        transition_type == PageTransition::FORWARD_BACK &&
        nav_type == NavigationType::EXISTING_PAGE) {
      return;
    }
  }

  if (source_tab_is_preview_tab) {
    // Remove the initiator tab's observers before erasing the mapping.
    TabContents* initiator_tab = GetInitiatorTab(source_tab);
    if (initiator_tab)
      RemoveObservers(initiator_tab);

    // Erase the map entry.
    preview_tab_map_.erase(source_tab);
  } else {
    // |source_tab| is an initiator tab, update the map entry.
    preview_tab_map_[preview_tab] = NULL;
  }
  RemoveObservers(source_tab);
}

// static
bool PrintPreviewTabController::IsPrintPreviewTab(TabContents* tab) {
  const GURL& url = tab->GetURL();
  return (url.SchemeIs(chrome::kChromeUIScheme) &&
          url.host() == chrome::kChromeUIPrintHost);
}

TabContents* PrintPreviewTabController::GetInitiatorTab(
    TabContents* preview_tab) {
  PrintPreviewTabMap::iterator it = preview_tab_map_.find(preview_tab);
  if (it != preview_tab_map_.end())
    return preview_tab_map_[preview_tab];
  return NULL;
}

TabContents* PrintPreviewTabController::CreatePrintPreviewTab(
    TabContents* initiator_tab, int browser_window_id) {
  Browser* current_browser = BrowserList::FindBrowserWithID(browser_window_id);
  // Add a new tab next to initiator tab.
  browser::NavigateParams params(current_browser,
                                 GURL(chrome::kChromeUIPrintURL),
                                 PageTransition::LINK);
  params.disposition = NEW_FOREGROUND_TAB;
  params.tabstrip_index = current_browser->tabstrip_model()->
      GetWrapperIndex(initiator_tab) + 1;
  browser::Navigate(&params);
  TabContentsWrapper* preview_tab = params.target_contents;
  preview_tab->tab_contents()->Activate();

  // Add an entry to the map.
  preview_tab_map_[preview_tab->tab_contents()] = initiator_tab;
  waiting_for_new_preview_page_ = true;

  AddObservers(initiator_tab);
  AddObservers(preview_tab->tab_contents());

  return preview_tab->tab_contents();
}

void PrintPreviewTabController::AddObservers(TabContents* tab) {
  registrar_.Add(this, NotificationType::TAB_CONTENTS_DESTROYED,
                 Source<TabContents>(tab));
  registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED,
                 Source<NavigationController>(&tab->controller()));
}

void PrintPreviewTabController::RemoveObservers(TabContents* tab) {
  registrar_.Remove(this, NotificationType::TAB_CONTENTS_DESTROYED,
                    Source<TabContents>(tab));
  registrar_.Remove(this, NotificationType::NAV_ENTRY_COMMITTED,
                    Source<NavigationController>(&tab->controller()));
}

}  // namespace printing
<|endoftext|>