<commit_before>/*
 * Copyright 2012 Open Source Robotics Foundation
 *
 * 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.
 *
 */
/* Desc: Time class
 * Author: Nate Koenig
 * Date: 3 Apr 2007
 */

#include <sys/time.h>
#include <time.h>
#include <math.h>
#include <boost/date_time.hpp>

#ifdef __MACH__
#include <mach/clock.h>
#include <mach/mach.h>
#endif

#define CLOCK_REALTIME 0
#define CLOCK_MONOTONIC 0

#include "gazebo/math/Helpers.hh"
#include "gazebo/common/Time.hh"
#include "gazebo/common/Console.hh"

using namespace gazebo;
using namespace common;

Time Time::wallTime;
std::string Time::wallTimeISO;

struct timespec Time::clockResolution;

const Time Time::Zero = common::Time(0, 0);

/////////////////////////////////////////////////
Time::Time()
{
  this->sec = 0;
  this->nsec = 0;

  // get clock resolution, skip sleep if resolution is larger then
  // requested sleep time
  clock_getres(CLOCK_REALTIME, &clockResolution);
}

/////////////////////////////////////////////////
Time::Time(const Time &_time)
: sec(_time.sec), nsec(_time.nsec)
{
}

/////////////////////////////////////////////////
Time::Time(const struct timeval &_tv)
{
  this->sec = _tv.tv_sec;
  this->nsec = _tv.tv_usec*1000;
}

/////////////////////////////////////////////////
Time::Time(const struct timespec &_tv)
{
  this->sec = _tv.tv_sec;
  this->nsec = _tv.tv_nsec;
}

/////////////////////////////////////////////////
Time::Time(int32_t _sec, int32_t _nsec)
: sec(_sec), nsec(_nsec)
{
  this->Correct();
}

/////////////////////////////////////////////////
Time::Time(double _time)
{
  this->Set(_time);
}

/////////////////////////////////////////////////
Time::~Time()
{
}

/////////////////////////////////////////////////
const Time &Time::GetWallTime()
{
  struct timespec tv;
    // OS X does not have clock_gettime, use clock_get_time
#ifdef __MACH__
    clock_serv_t cclock;
    mach_timespec_t mts;
    host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
    clock_get_time(cclock, &mts);
    mach_port_deallocate(mach_task_self(), cclock);
    tv.tv_sec = mts.tv_sec;
    tv.tv_nsec = mts.tv_nsec;
#else
    clock_gettime(0, &tv);
#endif
    wallTime = tv;
  return wallTime;
}

/////////////////////////////////////////////////
const std::string &Time::GetWallTimeAsISOString()
{
  wallTimeISO = boost::posix_time::to_iso_extended_string(
      boost::posix_time::microsec_clock::local_time());

  return wallTimeISO;
}

/////////////////////////////////////////////////
void Time::SetToWallTime()
{
  *this = this->GetWallTime();
}

/////////////////////////////////////////////////
void Time::Set(int32_t _sec, int32_t _nsec)
{
  this->sec = _sec;
  this->nsec = _nsec;

  this->Correct();
}

/////////////////////////////////////////////////
void Time::Set(double _seconds)
{
  this->sec = (int32_t)(floor(_seconds));
  this->nsec = (int32_t)(round((_seconds - this->sec) * 1e9));
  this->Correct();
}

/////////////////////////////////////////////////
double Time::Double() const
{
  return (static_cast<double>(this->sec) +
          static_cast<double>(this->nsec)*1e-9);
}

/////////////////////////////////////////////////
float Time::Float() const
{
  return (this->sec + this->nsec * 1e-9f);
}

/////////////////////////////////////////////////
Time Time::Sleep(const common::Time &_time)
{
  Time result;

  if (_time >= clockResolution)
  {
    struct timespec interval;
    struct timespec remainder;
    interval.tv_sec = _time.sec;
    interval.tv_nsec = _time.nsec;

    // Sleeping for negative time doesn't make sense
    if (interval.tv_sec < 0)
    {
      gzerr << "Cannot sleep for negative time[" << _time << "]\n";
      return result;
    }

    // This assert conforms to the manpage for nanosleep
    if (interval.tv_nsec < 0 || interval.tv_nsec > 999999999)
    {
      gzerr << "Nanoseconds of [" << interval.tv_nsec
            << "] must be in the range0 to 999999999.\n";
      return result;
    }

    if (nanosleep(&interval, &remainder) == -1)
    {
      result.sec = remainder.tv_sec;
      result.nsec = remainder.tv_nsec;
    }
  }
  else
  {
    /// \TODO Make this a gzlog
    gzwarn << "Sleep time is larger than clock resolution, skipping sleep\n";
  }

  return result;
}

/////////////////////////////////////////////////
Time Time::MSleep(unsigned int _ms)
{
  return Time::Sleep(Time(0, _ms*1000000));
}

/////////////////////////////////////////////////
Time Time::NSleep(unsigned int _ns)
{
  return Time::Sleep(Time(0, _ns));
}

/////////////////////////////////////////////////
Time Time::NSleep(Time _time)
{
  return Time::Sleep(_time);
}

/////////////////////////////////////////////////
Time &Time::operator =(const struct timeval &_tv)
{
  this->sec = _tv.tv_sec;
  this->nsec = _tv.tv_usec*1000;

  return *this;
}

/////////////////////////////////////////////////
Time &Time::operator =(const struct timespec &_tv)
{
  this->sec = _tv.tv_sec;
  this->nsec = _tv.tv_nsec;

  return *this;
}

/////////////////////////////////////////////////
Time &Time::operator =(const Time &_time)
{
  this->sec = _time.sec;
  this->nsec = _time.nsec;

  return *this;
}

/////////////////////////////////////////////////
Time Time::operator +(const struct timeval &_tv) const
{
  Time t(this->sec + _tv.tv_sec, this->nsec + _tv.tv_usec*1000);
  t.Correct();
  return t;
}

/////////////////////////////////////////////////
Time Time::operator +(const struct timespec &_tv) const
{
  Time t(this->sec + _tv.tv_sec, this->nsec + _tv.tv_nsec);
  t.Correct();
  return t;
}

/////////////////////////////////////////////////
const Time &Time::operator +=(const struct timeval &_tv)
{
  this->sec += _tv.tv_sec;
  this->nsec += _tv.tv_usec*1000;
  this->Correct();
  return *this;
}

/////////////////////////////////////////////////
const Time &Time::operator +=(const struct timespec &_tv)
{
  this->sec += _tv.tv_sec;
  this->nsec += _tv.tv_nsec;
  this->Correct();
  return *this;
}

/////////////////////////////////////////////////
Time Time::operator +(const Time &_time) const
{
  Time t(this->sec + _time.sec, this->nsec + _time.nsec);
  t.Correct();

  return t;
}

/////////////////////////////////////////////////
const Time &Time::operator +=(const Time &_time)
{
  this->sec += _time.sec;
  this->nsec += _time.nsec;
  this->Correct();
  return *this;
}

/////////////////////////////////////////////////
Time Time::operator -(const struct timeval &_tv) const
{
  Time t(this->sec - _tv.tv_sec, this->nsec - _tv.tv_usec*1000);
  t.Correct();

  return t;
}

/////////////////////////////////////////////////
const Time &Time::operator -=(const struct timeval &_tv)
{
  this->sec -= _tv.tv_sec;
  this->nsec -= _tv.tv_usec*1000;
  this->Correct();
  return *this;
}

/////////////////////////////////////////////////
Time Time::operator -(const struct timespec &_tv) const
{
  Time t(this->sec - _tv.tv_sec, this->nsec - _tv.tv_nsec);
  t.Correct();

  return t;
}

/////////////////////////////////////////////////
const Time &Time::operator -=(const struct timespec &_tv)
{
  this->sec -= _tv.tv_sec;
  this->nsec -= _tv.tv_nsec;
  this->Correct();
  return *this;
}

/////////////////////////////////////////////////
Time Time::operator -(const Time &_time) const
{
  Time t(this->sec - _time.sec, this->nsec - _time.nsec);
  t.Correct();
  return t;
}

/////////////////////////////////////////////////
const Time &Time::operator -=(const Time &_time)
{
  this->sec -= _time.sec;
  this->nsec -= _time.nsec;
  this->Correct();
  return *this;
}

/////////////////////////////////////////////////
Time Time::operator *(const struct timeval &_tv) const
{
  Time t2(_tv.tv_sec, _tv.tv_usec*1000);
  Time t(this->Double() * t2.Double());
  t.Correct();
  return t;
}

/////////////////////////////////////////////////
const Time &Time::operator *=(const struct timeval &_tv)
{
  Time t2(_tv.tv_sec, _tv.tv_usec*1000);
  this->Set(this->Double() * t2.Double());
  this->Correct();
  return *this;
}

/////////////////////////////////////////////////
Time Time::operator *(const struct timespec &_tv) const
{
  Time t2(_tv.tv_sec, _tv.tv_nsec);
  Time t(this->Double() * t2.Double());
  t.Correct();
  return t;
}

