<commit_before>#include <QDebug>
#include <QDir>
#include <QApplication>
#include <QIcon>
#include <QFile>
#include <QSettings>

#include "qticonloader.h"

static QString findIconHelper(const QString &pathName, const QString &icon)
{
    QStringList extensions;
    extensions << "";
    extensions << ".png";
    extensions << ".svg";
    qDebug() << "Trying " << pathName << " for " << icon;

    foreach (const QString &extension, extensions) {
        if (QFile::exists(pathName + QDir::separator() + icon + extension))
            return pathName + QDir::separator() + icon + extension;
    }

    QStringList entryList = QDir(pathName).entryList(QStringList(), QDir::AllDirs | QDir::NoDotAndDotDot);
    foreach (const QString &dir, entryList) {
        QString retval = findIconHelper(QDir(pathName).absoluteFilePath(dir), icon);
        if (!retval.isNull())
            return retval;
    }

    // all else failed
    return QString();
}

/*!
 * Returns a path to a given icon ID.
 */
QString QtIconLoader::icon(const QString &name)
{
    if (QFile::exists(name)) {
        // fast path: file given
        return name;
    }

    QSettings settings("MeeGo", "IconCache");
    QString cachedPath = settings.value(name).toString();

    if (!QFile::exists(cachedPath)) {
        qDebug() << Q_FUNC_INFO << "Negative cache hit for " << name << " to " << cachedPath;
    } else {
        return cachedPath;
    }

    QStringList themes = QDir("/usr/share/themes").entryList(QStringList(), QDir::AllDirs | QDir::NoDotAndDotDot);
    if (themes.isEmpty())
        return QString();

    // TODO: look up active theme in gconf and set it to the first search path, don't hardcode it.
    // TODO: would be nice to investigate if our fallback behaviour is actually correct, too, but meh.
    if (themes.contains("n900de") &&
        themes.at(0) != "n900de") {
        themes.removeAll("n900de");
        themes.insert(0, "n900de");
    }

    foreach (const QString &theme, themes) {
        QString retval = findIconHelper("/usr/share/themes/" + theme, name);
        if (!retval.isNull()) {
            settings.setValue(name, retval);
            return retval;
        }
    }

    // they also seem to get plonked here
    QString retval = findIconHelper("/usr/share/pixmaps/", name);
    if (!retval.isNull()) {
        settings.setValue(name, retval);
        return retval;
    }

    // I hate all application developers
    retval = findIconHelper("/usr/share/icons/hicolor/64x64/", name);
    if (!retval.isNull()) {
        settings.setValue(name, retval);
        return retval;
    }

    return QString();
}

<commit_msg>quiet down noisy debug<commit_after>#include <QDebug>
#include <QDir>
#include <QApplication>
#include <QIcon>
#include <QFile>
#include <QSettings>

#include "qticonloader.h"

static QString findIconHelper(const QString &pathName, const QString &icon)
{
    QStringList extensions;
    extensions << "";
    extensions << ".png";
    extensions << ".svg";
//    qDebug() << "Trying " << pathName << " for " << icon;

    foreach (const QString &extension, extensions) {
        if (QFile::exists(pathName + QDir::separator() + icon + extension))
            return pathName + QDir::separator() + icon + extension;
    }

    QStringList entryList = QDir(pathName).entryList(QStringList(), QDir::AllDirs | QDir::NoDotAndDotDot);
    foreach (const QString &dir, entryList) {
        QString retval = findIconHelper(QDir(pathName).absoluteFilePath(dir), icon);
        if (!retval.isNull())
            return retval;
    }

    // all else failed
    return QString();
}

/*!
 * Returns a path to a given icon ID.
 */
QString QtIconLoader::icon(const QString &name)
{
    if (QFile::exists(name)) {
        // fast path: file given
        return name;
    }

    QSettings settings("MeeGo", "IconCache");
    QString cachedPath = settings.value(name).toString();

    if (!QFile::exists(cachedPath)) {
        qDebug() << Q_FUNC_INFO << "Negative cache hit for " << name << " to " << cachedPath;
    } else {
        return cachedPath;
    }

    QStringList themes = QDir("/usr/share/themes").entryList(QStringList(), QDir::AllDirs | QDir::NoDotAndDotDot);
    if (themes.isEmpty())
        return QString();

    // TODO: look up active theme in gconf and set it to the first search path, don't hardcode it.
    // TODO: would be nice to investigate if our fallback behaviour is actually correct, too, but meh.
    if (themes.contains("n900de") &&
        themes.at(0) != "n900de") {
        themes.removeAll("n900de");
        themes.insert(0, "n900de");
    }

    foreach (const QString &theme, themes) {
        QString retval = findIconHelper("/usr/share/themes/" + theme, name);
        if (!retval.isNull()) {
            settings.setValue(name, retval);
            return retval;
        }
    }

    // they also seem to get plonked here
    QString retval = findIconHelper("/usr/share/pixmaps/", name);
    if (!retval.isNull()) {
        settings.setValue(name, retval);
        return retval;
    }

    // I hate all application developers
    retval = findIconHelper("/usr/share/icons/hicolor/64x64/", name);
    if (!retval.isNull()) {
        settings.setValue(name, retval);
        return retval;
    }

    return QString();
}

<|endoftext|>


<commit_before>#include "queuemanager.h"

#include <libxml/uri.h>

#include "configpaths.h"
#include "formatstring.h"
#include "rss.h"
#include "stflpp.h"
#include "utils.h"

namespace newsboat {

QueueManager::QueueManager(ConfigContainer* cfg_, ConfigPaths* paths_)
	: cfg(cfg_)
	, paths(paths_)
{}

void QueueManager::enqueue_url(const std::string& url,
	const std::string& title,
	const time_t pubDate,
	std::shared_ptr<RssFeed> feed)
{
	bool url_found = false;
	std::fstream f;
	f.open(paths->queue_file(), std::fstream::in);
	if (f.is_open()) {
		do {
			std::string line;
			getline(f, line);
			if (!f.eof() && !line.empty()) {
				std::vector<std::string> fields =
					utils::tokenize_quoted(line);
				if (!fields.empty() && fields[0] == url) {
					url_found = true;
					break;
				}
			}
		} while (!f.eof());
		f.close();
	}
	if (!url_found) {
		f.open(paths->queue_file(),
			std::fstream::app | std::fstream::out);
		const std::string filename =
			generate_enqueue_filename(url, title, pubDate, feed);
		f << url << " " << Stfl::quote(filename) << std::endl;
		f.close();
	}
}

std::string get_hostname_from_url(const std::string& url)
{
	xmlURIPtr uri = xmlParseURI(url.c_str());
	std::string hostname;
	if (uri) {
		hostname = uri->server;
		xmlFreeURI(uri);
	}
	return hostname;
}

std::string QueueManager::generate_enqueue_filename(const std::string& url,
	const std::string& title,
	const time_t pubDate,
	std::shared_ptr<RssFeed> feed)
{
	std::string dlformat = cfg->get_configvalue("download-path");
	if (dlformat[dlformat.length() - 1] != NEWSBEUTER_PATH_SEP[0]) {
		dlformat.append(NEWSBEUTER_PATH_SEP);
	}

	const std::string filemask = cfg->get_configvalue("download-filename-format");
	dlformat.append(filemask);

	auto time_formatter = [&pubDate](const char* format) {
		char pubDate_formatted[1024];
		strftime(pubDate_formatted,
			sizeof(pubDate_formatted),
			format,
			localtime(&pubDate));
		return std::string(pubDate_formatted);
	};

	const std::string base = utils::get_basename(url);
	std::string extension;
	const std::size_t pos = base.rfind('.');
	if (pos != std::string::npos) {
		extension.append(base.substr(pos + 1));
	}

	FmtStrFormatter fmt;
	fmt.register_fmt('n', feed->title());
	fmt.register_fmt('h', get_hostname_from_url(url));
	fmt.register_fmt('u', base);
	fmt.register_fmt('F', time_formatter("%F"));
	fmt.register_fmt('m', time_formatter("%m"));
	fmt.register_fmt('b', time_formatter("%b"));
	fmt.register_fmt('d', time_formatter("%d"));
	fmt.register_fmt('H', time_formatter("%H"));
	fmt.register_fmt('M', time_formatter("%M"));
	fmt.register_fmt('S', time_formatter("%S"));
	fmt.register_fmt('y', time_formatter("%y"));
	fmt.register_fmt('Y', time_formatter("%Y"));
	fmt.register_fmt('t', title);
	fmt.register_fmt('e', extension);

	const std::string dlpath = fmt.do_format(dlformat);
	return dlpath;
}

void QueueManager::autoenqueue(std::shared_ptr<RssFeed> feed)
{
	if (!cfg->get_configvalue_as_bool("podcast-auto-enqueue"))
		return;

	std::lock_guard<std::mutex> lock(feed->item_mutex);
	for (const auto& item : feed->items()) {
		if (!item->enqueued() && item->enclosure_url().length() > 0) {
			LOG(Level::DEBUG,
				"QueueManager::autoenqueue: enclosure_url = "
				"`%s' "
				"enclosure_type = `%s'",
				item->enclosure_url(),
				item->enclosure_type());
			if (utils::is_http_url(item->enclosure_url())) {
				LOG(Level::INFO,
					"QueueManager::autoenqueue: enqueuing "
					"`%s'",
					item->enclosure_url());
				enqueue_url(item->enclosure_url(),
					item->title(),
					item->pubDate_timestamp(),
					feed);
				item->set_enqueued(true);
			}
		}
	}
}

} // namespace newsboat
<commit_msg>Apply boyscout rule in one more place<commit_after>#include "queuemanager.h"

#include <libxml/uri.h>

#include "configpaths.h"
#include "formatstring.h"
#include "rss.h"
#include "stflpp.h"
#include "utils.h"

namespace newsboat {

QueueManager::QueueManager(ConfigContainer* cfg_, ConfigPaths* paths_)
	: cfg(cfg_)
	, paths(paths_)
{}

void QueueManager::enqueue_url(const std::string& url,
	const std::string& title,
	const time_t pubDate,
	std::shared_ptr<RssFeed> feed)
{
	bool url_found = false;
	std::fstream f;
	f.open(paths->queue_file(), std::fstream::in);
	if (f.is_open()) {
		do {
			std::string line;
			getline(f, line);
			if (!f.eof() && !line.empty()) {
				std::vector<std::string> fields =
					utils::tokenize_quoted(line);
				if (!fields.empty() && fields[0] == url) {
					url_found = true;
					break;
				}
			}
		} while (!f.eof());
		f.close();
	}
	if (!url_found) {
		f.open(paths->queue_file(),
			std::fstream::app | std::fstream::out);
		const std::string filename =
			generate_enqueue_filename(url, title, pubDate, feed);
		f << url << " " << Stfl::quote(filename) << std::endl;
		f.close();
	}
}

std::string get_hostname_from_url(const std::string& url)
{
	xmlURIPtr uri = xmlParseURI(url.c_str());
	std::string hostname;
	if (uri) {
		hostname = uri->server;
		xmlFreeURI(uri);
	}
	return hostname;
}

std::string QueueManager::generate_enqueue_filename(const std::string& url,
	const std::string& title,
	const time_t pubDate,
	std::shared_ptr<RssFeed> feed)
{
	std::string dlformat = cfg->get_configvalue("download-path");
	if (dlformat[dlformat.length() - 1] != NEWSBEUTER_PATH_SEP[0]) {
		dlformat.append(NEWSBEUTER_PATH_SEP);
	}

	const std::string filemask = cfg->get_configvalue("download-filename-format");
	dlformat.append(filemask);

	auto time_formatter = [&pubDate](const char* format) {
		char pubDate_formatted[1024];
		strftime(pubDate_formatted,
			sizeof(pubDate_formatted),
			format,
			localtime(&pubDate));
		return std::string(pubDate_formatted);
	};

	const std::string base = utils::get_basename(url);
	std::string extension;
	const std::size_t pos = base.rfind('.');
	if (pos != std::string::npos) {
		extension.append(base.substr(pos + 1));
	}

	FmtStrFormatter fmt;
	fmt.register_fmt('n', feed->title());
	fmt.register_fmt('h', get_hostname_from_url(url));
	fmt.register_fmt('u', base);
	fmt.register_fmt('F', time_formatter("%F"));
	fmt.register_fmt('m', time_formatter("%m"));
	fmt.register_fmt('b', time_formatter("%b"));
	fmt.register_fmt('d', time_formatter("%d"));
	fmt.register_fmt('H', time_formatter("%H"));
	fmt.register_fmt('M', time_formatter("%M"));
	fmt.register_fmt('S', time_formatter("%S"));
	fmt.register_fmt('y', time_formatter("%y"));
	fmt.register_fmt('Y', time_formatter("%Y"));
	fmt.register_fmt('t', title);
	fmt.register_fmt('e', extension);

	const std::string dlpath = fmt.do_format(dlformat);
	return dlpath;
}

void QueueManager::autoenqueue(std::shared_ptr<RssFeed> feed)
{
	if (!cfg->get_configvalue_as_bool("podcast-auto-enqueue")) {
		return;
	}

	std::lock_guard<std::mutex> lock(feed->item_mutex);
	for (const auto& item : feed->items()) {
		if (!item->enqueued() && item->enclosure_url().length() > 0) {
			LOG(Level::DEBUG,
				"QueueManager::autoenqueue: enclosure_url = "
				"`%s' "
				"enclosure_type = `%s'",
				item->enclosure_url(),
				item->enclosure_type());
			if (utils::is_http_url(item->enclosure_url())) {
				LOG(Level::INFO,
					"QueueManager::autoenqueue: enqueuing "
					"`%s'",
					item->enclosure_url());
				enqueue_url(item->enclosure_url(),
					item->title(),
					item->pubDate_timestamp(),
					feed);
				item->set_enqueued(true);
			}
		}
	}
}

} // namespace newsboat
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "otbGDALDriverManagerWrapper.h"
#include <vector>
#include "otbMacro.h"
#include "otbSystem.h"
#include "itkMacro.h"