/////////////////////////////////////////////////
const Time &Time::operator *=(const struct timespec &_tv)
{
  Time t2(_tv.tv_sec, _tv.tv_nsec);
  this->Set(this->Double() * t2.Double());
  this->Correct();
  return *this;
}

/////////////////////////////////////////////////
Time Time::operator *(const Time &_time) const
{
  Time t(this->Double() * _time.Double());
  t.Correct();
  return t;
}

/////////////////////////////////////////////////
const Time &Time::operator *=(const Time &_time)
{
  this->Set(this->Double() * _time.Double());
  this->Correct();
  return *this;
}

/////////////////////////////////////////////////
Time Time::operator /(const struct timeval &_tv) const
{
  return (*this) / Time(_tv);
}

/////////////////////////////////////////////////
const Time &Time::operator /=(const struct timeval &_tv)
{
  *this = *this / Time(_tv);
  return *this;
}

/////////////////////////////////////////////////
Time Time::operator /(const struct timespec &_tv) const
{
  return (*this) / Time(_tv);
}

/////////////////////////////////////////////////
const Time &Time::operator /=(const struct timespec &_tv)
{
  *this = *this / Time(_tv);
  return *this;
}

/////////////////////////////////////////////////
Time Time::operator /(const Time &_time) const
{
  Time result(*this);

  if (_time.sec == 0 && _time.nsec == 0)
    gzerr << "Time divide by zero\n";
  else
    result.Set(this->Double() / _time.Double());

  return result;
}

/////////////////////////////////////////////////
const Time &Time::operator /=(const Time &_time)
{
  *this = *this / _time;
  return *this;
}

/////////////////////////////////////////////////
bool Time::operator ==(const struct timeval &_tv) const
{
  return *this == Time(_tv);
}

/////////////////////////////////////////////////
bool Time::operator ==(const struct timespec &_tv) const
{
  return *this == Time(_tv);
}

/////////////////////////////////////////////////
bool Time::operator ==(const Time &_time) const
{
  return this->sec == _time.sec && this->nsec == _time.nsec;
}

/////////////////////////////////////////////////
bool Time::operator ==(double _time) const
{
  return *this == Time(_time);
}

/////////////////////////////////////////////////
bool Time::operator!=(const struct timeval &_tv) const
{
  return !(*this == _tv);
}

/////////////////////////////////////////////////
bool Time::operator!=(const struct timespec &_tv) const
{
  return !(*this == _tv);
}

/////////////////////////////////////////////////
bool Time::operator!=(const Time &_time) const
{
  return !(*this == _time);
}

/////////////////////////////////////////////////
bool Time::operator!=(double _time) const
{
  return !(*this == _time);
}

/////////////////////////////////////////////////
bool Time::operator<(const struct timeval &_tv) const
{
  return *this < Time(_tv);
}

/////////////////////////////////////////////////
bool Time::operator<(const struct timespec &_tv) const
{
  return *this < Time(_tv);
}

/////////////////////////////////////////////////
bool Time::operator<(const Time &_time) const
{
  return this->sec < _time.sec ||
    (this->sec == _time.sec && this->nsec < _time.nsec);
}

/////////////////////////////////////////////////
bool Time::operator<(double _time) const
{
  return *this < Time(_time);
}

/////////////////////////////////////////////////
bool Time::operator<=(const struct timeval &_tv) const
{
  return *this <= Time(_tv);
}

/////////////////////////////////////////////////
bool Time::operator<=(const struct timespec &_tv) const
{
  return *this <= Time(_tv);
}

/////////////////////////////////////////////////
bool Time::operator<=(const Time &_time) const
{
  return !(_time < *this);
}

/////////////////////////////////////////////////
bool Time::operator<=(double _time) const
{
  return *this <= Time(_time);
}

/////////////////////////////////////////////////
bool Time::operator>(const struct timeval &_tv) const
{
  return *this > Time(_tv);
}

/////////////////////////////////////////////////
bool Time::operator>(const struct timespec &_tv) const
{
  return *this > Time(_tv);
}

/////////////////////////////////////////////////
bool Time::operator>(const Time &_time) const
{
  return _time < *this;
}

/////////////////////////////////////////////////
bool Time::operator>(double _time) const
{
  return *this > Time(_time);
}

/////////////////////////////////////////////////
bool Time::operator>=(const struct timeval &_tv) const
{
  return *this >= Time(_tv);
}

/////////////////////////////////////////////////
bool Time::operator>=(const struct timespec &_tv) const
{
  return *this >= Time(_tv);
}

/////////////////////////////////////////////////
bool Time::operator>=(const Time &_time) const
{
  return !(*this < _time);
}

/////////////////////////////////////////////////
bool Time::operator>=(double _time) const
{
  return *this >= Time(_time);
}
<commit_msg>change in time for mac<commit_after>/*
 * Copyright 2012 Open Source Robotics Foundation
 *
 * 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.
 *
 */
/* Desc: Time class
 * Author: Nate Koenig
 * Date: 3 Apr 2007
 */

#include <sys/time.h>
#include <time.h>
#include <math.h>
#include <boost/date_time.hpp>

#ifdef __MACH__
#include <mach/clock.h>
#include <mach/mach.h>
#endif

#define CLOCK_REALTIME 0
#define CLOCK_MONOTONIC 0

#include "gazebo/math/Helpers.hh"
#include "gazebo/common/Time.hh"
#include "gazebo/common/Console.hh"

using namespace gazebo;
using namespace common;

Time Time::wallTime;
std::string Time::wallTimeISO;

struct timespec Time::clockResolution;

const Time Time::Zero = common::Time(0, 0);

/////////////////////////////////////////////////
Time::Time()
{
    this->sec = 0;
    this->nsec = 0;

#ifdef __MACH__
    clockResolution.tv_sec = 1 / sysconf(_SC_CLK_TCK);
#else
    // get clock resolution, skip sleep if resolution is larger then
    // requested sleep time
    clock_getres(CLOCK_REALTIME, &clockResolution);
#endif
}

/////////////////////////////////////////////////
Time::Time(const Time &_time)
: sec(_time.sec), nsec(_time.nsec)
{
}

/////////////////////////////////////////////////
Time::Time(const struct timeval &_tv)
{
  this->sec = _tv.tv_sec;
  this->nsec = _tv.tv_usec*1000;
}

/////////////////////////////////////////////////
Time::Time(const struct timespec &_tv)
{
  this->sec = _tv.tv_sec;
  this->nsec = _tv.tv_nsec;
}

/////////////////////////////////////////////////
Time::Time(int32_t _sec, int32_t _nsec)
: sec(_sec), nsec(_nsec)
{
  this->Correct();
}

/////////////////////////////////////////////////
Time::Time(double _time)
{
  this->Set(_time);
}

/////////////////////////////////////////////////
Time::~Time()
{
}

/////////////////////////////////////////////////
const Time &Time::GetWallTime()
{
  struct timespec tv;
    // OS X does not have clock_gettime, use clock_get_time
#ifdef __MACH__
    clock_serv_t cclock;
    mach_timespec_t mts;
    host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
    clock_get_time(cclock, &mts);
    mach_port_deallocate(mach_task_self(), cclock);
    tv.tv_sec = mts.tv_sec;
    tv.tv_nsec = mts.tv_nsec;
#else
    clock_gettime(0, &tv);
#endif
    wallTime = tv;
  return wallTime;
}

/////////////////////////////////////////////////
const std::string &Time::GetWallTimeAsISOString()
{
  wallTimeISO = boost::posix_time::to_iso_extended_string(
      boost::posix_time::microsec_clock::local_time());

  return wallTimeISO;
}

/////////////////////////////////////////////////
void Time::SetToWallTime()
{
  *this = this->GetWallTime();
}

/////////////////////////////////////////////////
void Time::Set(int32_t _sec, int32_t _nsec)
{
  this->sec = _sec;
  this->nsec = _nsec;

  this->Correct();
}

/////////////////////////////////////////////////
void Time::Set(double _seconds)
{
  this->sec = (int32_t)(floor(_seconds));
  this->nsec = (int32_t)(round((_seconds - this->sec) * 1e9));
  this->Correct();
}

/////////////////////////////////////////////////
double Time::Double() const
{
  return (static_cast<double>(this->sec) +
          static_cast<double>(this->nsec)*1e-9);
}

/////////////////////////////////////////////////
float Time::Float() const
{
  return (this->sec + this->nsec * 1e-9f);
}

/////////////////////////////////////////////////
Time Time::Sleep(const common::Time &_time)
{
  Time result;

  if (_time >= clockResolution)
  {
    struct timespec interval;
    struct timespec remainder;
    interval.tv_sec = _time.sec;
    interval.tv_nsec = _time.nsec;

    // Sleeping for negative time doesn't make sense
    if (interval.tv_sec < 0)
    {
      gzerr << "Cannot sleep for negative time[" << _time << "]\n";
      return result;
    }

    // This assert conforms to the manpage for nanosleep
    if (interval.tv_nsec < 0 || interval.tv_nsec > 999999999)
    {
      gzerr << "Nanoseconds of [" << interval.tv_nsec
            << "] must be in the range0 to 999999999.\n";
      return result;
    }

    if (nanosleep(&interval, &remainder) == -1)
    {
      result.sec = remainder.tv_sec;
      result.nsec = remainder.tv_nsec;
    }
  }
  else
  {
    /// \TODO Make this a gzlog
    gzwarn << "Sleep time is larger than clock resolution, skipping sleep\n";
  }

  return result;
}

/////////////////////////////////////////////////
Time Time::MSleep(unsigned int _ms)
{
  return Time::Sleep(Time(0, _ms*1000000));
}

/////////////////////////////////////////////////
Time Time::NSleep(unsigned int _ns)
{
  return Time::Sleep(Time(0, _ns));
}

/////////////////////////////////////////////////
Time Time::NSleep(Time _time)
{
  return Time::Sleep(_time);
}

/////////////////////////////////////////////////
Time &Time::operator =(const struct timeval &_tv)
{
  this->sec = _tv.tv_sec;
  this->nsec = _tv.tv_usec*1000;

  return *this;
}

/////////////////////////////////////////////////
Time &Time::operator =(const struct timespec &_tv)
{
  this->sec = _tv.tv_sec;
  this->nsec = _tv.tv_nsec;

  return *this;
}

/////////////////////////////////////////////////
Time &Time::operator =(const Time &_time)
{
  this->sec = _time.sec;
  this->nsec = _time.nsec;

  return *this;
}

/////////////////////////////////////////////////
Time Time::operator +(const struct timeval &_tv) const
{
  Time t(this->sec + _tv.tv_sec, this->nsec + _tv.tv_usec*1000);
  t.Correct();
  return t;
}

/////////////////////////////////////////////////
Time Time::operator +(const struct timespec &_tv) const
{
  Time t(this->sec + _tv.tv_sec, this->nsec + _tv.tv_nsec);
  t.Correct();
  return t;
}

/////////////////////////////////////////////////
const Time &Time::operator +=(const struct timeval &_tv)
{
  this->sec += _tv.tv_sec;
  this->nsec += _tv.tv_usec*1000;
  this->Correct();
  return *this;
}

/////////////////////////////////////////////////
const Time &Time::operator +=(const struct timespec &_tv)
{
  this->sec += _tv.tv_sec;
  this->nsec += _tv.tv_nsec;
  this->Correct();
  return *this;
}

/////////////////////////////////////////////////
Time Time::operator +(const Time &_time) const
{
  Time t(this->sec + _time.sec, this->nsec + _time.nsec);
  t.Correct();

  return t;
}

/////////////////////////////////////////////////
const Time &Time::operator +=(const Time &_time)
{
  this->sec += _time.sec;
  this->nsec += _time.nsec;
  this->Correct();
  return *this;
}

/////////////////////////////////////////////////
Time Time::operator -(const struct timeval &_tv) const
{
  Time t(this->sec - _tv.tv_sec, this->nsec - _tv.tv_usec*1000);
  t.Correct();

  return t;
}

/////////////////////////////////////////////////
const Time &Time::operator -=(const struct timeval &_tv)
{
  this->sec -= _tv.tv_sec;
  this->nsec -= _tv.tv_usec*1000;
  this->Correct();
  return *this;
}

/////////////////////////////////////////////////
Time Time::operator -(const struct timespec &_tv) const
{
  Time t(this->sec - _tv.tv_sec, this->nsec - _tv.tv_nsec);
  t.Correct();

  return t;
}

/////////////////////////////////////////////////
const Time &Time::operator -=(const struct timespec &_tv)
{
  this->sec -= _tv.tv_sec;
  this->nsec -= _tv.tv_nsec;
  this->Correct();
  return *this;
}

/////////////////////////////////////////////////
Time Time::operator -(const Time &_time) const
{
  Time t(this->sec - _time.sec, this->nsec - _time.nsec);
  t.Correct();
  return t;
}

/////////////////////////////////////////////////
const Time &Time::operator -=(const Time &_time)
{
  this->sec -= _time.sec;
  this->nsec -= _time.nsec;
  this->Correct();
  return *this;
}

/////////////////////////////////////////////////
Time Time::operator *(const struct timeval &_tv) const
{
  Time t2(_tv.tv_sec, _tv.tv_usec*1000);
  Time t(this->Double() * t2.Double());
  t.Correct();
  return t;
}

/////////////////////////////////////////////////
const Time &Time::operator *=(const struct timeval &_tv)
{
  Time t2(_tv.tv_sec, _tv.tv_usec*1000);
  this->Set(this->Double() * t2.Double());
  this->Correct();
  return *this;
}

/////////////////////////////////////////////////
Time Time::operator *(const struct timespec &_tv) const
{
  Time t2(_tv.tv_sec, _tv.tv_nsec);
  Time t(this->Double() * t2.Double());
  t.Correct();
  return t;
}

/////////////////////////////////////////////////
const Time &Time::operator *=(const struct timespec &_tv)
{
  Time t2(_tv.tv_sec, _tv.tv_nsec);
  this->Set(this->Double() * t2.Double());
  this->Correct();
  return *this;
}

/////////////////////////////////////////////////
Time Time::operator *(const Time &_time) const
{
  Time t(this->Double() * _time.Double());
  t.Correct();
  return t;
}

/////////////////////////////////////////////////
const Time &Time::operator *=(const Time &_time)
{
  this->Set(this->Double() * _time.Double());
  this->Correct();
  return *this;
}

/////////////////////////////////////////////////
Time Time::operator /(const struct timeval &_tv) const
{
  return (*this) / Time(_tv);
}

/////////////////////////////////////////////////
const Time &Time::operator /=(const struct timeval &_tv)
{
  *this = *this / Time(_tv);
  return *this;
}

/////////////////////////////////////////////////
Time Time::operator /(const struct timespec &_tv) const
{
  return (*this) / Time(_tv);
}

/////////////////////////////////////////////////
const Time &Time::operator /=(const struct timespec &_tv)
{
  *this = *this / Time(_tv);
  return *this;
}

/////////////////////////////////////////////////
Time Time::operator /(const Time &_time) const
{
  Time result(*this);

  if (_time.sec == 0 && _time.nsec == 0)
    gzerr << "Time divide by zero\n";
  else
    result.Set(this->Double() / _time.Double());

  return result;
}

/////////////////////////////////////////////////
const Time &Time::operator /=(const Time &_time)
{
  *this = *this / _time;
  return *this;
}

/////////////////////////////////////////////////
bool Time::operator ==(const struct timeval &_tv) const
{
  return *this == Time(_tv);
}

/////////////////////////////////////////////////
bool Time::operator ==(const struct timespec &_tv) const
{
  return *this == Time(_tv);
}

/////////////////////////////////////////////////
bool Time::operator ==(const Time &_time) const
{
  return this->sec == _time.sec && this->nsec == _time.nsec;
}

/////////////////////////////////////////////////
bool Time::operator ==(double _time) const
{
  return *this == Time(_time);
}

/////////////////////////////////////////////////
bool Time::operator!=(const struct timeval &_tv) const
{
  return !(*this == _tv);
}

/////////////////////////////////////////////////
bool Time::operator!=(const struct timespec &_tv) const
{
  return !(*this == _tv);
}

/////////////////////////////////////////////////
bool Time::operator!=(const Time &_time) const
{
  return !(*this == _time);
}

/////////////////////////////////////////////////
bool Time::operator!=(double _time) const
{
  return !(*this == _time);
}

/////////////////////////////////////////////////
bool Time::operator<(const struct timeval &_tv) const
{
  return *this < Time(_tv);
}

/////////////////////////////////////////////////
bool Time::operator<(const struct timespec &_tv) const
{
  return *this < Time(_tv);
}

/////////////////////////////////////////////////
bool Time::operator<(const Time &_time) const
{
  return this->sec < _time.sec ||
    (this->sec == _time.sec && this->nsec < _time.nsec);
}

/////////////////////////////////////////////////
bool Time::operator<(double _time) const
{
  return *this < Time(_time);
}

/////////////////////////////////////////////////
bool Time::operator<=(const struct timeval &_tv) const
{
  return *this <= Time(_tv);
}

/////////////////////////////////////////////////
bool Time::operator<=(const struct timespec &_tv) const
{
  return *this <= Time(_tv);
}

/////////////////////////////////////////////////
bool Time::operator<=(const Time &_time) const
{
  return !(_time < *this);
}

/////////////////////////////////////////////////
bool Time::operator<=(double _time) const
{
  return *this <= Time(_time);
}

/////////////////////////////////////////////////
bool Time::operator>(const struct timeval &_tv) const
{
  return *this > Time(_tv);
}

/////////////////////////////////////////////////
bool Time::operator>(const struct timespec &_tv) const
{
  return *this > Time(_tv);
}