namespace otb
{

GDALDatasetWrapper::GDALDatasetWrapper(): m_Dataset(NULL)
{
}

GDALDatasetWrapper::~GDALDatasetWrapper()
{
  if (m_Dataset)
    {
    GDALClose(m_Dataset);
    }
}

// GetDataSet
GDALDataset*
GDALDatasetWrapper::GetDataSet() const
{
  return m_Dataset;
}

// GDALDriverManagerWrapper method implementation

GDALDriverManagerWrapper::GDALDriverManagerWrapper()
{
    GDALAllRegister();

    GDALDriver* driver = 0;

    // Ignore incompatible Jpeg2000 drivers (Jasper)
    driver = GetGDALDriverManager()->GetDriverByName( "JPEG2000" );
    if (driver)
      GetGDALDriverManager()->DeregisterDriver( driver );

#ifndef CHECK_HDF4OPEN_SYMBOL
    // Get rid of the HDF4 driver when it is buggy
    driver = GetGDALDriverManager()->GetDriverByName( "hdf4" );
    if (driver)
      GetGDALDriverManager()->DeregisterDriver( driver );
#endif
}

GDALDriverManagerWrapper::~GDALDriverManagerWrapper()
{
  GDALDestroyDriverManager();
}

// Open the file for reading and returns a smart dataset pointer
GDALDatasetWrapper::Pointer
GDALDriverManagerWrapper::Open( std::string filename ) const
{
  GDALDatasetWrapper::Pointer datasetWrapper;
  GDALDatasetH dataset = GDALOpen(filename.c_str(), GA_ReadOnly);

  if (dataset != NULL)
    {
    datasetWrapper = GDALDatasetWrapper::New();
    datasetWrapper->m_Dataset = static_cast<GDALDataset*>(dataset);
    }
  return datasetWrapper;
}

// Open the new  file for writing and returns a smart dataset pointer
GDALDatasetWrapper::Pointer
GDALDriverManagerWrapper::Create( std::string driverShortName, std::string filename,
                                    int nXSize, int nYSize, int nBands,
                                    GDALDataType eType, char ** papszOptions ) const
{
  GDALDatasetWrapper::Pointer datasetWrapper;

  GDALDriver*  driver = GetDriverByName( driverShortName );
  if(driver != NULL)
    {
    GDALDataset* dataset = driver->Create(filename.c_str(),
                                          nXSize, nYSize,
                                          nBands, eType,
                                          papszOptions );

    if (dataset != NULL)
      {
      datasetWrapper = GDALDatasetWrapper::New();
      datasetWrapper->m_Dataset = dataset;
      }
    }
  return datasetWrapper;
}

GDALDriver*
GDALDriverManagerWrapper::GetDriverByName( std::string driverShortName ) const
{
  return GetGDALDriverManager()->GetDriverByName(driverShortName.c_str());
}

GDALOverviewsBuilder::GDALOverviewsBuilder()
{
  m_NbOfResolutions = 1;
  m_ResolutionFactor = 2;
  m_ResamplingMethod = NEAREST;
  Superclass::SetNumberOfRequiredInputs(0);
  Superclass::SetNumberOfRequiredOutputs(0);
}

void GDALOverviewsBuilder::
PrintSelf(std::ostream& os, itk::Indent indent) const
{
  Superclass::PrintSelf(os,indent);

  os << indent << "Input Filename: " << m_InputFileName << std::endl;
  os << indent << "Number of Resolution requested: " << m_NbOfResolutions << std::endl;
  os << indent << "Resampling method: " << m_ResamplingMethod << std::endl;
}

void GDALOverviewsBuilder::GetGDALResamplingMethod(std::string &resamplingMethod)
{
  resamplingMethod.clear();
  switch(m_ResamplingMethod)
  {
    case NONE:
      resamplingMethod = "NONE";
      break;
    case NEAREST:
      resamplingMethod = "NEAREST";
      break;
    case GAUSS:
      resamplingMethod = "GAUSS";
      break;
    case CUBIC:
      resamplingMethod = "CUBIC";
      break;
    case AVERAGE:
      resamplingMethod = "AVERAGE";
      break;
    case MODE:
      resamplingMethod = "MODE";
      break;
    case AVERAGE_MAGPHASE:
      resamplingMethod = "AVERAGE_MAGPHASE";
      break;
    default:
      resamplingMethod = "NONE";
      break;
  }
}

// Progress reporting functions compatible with GDAL C API
extern "C"
{
  static int CPL_STDCALL otb_UpdateGDALProgress(double dfComplete,
                                                const char *pszMessage,
                                                void * pProgressArg)
  {
    otb::GDALOverviewsBuilder* _this = (otb::GDALOverviewsBuilder*)pProgressArg;
    _this->UpdateProgress(dfComplete);
    return 1;
  }
}

void GDALOverviewsBuilder::Update()
{
  typedef itk::SmartPointer<GDALDatasetWrapper> GDALDatasetWrapperPointer;
    GDALDatasetWrapperPointer wrappedDataset =
        GDALDriverManagerWrapper::GetInstance().Open(m_InputFileName);
    if (wrappedDataset.IsNull())
      {
      itkExceptionMacro(<< "Error while opening the file "<< m_InputFileName.c_str() << ".");
      }

    if( m_NbOfResolutions==0 )
      {
      itkExceptionMacro(
       << "Wrong number of resolutions: " << m_NbOfResolutions
      );
      }

    // Build the overviews list from nb of resolution desired
    std::vector<int> ovwlist;
    unsigned int factor = 1;
    for (unsigned int i = 1; i < m_NbOfResolutions; i++)
      {
      factor*=m_ResolutionFactor;
      ovwlist.push_back(factor);
      }

    /*std::cout << "list of overviews level= ";
    for (unsigned int i = 0; i < ovwlist.size(); i++)
        {
        std::cout << ovwlist[i] << ",";
        }
    std::cout << std::endl; */

    std::string resampMethod;
    this->GetGDALResamplingMethod(resampMethod);

    CPLErr lCrGdal = wrappedDataset->GetDataSet()->
          BuildOverviews( resampMethod.c_str(),
                          static_cast<int>(m_NbOfResolutions-1),
                          &ovwlist.front(),
                          0, // All bands
                          NULL, // All bands
                          (GDALProgressFunc)otb_UpdateGDALProgress,
                          this);
    if (lCrGdal == CE_Failure)
      {
      itkExceptionMacro(<< "Error while building the GDAL overviews from " << m_InputFileName.c_str() << ".");
      }
}

} // end namespace otb

<commit_msg>ENH: OTB-297 : don't deregister Jasper driver, users should do it, throw an exception before using this driver<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "otbGDALDriverManagerWrapper.h"
#include <vector>
#include "otbMacro.h"
#include "otbSystem.h"
#include "itkMacro.h"

namespace otb
{

GDALDatasetWrapper::GDALDatasetWrapper(): m_Dataset(NULL)
{
}

GDALDatasetWrapper::~GDALDatasetWrapper()
{
  if (m_Dataset)
    {
    GDALClose(m_Dataset);
    }
}

// GetDataSet
GDALDataset*
GDALDatasetWrapper::GetDataSet() const
{
  return m_Dataset;
}

// GDALDriverManagerWrapper method implementation

GDALDriverManagerWrapper::GDALDriverManagerWrapper()
{
    GDALAllRegister();

    GDALDriver* driver = 0;

    // Ignore incompatible Jpeg2000 drivers (Jasper)
    /*
    driver = GetGDALDriverManager()->GetDriverByName( "JPEG2000" );
    if (driver)
      GetGDALDriverManager()->DeregisterDriver( driver );
    */

#ifndef CHECK_HDF4OPEN_SYMBOL
    // Get rid of the HDF4 driver when it is buggy
    driver = GetGDALDriverManager()->GetDriverByName( "hdf4" );
    if (driver)
      GetGDALDriverManager()->DeregisterDriver( driver );
#endif
}

GDALDriverManagerWrapper::~GDALDriverManagerWrapper()
{
  GDALDestroyDriverManager();
}

// Open the file for reading and returns a smart dataset pointer
GDALDatasetWrapper::Pointer
GDALDriverManagerWrapper::Open( std::string filename ) const
{
  GDALDatasetWrapper::Pointer datasetWrapper;

  // first : test if a driver can identify the dataset
  GDALDriverH identifyDriverH = GDALIdentifyDriver(filename.c_str(), NULL);
  if(identifyDriverH == NULL)
    {
    // don't try to open it and exit
    return datasetWrapper;
    }

  GDALDriver *identifyDriver = static_cast<GDALDriver*>(identifyDriverH);

  // check if Jasper will be used
  if (strcmp(identifyDriver->GetDescription(),"JPEG2000") == 0)
    {
    itkGenericExceptionMacro(<< "Error : tried to open the file "
      << filename.c_str() << " with GDAL driver Jasper "
      "(which fails on OTB). Try setting the environment variable GDAL_SKIP"
      " in order to avoid this driver.");
    }

  GDALDatasetH dataset = GDALOpen(filename.c_str(), GA_ReadOnly);

  if (dataset != NULL)
    {
    datasetWrapper = GDALDatasetWrapper::New();
    datasetWrapper->m_Dataset = static_cast<GDALDataset*>(dataset);
    }
  return datasetWrapper;
}

// Open the new  file for writing and returns a smart dataset pointer
GDALDatasetWrapper::Pointer
GDALDriverManagerWrapper::Create( std::string driverShortName, std::string filename,
                                    int nXSize, int nYSize, int nBands,
                                    GDALDataType eType, char ** papszOptions ) const
{
  GDALDatasetWrapper::Pointer datasetWrapper;

  GDALDriver*  driver = GetDriverByName( driverShortName );
  if(driver != NULL)
    {
    GDALDataset* dataset = driver->Create(filename.c_str(),
                                          nXSize, nYSize,
                                          nBands, eType,
                                          papszOptions );

    if (dataset != NULL)
      {
      datasetWrapper = GDALDatasetWrapper::New();
      datasetWrapper->m_Dataset = dataset;
      }
    }
  return datasetWrapper;
}

GDALDriver*
GDALDriverManagerWrapper::GetDriverByName( std::string driverShortName ) const
{
  return GetGDALDriverManager()->GetDriverByName(driverShortName.c_str());
}

GDALOverviewsBuilder::GDALOverviewsBuilder()
{
  m_NbOfResolutions = 1;
  m_ResolutionFactor = 2;
  m_ResamplingMethod = NEAREST;
  Superclass::SetNumberOfRequiredInputs(0);
  Superclass::SetNumberOfRequiredOutputs(0);
}

void GDALOverviewsBuilder::
PrintSelf(std::ostream& os, itk::Indent indent) const
{
  Superclass::PrintSelf(os,indent);

  os << indent << "Input Filename: " << m_InputFileName << std::endl;
  os << indent << "Number of Resolution requested: " << m_NbOfResolutions << std::endl;
  os << indent << "Resampling method: " << m_ResamplingMethod << std::endl;
}

void GDALOverviewsBuilder::GetGDALResamplingMethod(std::string &resamplingMethod)
{
  resamplingMethod.clear();
  switch(m_ResamplingMethod)
  {
    case NONE:
      resamplingMethod = "NONE";
      break;
    case NEAREST:
      resamplingMethod = "NEAREST";
      break;
    case GAUSS:
      resamplingMethod = "GAUSS";
      break;
    case CUBIC:
      resamplingMethod = "CUBIC";
      break;
    case AVERAGE:
      resamplingMethod = "AVERAGE";
      break;
    case MODE:
      resamplingMethod = "MODE";
      break;
    case AVERAGE_MAGPHASE:
      resamplingMethod = "AVERAGE_MAGPHASE";
      break;
    default:
      resamplingMethod = "NONE";
      break;
  }
}

// Progress reporting functions compatible with GDAL C API
extern "C"
{
  static int CPL_STDCALL otb_UpdateGDALProgress(double dfComplete,
                                                const char *pszMessage,
                                                void * pProgressArg)
  {
    otb::GDALOverviewsBuilder* _this = (otb::GDALOverviewsBuilder*)pProgressArg;
    _this->UpdateProgress(dfComplete);
    return 1;
  }
}

void GDALOverviewsBuilder::Update()
{
  typedef itk::SmartPointer<GDALDatasetWrapper> GDALDatasetWrapperPointer;
    GDALDatasetWrapperPointer wrappedDataset =
        GDALDriverManagerWrapper::GetInstance().Open(m_InputFileName);
    if (wrappedDataset.IsNull())
      {
      itkExceptionMacro(<< "Error while opening the file "<< m_InputFileName.c_str() << ".");
      }

    if( m_NbOfResolutions==0 )
      {
      itkExceptionMacro(
       << "Wrong number of resolutions: " << m_NbOfResolutions
      );
      }

    // Build the overviews list from nb of resolution desired
    std::vector<int> ovwlist;
    unsigned int factor = 1;
    for (unsigned int i = 1; i < m_NbOfResolutions; i++)
      {
      factor*=m_ResolutionFactor;
      ovwlist.push_back(factor);
      }

    /*std::cout << "list of overviews level= ";
    for (unsigned int i = 0; i < ovwlist.size(); i++)
        {
        std::cout << ovwlist[i] << ",";
        }
    std::cout << std::endl; */

    std::string resampMethod;
    this->GetGDALResamplingMethod(resampMethod);

    CPLErr lCrGdal = wrappedDataset->GetDataSet()->
          BuildOverviews( resampMethod.c_str(),
                          static_cast<int>(m_NbOfResolutions-1),
                          &ovwlist.front(),
                          0, // All bands
                          NULL, // All bands
                          (GDALProgressFunc)otb_UpdateGDALProgress,
                          this);
    if (lCrGdal == CE_Failure)
      {
      itkExceptionMacro(<< "Error while building the GDAL overviews from " << m_InputFileName.c_str() << ".");
      }
}

} // end namespace otb

<|endoftext|>


<commit_before>#include <iostream>
#include <condition_variable>
#include <thread>
#include <queue>
#include <string>

std::mutex m;
std::queue<std::string> messages;
std::condition_variable data_condition;

void data_reading()
{
	std::string line;
	while ( getline(std::cin, line) )
	{
		std::lock_guard<std::mutex> lg(m);
		messages.push(line);
		data_condition.notify_one();
	}
}

void data_printing()
{
	while (true)
	{
		std::unique_lock<std::mutex> l(m);
		data_condition.wait( l, [] { return ! messages.empty(); });
		auto message = std::move(messages.front());
		messages.pop();
		l.unlock();
		std::cout << "READ: " << message << std::endl;
	}
}

int main(int argc, char* argv[])
{
	std::thread t_read(data_reading);
	std::thread t_print(data_printing);
	t_read.join();
	t_print.join();
}

<commit_msg>Condition variable toy example<commit_after>#include <iostream>
#include <condition_variable>
#include <thread>
#include <queue>
#include <string>

std::mutex m;
std::queue<std::string> messages;
std::condition_variable data_condition;

void data_reading()
{
	std::string line;
	std::cout << "Input: (Empty line exits) ";
	while ( getline(std::cin, line) )
	{
		if ( line.empty() )
			break;
		std::lock_guard<std::mutex> lg(m);
		messages.push(line);
		data_condition.notify_one();
	}
}

void data_printing()
{
	while (true)
	{
		std::unique_lock<std::mutex> l(m);
		data_condition.wait( l, [] { return ! messages.empty(); });
		auto message = std::move(messages.front());
		messages.pop();
		l.unlock();
		std::cout << "READ: " << message << std::endl;
	}
}

int main(int argc, char* argv[])
{
	std::thread t_read(data_reading);
	std::thread t_print(data_printing);
	t_print.detach();
	t_read.join();
}

<|endoftext|>


<commit_before>// Copyright 2018 Google LLC
//
// 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
//
//     https://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 "tools/render/processed_trace.h"

#include "absl/algorithm/container.h"
#include "absl/strings/str_cat.h"
#include "tools/render/layout_constants.h"

namespace quic_trace {
namespace render {

namespace {

std::string FormatBandwidth(size_t total_bytes, uint64_t time_delta_us) {
  double rate = 8e6 * total_bytes / time_delta_us;

  const char* unit = "";
  for (const char* current_unit : {"k", "M", "G"}) {
    if (rate < 1e3) {
      break;
    }
    rate /= 1e3;
    unit = current_unit;
  }

  char buffer[16];
  snprintf(buffer, sizeof(buffer), "%.2f %sbps", rate, unit);
  return buffer;
}

std::string FormatPercentage(size_t numerator, size_t denominator) {
  double percentage = 100. * numerator / denominator;
  char buffer[8];
  snprintf(buffer, sizeof(buffer), "%.2f%%", percentage);
  return buffer;
}

std::string FormatTime(uint64_t time_us) {
  char buffer[16];
  snprintf(buffer, sizeof(buffer), "%.3fs", time_us / 1e6);
  return buffer;
}

std::string FormatRtt(uint64_t rtt_us) {
  if (rtt_us < 10 * 1000) {
    return absl::StrCat(rtt_us, "µs");
  }
  if (rtt_us < 1000 * 1000) {
    return absl::StrCat(rtt_us / 1000, "ms");
  }
  return FormatTime(rtt_us);
}

}  // namespace

void ProcessedTrace::AddPacket(TraceRenderer* renderer,
                               const Event& packet,
                               Interval interval,
                               PacketType type) {
  renderer->AddPacket(packet.time_us(), interval.offset, interval.size, type);
  rendered_packets_.push_back(
      RenderedPacket{Box{vec2(packet.time_us(), interval.offset),
                         vec2(kSentPacketDurationMs, interval.size)},
                     &packet});
}

ProcessedTrace::ProcessedTrace(std::unique_ptr<Trace> trace,
                               TraceRenderer* renderer) {
  renderer->PacketCountHint(trace->events_size());

  quic_trace::NumberingWithoutRetransmissions numbering;
  size_t largest_sent = 0;
  uint64_t largest_time = 0;
  for (const Event& event : trace->events()) {
    if (!event.has_time_us() || event.time_us() < largest_time) {
      LOG(FATAL)
          << "All events in the trace have to be sorted in chronological order";
    }
    largest_time = event.time_us();

    if (event.event_type() == PACKET_SENT) {
      Interval mapped = numbering.AssignTraceNumbering(event);
      AddPacket(renderer, event, mapped, PacketType::SENT);
      largest_sent =
          std::max<size_t>(mapped.offset + mapped.size, largest_sent);
    }
    if (event.event_type() == PACKET_RECEIVED) {
      for (const Frame& frame : event.frames()) {
        for (const AckBlock& range : frame.ack_info().acked_packets()) {
          for (size_t i = range.first_packet(); i <= range.last_packet(); i++) {
            if (!packets_acked_.insert(i).second) {
              continue;
            }
            Interval mapped = numbering.GetTraceNumbering(i);
            AddPacket(renderer, event, mapped, PacketType::ACKED);
            acks_.emplace(vec2(event.time_us(), mapped.offset), i);
            // Don't count spurious retransmissions as losses.
            packets_lost_.erase(i);
          }
        }
      }
    }
    if (event.event_type() == PACKET_LOST) {
      Interval mapped = numbering.GetTraceNumbering(event.packet_number());
      AddPacket(renderer, event, mapped, PacketType::LOST);
      packets_lost_.insert(event.packet_number());
    }
    if (event.event_type() == APPLICATION_LIMITED) {
      // Normally, we would use the size of the packet as height, but
      // app-limited events have no size, so we pick an arbitrary number (in
      // bytes).
      const size_t kAppLimitedHeigth = 800;
      AddPacket(renderer, event, Interval{largest_sent, kAppLimitedHeigth},
                PacketType::APP_LIMITED);
    }
  }

  renderer->FinishPackets();
  trace_ = std::move(trace);
}

bool ProcessedTrace::SummaryTable(Table* table,
                                  float start_time,
                                  float end_time) {
  auto compare = [](Event a, Event b) { return a.time_us() < b.time_us(); };
  Event key_event;

  key_event.set_time_us(start_time);
  auto start_it = absl::c_lower_bound(trace_->events(), key_event, compare);

  key_event.set_time_us(end_time);
  auto end_it = absl::c_upper_bound(trace_->events(), key_event, compare);

  if (start_it > end_it) {
    return false;
  }

  // TODO(vasilvv): add actually useful information.
  size_t count_sent = 0;
  size_t bytes_sent = 0;
  size_t bytes_sent_acked = 0;
  size_t bytes_sent_lost = 0;
  for (auto it = start_it; it != end_it; it++) {
    switch (it->event_type()) {
      case PACKET_SENT:
        count_sent++;
        bytes_sent += it->packet_size();
        if (packets_acked_.count(it->packet_number()) > 0) {
          bytes_sent_acked += it->packet_size();
        }
        if (packets_lost_.count(it->packet_number()) > 0) {
          bytes_sent_lost += it->packet_size();
        }
        break;
      default:
        break;
    };
  }

  table->AddHeader("Selection summary");
  table->AddRow("#sent", absl::StrCat(count_sent));
  table->AddRow("Send rate",
                FormatBandwidth(bytes_sent, end_time - start_time));
  table->AddRow("Goodput",
                FormatBandwidth(bytes_sent_acked, end_time - start_time));
  table->AddRow("Loss rate", FormatPercentage(bytes_sent_lost, bytes_sent));
  return true;
}

ProcessedTrace::PacketSearchResult ProcessedTrace::FindPacketContainingPoint(
    vec2 point,
    vec2 margin) {
  RenderedPacket key{Box(), nullptr};

  key.box.origin.x = point.x - kSentPacketDurationMs - margin.x;
  auto start_it = absl::c_lower_bound(rendered_packets_, key);

  key.box.origin.x = point.x + kSentPacketDurationMs + margin.x;
  auto end_it = absl::c_upper_bound(rendered_packets_, key);

  if (start_it > end_it) {
    return PacketSearchResult();
  }

  auto closest_box = end_it;
  float closest_distance;
  for (auto it = start_it; it != end_it; it++) {
    Box target_box{it->box.origin - margin, it->box.size + 2 * margin};
    if (IsInside(point, target_box)) {
      float distance = DistanceSquared(point, BoxCenter(target_box));
      if (closest_box == end_it || distance < closest_distance) {
        closest_box = it;
        closest_distance = distance;
      }
    }
  }
  if (closest_box != end_it) {
    PacketSearchResult result;
    result.index = closest_box - rendered_packets_.cbegin();
    result.as_rendered = &closest_box->box;
    result.event = closest_box->packet;
    return result;
  }

  return PacketSearchResult();
}

namespace {
const char* EncryptionLevelToString(EncryptionLevel level) {
  switch (level) {
    case ENCRYPTION_INITIAL:
      return "Initial";
    case ENCRYPTION_0RTT:
      return "0-RTT";
    case ENCRYPTION_1RTT:
      return "1-RTT";

    case ENCRYPTION_UNKNOWN:
    default:
      return "???";
  }
}
}  // namespace

void ProcessedTrace::FillTableForPacket(Table* table,
                                        const Box* as_rendered,
                                        const Event* packet) {
  switch (packet->event_type()) {
    case PACKET_SENT:
      table->AddHeader(absl::StrCat("Sent packet #", packet->packet_number()));
      break;
    case PACKET_RECEIVED: {
      std::string packet_acked = "???";
      auto it = acks_.find(as_rendered->origin);
      if (it != acks_.end()) {
        packet_acked = absl::StrCat(it->second);
      }
      table->AddHeader(absl::StrCat("Ack for packet #", packet_acked));
      break;
    }
    case PACKET_LOST:
      table->AddHeader(absl::StrCat("Lost packet #", packet->packet_number()));
      break;
    case APPLICATION_LIMITED:
      table->AddHeader("Application limited");
      break;
    default:
      return;
  }

  table->AddRow("Time", FormatTime(packet->time_us()));

  if (packet->event_type() == PACKET_SENT) {
    table->AddRow("Size", absl::StrCat(packet->packet_size(), "bytes"));
    table->AddRow("Encryption",
                  EncryptionLevelToString(packet->encryption_level()));

    table->AddHeader("Frame list");
    for (const Frame& frame : packet->frames()) {
      switch (frame.frame_type()) {
        case STREAM:
          table->AddRow(
              "Stream",
              absl::StrCat("#", frame.stream_frame_info().stream_id(), ": ",
                           frame.stream_frame_info().offset(), "-",
                           frame.stream_frame_info().offset() +
                           frame.stream_frame_info().length(),
                           " (", frame.stream_frame_info().length(), ")"));
          break;
        case RESET_STREAM:
          table->AddRow(
              "Reset stream",
              absl::StrCat("#", frame.reset_stream_info().stream_id()));
          break;
        case CONNECTION_CLOSE:
          table->AddRow(
              "Connection close",
              absl::StrCat(absl::Hex(frame.close_info().error_code())));
          break;
        case PING:
          table->AddRow("Ping", "");
          break;
        case BLOCKED:
          table->AddRow("Blocked", "");
          break;
        case STREAM_BLOCKED:
          table->AddRow("Stream blocked",
                        absl::StrCat(frame.flow_control_info().stream_id()));
          break;
        default:
          table->AddRow("Unknown", "");
          break;
      }
    }
  }

  if (packet->has_transport_state()) {
    const TransportState& state = packet->transport_state();
    table->AddHeader("Transport state");
    if (state.has_last_rtt_us()) {
      table->AddRow("RTT", FormatRtt(state.last_rtt_us()));
    }
    if (state.has_smoothed_rtt_us()) {
      table->AddRow("SRTT", FormatRtt(state.smoothed_rtt_us()));
    }
    if (state.has_min_rtt_us()) {
      table->AddRow("Min RTT", FormatRtt(state.min_rtt_us()));
    }
    if (state.has_in_flight_bytes()) {
      table->AddRow("In flight",
                    absl::StrCat(state.in_flight_bytes(), " bytes"));
    }
    if (state.has_cwnd_bytes()) {
      table->AddRow("CWND", absl::StrCat(state.cwnd_bytes(), " bytes"));
    }
    if (state.has_pacing_rate_bps()) {
      table->AddRow("Pacing rate",
                    FormatBandwidth(state.pacing_rate_bps(), 8000 * 1000));
    }
  }
}

absl::optional<Box> ProcessedTrace::BoundContainedPackets(Box boundary) {
  RenderedPacket key{Box(), nullptr};

  key.box.origin.x = boundary.origin.x;
  auto range_start = absl::c_lower_bound(rendered_packets_, key);

  key.box.origin.x =
      boundary.origin.x + boundary.size.x + kSentPacketDurationMs;
  auto range_end = absl::c_upper_bound(rendered_packets_, key);

  if (range_start == rendered_packets_.end() ||
      range_end == rendered_packets_.end() || range_start > range_end) {
    return absl::nullopt;
  }

  absl::optional<Box> result;
  for (auto it = range_start; it <= range_end; it++) {
    if (IsInside(it->box, boundary)) {
      result = result.has_value() ? BoundingBox(*result, it->box) : it->box;
    }
  }
  return result;
}

}  // namespace render
}  // namespace quic_trace
<commit_msg>Show ack frames in sent packets<commit_after>// Copyright 2018 Google LLC
//
// 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
//
//     https://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 "tools/render/processed_trace.h"