/////////////////////////////////////////////////
bool Time::operator>(const Time &_time) const
{
  return _time < *this;
}

/////////////////////////////////////////////////
bool Time::operator>(double _time) const
{
  return *this > Time(_time);
}

/////////////////////////////////////////////////
bool Time::operator>=(const struct timeval &_tv) const
{
  return *this >= Time(_tv);
}

/////////////////////////////////////////////////
bool Time::operator>=(const struct timespec &_tv) const
{
  return *this >= Time(_tv);
}

/////////////////////////////////////////////////
bool Time::operator>=(const Time &_time) const
{
  return !(*this < _time);
}

/////////////////////////////////////////////////
bool Time::operator>=(double _time) const
{
  return *this >= Time(_time);
}
<|endoftext|>


<commit_before>/**
 *
 *  wngCSV is a wrong-entertainment production
 *
 *
 *  Copyright 2011 wrong-entertainment
 *                 <wrongentertainment@yahoo.de>
 *                 <http://wrong-entertainment.com>
 *
 *  This file is part of wnglibs.
 *
 *  wngCSV is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  wngCSV 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 Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with wngCSV. If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "wngCSV.h"

namespace wng {

	/**
	 * A Constructor, usually called to initialize and start the class.
	 */
	wngCSV::wngCSV(){
	}

	/**
	 * loadFile
	 *
	 * @param path
	 *        Set the File Path.
	 * @param separator
	 *        Set the Separator to split CSV file.
	 * @param comments
	 *        Set the Comments sign.
	 */
	void wngCSV::loadFile(string path, string separator, string comments){
		// Save string variables.
		filePath = path;
		fileSeparator = separator;
		fileComments = comments;

		// Declare a File Stream.
		ifstream fileIn;

		// Open your Text File:
		fileIn.open(path.c_str());

		// Check if File is open.
		if(fileIn.is_open()) {
			int lineCount = 0;
			vector<string> rows;

			while(fileIn != NULL) {
				string temp;
				getline(fileIn, temp);

				// Skip empty lines.
				if(temp.length() == 0) {
					//cout << "Skip empty line no: " << lineCount << endl;
				}
				// Skip Comment lines.
				else if(ofToString(temp[0]) == comments) {
					//cout << "Skip Comment line no: " << lineCount << endl;
				} else {
					rows.push_back(temp);

					// Split row into cols.
					vector<string> cols = ofSplitString(rows[lineCount], ",");

					// Write the string to data.
					data.push_back(cols);

					// Erase remaining elements.
					cols.erase(cols.begin(), cols.end());
					//cout << "cols: After erasing all elements, vector integers " << (cols.empty() ? "is" : "is not" ) << " empty" << endl;

					lineCount++;
				}
			}

			// Save the Number of Rows.
			numRows = rows.size();

			// Erase remaining elements.
			rows.erase(rows.begin(), rows.end());
			//cout << "rows: After erasing all elements, vector integers " << (rows.empty() ? "is" : "is not" ) << " empty" << endl;

			// If File cannot opening, print a message to console.
		} else {
		cout << "Error opening " << path << ".\n";
		}
	}

	void wngCSV::loadFile(string path, string separator) {
		loadFile(path, separator, "#");
	}

	void wngCSV::loadFile(string path) {
		loadFile(path, ",", "#");
	}

	/**
	 * saveFile
	 *
	 * @param path
	 *        Set the File Path.
	 * @param separator
	 *        Set the Separator to split CSV file.
	 * @param comments
	 *        Set the Comments sign.
	 */
	void wngCSV::saveFile(string path, string separator, string comments) {
		createFile(path);

		ofstream myfile;
		myfile.open(path.c_str());
		if (myfile.is_open()) {
			// Write data to file.
			for(int i=0; i<numRows; i++) {
				for(int j=0; j<data[i].size(); j++) {
					myfile << data[i][j] << separator;
					if(j==(data[i].size()-1)) {
						myfile << "\n";
					}
				}
			}
			myfile.close();
			//cout << "Open file" << endl;
		} else {
			//cout << "Unable to open file" << endl;
		}

	}

	void wngCSV::saveFile(string path, string separator) {
		createFile(path);
		saveFile(path, separator, fileComments);
	}

	void wngCSV::saveFile(string path) {
		createFile(path);
		saveFile(path, fileSeparator, fileComments);
	}

	void wngCSV::saveFile() {
		saveFile(filePath, fileSeparator, fileComments);
	}

	/**
	 * createFile
	 *
	 * @param path
	 *        Set the File Path.
	 */
	void wngCSV::createFile(string path) {
		FILE * pFile;
		pFile = fopen (path.c_str(),"w");
		if (pFile!=NULL) {
			//fputs ("fopen example",pFile);
			fclose (pFile);
		}
	}

	/**
	 * loadFromString
	 *
	 * @param s
	 *        String Input.
	 */
	vector<string> wngCSV::getFromString(string s, string separator) {
		vector<string> cols = ofSplitString(s, separator);
		return cols;
	}

	vector<string> wngCSV::getFromString(string s) {
		getFromString(s, ",");
	}

	/**
	 * getInt
	 * get the Integer of a specific row and column.
	 *
	 * @param row
	 *        row number
	 * @param col
	 *        column number
	 * @return integer
	 */
	int wngCSV::getInt(int row, int col) {
		int temp = 0;
		istringstream buffer(data[row][col]);
		buffer >> temp;
		return temp;
	}

	/**
	 * getFloat
	 * get the Float of a specific row and column.
	 *
	 * @param row
	 *        row number
	 * @param col
	 *        column number
	 * @return float
	 */
	float wngCSV::getFloat(int row, int col) {
		float temp = 0;
		istringstream buffer(data[row][col]);
		buffer >> temp;
		return temp;
	}

	/**
	 * getString
	 * get the String of a specific row and column.
	 *
	 * @param row
	 *        row number
	 * @param col
	 *        column number
	 * @return float
	 */
	string wngCSV::getString(int row, int col) {
		string temp = data[row][col];
		return temp;
	}

	/**
	 * getBool
	 * get the Boolean of a specific row and column.
	 *
	 * @param row
	 *        row number
	 * @param col
	 *        column number
	 * @return bool
	 */
	bool wngCSV::getBool(int row, int col) {
		static const string trueString = "true";
		static const string falseString = "false";
		string lower = ofToLower(data[row][col]);
		if(lower == trueString) {
			return true;
		}
		if(lower == falseString) {
			return false;
		}
		bool temp = false;
		istringstream cur(lower);
		cur >> temp;
		return temp;
	}

	/**
	 * setInt
	 * set a specific Integer to a new value.
	 *
	 * @param row
	 *        row number
	 * @param col
	 *        column number
	 * @param what
	 *        new Integer
	 */
	void wngCSV::setInt(int row, int col, int what) {
		data[row][col] = ofToString(what);
	}

	/**
	 * setFloat
	 * set a specific Float to a new value.
	 *
	 * @param row
	 *        row number
	 * @param col
	 *        column number
	 * @param what
	 *        new row Float
	 */
	void wngCSV::setFloat(int row, int col, float what) {
		data[row][col] = ofToString(what);
	}

	/**
	 * setString
	 * set a specific String to a new value.
	 *
	 * @param row
	 *        row number
	 * @param col
	 *        column number
	 * @param what
	 *        new row String
	 */
	void wngCSV::setString(int row, int col, string what) {
		data[row][col] = ofToString(what);
	}

	/**
	 * setBool
	 * set a specific Boolean to a new value.
	 *
	 * @param row
	 *        row number
	 * @param col
	 *        column number
	 * @param what
	 *        new row Boolean
	 */
	void wngCSV::setBool(int row, int col, bool what) {
		data[row][col] = ofToString(what);
	}

}<commit_msg>Changes at getString()<commit_after>/**
 *
 *  wngCSV is a wrong-entertainment production
 *
 *
 *  Copyright 2011 wrong-entertainment
 *                 <wrongentertainment@yahoo.de>
 *                 <http://wrong-entertainment.com>
 *
 *  This file is part of wnglibs.
 *
 *  wngCSV is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  wngCSV 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 Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with wngCSV. If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "wngCSV.h"

namespace wng {

	/**
	 * A Constructor, usually called to initialize and start the class.
	 */
	wngCSV::wngCSV(){
	}

	/**
	 * loadFile
	 *
	 * @param path
	 *        Set the File Path.
	 * @param separator
	 *        Set the Separator to split CSV file.
	 * @param comments
	 *        Set the Comments sign.
	 */
	void wngCSV::loadFile(string path, string separator, string comments){
		// Save string variables.
		filePath = path;
		fileSeparator = separator;
		fileComments = comments;

		// Declare a File Stream.
		ifstream fileIn;

		// Open your Text File:
		fileIn.open(path.c_str());

		// Check if File is open.
		if(fileIn.is_open()) {
			int lineCount = 0;
			vector<string> rows;

			while(fileIn != NULL) {
				string temp;
				getline(fileIn, temp);

				// Skip empty lines.
				if(temp.length() == 0) {
					//cout << "Skip empty line no: " << lineCount << endl;
				}
				// Skip Comment lines.
				else if(ofToString(temp[0]) == comments) {
					//cout << "Skip Comment line no: " << lineCount << endl;
				} else {
					rows.push_back(temp);

					// Split row into cols.
					vector<string> cols = ofSplitString(rows[lineCount], ",");

					// Write the string to data.
					data.push_back(cols);

					// Erase remaining elements.
					cols.erase(cols.begin(), cols.end());
					//cout << "cols: After erasing all elements, vector integers " << (cols.empty() ? "is" : "is not" ) << " empty" << endl;

					lineCount++;
				}
			}

			// Save the Number of Rows.
			numRows = rows.size();

			// Erase remaining elements.
			rows.erase(rows.begin(), rows.end());
			//cout << "rows: After erasing all elements, vector integers " << (rows.empty() ? "is" : "is not" ) << " empty" << endl;

			// If File cannot opening, print a message to console.
		} else {
		cout << "Error opening " << path << ".\n";
		}
	}

	void wngCSV::loadFile(string path, string separator) {
		loadFile(path, separator, "#");
	}

	void wngCSV::loadFile(string path) {
		loadFile(path, ",", "#");
	}

	/**
	 * saveFile
	 *
	 * @param path
	 *        Set the File Path.
	 * @param separator
	 *        Set the Separator to split CSV file.
	 * @param comments
	 *        Set the Comments sign.
	 */
	void wngCSV::saveFile(string path, string separator, string comments) {
		createFile(path);

		ofstream myfile;
		myfile.open(path.c_str());
		if (myfile.is_open()) {
			// Write data to file.
			for(int i=0; i<numRows; i++) {
				for(int j=0; j<data[i].size(); j++) {
					myfile << data[i][j] << separator;
					if(j==(data[i].size()-1)) {
						myfile << "\n";
					}
				}
			}
			myfile.close();
			//cout << "Open file" << endl;
		} else {
			//cout << "Unable to open file" << endl;
		}

	}

	void wngCSV::saveFile(string path, string separator) {
		createFile(path);
		saveFile(path, separator, fileComments);
	}

	void wngCSV::saveFile(string path) {
		createFile(path);
		saveFile(path, fileSeparator, fileComments);
	}

	void wngCSV::saveFile() {
		saveFile(filePath, fileSeparator, fileComments);
	}

	/**
	 * createFile
	 *
	 * @param path
	 *        Set the File Path.
	 */
	void wngCSV::createFile(string path) {
		FILE * pFile;
		pFile = fopen (path.c_str(),"w");
		if (pFile!=NULL) {
			//fputs ("fopen example",pFile);
			fclose (pFile);
		}
	}

	/**
	 * loadFromString
	 *
	 * @param s
	 *        String Input.
	 */
	vector<string> wngCSV::getFromString(string s, string separator) {
		vector<string> cols = ofSplitString(s, separator);
		return cols;
	}

	vector<string> wngCSV::getFromString(string s) {
		getFromString(s, ",");
	}

	/**
	 * getInt
	 * get the Integer of a specific row and column.
	 *
	 * @param row
	 *        row number
	 * @param col
	 *        column number
	 * @return integer
	 */
	int wngCSV::getInt(int row, int col) {
		int temp = 0;
		istringstream buffer(data[row][col]);
		buffer >> temp;
		return temp;
	}

	/**
	 * getFloat
	 * get the Float of a specific row and column.
	 *
	 * @param row
	 *        row number
	 * @param col
	 *        column number
	 * @return float
	 */
	float wngCSV::getFloat(int row, int col) {
		float temp = 0;
		istringstream buffer(data[row][col]);
		buffer >> temp;
		return temp;
	}

	/**
	 * getString
	 * get the String of a specific row and column.
	 *
	 * @param row
	 *        row number
	 * @param col
	 *        column number
	 * @return float
	 */
	string wngCSV::getString(int row, int col) {
		return data[row][col];
	}

	/**
	 * getBool
	 * get the Boolean of a specific row and column.
	 *
	 * @param row
	 *        row number
	 * @param col
	 *        column number
	 * @return bool
	 */
	bool wngCSV::getBool(int row, int col) {
		static const string trueString = "true";
		static const string falseString = "false";
		string lower = ofToLower(data[row][col]);
		if(lower == trueString) {
			return true;
		}
		if(lower == falseString) {
			return false;
		}
		bool temp = false;
		istringstream cur(lower);
		cur >> temp;
		return temp;
	}

	/**
	 * setInt
	 * set a specific Integer to a new value.
	 *
	 * @param row
	 *        row number
	 * @param col
	 *        column number
	 * @param what
	 *        new Integer
	 */
	void wngCSV::setInt(int row, int col, int what) {
		data[row][col] = ofToString(what);
	}

	/**
	 * setFloat
	 * set a specific Float to a new value.
	 *
	 * @param row
	 *        row number
	 * @param col
	 *        column number
	 * @param what
	 *        new row Float
	 */
	void wngCSV::setFloat(int row, int col, float what) {
		data[row][col] = ofToString(what);
	}

	/**
	 * setString
	 * set a specific String to a new value.
	 *
	 * @param row
	 *        row number
	 * @param col
	 *        column number
	 * @param what
	 *        new row String
	 */
	void wngCSV::setString(int row, int col, string what) {
		data[row][col] = ofToString(what);
	}

	/**
	 * setBool
	 * set a specific Boolean to a new value.
	 *
	 * @param row
	 *        row number
	 * @param col
	 *        column number
	 * @param what
	 *        new row Boolean
	 */
	void wngCSV::setBool(int row, int col, bool what) {
		data[row][col] = ofToString(what);
	}

}<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: astunion.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2004-03-30 16:46:21 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _IDLC_ASTUNION_HXX_
#include <idlc/astunion.hxx>
#endif
#ifndef _IDLC_ASTBASETYPE_HXX_
#include <idlc/astbasetype.hxx>
#endif
#ifndef _IDLC_ERRORHANDLER_HXX_
#include <idlc/errorhandler.hxx>
#endif