#include "absl/algorithm/container.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_join.h"
#include "tools/render/layout_constants.h"

namespace quic_trace {
namespace render {

namespace {

std::string FormatBandwidth(size_t total_bytes, uint64_t time_delta_us) {
  double rate = 8e6 * total_bytes / time_delta_us;

  const char* unit = "";
  for (const char* current_unit : {"k", "M", "G"}) {
    if (rate < 1e3) {
      break;
    }
    rate /= 1e3;
    unit = current_unit;
  }

  char buffer[16];
  snprintf(buffer, sizeof(buffer), "%.2f %sbps", rate, unit);
  return buffer;
}

std::string FormatPercentage(size_t numerator, size_t denominator) {
  double percentage = 100. * numerator / denominator;
  char buffer[8];
  snprintf(buffer, sizeof(buffer), "%.2f%%", percentage);
  return buffer;
}

std::string FormatTime(uint64_t time_us) {
  char buffer[16];
  snprintf(buffer, sizeof(buffer), "%.3fs", time_us / 1e6);
  return buffer;
}

std::string FormatRtt(uint64_t rtt_us) {
  if (rtt_us < 10 * 1000) {
    return absl::StrCat(rtt_us, "µs");
  }
  if (rtt_us < 1000 * 1000) {
    return absl::StrCat(rtt_us / 1000, "ms");
  }
  return FormatTime(rtt_us);
}

}  // namespace

void ProcessedTrace::AddPacket(TraceRenderer* renderer,
                               const Event& packet,
                               Interval interval,
                               PacketType type) {
  renderer->AddPacket(packet.time_us(), interval.offset, interval.size, type);
  rendered_packets_.push_back(
      RenderedPacket{Box{vec2(packet.time_us(), interval.offset),
                         vec2(kSentPacketDurationMs, interval.size)},
                     &packet});
}

ProcessedTrace::ProcessedTrace(std::unique_ptr<Trace> trace,
                               TraceRenderer* renderer) {
  renderer->PacketCountHint(trace->events_size());

  quic_trace::NumberingWithoutRetransmissions numbering;
  size_t largest_sent = 0;
  uint64_t largest_time = 0;
  for (const Event& event : trace->events()) {
    if (!event.has_time_us() || event.time_us() < largest_time) {
      LOG(FATAL)
          << "All events in the trace have to be sorted in chronological order";
    }
    largest_time = event.time_us();

    if (event.event_type() == PACKET_SENT) {
      Interval mapped = numbering.AssignTraceNumbering(event);
      AddPacket(renderer, event, mapped, PacketType::SENT);
      largest_sent =
          std::max<size_t>(mapped.offset + mapped.size, largest_sent);
    }
    if (event.event_type() == PACKET_RECEIVED) {
      for (const Frame& frame : event.frames()) {
        for (const AckBlock& range : frame.ack_info().acked_packets()) {
          for (size_t i = range.first_packet(); i <= range.last_packet(); i++) {
            if (!packets_acked_.insert(i).second) {
              continue;
            }
            Interval mapped = numbering.GetTraceNumbering(i);
            AddPacket(renderer, event, mapped, PacketType::ACKED);
            acks_.emplace(vec2(event.time_us(), mapped.offset), i);
            // Don't count spurious retransmissions as losses.
            packets_lost_.erase(i);
          }
        }
      }
    }
    if (event.event_type() == PACKET_LOST) {
      Interval mapped = numbering.GetTraceNumbering(event.packet_number());
      AddPacket(renderer, event, mapped, PacketType::LOST);
      packets_lost_.insert(event.packet_number());
    }
    if (event.event_type() == APPLICATION_LIMITED) {
      // Normally, we would use the size of the packet as height, but
      // app-limited events have no size, so we pick an arbitrary number (in
      // bytes).
      const size_t kAppLimitedHeigth = 800;
      AddPacket(renderer, event, Interval{largest_sent, kAppLimitedHeigth},
                PacketType::APP_LIMITED);
    }
  }

  renderer->FinishPackets();
  trace_ = std::move(trace);
}

bool ProcessedTrace::SummaryTable(Table* table,
                                  float start_time,
                                  float end_time) {
  auto compare = [](Event a, Event b) { return a.time_us() < b.time_us(); };
  Event key_event;

  key_event.set_time_us(start_time);
  auto start_it = absl::c_lower_bound(trace_->events(), key_event, compare);

  key_event.set_time_us(end_time);
  auto end_it = absl::c_upper_bound(trace_->events(), key_event, compare);

  if (start_it > end_it) {
    return false;
  }

  // TODO(vasilvv): add actually useful information.
  size_t count_sent = 0;
  size_t bytes_sent = 0;
  size_t bytes_sent_acked = 0;
  size_t bytes_sent_lost = 0;
  for (auto it = start_it; it != end_it; it++) {
    switch (it->event_type()) {
      case PACKET_SENT:
        count_sent++;
        bytes_sent += it->packet_size();
        if (packets_acked_.count(it->packet_number()) > 0) {
          bytes_sent_acked += it->packet_size();
        }
        if (packets_lost_.count(it->packet_number()) > 0) {
          bytes_sent_lost += it->packet_size();
        }
        break;
      default:
        break;
    };
  }

  table->AddHeader("Selection summary");
  table->AddRow("#sent", absl::StrCat(count_sent));
  table->AddRow("Send rate",
                FormatBandwidth(bytes_sent, end_time - start_time));
  table->AddRow("Goodput",
                FormatBandwidth(bytes_sent_acked, end_time - start_time));
  table->AddRow("Loss rate", FormatPercentage(bytes_sent_lost, bytes_sent));
  return true;
}

ProcessedTrace::PacketSearchResult ProcessedTrace::FindPacketContainingPoint(
    vec2 point,
    vec2 margin) {
  RenderedPacket key{Box(), nullptr};

  key.box.origin.x = point.x - kSentPacketDurationMs - margin.x;
  auto start_it = absl::c_lower_bound(rendered_packets_, key);

  key.box.origin.x = point.x + kSentPacketDurationMs + margin.x;
  auto end_it = absl::c_upper_bound(rendered_packets_, key);

  if (start_it > end_it) {
    return PacketSearchResult();
  }

  auto closest_box = end_it;
  float closest_distance;
  for (auto it = start_it; it != end_it; it++) {
    Box target_box{it->box.origin - margin, it->box.size + 2 * margin};
    if (IsInside(point, target_box)) {
      float distance = DistanceSquared(point, BoxCenter(target_box));
      if (closest_box == end_it || distance < closest_distance) {
        closest_box = it;
        closest_distance = distance;
      }
    }
  }
  if (closest_box != end_it) {
    PacketSearchResult result;
    result.index = closest_box - rendered_packets_.cbegin();
    result.as_rendered = &closest_box->box;
    result.event = closest_box->packet;
    return result;
  }

  return PacketSearchResult();
}

namespace {
const char* EncryptionLevelToString(EncryptionLevel level) {
  switch (level) {
    case ENCRYPTION_INITIAL:
      return "Initial";
    case ENCRYPTION_0RTT:
      return "0-RTT";
    case ENCRYPTION_1RTT:
      return "1-RTT";

    case ENCRYPTION_UNKNOWN:
    default:
      return "???";
  }
}

constexpr int kMaxAckBlocksShown = 3;
std::string AckSummary(const AckInfo& ack) {
  if (ack.acked_packets_size() == 0) {
    return "";
  }

  bool overflow = false;
  int blocks_to_show = ack.acked_packets_size();
  if (blocks_to_show > kMaxAckBlocksShown) {
    blocks_to_show = kMaxAckBlocksShown;
    overflow = true;
  }

  std::vector<std::string> ack_ranges;
  for (int i = 0; i < blocks_to_show; i++) {
    const AckBlock& block = ack.acked_packets(i);
    if (block.first_packet() == block.last_packet()) {
      ack_ranges.push_back(absl::StrCat(block.first_packet()));
    } else {
      ack_ranges.push_back(
          absl::StrCat(block.first_packet(), ":", block.last_packet()));
    }
  }

  std::string result = absl::StrJoin(ack_ranges, ", ");
  if (overflow) {
    absl::StrAppend(&result, "...");
  }
  return result;
}
}  // namespace

void ProcessedTrace::FillTableForPacket(Table* table,
                                        const Box* as_rendered,
                                        const Event* packet) {
  switch (packet->event_type()) {
    case PACKET_SENT:
      table->AddHeader(absl::StrCat("Sent packet #", packet->packet_number()));
      break;
    case PACKET_RECEIVED: {
      std::string packet_acked = "???";
      auto it = acks_.find(as_rendered->origin);
      if (it != acks_.end()) {
        packet_acked = absl::StrCat(it->second);
      }
      table->AddHeader(absl::StrCat("Ack for packet #", packet_acked));
      break;
    }
    case PACKET_LOST:
      table->AddHeader(absl::StrCat("Lost packet #", packet->packet_number()));
      break;
    case APPLICATION_LIMITED:
      table->AddHeader("Application limited");
      break;
    default:
      return;
  }

  table->AddRow("Time", FormatTime(packet->time_us()));

  if (packet->event_type() == PACKET_SENT) {
    table->AddRow("Size", absl::StrCat(packet->packet_size(), "bytes"));
    table->AddRow("Encryption",
                  EncryptionLevelToString(packet->encryption_level()));

    table->AddHeader("Frame list");
    for (const Frame& frame : packet->frames()) {
      switch (frame.frame_type()) {
        case STREAM:
          table->AddRow(
              "Stream",
              absl::StrCat("#", frame.stream_frame_info().stream_id(), ": ",
                           frame.stream_frame_info().offset(), "-",
                           frame.stream_frame_info().offset() +
                               frame.stream_frame_info().length(),
                           " (", frame.stream_frame_info().length(), ")"));
          break;
        case RESET_STREAM:
          table->AddRow(
              "Reset stream",
              absl::StrCat("#", frame.reset_stream_info().stream_id()));
          break;
        case CONNECTION_CLOSE:
          table->AddRow(
              "Connection close",
              absl::StrCat(absl::Hex(frame.close_info().error_code())));
          break;
        case PING:
          table->AddRow("Ping", "");
          break;
        case BLOCKED:
          table->AddRow("Blocked", "");
          break;
        case STREAM_BLOCKED:
          table->AddRow("Stream blocked",
                        absl::StrCat(frame.flow_control_info().stream_id()));
          break;
        case ACK:
          table->AddRow("Ack", AckSummary(frame.ack_info()));
          break;
        default:
          table->AddRow("Unknown", "");
          break;
      }
    }
  }

  if (packet->has_transport_state()) {
    const TransportState& state = packet->transport_state();
    table->AddHeader("Transport state");
    if (state.has_last_rtt_us()) {
      table->AddRow("RTT", FormatRtt(state.last_rtt_us()));
    }
    if (state.has_smoothed_rtt_us()) {
      table->AddRow("SRTT", FormatRtt(state.smoothed_rtt_us()));
    }
    if (state.has_min_rtt_us()) {
      table->AddRow("Min RTT", FormatRtt(state.min_rtt_us()));
    }
    if (state.has_in_flight_bytes()) {
      table->AddRow("In flight",
                    absl::StrCat(state.in_flight_bytes(), " bytes"));
    }
    if (state.has_cwnd_bytes()) {
      table->AddRow("CWND", absl::StrCat(state.cwnd_bytes(), " bytes"));
    }
    if (state.has_pacing_rate_bps()) {
      table->AddRow("Pacing rate",
                    FormatBandwidth(state.pacing_rate_bps(), 8000 * 1000));
    }
  }
}

absl::optional<Box> ProcessedTrace::BoundContainedPackets(Box boundary) {
  RenderedPacket key{Box(), nullptr};

  key.box.origin.x = boundary.origin.x;
  auto range_start = absl::c_lower_bound(rendered_packets_, key);

  key.box.origin.x =
      boundary.origin.x + boundary.size.x + kSentPacketDurationMs;
  auto range_end = absl::c_upper_bound(rendered_packets_, key);

  if (range_start == rendered_packets_.end() ||
      range_end == rendered_packets_.end() || range_start > range_end) {
    return absl::nullopt;
  }

  absl::optional<Box> result;
  for (auto it = range_start; it <= range_end; it++) {
    if (IsInside(it->box, boundary)) {
      result = result.has_value() ? BoundingBox(*result, it->box) : it->box;
    }
  }
  return result;
}

}  // namespace render
}  // namespace quic_trace
<|endoftext|>