#include "registry/version.h"
#include "registry/writer.hxx"

using namespace ::rtl;

AstUnion::AstUnion(const ::rtl::OString& name, AstType* pDiscType, AstScope* pScope)
    : AstStruct(NT_union, name, NULL, pScope)
    , m_pDiscriminantType(pDiscType)
    , m_discExprType(ET_long)
{
    AstBaseType* pBaseType;

    if ( !pDiscType )
    {
        m_pDiscriminantType = NULL;
        m_discExprType = ET_none;
        return;
    }
    /*
     * If the discriminator type is a predefined type
     * then install the equivalent coercion target type in
     * the pd_udisc_type field.
     */
    if ( pDiscType->getNodeType() == NT_predefined )
    {
        pBaseType = (AstBaseType*)pDiscType;
        if ( !pBaseType )
        {
            m_pDiscriminantType = NULL;
            m_discExprType = ET_none;
            return;
        }
        m_pDiscriminantType = pDiscType;
        switch (pBaseType->getExprType())
        {
            case ET_long:
            case ET_ulong:
            case ET_short:
            case ET_ushort:
            case ET_char:
            case ET_boolean:
                m_discExprType = pBaseType->getExprType();
                break;
            default:
                m_discExprType = ET_none;
                m_pDiscriminantType = NULL;
                break;
        }
    } else
        if (pDiscType->getNodeType() == NT_enum)
        {
            m_discExprType = ET_any;
            m_pDiscriminantType = pDiscType;
        } else
        {
            m_discExprType = ET_none;
            m_pDiscriminantType = NULL;
        }

    if ( !m_pDiscriminantType )
        idlc()->error()->error2(EIDL_DISC_TYPE, this, pDiscType);
}

AstUnion::~AstUnion()
{
}

AstDeclaration* AstUnion::addDeclaration(AstDeclaration* pDecl)
{
    if ( pDecl->getNodeType() == NT_union_branch )
    {
        AstUnionBranch* pBranch = (AstUnionBranch*)pDecl;
        if ( lookupBranch(pBranch) )
        {
            idlc()->error()->error2(EIDL_MULTIPLE_BRANCH, this, pDecl);
            return NULL;
        }
    }

    return AstScope::addDeclaration(pDecl);
}

AstUnionBranch* AstUnion::lookupBranch(AstUnionBranch* pBranch)
{
    AstUnionLabel* pLabel = NULL;

    if ( pBranch )
        pLabel = pBranch->getLabel();

    if ( pLabel )
    {
        if (pLabel->getLabelKind() == UL_default)
            return lookupDefault();
        if (m_discExprType == ET_any)
            /* CONVENTION: indicates enum discr */
            return lookupEnum(pBranch);
        return lookupLabel(pBranch);
    }
    return NULL;
}