<commit_before>#include "FlightTask.hpp"
#include <mathlib/mathlib.h>
#include <lib/ecl/geo/geo.h>

constexpr uint64_t FlightTask::_timeout;
// First index of empty_setpoint corresponds to time-stamp and requires a finite number.
const vehicle_local_position_setpoint_s FlightTask::empty_setpoint = {0, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, {NAN, NAN, NAN}};
const vehicle_constraints_s FlightTask::empty_constraints = {0, NAN, NAN, NAN, NAN, NAN, NAN, NAN, vehicle_constraints_s::GEAR_KEEP, {}};
bool FlightTask::initializeSubscriptions(SubscriptionArray &subscription_array)
{
	if (!subscription_array.get(ORB_ID(vehicle_local_position), _sub_vehicle_local_position)) {
		return false;
	}

	if (!subscription_array.get(ORB_ID(vehicle_attitude), _sub_attitude)) {
		return false;
	}

	return true;
}

bool FlightTask::activate()
{
	_resetSetpoints();
	_setDefaultConstraints();
	_time_stamp_activate = hrt_absolute_time();
	_heading_reset_counter = _sub_attitude->get().quat_reset_counter;
	return true;
}

bool FlightTask::updateInitialize()
{
	_time_stamp_current = hrt_absolute_time();
	_time = (_time_stamp_current - _time_stamp_activate) / 1e6f;
	_deltatime  = math::min((_time_stamp_current - _time_stamp_last), _timeout) / 1e6f;
	_time_stamp_last = _time_stamp_current;
	return _evaluateVehicleLocalPosition();
}

const vehicle_local_position_setpoint_s FlightTask::getPositionSetpoint()
{
	/* fill position setpoint message */
	vehicle_local_position_setpoint_s vehicle_local_position_setpoint;
	vehicle_local_position_setpoint.timestamp = hrt_absolute_time();
	_position_setpoint.copyToRaw(&vehicle_local_position_setpoint.x);
	_velocity_setpoint.copyToRaw(&vehicle_local_position_setpoint.vx);
	_acceleration_setpoint.copyToRaw(&vehicle_local_position_setpoint.acc_x);
	_thrust_setpoint.copyTo(vehicle_local_position_setpoint.thrust);
	vehicle_local_position_setpoint.yaw = _yaw_setpoint;
	vehicle_local_position_setpoint.yawspeed = _yawspeed_setpoint;
	return vehicle_local_position_setpoint;
}

void FlightTask::_resetSetpoints()
{
	_position_setpoint *= NAN;
	_velocity_setpoint *= NAN;
	_acceleration_setpoint *= NAN;
	_thrust_setpoint *= NAN;
	_yaw_setpoint = _yawspeed_setpoint = NAN;
}

bool FlightTask::_evaluateVehicleLocalPosition()
{
	if ((_time_stamp_current - _sub_vehicle_local_position->get().timestamp) < _timeout) {

		// position
		if (_sub_vehicle_local_position->get().xy_valid) {
			_position(0) = _sub_vehicle_local_position->get().x;
			_position(1) = _sub_vehicle_local_position->get().y;

		} else {
			_position(0) = _position(1) = NAN;
		}

		if (_sub_vehicle_local_position->get().z_valid) {
			_position(2) = _sub_vehicle_local_position->get().z;

		} else {
			_position(2) = NAN;
		}

		// velocity
		if (_sub_vehicle_local_position->get().v_xy_valid) {
			_velocity(0) = _sub_vehicle_local_position->get().vx;
			_velocity(1) = _sub_vehicle_local_position->get().vy;

		} else {
			_velocity(0) = _velocity(1) = NAN;
		}

		if (_sub_vehicle_local_position->get().v_z_valid) {
			_velocity(2) = _sub_vehicle_local_position->get().vz;

		} else {
			_velocity(2) = NAN;
		}

		// yaw
		_yaw = _sub_vehicle_local_position->get().yaw;

		// distance to bottom
		_dist_to_bottom = NAN;

		if (_sub_vehicle_local_position->get().dist_bottom_valid
		    && PX4_ISFINITE(_sub_vehicle_local_position->get().dist_bottom)) {
			_dist_to_bottom =  _sub_vehicle_local_position->get().dist_bottom;
		}

		// global frame reference coordinates to enable conversions
		if (_sub_vehicle_local_position->get().xy_global && _sub_vehicle_local_position->get().z_global) {
			globallocalconverter_init(_sub_vehicle_local_position->get().ref_lat, _sub_vehicle_local_position->get().ref_lon,
						  _sub_vehicle_local_position->get().ref_alt, _sub_vehicle_local_position->get().ref_timestamp);
		}

		// We don't check here if states are valid or not.
		// Validity checks are done in the sub-classes.
		return true;

	} else {
		_resetSetpoints();
		return false;
	}
}

void FlightTask::_setDefaultConstraints()
{
	_constraints.speed_xy = MPC_XY_VEL_MAX.get();
	_constraints.speed_up = MPC_Z_VEL_MAX_UP.get();
	_constraints.speed_down = MPC_Z_VEL_MAX_DN.get();
	_constraints.tilt = math::radians(MPC_TILTMAX_AIR.get());
	_constraints.landing_gear = vehicle_constraints_s::GEAR_KEEP;
	_constraints.min_distance_to_ground = NAN;
	_constraints.max_distance_to_ground = NAN;
}
<commit_msg>FlightTasks local position setpoint don't use copyRaw<commit_after>#include "FlightTask.hpp"
#include <mathlib/mathlib.h>
#include <lib/ecl/geo/geo.h>

constexpr uint64_t FlightTask::_timeout;
// First index of empty_setpoint corresponds to time-stamp and requires a finite number.
const vehicle_local_position_setpoint_s FlightTask::empty_setpoint = {0, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, {NAN, NAN, NAN}};
const vehicle_constraints_s FlightTask::empty_constraints = {0, NAN, NAN, NAN, NAN, NAN, NAN, NAN, vehicle_constraints_s::GEAR_KEEP, {}};
bool FlightTask::initializeSubscriptions(SubscriptionArray &subscription_array)
{
	if (!subscription_array.get(ORB_ID(vehicle_local_position), _sub_vehicle_local_position)) {
		return false;
	}

	if (!subscription_array.get(ORB_ID(vehicle_attitude), _sub_attitude)) {
		return false;
	}

	return true;
}

bool FlightTask::activate()
{
	_resetSetpoints();
	_setDefaultConstraints();
	_time_stamp_activate = hrt_absolute_time();
	_heading_reset_counter = _sub_attitude->get().quat_reset_counter;
	return true;
}

bool FlightTask::updateInitialize()
{
	_time_stamp_current = hrt_absolute_time();
	_time = (_time_stamp_current - _time_stamp_activate) / 1e6f;
	_deltatime  = math::min((_time_stamp_current - _time_stamp_last), _timeout) / 1e6f;
	_time_stamp_last = _time_stamp_current;
	return _evaluateVehicleLocalPosition();
}

const vehicle_local_position_setpoint_s FlightTask::getPositionSetpoint()
{
	/* fill position setpoint message */
	vehicle_local_position_setpoint_s vehicle_local_position_setpoint;
	vehicle_local_position_setpoint.timestamp = hrt_absolute_time();

	vehicle_local_position_setpoint.x = _position_setpoint(0);
	vehicle_local_position_setpoint.y = _position_setpoint(1);
	vehicle_local_position_setpoint.z = _position_setpoint(2);

	vehicle_local_position_setpoint.vx = _velocity_setpoint(0);
	vehicle_local_position_setpoint.vy = _velocity_setpoint(1);
	vehicle_local_position_setpoint.vz = _velocity_setpoint(2);

	vehicle_local_position_setpoint.acc_x = _acceleration_setpoint(0);
	vehicle_local_position_setpoint.acc_y = _acceleration_setpoint(1);
	vehicle_local_position_setpoint.acc_z = _acceleration_setpoint(2);

	_thrust_setpoint.copyTo(vehicle_local_position_setpoint.thrust);
	vehicle_local_position_setpoint.yaw = _yaw_setpoint;
	vehicle_local_position_setpoint.yawspeed = _yawspeed_setpoint;

	return vehicle_local_position_setpoint;
}

void FlightTask::_resetSetpoints()
{
	_position_setpoint *= NAN;
	_velocity_setpoint *= NAN;
	_acceleration_setpoint *= NAN;
	_thrust_setpoint *= NAN;
	_yaw_setpoint = _yawspeed_setpoint = NAN;
}

bool FlightTask::_evaluateVehicleLocalPosition()
{
	if ((_time_stamp_current - _sub_vehicle_local_position->get().timestamp) < _timeout) {

		// position
		if (_sub_vehicle_local_position->get().xy_valid) {
			_position(0) = _sub_vehicle_local_position->get().x;
			_position(1) = _sub_vehicle_local_position->get().y;

		} else {
			_position(0) = _position(1) = NAN;
		}

		if (_sub_vehicle_local_position->get().z_valid) {
			_position(2) = _sub_vehicle_local_position->get().z;

		} else {
			_position(2) = NAN;
		}

		// velocity
		if (_sub_vehicle_local_position->get().v_xy_valid) {
			_velocity(0) = _sub_vehicle_local_position->get().vx;
			_velocity(1) = _sub_vehicle_local_position->get().vy;

		} else {
			_velocity(0) = _velocity(1) = NAN;
		}

		if (_sub_vehicle_local_position->get().v_z_valid) {
			_velocity(2) = _sub_vehicle_local_position->get().vz;

		} else {
			_velocity(2) = NAN;
		}

		// yaw
		_yaw = _sub_vehicle_local_position->get().yaw;

		// distance to bottom
		_dist_to_bottom = NAN;

		if (_sub_vehicle_local_position->get().dist_bottom_valid
		    && PX4_ISFINITE(_sub_vehicle_local_position->get().dist_bottom)) {
			_dist_to_bottom =  _sub_vehicle_local_position->get().dist_bottom;
		}

		// global frame reference coordinates to enable conversions
		if (_sub_vehicle_local_position->get().xy_global && _sub_vehicle_local_position->get().z_global) {
			globallocalconverter_init(_sub_vehicle_local_position->get().ref_lat, _sub_vehicle_local_position->get().ref_lon,
						  _sub_vehicle_local_position->get().ref_alt, _sub_vehicle_local_position->get().ref_timestamp);
		}

		// We don't check here if states are valid or not.
		// Validity checks are done in the sub-classes.
		return true;

	} else {
		_resetSetpoints();
		return false;
	}
}

void FlightTask::_setDefaultConstraints()
{
	_constraints.speed_xy = MPC_XY_VEL_MAX.get();
	_constraints.speed_up = MPC_Z_VEL_MAX_UP.get();
	_constraints.speed_down = MPC_Z_VEL_MAX_DN.get();
	_constraints.tilt = math::radians(MPC_TILTMAX_AIR.get());
	_constraints.landing_gear = vehicle_constraints_s::GEAR_KEEP;
	_constraints.min_distance_to_ground = NAN;
	_constraints.max_distance_to_ground = NAN;
}
<|endoftext|>


<commit_before>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "QmitkApplicationCursor.h"

#include <qapplication.h>
#include <qcursor.h>
#include <qpixmap.h>

#include <iostream>

QmitkApplicationCursor::QmitkApplicationCursor()
{
  mitk::ApplicationCursor::RegisterImplementation(this);
}

void QmitkApplicationCursor::PushCursor(const char* XPM[], int hotspotX, int hotspotY)
{
  QPixmap pixmap( XPM );
  QCursor cursor( pixmap, hotspotX, hotspotY ); // no test for validity in QPixmap(xpm)!
  QApplication::setOverrideCursor( cursor );
}

void QmitkApplicationCursor::PopCursor()
{
  QApplication::restoreOverrideCursor();
}

const mitk::Point2I QmitkApplicationCursor::GetCursorPosition()
{
  mitk::Point2I mp;
  QPoint qp = QCursor::pos();
  mp[0] = qp.x();
  mp[1] = qp.y();
  return mp;
}

void QmitkApplicationCursor::SetCursorPosition(const mitk::Point2I& p)
{
  QCursor::setPos( p[0], p[1] );
}

<commit_msg>FIX (#3357): avoid infinite recursion<commit_after>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "QmitkApplicationCursor.h"

#include <qapplication.h>
#include <qcursor.h>
#include <qpixmap.h>

#include <iostream>

QmitkApplicationCursor::QmitkApplicationCursor()
{
  mitk::ApplicationCursor::RegisterImplementation(this);
}

void QmitkApplicationCursor::PushCursor(const char* XPM[], int hotspotX, int hotspotY)
{
  QPixmap pixmap( XPM );
  QCursor cursor( pixmap, hotspotX, hotspotY ); // no test for validity in QPixmap(xpm)!
  QApplication::setOverrideCursor( cursor );
}

void QmitkApplicationCursor::PopCursor()
{
  QApplication::restoreOverrideCursor();
}

const mitk::Point2I QmitkApplicationCursor::GetCursorPosition()
{
  mitk::Point2I mp;
  QPoint qp = QCursor::pos();
  mp[0] = qp.x();
  mp[1] = qp.y();
  return mp;
}

void QmitkApplicationCursor::SetCursorPosition(const mitk::Point2I& p)
{
  static bool selfCall = false;
  if (selfCall) return;  // this is to avoid recursive calls
  selfCall = true;
  QCursor::setPos( p[0], p[1] );
  selfCall = false;
}

<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2013 Petar Perisin <petar.perisin@gmail.com>
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "ansiescapecodehandler.h"
#include <utils/qtcassert.h>

namespace Utils {

/*!
    \class Utils::AnsiEscapeCodeHandler

    \brief The AnsiEscapeCodeHandler class parses text and extracts ANSI escape codes from it.

    In order to preserve color information across text segments, an instance of this class
    must be stored for the lifetime of a stream.
    Also, one instance of this class should not handle multiple streams (at least not
    at the same time).

    Its main method is parseText(), which accepts text and default QTextCharFormat.
    This method is designed to parse text and split colored text to smaller strings,
    with their appropriate formatting information set inside QTextCharFormat.

    Usage:
    \list
    \li Create new instance of AnsiEscapeCodeHandler for a stream.
    \li To add new text, call parseText() with the text and a default QTextCharFormat.
        The result of this method is a list of strings with formats set in appropriate
        QTextCharFormat.
    \endlist
*/

AnsiEscapeCodeHandler::AnsiEscapeCodeHandler() :
    m_previousFormatClosed(true)
{
}

static QColor ansiColor(uint code)
{
    QTC_ASSERT(code < 8, return QColor());

    const int red   = code & 1 ? 170 : 0;
    const int green = code & 2 ? 170 : 0;
    const int blue  = code & 4 ? 170 : 0;
    return QColor(red, green, blue);
}

QList<StringFormatPair> AnsiEscapeCodeHandler::parseText(const QString &text,
                                                         const QTextCharFormat &defaultFormat)
{
    QList<StringFormatPair> outputData;

    QTextCharFormat charFormat = m_previousFormatClosed ? defaultFormat : m_previousFormat;

    const QString escape = QLatin1Char(27) + QLatin1Char('[');
    if (!text.contains(escape)) {
        outputData << StringFormatPair(text, charFormat);
        return outputData;
    } else if (!text.startsWith(escape)) {
        outputData << StringFormatPair(text.left(text.indexOf(escape)), charFormat);
    }

    const QChar semicolon       = QLatin1Char(';');
    const QChar colorTerminator = QLatin1Char('m');
    // strippedText always starts with "\e["
    QString strippedText = text.mid(text.indexOf(escape));
    while (!strippedText.isEmpty()) {
        while (strippedText.startsWith(escape)) {
            strippedText.remove(0, 2);

            // get the number
            QString strNumber;
            QStringList numbers;
            while (strippedText.at(0).isDigit() || strippedText.at(0) == semicolon) {
                if (strippedText.at(0).isDigit()) {
                    strNumber += strippedText.at(0);
                } else {
                    numbers << strNumber;
                    strNumber.clear();
                }
                strippedText.remove(0, 1);
            }
            if (!strNumber.isEmpty())
                numbers << strNumber;

            // remove terminating char
            if (!strippedText.startsWith(colorTerminator)) {
                strippedText.remove(0, 1);
                continue;
            }
            strippedText.remove(0, 1);

            for (int i = 0; i < numbers.size(); ++i) {
                const int code = numbers.at(i).toInt();

                if (code >= TextColorStart && code <= TextColorEnd) {
                    charFormat.setForeground(ansiColor(code - TextColorStart));
                    setFormatScope(charFormat);
                } else if (code >= BackgroundColorStart && code <= BackgroundColorEnd) {
                    charFormat.setBackground(ansiColor(code - BackgroundColorStart));
                    setFormatScope(charFormat);
                } else {
                    switch (code) {
                    case ResetFormat:
                        charFormat = defaultFormat;
                        endFormatScope();
                        break;
                    case BoldText:
                        charFormat.setFontWeight(QFont::Bold);
                        setFormatScope(charFormat);
                        break;
                    case DefaultTextColor:
                        charFormat.setForeground(defaultFormat.foreground());
                        setFormatScope(charFormat);
                        break;
                    case DefaultBackgroundColor:
                        charFormat.setBackground(defaultFormat.background());
                        setFormatScope(charFormat);
                        break;
                    case RgbTextColor:
                    case RgbBackgroundColor:
                        if (++i >= numbers.size())
                            break;
                        if (numbers.at(i).toInt() == 2) {
                            // RGB set with format: 38;2;<r>;<g>;<b>
                            if ((i + 3) < numbers.size()) {
                                (code == RgbTextColor) ?
                                      charFormat.setForeground(QColor(numbers.at(i + 1).toInt(),
                                                                      numbers.at(i + 2).toInt(),
                                                                      numbers.at(i + 3).toInt())) :
                                      charFormat.setBackground(QColor(numbers.at(i + 1).toInt(),
                                                                      numbers.at(i + 2).toInt(),
                                                                      numbers.at(i + 3).toInt()));
                                setFormatScope(charFormat);
                            }
                            i += 3;
                        } else if (numbers.at(i).toInt() == 5) {
                            // rgb set with format: 38;5;<i>
                            // unsupported because of unclear documentation, so we just skip <i>
                            ++i;
                        }
                        break;
                    default:
                        break;
                    }
                }
            }
        }

        if (strippedText.isEmpty())
            break;
        int index = strippedText.indexOf(escape);
        if (index > 0) {
            outputData << StringFormatPair(strippedText.left(index), charFormat);
            strippedText.remove(0, index);
        } else if (index == -1) {
            outputData << StringFormatPair(strippedText, charFormat);
            break;
        }
    }
    return outputData;
}

void AnsiEscapeCodeHandler::endFormatScope()
{
    m_previousFormatClosed = true;
}

void AnsiEscapeCodeHandler::setFormatScope(const QTextCharFormat &charFormat)
{
    m_previousFormat = charFormat;
    m_previousFormatClosed = false;
}

} // namespace Utils
<commit_msg>Clear formatting if there is no number<commit_after>/****************************************************************************
**
** Copyright (C) 2013 Petar Perisin <petar.perisin@gmail.com>
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "ansiescapecodehandler.h"
#include <utils/qtcassert.h>

namespace Utils {

/*!
    \class Utils::AnsiEscapeCodeHandler

    \brief The AnsiEscapeCodeHandler class parses text and extracts ANSI escape codes from it.

    In order to preserve color information across text segments, an instance of this class
    must be stored for the lifetime of a stream.
    Also, one instance of this class should not handle multiple streams (at least not
    at the same time).

    Its main method is parseText(), which accepts text and default QTextCharFormat.
    This method is designed to parse text and split colored text to smaller strings,
    with their appropriate formatting information set inside QTextCharFormat.

    Usage:
    \list
    \li Create new instance of AnsiEscapeCodeHandler for a stream.
    \li To add new text, call parseText() with the text and a default QTextCharFormat.
        The result of this method is a list of strings with formats set in appropriate
        QTextCharFormat.
    \endlist
*/

AnsiEscapeCodeHandler::AnsiEscapeCodeHandler() :
    m_previousFormatClosed(true)
{
}

static QColor ansiColor(uint code)
{
    QTC_ASSERT(code < 8, return QColor());

    const int red   = code & 1 ? 170 : 0;
    const int green = code & 2 ? 170 : 0;
    const int blue  = code & 4 ? 170 : 0;
    return QColor(red, green, blue);
}

QList<StringFormatPair> AnsiEscapeCodeHandler::parseText(const QString &text,
                                                         const QTextCharFormat &defaultFormat)
{
    QList<StringFormatPair> outputData;

    QTextCharFormat charFormat = m_previousFormatClosed ? defaultFormat : m_previousFormat;

    const QString escape = QLatin1Char(27) + QLatin1Char('[');
    if (!text.contains(escape)) {
        outputData << StringFormatPair(text, charFormat);
        return outputData;
    } else if (!text.startsWith(escape)) {
        outputData << StringFormatPair(text.left(text.indexOf(escape)), charFormat);
    }

    const QChar semicolon       = QLatin1Char(';');
    const QChar colorTerminator = QLatin1Char('m');
    // strippedText always starts with "\e["
    QString strippedText = text.mid(text.indexOf(escape));
    while (!strippedText.isEmpty()) {
        while (strippedText.startsWith(escape)) {
            strippedText.remove(0, 2);

            // get the number
            QString strNumber;
            QStringList numbers;
            while (strippedText.at(0).isDigit() || strippedText.at(0) == semicolon) {
                if (strippedText.at(0).isDigit()) {
                    strNumber += strippedText.at(0);
                } else {
                    numbers << strNumber;
                    strNumber.clear();
                }
                strippedText.remove(0, 1);
            }
            if (!strNumber.isEmpty())
                numbers << strNumber;

            // remove terminating char
            if (!strippedText.startsWith(colorTerminator)) {
                strippedText.remove(0, 1);
                continue;
            }
            strippedText.remove(0, 1);

            if (numbers.isEmpty()) {
                charFormat = defaultFormat;
                endFormatScope();
            }

            for (int i = 0; i < numbers.size(); ++i) {
                const int code = numbers.at(i).toInt();

                if (code >= TextColorStart && code <= TextColorEnd) {
                    charFormat.setForeground(ansiColor(code - TextColorStart));
                    setFormatScope(charFormat);
                } else if (code >= BackgroundColorStart && code <= BackgroundColorEnd) {
                    charFormat.setBackground(ansiColor(code - BackgroundColorStart));
                    setFormatScope(charFormat);
                } else {
                    switch (code) {
                    case ResetFormat:
                        charFormat = defaultFormat;
                        endFormatScope();
                        break;
                    case BoldText:
                        charFormat.setFontWeight(QFont::Bold);
                        setFormatScope(charFormat);
                        break;
                    case DefaultTextColor:
                        charFormat.setForeground(defaultFormat.foreground());
                        setFormatScope(charFormat);
                        break;
                    case DefaultBackgroundColor:
                        charFormat.setBackground(defaultFormat.background());
                        setFormatScope(charFormat);
                        break;
                    case RgbTextColor:
                    case RgbBackgroundColor:
                        if (++i >= numbers.size())
                            break;
                        if (numbers.at(i).toInt() == 2) {
                            // RGB set with format: 38;2;<r>;<g>;<b>
                            if ((i + 3) < numbers.size()) {
                                (code == RgbTextColor) ?
                                      charFormat.setForeground(QColor(numbers.at(i + 1).toInt(),
                                                                      numbers.at(i + 2).toInt(),
                                                                      numbers.at(i + 3).toInt())) :
                                      charFormat.setBackground(QColor(numbers.at(i + 1).toInt(),
                                                                      numbers.at(i + 2).toInt(),
                                                                      numbers.at(i + 3).toInt()));
                                setFormatScope(charFormat);
                            }
                            i += 3;
                        } else if (numbers.at(i).toInt() == 5) {
                            // rgb set with format: 38;5;<i>
                            // unsupported because of unclear documentation, so we just skip <i>
                            ++i;
                        }
                        break;
                    default:
                        break;
                    }
                }
            }
        }

        if (strippedText.isEmpty())
            break;
        int index = strippedText.indexOf(escape);
        if (index > 0) {
            outputData << StringFormatPair(strippedText.left(index), charFormat);
            strippedText.remove(0, index);
        } else if (index == -1) {
            outputData << StringFormatPair(strippedText, charFormat);
            break;
        }
    }
    return outputData;
}

void AnsiEscapeCodeHandler::endFormatScope()
{
    m_previousFormatClosed = true;
}

void AnsiEscapeCodeHandler::setFormatScope(const QTextCharFormat &charFormat)
{
    m_previousFormat = charFormat;
    m_previousFormatClosed = false;
}

} // namespace Utils
<|endoftext|>