AstUnionBranch* AstUnion::lookupDefault(sal_Bool bReportError)
{
    DeclList::const_iterator iter = getIteratorBegin();
    DeclList::const_iterator end = getIteratorEnd();
    AstUnionBranch      *pBranch = NULL;
    AstDeclaration      *pDecl = NULL;

    while ( iter != end )
    {
        pDecl = *iter;
        if ( pDecl->getNodeType() == NT_union_branch )
        {
            pBranch = (AstUnionBranch*)pDecl;
            if (pBranch == NULL)
            {
                ++iter;
                continue;
            }
            if ( pBranch->getLabel() != NULL &&
                 pBranch->getLabel()->getLabelKind() == UL_default)
            {
                if ( bReportError )
                    idlc()->error()->error2(EIDL_MULTIPLE_BRANCH, this, pBranch);
                return pBranch;
            }
        }
        ++iter;
    }
    return NULL;
}

AstUnionBranch* AstUnion::lookupLabel(AstUnionBranch* pBranch)
{
    AstUnionLabel* pLabel = pBranch->getLabel();

    if ( !pLabel->getLabelValue() )
        return pBranch;
//  pLabel->getLabelValue()->setExprValue(pLabel->getLabelValue()->coerce(m_discExprType, sal_False));
    AstExprValue* pLabelValue = NULL;
    if ( !(pLabelValue = pLabel->getLabelValue()->coerce(m_discExprType, sal_False)) )
    {
        idlc()->error()->evalError(pLabel->getLabelValue());
        return pBranch;
    } else
    {
        pLabel->getLabelValue()->setExprValue(pLabelValue);
    }

    DeclList::const_iterator iter = getIteratorBegin();
    DeclList::const_iterator end = getIteratorEnd();
    AstUnionBranch* pB = NULL;
    AstDeclaration* pDecl = NULL;

    while ( iter != end )
    {
        pDecl = *iter;
        if ( pDecl->getNodeType() == NT_union_branch )
        {
            pB = (AstUnionBranch*)pDecl;
            if ( !pB )
            {
                ++iter;
                continue;
            }
            if ( pB->getLabel() != NULL &&
                 pB->getLabel()->getLabelKind() == UL_label &&
                 pB->getLabel()->getLabelValue()->compare(pLabel->getLabelValue()) )
            {
                idlc()->error()->error2(EIDL_MULTIPLE_BRANCH, this, pBranch);
                return pBranch;
            }
        }
        ++iter;
    }
    return NULL;
}

AstUnionBranch* AstUnion::lookupEnum(AstUnionBranch* pBranch)
{
    AstType const * pType = resolveTypedefs(m_pDiscriminantType);
    if ( pType->getNodeType() != NT_enum )
        return NULL;

    AstUnionLabel* pLabel = pBranch->getLabel();
    AstExpression* pExpr = pLabel->getLabelValue();
    if ( !pExpr )
        return pBranch;

    /*
     * Expecting a symbol label
     */
    if ( pExpr->getCombOperator() != EC_symbol)
    {
        idlc()->error()->enumValExpected(this, pLabel);
        return pBranch;
    }

    /*
     * See if the symbol defines a constant in the discriminator enum
     */
    AstEnum* pEnum = (AstEnum*)pType;
    AstDeclaration* pDecl = pEnum->lookupByName(*pExpr->getSymbolicName());
    if ( pDecl == NULL || pDecl->getScope() != pEnum)
    {
        idlc()->error()->enumValLookupFailure(this, pEnum, *pExpr->getSymbolicName());
        return pBranch;
    }

    DeclList::const_iterator iter = getIteratorBegin();
    DeclList::const_iterator end = getIteratorEnd();
    AstUnionBranch* pB = NULL;
    pDecl = NULL;

    while ( iter != end )
    {
        pDecl = *iter;
        if ( pDecl->getNodeType() == NT_union_branch )
        {
            pB = (AstUnionBranch*)pDecl;
            if ( !pB )
            {
                ++iter;
                continue;
            }
            if ( pB->getLabel() != NULL &&
                 pB->getLabel()->getLabelKind() == UL_label &&
                 pB->getLabel()->getLabelValue()->compare(pLabel->getLabelValue()) )
            {
                idlc()->error()->error2(EIDL_MULTIPLE_BRANCH, this, pBranch);
                return pBranch;
            }
        }
        ++iter;
    }
    return NULL;
}