<commit_before>/*
 * 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 3 of the License, or
 * (at your option) any later version.
 *
 * Written (W) 2007-2008 Vojtech Franc
 * Written (W) 2007-2009 Soeren Sonnenburg
 * Copyright (C) 2007-2009 Fraunhofer Institute FIRST and Max-Planck-Society
 */

#include "features/Labels.h"
#include "lib/Mathematics.h"
#include "lib/Time.h"
#include "base/Parallel.h"
#include "classifier/LinearClassifier.h"
#include "classifier/svm/SVMOcas.h"
#include "classifier/svm/libocas.h"
#include "features/DotFeatures.h"
#include "features/Labels.h"

using namespace shogun;

CSVMOcas::CSVMOcas(E_SVM_TYPE type)
: CLinearClassifier(), use_bias(true), bufsize(3000), C1(1), C2(1),
	epsilon(1e-3), method(type)
{
	w=NULL;
	old_w=NULL;
}

CSVMOcas::CSVMOcas(
	float64_t C, CDotFeatures* traindat, CLabels* trainlab)
: CLinearClassifier(), use_bias(true), bufsize(3000), C1(C), C2(C),
	epsilon(1e-3)
{
	w=NULL;
	old_w=NULL;
	method=SVM_OCAS;
	set_features(traindat);
	set_labels(trainlab);
}

CSVMOcas::~CSVMOcas()
{
}

bool CSVMOcas::train(CFeatures* data)
{
	SG_INFO("C=%f, epsilon=%f, bufsize=%d\n", get_C1(), get_epsilon(), bufsize);
	SG_DEBUG("use_bias = %i\n", get_bias_enabled()) ;

	ASSERT(labels);
	if (data)
	{
		if (!data->has_property(FP_DOT))
			SG_ERROR("Specified features are not of type CDotFeatures\n");
		set_features((CDotFeatures*) data);
	}
	ASSERT(features);
	ASSERT(labels->is_two_class_labeling());

	int32_t num_train_labels=0;
	lab=labels->get_labels(num_train_labels);
	w_dim=features->get_dim_feature_space();
	int32_t num_vec=features->get_num_vectors();

	ASSERT(num_vec==num_train_labels);
	ASSERT(num_vec>0);

	delete[] w;
	w=new float64_t[w_dim];
	memset(w, 0, w_dim*sizeof(float64_t));

	delete[] old_w;
	old_w=new float64_t[w_dim];
	memset(old_w, 0, w_dim*sizeof(float64_t));
	bias=0;
	old_bias=0;

	tmp_a_buf=new float64_t[w_dim];
	cp_value=new float64_t*[bufsize];
	cp_index=new uint32_t*[bufsize];
	cp_nz_dims=new uint32_t[bufsize];
	cp_bias=new float64_t[bufsize];
	memset(cp_bias, 0, sizeof(float64_t)*bufsize);

	float64_t TolAbs=0;
	float64_t QPBound=0;
	int32_t Method=0;
	if (method == SVM_OCAS)
		Method = 1;
	ocas_return_value_T result = svm_ocas_solver( get_C1(), num_vec, get_epsilon(),
			TolAbs, QPBound, bufsize, Method,
			&CSVMOcas::compute_W,
			&CSVMOcas::update_W,
			&CSVMOcas::add_new_cut,
			&CSVMOcas::compute_output,
			&CSVMOcas::sort,
			this);

	SG_INFO("Ocas Converged after %d iterations\n"
			"==================================\n"
			"timing statistics:\n"
			"output_time: %f s\n"
			"sort_time: %f s\n"
			"add_time: %f s\n"
			"w_time: %f s\n"
			"solver_time %f s\n"
			"ocas_time %f s\n\n", result.nIter, result.output_time, result.sort_time,
			result.add_time, result.w_time, result.solver_time, result.ocas_time);

	delete[] tmp_a_buf;

	uint32_t num_cut_planes = result.nCutPlanes;

	for (uint32_t i=0; i<num_cut_planes; i++)
	{
		delete[] cp_value[i];
		delete[] cp_index[i];
	}

	delete[] cp_value;
	cp_value=NULL;
	delete[] cp_index;
	cp_index=NULL;
	delete[] cp_nz_dims;
	cp_nz_dims=NULL;
	delete[] cp_bias;
	cp_bias=NULL;

	delete[] lab;
	lab=NULL;

	delete[] old_w;
	old_w=NULL;

	return true;
}

/*----------------------------------------------------------------------------------
  sq_norm_W = sparse_update_W( t ) does the following:

  W = oldW*(1-t) + t*W;
  sq_norm_W = W'*W;

  ---------------------------------------------------------------------------------*/
float64_t CSVMOcas::update_W( float64_t t, void* ptr )
{
  float64_t sq_norm_W = 0;
  CSVMOcas* o = (CSVMOcas*) ptr;
  uint32_t nDim = (uint32_t) o->w_dim;
  float64_t* W=o->w;
  float64_t* oldW=o->old_w;

  for(uint32_t j=0; j <nDim; j++)
  {
	  W[j] = oldW[j]*(1-t) + t*W[j];
	  sq_norm_W += W[j]*W[j];
  }
  o->bias=o->old_bias*(1-t) + t*o->bias;
  sq_norm_W += CMath::sq(o->bias);

  return( sq_norm_W );
}

/*----------------------------------------------------------------------------------
  sparse_add_new_cut( new_col_H, new_cut, cut_length, nSel ) does the following:

    new_a = sum(data_X(:,find(new_cut ~=0 )),2);
    new_col_H = [sparse_A(:,1:nSel)'*new_a ; new_a'*new_a];
    sparse_A(:,nSel+1) = new_a;

  ---------------------------------------------------------------------------------*/
void CSVMOcas::add_new_cut(
	float64_t *new_col_H, uint32_t *new_cut, uint32_t cut_length,
	uint32_t nSel, void* ptr)
{
	CSVMOcas* o = (CSVMOcas*) ptr;
	CDotFeatures* f = o->features;
	uint32_t nDim=(uint32_t) o->w_dim;
	float64_t* y = o->lab;

	float64_t** c_val = o->cp_value;
	uint32_t** c_idx = o->cp_index;
	uint32_t* c_nzd = o->cp_nz_dims;
	float64_t* c_bias = o->cp_bias;

	float64_t sq_norm_a;
	uint32_t i, j, nz_dims;

	/* temporary vector */
	float64_t* new_a = o->tmp_a_buf;
	memset(new_a, 0, sizeof(float64_t)*nDim);

	for(i=0; i < cut_length; i++)
	{
		f->add_to_dense_vec(y[new_cut[i]], new_cut[i], new_a, nDim);

		if (o->use_bias)
			c_bias[nSel]+=y[new_cut[i]];
	}

	/* compute new_a'*new_a and count number of non-zerou dimensions */
	nz_dims = 0;
	sq_norm_a = CMath::sq(c_bias[nSel]);
	for(j=0; j < nDim; j++ ) {
		if(new_a[j] != 0) {
			nz_dims++;
			sq_norm_a += new_a[j]*new_a[j];
		}
	}

	/* sparsify new_a and insert it to the last column of sparse_A */
	c_nzd[nSel] = nz_dims;
	if(nz_dims > 0)
	{
		c_idx[nSel]=new uint32_t[nz_dims];
		c_val[nSel]=new float64_t[nz_dims];

		uint32_t idx=0;
		for(j=0; j < nDim; j++ )
		{
			if(new_a[j] != 0)
			{
				c_idx[nSel][idx] = j;
				c_val[nSel][idx++] = new_a[j];
			}
		}
	}

	new_col_H[nSel] = sq_norm_a;

	for(i=0; i < nSel; i++)
	{
		float64_t tmp = c_bias[nSel]*c_bias[i];
		for(j=0; j < c_nzd[i]; j++)
			tmp += new_a[c_idx[i][j]]*c_val[i][j];

		new_col_H[i] = tmp;
	}
	//CMath::display_vector(new_col_H, nSel+1, "new_col_H");
	//CMath::display_vector((int32_t*) c_idx[nSel], (int32_t) nz_dims, "c_idx");
	//CMath::display_vector((float64_t*) c_val[nSel], nz_dims, "c_val");
}

void CSVMOcas::sort(float64_t* vals, uint32_t* idx, uint32_t size)
{
	CMath::qsort_index(vals, idx, size);
}

/*----------------------------------------------------------------------
  sparse_compute_output( output ) does the follwing:

  output = data_X'*W;
  ----------------------------------------------------------------------*/
void CSVMOcas::compute_output(float64_t *output, void* ptr)
{
	CSVMOcas* o = (CSVMOcas*) ptr;
	CDotFeatures* f=o->features;
	int32_t nData=f->get_num_vectors();

	float64_t* y = o->lab;

	f->dense_dot_range(output, 0, nData, y, o->w, o->w_dim, 0.0);

	for (int32_t i=0; i<nData; i++)
		output[i]+=y[i]*o->bias;
	//CMath::display_vector(o->w, o->w_dim, "w");
	//CMath::display_vector(output, nData, "out");
}

/*----------------------------------------------------------------------
  sq_norm_W = compute_W( alpha, nSel ) does the following:

  oldW = W;
  W = sparse_A(:,1:nSel)'*alpha;
  sq_norm_W = W'*W;
  dp_WoldW = W'*oldW';

  ----------------------------------------------------------------------*/
void CSVMOcas::compute_W(
	float64_t *sq_norm_W, float64_t *dp_WoldW, float64_t *alpha, uint32_t nSel,
	void* ptr )
{
	CSVMOcas* o = (CSVMOcas*) ptr;
	uint32_t nDim= (uint32_t) o->w_dim;
	CMath::swap(o->w, o->old_w);
	float64_t* W=o->w;
	float64_t* oldW=o->old_w;
	memset(W, 0, sizeof(float64_t)*nDim);
	float64_t old_bias=o->bias;
	float64_t bias=0;

	float64_t** c_val = o->cp_value;
	uint32_t** c_idx = o->cp_index;
	uint32_t* c_nzd = o->cp_nz_dims;
	float64_t* c_bias = o->cp_bias;

	for(uint32_t i=0; i<nSel; i++)
	{
		uint32_t nz_dims = c_nzd[i];

		if(nz_dims > 0 && alpha[i] > 0)
		{
			for(uint32_t j=0; j < nz_dims; j++)
				W[c_idx[i][j]] += alpha[i]*c_val[i][j];
		}
		bias += c_bias[i]*alpha[i];
	}

	*sq_norm_W = CMath::dot(W,W, nDim) + CMath::sq(bias);
	*dp_WoldW = CMath::dot(W,oldW, nDim) + bias*old_bias;
	//SG_PRINT("nSel=%d sq_norm_W=%f dp_WoldW=%f\n", nSel, *sq_norm_W, *dp_WoldW);

	o->bias = bias;
	o->old_bias = old_bias;
}
<commit_msg>potentially fix crasher in svmocas (reported by yaroslav)<commit_after>/*
 * 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 3 of the License, or
 * (at your option) any later version.
 *
 * Written (W) 2007-2008 Vojtech Franc
 * Written (W) 2007-2009 Soeren Sonnenburg
 * Copyright (C) 2007-2009 Fraunhofer Institute FIRST and Max-Planck-Society
 */

#include "features/Labels.h"
#include "lib/Mathematics.h"
#include "lib/Time.h"
#include "base/Parallel.h"
#include "classifier/LinearClassifier.h"
#include "classifier/svm/SVMOcas.h"
#include "classifier/svm/libocas.h"
#include "features/DotFeatures.h"
#include "features/Labels.h"

using namespace shogun;

CSVMOcas::CSVMOcas(E_SVM_TYPE type)
: CLinearClassifier(), use_bias(true), bufsize(3000), C1(1), C2(1),
	epsilon(1e-3), method(type)
{
	w=NULL;
	old_w=NULL;
}

CSVMOcas::CSVMOcas(
	float64_t C, CDotFeatures* traindat, CLabels* trainlab)
: CLinearClassifier(), use_bias(true), bufsize(3000), C1(C), C2(C),
	epsilon(1e-3)
{
	w=NULL;
	old_w=NULL;
	method=SVM_OCAS;
	set_features(traindat);
	set_labels(trainlab);
}

CSVMOcas::~CSVMOcas()
{
}

bool CSVMOcas::train(CFeatures* data)
{
	SG_INFO("C=%f, epsilon=%f, bufsize=%d\n", get_C1(), get_epsilon(), bufsize);
	SG_DEBUG("use_bias = %i\n", get_bias_enabled()) ;

	ASSERT(labels);
	if (data)
	{
		if (!data->has_property(FP_DOT))
			SG_ERROR("Specified features are not of type CDotFeatures\n");
		set_features((CDotFeatures*) data);
	}
	ASSERT(features);
	ASSERT(labels->is_two_class_labeling());

	int32_t num_train_labels=0;
	lab=labels->get_labels(num_train_labels);
	w_dim=features->get_dim_feature_space();
	int32_t num_vec=features->get_num_vectors();

	ASSERT(num_vec==num_train_labels);
	ASSERT(num_vec>0);

	delete[] w;
	w=new float64_t[w_dim];
	memset(w, 0, w_dim*sizeof(float64_t));

	delete[] old_w;
	old_w=new float64_t[w_dim];
	memset(old_w, 0, w_dim*sizeof(float64_t));
	bias=0;
	old_bias=0;

	tmp_a_buf=new float64_t[w_dim];
	cp_value=new float64_t*[bufsize];
	memset(cp_value, sizeof(float64_t*)*bufsize, 0);
	cp_index=new uint32_t*[bufsize];
	memset(cp_index, sizeof(float64_t*)*bufsize, 0);
	cp_nz_dims=new uint32_t[bufsize];
	cp_bias=new float64_t[bufsize];
	memset(cp_bias, 0, sizeof(float64_t)*bufsize);

	float64_t TolAbs=0;
	float64_t QPBound=0;
	int32_t Method=0;
	if (method == SVM_OCAS)
		Method = 1;
	ocas_return_value_T result = svm_ocas_solver( get_C1(), num_vec, get_epsilon(),
			TolAbs, QPBound, bufsize, Method,
			&CSVMOcas::compute_W,
			&CSVMOcas::update_W,
			&CSVMOcas::add_new_cut,
			&CSVMOcas::compute_output,
			&CSVMOcas::sort,
			this);

	SG_INFO("Ocas Converged after %d iterations\n"
			"==================================\n"
			"timing statistics:\n"
			"output_time: %f s\n"
			"sort_time: %f s\n"
			"add_time: %f s\n"
			"w_time: %f s\n"
			"solver_time %f s\n"
			"ocas_time %f s\n\n", result.nIter, result.output_time, result.sort_time,
			result.add_time, result.w_time, result.solver_time, result.ocas_time);

	delete[] tmp_a_buf;

	uint32_t num_cut_planes = result.nCutPlanes;

	for (uint32_t i=0; i<num_cut_planes; i++)
	{
		delete[] cp_value[i];
		delete[] cp_index[i];
	}

	delete[] cp_value;
	cp_value=NULL;
	delete[] cp_index;
	cp_index=NULL;
	delete[] cp_nz_dims;
	cp_nz_dims=NULL;
	delete[] cp_bias;
	cp_bias=NULL;

	delete[] lab;
	lab=NULL;

	delete[] old_w;
	old_w=NULL;

	return true;
}

/*----------------------------------------------------------------------------------
  sq_norm_W = sparse_update_W( t ) does the following:

  W = oldW*(1-t) + t*W;
  sq_norm_W = W'*W;

  ---------------------------------------------------------------------------------*/
float64_t CSVMOcas::update_W( float64_t t, void* ptr )
{
  float64_t sq_norm_W = 0;
  CSVMOcas* o = (CSVMOcas*) ptr;
  uint32_t nDim = (uint32_t) o->w_dim;
  float64_t* W=o->w;
  float64_t* oldW=o->old_w;

  for(uint32_t j=0; j <nDim; j++)
  {
	  W[j] = oldW[j]*(1-t) + t*W[j];
	  sq_norm_W += W[j]*W[j];
  }
  o->bias=o->old_bias*(1-t) + t*o->bias;
  sq_norm_W += CMath::sq(o->bias);

  return( sq_norm_W );
}

/*----------------------------------------------------------------------------------
  sparse_add_new_cut( new_col_H, new_cut, cut_length, nSel ) does the following:

    new_a = sum(data_X(:,find(new_cut ~=0 )),2);
    new_col_H = [sparse_A(:,1:nSel)'*new_a ; new_a'*new_a];
    sparse_A(:,nSel+1) = new_a;

  ---------------------------------------------------------------------------------*/
void CSVMOcas::add_new_cut(
	float64_t *new_col_H, uint32_t *new_cut, uint32_t cut_length,
	uint32_t nSel, void* ptr)
{
	CSVMOcas* o = (CSVMOcas*) ptr;
	CDotFeatures* f = o->features;
	uint32_t nDim=(uint32_t) o->w_dim;
	float64_t* y = o->lab;

	float64_t** c_val = o->cp_value;
	uint32_t** c_idx = o->cp_index;
	uint32_t* c_nzd = o->cp_nz_dims;
	float64_t* c_bias = o->cp_bias;

	float64_t sq_norm_a;
	uint32_t i, j, nz_dims;

	/* temporary vector */
	float64_t* new_a = o->tmp_a_buf;
	memset(new_a, 0, sizeof(float64_t)*nDim);

	for(i=0; i < cut_length; i++)
	{
		f->add_to_dense_vec(y[new_cut[i]], new_cut[i], new_a, nDim);

		if (o->use_bias)
			c_bias[nSel]+=y[new_cut[i]];
	}

	/* compute new_a'*new_a and count number of non-zerou dimensions */
	nz_dims = 0;
	sq_norm_a = CMath::sq(c_bias[nSel]);
	for(j=0; j < nDim; j++ ) {
		if(new_a[j] != 0) {
			nz_dims++;
			sq_norm_a += new_a[j]*new_a[j];
		}
	}

	/* sparsify new_a and insert it to the last column of sparse_A */
	c_nzd[nSel] = nz_dims;
	if(nz_dims > 0)
	{
		c_idx[nSel]=new uint32_t[nz_dims];
		c_val[nSel]=new float64_t[nz_dims];

		uint32_t idx=0;
		for(j=0; j < nDim; j++ )
		{
			if(new_a[j] != 0)
			{
				c_idx[nSel][idx] = j;
				c_val[nSel][idx++] = new_a[j];
			}
		}
	}

	new_col_H[nSel] = sq_norm_a;

	for(i=0; i < nSel; i++)
	{
		float64_t tmp = c_bias[nSel]*c_bias[i];
		for(j=0; j < c_nzd[i]; j++)
			tmp += new_a[c_idx[i][j]]*c_val[i][j];

		new_col_H[i] = tmp;
	}
	//CMath::display_vector(new_col_H, nSel+1, "new_col_H");
	//CMath::display_vector((int32_t*) c_idx[nSel], (int32_t) nz_dims, "c_idx");
	//CMath::display_vector((float64_t*) c_val[nSel], nz_dims, "c_val");
}

void CSVMOcas::sort(float64_t* vals, uint32_t* idx, uint32_t size)
{
	CMath::qsort_index(vals, idx, size);
}

/*----------------------------------------------------------------------
  sparse_compute_output( output ) does the follwing:

  output = data_X'*W;
  ----------------------------------------------------------------------*/
void CSVMOcas::compute_output(float64_t *output, void* ptr)
{
	CSVMOcas* o = (CSVMOcas*) ptr;
	CDotFeatures* f=o->features;
	int32_t nData=f->get_num_vectors();

	float64_t* y = o->lab;

	f->dense_dot_range(output, 0, nData, y, o->w, o->w_dim, 0.0);

	for (int32_t i=0; i<nData; i++)
		output[i]+=y[i]*o->bias;
	//CMath::display_vector(o->w, o->w_dim, "w");
	//CMath::display_vector(output, nData, "out");
}

/*----------------------------------------------------------------------
  sq_norm_W = compute_W( alpha, nSel ) does the following:

  oldW = W;
  W = sparse_A(:,1:nSel)'*alpha;
  sq_norm_W = W'*W;
  dp_WoldW = W'*oldW';

  ----------------------------------------------------------------------*/
void CSVMOcas::compute_W(
	float64_t *sq_norm_W, float64_t *dp_WoldW, float64_t *alpha, uint32_t nSel,
	void* ptr )
{
	CSVMOcas* o = (CSVMOcas*) ptr;
	uint32_t nDim= (uint32_t) o->w_dim;
	CMath::swap(o->w, o->old_w);
	float64_t* W=o->w;
	float64_t* oldW=o->old_w;
	memset(W, 0, sizeof(float64_t)*nDim);
	float64_t old_bias=o->bias;
	float64_t bias=0;

	float64_t** c_val = o->cp_value;
	uint32_t** c_idx = o->cp_index;
	uint32_t* c_nzd = o->cp_nz_dims;
	float64_t* c_bias = o->cp_bias;

	for(uint32_t i=0; i<nSel; i++)
	{
		uint32_t nz_dims = c_nzd[i];

		if(nz_dims > 0 && alpha[i] > 0)
		{
			for(uint32_t j=0; j < nz_dims; j++)
				W[c_idx[i][j]] += alpha[i]*c_val[i][j];
		}
		bias += c_bias[i]*alpha[i];
	}

	*sq_norm_W = CMath::dot(W,W, nDim) + CMath::sq(bias);
	*dp_WoldW = CMath::dot(W,oldW, nDim) + bias*old_bias;
	//SG_PRINT("nSel=%d sq_norm_W=%f dp_WoldW=%f\n", nSel, *sq_norm_W, *dp_WoldW);

	o->bias = bias;
	o->old_bias = old_bias;
}
<|endoftext|>