sal_Bool AstUnion::dump(RegistryKey& rKey)
{
    RegistryKey localKey;
    if (rKey.createKey( OStringToOUString(getFullName(), RTL_TEXTENCODING_UTF8 ), localKey))
    {
        fprintf(stderr, "%s: warning, could not create key '%s' in '%s'\n",
                idlc()->getOptions()->getProgramName().getStr(),
                getFullName().getStr(), OUStringToOString(rKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr());
        return sal_False;
    }

    sal_uInt16 nMember = getNodeCount(NT_union_branch);

    typereg::Writer aBlob(
        TYPEREG_VERSION_0, getDocumentation(),
        OStringToOUString(getFileName(), RTL_TEXTENCODING_UTF8), RT_TYPE_UNION,
        OStringToOUString(getRelativName(), RTL_TEXTENCODING_UTF8), 1, nMember,
        0, 0);
    aBlob.setSuperTypeName(
        0,
        OStringToOUString(
            getDiscrimantType()->getScopedName(), RTL_TEXTENCODING_UTF8));

    if ( nMember > 0 )
    {
        DeclList::const_iterator iter = getIteratorBegin();
        DeclList::const_iterator end = getIteratorEnd();
        AstDeclaration* pDecl = NULL;
        AstUnionBranch* pBranch = NULL;
        AstUnionBranch* pDefault = lookupDefault(sal_False);
        AstUnionLabel*  pLabel = NULL;
        AstExprValue*   pExprValue = NULL;
        RTConstValue    aConst;
        RTFieldAccess   access = RT_ACCESS_READWRITE;
        OUString    docu;
        sal_uInt16  index = 0;
        if ( pDefault )
            index = 1;

        sal_Int64   disc = 0;
        while ( iter != end )
        {
            pDecl = *iter;
            if ( pDecl->getNodeType() == NT_union_branch )
            {
                pBranch = (AstUnionBranch*)pDecl;
                if (pBranch == pDefault)
                {
                    ++iter;
                    continue;
                }

                pLabel = pBranch->getLabel();
                pExprValue = pLabel->getLabelValue()->coerce(ET_hyper, sal_False);
                aConst.m_type = RT_TYPE_INT64;
                aConst.m_value.aHyper = pExprValue->u.hval;
                if ( aConst.m_value.aHyper > disc )
                    disc = aConst.m_value.aHyper;

                aBlob.setFieldData(
                    index++, pBranch->getDocumentation(), OUString(),
                    RT_ACCESS_READWRITE,
                    OStringToOUString(
                        pBranch->getLocalName(), RTL_TEXTENCODING_UTF8),
                    OStringToOUString(
                        pBranch->getType()->getRelativName(),
                        RTL_TEXTENCODING_UTF8),
                    aConst);
            }
            ++iter;
        }

        if ( pDefault )
        {
            access = RT_ACCESS_DEFAULT;
            aConst.m_type = RT_TYPE_INT64;
            aConst.m_value.aHyper = disc + 1;
            aBlob.setFieldData(
                0, pDefault->getDocumentation(), OUString(), RT_ACCESS_DEFAULT,
                OStringToOUString(
                    pDefault->getLocalName(), RTL_TEXTENCODING_UTF8),
                OStringToOUString(
                    pDefault->getType()->getRelativName(),
                    RTL_TEXTENCODING_UTF8),
                aConst);
        }
    }

    sal_uInt32 aBlobSize;
    void const * pBlob = aBlob.getBlob(&aBlobSize);

    if (localKey.setValue(OUString(), RG_VALUETYPE_BINARY,
                            (RegValue)pBlob, aBlobSize))
    {
        fprintf(stderr, "%s: warning, could not set value of key \"%s\" in %s\n",
                idlc()->getOptions()->getProgramName().getStr(),
                getFullName().getStr(), OUStringToOString(localKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr());
        return sal_False;
    }

    return sal_True;
}

AstUnionBranch::AstUnionBranch(AstUnionLabel* pLabel, AstType const * pType, const ::rtl::OString& name, AstScope* pScope)
    : AstMember(NT_union_branch, pType, name, pScope)
    , m_pLabel(pLabel)
{
}

AstUnionBranch::~AstUnionBranch()
{
    if ( m_pLabel )
        delete m_pLabel;
}

AstUnionLabel::AstUnionLabel()
    : m_label(UL_default)
    , m_pLabelValue(NULL)
{
}

AstUnionLabel::AstUnionLabel(UnionLabel labelKind, AstExpression* pExpr)
    : m_label(labelKind)
    , m_pLabelValue(pExpr)
{
    if ( m_pLabelValue )
        m_pLabelValue->evaluate(EK_const);
}

AstUnionLabel::~AstUnionLabel()
{
    if ( m_pLabelValue )
        delete m_pLabelValue;
}

<commit_msg>INTEGRATION: CWS sb18 (1.4.4); FILE MERGED 2004/05/18 15:36:50 sb 1.4.4.2: #i21150# Added new feature: published. 2004/04/08 14:37:16 sb 1.4.4.1: #i21150# Fixed UNOIDL typedef support; initial support for polymorphic struct types.<commit_after>/*************************************************************************
 *
 *  $RCSfile: astunion.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: obo $ $Date: 2004-06-03 15:09:35 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _IDLC_ASTUNION_HXX_
#include <idlc/astunion.hxx>
#endif
#ifndef _IDLC_ASTBASETYPE_HXX_
#include <idlc/astbasetype.hxx>
#endif
#ifndef _IDLC_ERRORHANDLER_HXX_
#include <idlc/errorhandler.hxx>
#endif

#include "registry/version.h"
#include "registry/writer.hxx"

using namespace ::rtl;

AstUnion::AstUnion(const ::rtl::OString& name, AstType* pDiscType, AstScope* pScope)
    : AstStruct(NT_union, name, NULL, pScope)
    , m_pDiscriminantType(pDiscType)
    , m_discExprType(ET_long)
{
    AstBaseType* pBaseType;

    if ( !pDiscType )
    {
        m_pDiscriminantType = NULL;
        m_discExprType = ET_none;
        return;
    }
    /*
     * If the discriminator type is a predefined type
     * then install the equivalent coercion target type in
     * the pd_udisc_type field.
     */
    if ( pDiscType->getNodeType() == NT_predefined )
    {
        pBaseType = (AstBaseType*)pDiscType;
        if ( !pBaseType )
        {
            m_pDiscriminantType = NULL;
            m_discExprType = ET_none;
            return;
        }
        m_pDiscriminantType = pDiscType;
        switch (pBaseType->getExprType())
        {
            case ET_long:
            case ET_ulong:
            case ET_short:
            case ET_ushort:
            case ET_char:
            case ET_boolean:
                m_discExprType = pBaseType->getExprType();
                break;
            default:
                m_discExprType = ET_none;
                m_pDiscriminantType = NULL;
                break;
        }
    } else
        if (pDiscType->getNodeType() == NT_enum)
        {
            m_discExprType = ET_any;
            m_pDiscriminantType = pDiscType;
        } else
        {
            m_discExprType = ET_none;
            m_pDiscriminantType = NULL;
        }

    if ( !m_pDiscriminantType )
        idlc()->error()->error2(EIDL_DISC_TYPE, this, pDiscType);
}

AstUnion::~AstUnion()
{
}

AstDeclaration* AstUnion::addDeclaration(AstDeclaration* pDecl)
{
    if ( pDecl->getNodeType() == NT_union_branch )
    {
        AstUnionBranch* pBranch = (AstUnionBranch*)pDecl;
        if ( lookupBranch(pBranch) )
        {
            idlc()->error()->error2(EIDL_MULTIPLE_BRANCH, this, pDecl);
            return NULL;
        }
    }

    return AstScope::addDeclaration(pDecl);
}

AstUnionBranch* AstUnion::lookupBranch(AstUnionBranch* pBranch)
{
    AstUnionLabel* pLabel = NULL;

    if ( pBranch )
        pLabel = pBranch->getLabel();

    if ( pLabel )
    {
        if (pLabel->getLabelKind() == UL_default)
            return lookupDefault();
        if (m_discExprType == ET_any)
            /* CONVENTION: indicates enum discr */
            return lookupEnum(pBranch);
        return lookupLabel(pBranch);
    }
    return NULL;
}

AstUnionBranch* AstUnion::lookupDefault(sal_Bool bReportError)
{
    DeclList::const_iterator iter = getIteratorBegin();
    DeclList::const_iterator end = getIteratorEnd();
    AstUnionBranch      *pBranch = NULL;
    AstDeclaration      *pDecl = NULL;

    while ( iter != end )
    {
        pDecl = *iter;
        if ( pDecl->getNodeType() == NT_union_branch )
        {
            pBranch = (AstUnionBranch*)pDecl;
            if (pBranch == NULL)
            {
                ++iter;
                continue;
            }
            if ( pBranch->getLabel() != NULL &&
                 pBranch->getLabel()->getLabelKind() == UL_default)
            {
                if ( bReportError )
                    idlc()->error()->error2(EIDL_MULTIPLE_BRANCH, this, pBranch);
                return pBranch;
            }
        }
        ++iter;
    }
    return NULL;
}

AstUnionBranch* AstUnion::lookupLabel(AstUnionBranch* pBranch)
{
    AstUnionLabel* pLabel = pBranch->getLabel();

    if ( !pLabel->getLabelValue() )
        return pBranch;
//  pLabel->getLabelValue()->setExprValue(pLabel->getLabelValue()->coerce(m_discExprType, sal_False));
    AstExprValue* pLabelValue = NULL;
    if ( !(pLabelValue = pLabel->getLabelValue()->coerce(m_discExprType, sal_False)) )
    {
        idlc()->error()->evalError(pLabel->getLabelValue());
        return pBranch;
    } else
    {
        pLabel->getLabelValue()->setExprValue(pLabelValue);
    }

    DeclList::const_iterator iter = getIteratorBegin();
    DeclList::const_iterator end = getIteratorEnd();
    AstUnionBranch* pB = NULL;
    AstDeclaration* pDecl = NULL;

    while ( iter != end )
    {
        pDecl = *iter;
        if ( pDecl->getNodeType() == NT_union_branch )
        {
            pB = (AstUnionBranch*)pDecl;
            if ( !pB )
            {
                ++iter;
                continue;
            }
            if ( pB->getLabel() != NULL &&
                 pB->getLabel()->getLabelKind() == UL_label &&
                 pB->getLabel()->getLabelValue()->compare(pLabel->getLabelValue()) )
            {
                idlc()->error()->error2(EIDL_MULTIPLE_BRANCH, this, pBranch);
                return pBranch;
            }
        }
        ++iter;
    }
    return NULL;
}

AstUnionBranch* AstUnion::lookupEnum(AstUnionBranch* pBranch)
{
    AstDeclaration const * pType = resolveTypedefs(m_pDiscriminantType);
    if ( pType->getNodeType() != NT_enum )
        return NULL;

    AstUnionLabel* pLabel = pBranch->getLabel();
    AstExpression* pExpr = pLabel->getLabelValue();
    if ( !pExpr )
        return pBranch;

    /*
     * Expecting a symbol label
     */
    if ( pExpr->getCombOperator() != EC_symbol)
    {
        idlc()->error()->enumValExpected(this, pLabel);
        return pBranch;
    }

    /*
     * See if the symbol defines a constant in the discriminator enum
     */
    AstEnum* pEnum = (AstEnum*)pType;
    AstDeclaration* pDecl = pEnum->lookupByName(*pExpr->getSymbolicName());
    if ( pDecl == NULL || pDecl->getScope() != pEnum)
    {
        idlc()->error()->enumValLookupFailure(this, pEnum, *pExpr->getSymbolicName());
        return pBranch;
    }

    DeclList::const_iterator iter = getIteratorBegin();
    DeclList::const_iterator end = getIteratorEnd();
    AstUnionBranch* pB = NULL;
    pDecl = NULL;

    while ( iter != end )
    {
        pDecl = *iter;
        if ( pDecl->getNodeType() == NT_union_branch )
        {
            pB = (AstUnionBranch*)pDecl;
            if ( !pB )
            {
                ++iter;
                continue;
            }
            if ( pB->getLabel() != NULL &&
                 pB->getLabel()->getLabelKind() == UL_label &&
                 pB->getLabel()->getLabelValue()->compare(pLabel->getLabelValue()) )
            {
                idlc()->error()->error2(EIDL_MULTIPLE_BRANCH, this, pBranch);
                return pBranch;
            }
        }
        ++iter;
    }
    return NULL;
}

sal_Bool AstUnion::dump(RegistryKey& rKey)
{
    RegistryKey localKey;
    if (rKey.createKey( OStringToOUString(getFullName(), RTL_TEXTENCODING_UTF8 ), localKey))
    {
        fprintf(stderr, "%s: warning, could not create key '%s' in '%s'\n",
                idlc()->getOptions()->getProgramName().getStr(),
                getFullName().getStr(), OUStringToOString(rKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr());
        return sal_False;
    }

    sal_uInt16 nMember = getNodeCount(NT_union_branch);

    typereg::Writer aBlob(
        TYPEREG_VERSION_0, getDocumentation(),
        OStringToOUString(getFileName(), RTL_TEXTENCODING_UTF8), RT_TYPE_UNION,
        false, OStringToOUString(getRelativName(), RTL_TEXTENCODING_UTF8), 1,
        nMember, 0, 0);
    aBlob.setSuperTypeName(
        0,
        OStringToOUString(
            getDiscrimantType()->getScopedName(), RTL_TEXTENCODING_UTF8));

    if ( nMember > 0 )
    {
        DeclList::const_iterator iter = getIteratorBegin();
        DeclList::const_iterator end = getIteratorEnd();
        AstDeclaration* pDecl = NULL;
        AstUnionBranch* pBranch = NULL;
        AstUnionBranch* pDefault = lookupDefault(sal_False);
        AstUnionLabel*  pLabel = NULL;
        AstExprValue*   pExprValue = NULL;
        RTConstValue    aConst;
        RTFieldAccess   access = RT_ACCESS_READWRITE;
        OUString    docu;
        sal_uInt16  index = 0;
        if ( pDefault )
            index = 1;

        sal_Int64   disc = 0;
        while ( iter != end )
        {
            pDecl = *iter;
            if ( pDecl->getNodeType() == NT_union_branch )
            {
                pBranch = (AstUnionBranch*)pDecl;
                if (pBranch == pDefault)
                {
                    ++iter;
                    continue;
                }

                pLabel = pBranch->getLabel();
                pExprValue = pLabel->getLabelValue()->coerce(ET_hyper, sal_False);
                aConst.m_type = RT_TYPE_INT64;
                aConst.m_value.aHyper = pExprValue->u.hval;
                if ( aConst.m_value.aHyper > disc )
                    disc = aConst.m_value.aHyper;

                aBlob.setFieldData(
                    index++, pBranch->getDocumentation(), OUString(),
                    RT_ACCESS_READWRITE,
                    OStringToOUString(
                        pBranch->getLocalName(), RTL_TEXTENCODING_UTF8),
                    OStringToOUString(
                        pBranch->getType()->getRelativName(),
                        RTL_TEXTENCODING_UTF8),
                    aConst);
            }
            ++iter;
        }

        if ( pDefault )
        {
            access = RT_ACCESS_DEFAULT;
            aConst.m_type = RT_TYPE_INT64;
            aConst.m_value.aHyper = disc + 1;
            aBlob.setFieldData(
                0, pDefault->getDocumentation(), OUString(), RT_ACCESS_DEFAULT,
                OStringToOUString(
                    pDefault->getLocalName(), RTL_TEXTENCODING_UTF8),
                OStringToOUString(
                    pDefault->getType()->getRelativName(),
                    RTL_TEXTENCODING_UTF8),
                aConst);
        }
    }

    sal_uInt32 aBlobSize;
    void const * pBlob = aBlob.getBlob(&aBlobSize);

    if (localKey.setValue(OUString(), RG_VALUETYPE_BINARY,
                            (RegValue)pBlob, aBlobSize))
    {
        fprintf(stderr, "%s: warning, could not set value of key \"%s\" in %s\n",
                idlc()->getOptions()->getProgramName().getStr(),
                getFullName().getStr(), OUStringToOString(localKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr());
        return sal_False;
    }

    return sal_True;
}

AstUnionBranch::AstUnionBranch(AstUnionLabel* pLabel, AstType const * pType, const ::rtl::OString& name, AstScope* pScope)
    : AstMember(NT_union_branch, pType, name, pScope)
    , m_pLabel(pLabel)
{
}

AstUnionBranch::~AstUnionBranch()
{
    if ( m_pLabel )
        delete m_pLabel;
}

AstUnionLabel::AstUnionLabel()
    : m_label(UL_default)
    , m_pLabelValue(NULL)
{
}

AstUnionLabel::AstUnionLabel(UnionLabel labelKind, AstExpression* pExpr)
    : m_label(labelKind)
    , m_pLabelValue(pExpr)
{
    if ( m_pLabelValue )
        m_pLabelValue->evaluate(EK_const);
}

AstUnionLabel::~AstUnionLabel()
{
    if ( m_pLabelValue )
        delete m_pLabelValue;
}

<|endoftext|>


<commit_before>#include <ros/ros.h>
#include <stdlib.h>
#include <ros/publisher.h>
#include <tf/tf.h>
#include <tf/transform_listener.h>
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <iterator>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl_ros/point_cloud.h>
#include <pcl_ros/transforms.h>
#include <set>

using namespace std;
using namespace pcl;
using namespace ros;

PointCloud<PointXYZ>::Ptr map_cloud;
Publisher _pointcloud_pub;
tf::TransformListener *tf_listener;
set<string> frames_seen;

void filterOutDuplicates(PointCloud<PointXYZ>::ConstPtr cloud)
{
    VoxelGrid<PointXYZ> filter;
    filter.setInputCloud(cloud);
    filter.setLeafSize(0.01f, 0.01f, 0.01f);
    filter.filter(*map_cloud);
}

void nodeCallback(const PointCloud<PointXYZ>::ConstPtr &msg)
{
    PointCloud<PointXYZ> transformed;
    tf::StampedTransform transform;
    if(frames_seen.find(msg->header.frame_id) != frames_seen.end())
    {
        frames_seen.insert(msg->header.frame_id);
        tf_listener->waitForTransform("/map", msg->header.frame_id, Time(0), Duration(5));
    }
    tf_listener->lookupTransform("/map", msg->header.frame_id, Time(0), transform);
    pcl_ros::transformPointCloud(*msg, transformed, transform);

    *map_cloud += transformed;

    filterOutDuplicates(map_cloud);

    _pointcloud_pub.publish(map_cloud);
}

int main(int argc, char** argv)
{
    map_cloud = PointCloud<PointXYZ>::Ptr(new PointCloud<PointXYZ>());

    init(argc, argv, "mapper");

    NodeHandle nh;
    tf_listener = new tf::TransformListener();

    string topics;

    list<Subscriber> subs;

    NodeHandle pNh("~");

    if(!pNh.hasParam("topics"))
        ROS_WARN_STREAM("No topics specified for mapper. No map will be generated.");

    pNh.getParam("topics", topics);

    if(topics.empty())
        ROS_WARN_STREAM("No topics specified for mapper. No map will be generated.");

    istringstream iss(topics);
    vector<string> tokens { istream_iterator<string>(iss), istream_iterator<string>() };

    for(auto topic : tokens)
    {
        ROS_INFO_STREAM("Mapper subscribing to " << topic);
        subs.push_back(nh.subscribe(topic, 1, nodeCallback));
    }

    map_cloud->header.frame_id = "/map";

    _pointcloud_pub = nh.advertise<PointCloud<PointXYZ> >("/map", 1);

    spin();
}
<commit_msg>Bug fix in frames_seen logic.<commit_after>#include <ros/ros.h>
#include <stdlib.h>
#include <ros/publisher.h>
#include <tf/tf.h>
#include <tf/transform_listener.h>
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <iterator>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl_ros/point_cloud.h>
#include <pcl_ros/transforms.h>
#include <set>

using namespace std;
using namespace pcl;
using namespace ros;

PointCloud<PointXYZ>::Ptr map_cloud;
Publisher _pointcloud_pub;
tf::TransformListener *tf_listener;
set<string> frames_seen;

void filterOutDuplicates(PointCloud<PointXYZ>::ConstPtr cloud)
{
    VoxelGrid<PointXYZ> filter;
    filter.setInputCloud(cloud);
    filter.setLeafSize(0.01f, 0.01f, 0.01f);
    filter.filter(*map_cloud);
}

void nodeCallback(const PointCloud<PointXYZ>::ConstPtr &msg)
{
    PointCloud<PointXYZ> transformed;
    tf::StampedTransform transform;
    if(frames_seen.find(msg->header.frame_id) == frames_seen.end())
    {
        frames_seen.insert(msg->header.frame_id);
        tf_listener->waitForTransform("/map", msg->header.frame_id, Time(0), Duration(5));
    }
    tf_listener->lookupTransform("/map", msg->header.frame_id, Time(0), transform);
    pcl_ros::transformPointCloud(*msg, transformed, transform);

    *map_cloud += transformed;

    filterOutDuplicates(map_cloud);

    _pointcloud_pub.publish(map_cloud);
}

int main(int argc, char** argv)
{
    map_cloud = PointCloud<PointXYZ>::Ptr(new PointCloud<PointXYZ>());

    init(argc, argv, "mapper");

    NodeHandle nh;
    tf_listener = new tf::TransformListener();

    string topics;

    list<Subscriber> subs;

    NodeHandle pNh("~");

    if(!pNh.hasParam("topics"))
        ROS_WARN_STREAM("No topics specified for mapper. No map will be generated.");

    pNh.getParam("topics", topics);

    if(topics.empty())
        ROS_WARN_STREAM("No topics specified for mapper. No map will be generated.");

    istringstream iss(topics);
    vector<string> tokens { istream_iterator<string>(iss), istream_iterator<string>() };

    for(auto topic : tokens)
    {
        ROS_INFO_STREAM("Mapper subscribing to " << topic);
        subs.push_back(nh.subscribe(topic, 1, nodeCallback));
    }

    map_cloud->header.frame_id = "/map";

    _pointcloud_pub = nh.advertise<PointCloud<PointXYZ> >("/map", 1);

    spin();
}
<|endoftext|>